]> rtime.felk.cvut.cz Git - can-eth-gw-linux.git/blob - sound/pci/hda/patch_analog.c
ARM: davinci: da850: generate dtbs for da850 boards
[can-eth-gw-linux.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                 info->name = "AD198x Digital";
549                 info->pcm_type = HDA_PCM_TYPE_SPDIF;
550                 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad198x_pcm_digital_playback;
551                 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
552                 if (spec->dig_in_nid) {
553                         info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad198x_pcm_digital_capture;
554                         info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
555                 }
556         }
557
558         if (spec->alt_dac_nid && spec->stream_analog_alt_playback) {
559                 codec->num_pcms++;
560                 info = spec->pcm_rec + 2;
561                 info->name = "AD198x Headphone";
562                 info->pcm_type = HDA_PCM_TYPE_AUDIO;
563                 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
564                         *spec->stream_analog_alt_playback;
565                 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
566                         spec->alt_dac_nid[0];
567         }
568
569         return 0;
570 }
571
572 static void ad198x_free_kctls(struct hda_codec *codec)
573 {
574         struct ad198x_spec *spec = codec->spec;
575
576         if (spec->kctls.list) {
577                 struct snd_kcontrol_new *kctl = spec->kctls.list;
578                 int i;
579                 for (i = 0; i < spec->kctls.used; i++)
580                         kfree(kctl[i].name);
581         }
582         snd_array_free(&spec->kctls);
583 }
584
585 static void ad198x_power_eapd_write(struct hda_codec *codec, hda_nid_t front,
586                                 hda_nid_t hp)
587 {
588         struct ad198x_spec *spec = codec->spec;
589         if (snd_hda_query_pin_caps(codec, front) & AC_PINCAP_EAPD)
590                 snd_hda_codec_write(codec, front, 0, AC_VERB_SET_EAPD_BTLENABLE,
591                             !spec->inv_eapd ? 0x00 : 0x02);
592         if (snd_hda_query_pin_caps(codec, hp) & AC_PINCAP_EAPD)
593                 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_EAPD_BTLENABLE,
594                             !spec->inv_eapd ? 0x00 : 0x02);
595 }
596
597 static void ad198x_power_eapd(struct hda_codec *codec)
598 {
599         /* We currently only handle front, HP */
600         switch (codec->vendor_id) {
601         case 0x11d41882:
602         case 0x11d4882a:
603         case 0x11d41884:
604         case 0x11d41984:
605         case 0x11d41883:
606         case 0x11d4184a:
607         case 0x11d4194a:
608         case 0x11d4194b:
609         case 0x11d41988:
610         case 0x11d4198b:
611         case 0x11d4989a:
612         case 0x11d4989b:
613                 ad198x_power_eapd_write(codec, 0x12, 0x11);
614                 break;
615         case 0x11d41981:
616         case 0x11d41983:
617                 ad198x_power_eapd_write(codec, 0x05, 0x06);
618                 break;
619         case 0x11d41986:
620                 ad198x_power_eapd_write(codec, 0x1b, 0x1a);
621                 break;
622         }
623 }
624
625 static void ad198x_shutup(struct hda_codec *codec)
626 {
627         snd_hda_shutup_pins(codec);
628         ad198x_power_eapd(codec);
629 }
630
631 static void ad198x_free(struct hda_codec *codec)
632 {
633         struct ad198x_spec *spec = codec->spec;
634
635         if (!spec)
636                 return;
637
638         ad198x_shutup(codec);
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 patch_ad1986a(struct hda_codec *codec)
1250 {
1251         struct ad198x_spec *spec;
1252         int err, board_config;
1253
1254         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1255         if (spec == NULL)
1256                 return -ENOMEM;
1257
1258         codec->spec = spec;
1259
1260         err = snd_hda_attach_beep_device(codec, 0x19);
1261         if (err < 0) {
1262                 ad198x_free(codec);
1263                 return err;
1264         }
1265         set_beep_amp(spec, 0x18, 0, HDA_OUTPUT);
1266
1267         spec->multiout.max_channels = 6;
1268         spec->multiout.num_dacs = ARRAY_SIZE(ad1986a_dac_nids);
1269         spec->multiout.dac_nids = ad1986a_dac_nids;
1270         spec->multiout.dig_out_nid = AD1986A_SPDIF_OUT;
1271         spec->num_adc_nids = 1;
1272         spec->adc_nids = ad1986a_adc_nids;
1273         spec->capsrc_nids = ad1986a_capsrc_nids;
1274         spec->input_mux = &ad1986a_capture_source;
1275         spec->num_mixers = 1;
1276         spec->mixers[0] = ad1986a_mixers;
1277         spec->num_init_verbs = 1;
1278         spec->init_verbs[0] = ad1986a_init_verbs;
1279 #ifdef CONFIG_PM
1280         spec->loopback.amplist = ad1986a_loopbacks;
1281 #endif
1282         spec->vmaster_nid = 0x1b;
1283         spec->inv_eapd = 1; /* AD1986A has the inverted EAPD implementation */
1284
1285         codec->patch_ops = ad198x_patch_ops;
1286
1287         /* override some parameters */
1288         board_config = snd_hda_check_board_config(codec, AD1986A_MODELS,
1289                                                   ad1986a_models,
1290                                                   ad1986a_cfg_tbl);
1291         switch (board_config) {
1292         case AD1986A_3STACK:
1293                 spec->num_mixers = 2;
1294                 spec->mixers[1] = ad1986a_3st_mixers;
1295                 spec->num_init_verbs = 2;
1296                 spec->init_verbs[1] = ad1986a_ch2_init;
1297                 spec->channel_mode = ad1986a_modes;
1298                 spec->num_channel_mode = ARRAY_SIZE(ad1986a_modes);
1299                 spec->need_dac_fix = 1;
1300                 spec->multiout.max_channels = 2;
1301                 spec->multiout.num_dacs = 1;
1302                 break;
1303         case AD1986A_LAPTOP:
1304                 spec->mixers[0] = ad1986a_laptop_mixers;
1305                 spec->multiout.max_channels = 2;
1306                 spec->multiout.num_dacs = 1;
1307                 spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
1308                 break;
1309         case AD1986A_LAPTOP_EAPD:
1310                 spec->num_mixers = 3;
1311                 spec->mixers[0] = ad1986a_laptop_master_mixers;
1312                 spec->mixers[1] = ad1986a_laptop_eapd_mixers;
1313                 spec->mixers[2] = ad1986a_laptop_intmic_mixers;
1314                 spec->num_init_verbs = 2;
1315                 spec->init_verbs[1] = ad1986a_eapd_init_verbs;
1316                 spec->multiout.max_channels = 2;
1317                 spec->multiout.num_dacs = 1;
1318                 spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
1319                 if (!is_jack_available(codec, 0x25))
1320                         spec->multiout.dig_out_nid = 0;
1321                 spec->input_mux = &ad1986a_laptop_eapd_capture_source;
1322                 break;
1323         case AD1986A_SAMSUNG:
1324                 spec->num_mixers = 2;
1325                 spec->mixers[0] = ad1986a_laptop_master_mixers;
1326                 spec->mixers[1] = ad1986a_laptop_eapd_mixers;
1327                 spec->num_init_verbs = 3;
1328                 spec->init_verbs[1] = ad1986a_eapd_init_verbs;
1329                 spec->init_verbs[2] = ad1986a_automic_verbs;
1330                 spec->multiout.max_channels = 2;
1331                 spec->multiout.num_dacs = 1;
1332                 spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
1333                 if (!is_jack_available(codec, 0x25))
1334                         spec->multiout.dig_out_nid = 0;
1335                 spec->input_mux = &ad1986a_automic_capture_source;
1336                 codec->patch_ops.unsol_event = ad1986a_automic_unsol_event;
1337                 codec->patch_ops.init = ad1986a_automic_init;
1338                 break;
1339         case AD1986A_SAMSUNG_P50:
1340                 spec->num_mixers = 2;
1341                 spec->mixers[0] = ad1986a_automute_master_mixers;
1342                 spec->mixers[1] = ad1986a_laptop_eapd_mixers;
1343                 spec->num_init_verbs = 4;
1344                 spec->init_verbs[1] = ad1986a_eapd_init_verbs;
1345                 spec->init_verbs[2] = ad1986a_automic_verbs;
1346                 spec->init_verbs[3] = ad1986a_hp_init_verbs;
1347                 spec->multiout.max_channels = 2;
1348                 spec->multiout.num_dacs = 1;
1349                 spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
1350                 if (!is_jack_available(codec, 0x25))
1351                         spec->multiout.dig_out_nid = 0;
1352                 spec->input_mux = &ad1986a_automic_capture_source;
1353                 codec->patch_ops.unsol_event = ad1986a_samsung_p50_unsol_event;
1354                 codec->patch_ops.init = ad1986a_samsung_p50_init;
1355                 break;
1356         case AD1986A_LAPTOP_AUTOMUTE:
1357                 spec->num_mixers = 3;
1358                 spec->mixers[0] = ad1986a_automute_master_mixers;
1359                 spec->mixers[1] = ad1986a_laptop_eapd_mixers;
1360                 spec->mixers[2] = ad1986a_laptop_intmic_mixers;
1361                 spec->num_init_verbs = 3;
1362                 spec->init_verbs[1] = ad1986a_eapd_init_verbs;
1363                 spec->init_verbs[2] = ad1986a_hp_init_verbs;
1364                 spec->multiout.max_channels = 2;
1365                 spec->multiout.num_dacs = 1;
1366                 spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
1367                 if (!is_jack_available(codec, 0x25))
1368                         spec->multiout.dig_out_nid = 0;
1369                 spec->input_mux = &ad1986a_laptop_eapd_capture_source;
1370                 codec->patch_ops.unsol_event = ad1986a_hp_unsol_event;
1371                 codec->patch_ops.init = ad1986a_hp_init;
1372                 /* Lenovo N100 seems to report the reversed bit
1373                  * for HP jack-sensing
1374                  */
1375                 spec->inv_jack_detect = 1;
1376                 break;
1377         case AD1986A_ULTRA:
1378                 spec->mixers[0] = ad1986a_laptop_eapd_mixers;
1379                 spec->num_init_verbs = 2;
1380                 spec->init_verbs[1] = ad1986a_ultra_init;
1381                 spec->multiout.max_channels = 2;
1382                 spec->multiout.num_dacs = 1;
1383                 spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
1384                 spec->multiout.dig_out_nid = 0;
1385                 break;
1386         }
1387
1388         /* AD1986A has a hardware problem that it can't share a stream
1389          * with multiple output pins.  The copy of front to surrounds
1390          * causes noisy or silent outputs at a certain timing, e.g.
1391          * changing the volume.
1392          * So, let's disable the shared stream.
1393          */
1394         spec->multiout.no_share_stream = 1;
1395
1396         codec->no_trigger_sense = 1;
1397         codec->no_sticky_stream = 1;
1398
1399         return 0;
1400 }
1401
1402 /*
1403  * AD1983 specific
1404  */
1405
1406 #define AD1983_SPDIF_OUT        0x02
1407 #define AD1983_DAC              0x03
1408 #define AD1983_ADC              0x04
1409
1410 static const hda_nid_t ad1983_dac_nids[1] = { AD1983_DAC };
1411 static const hda_nid_t ad1983_adc_nids[1] = { AD1983_ADC };
1412 static const hda_nid_t ad1983_capsrc_nids[1] = { 0x15 };
1413
1414 static const struct hda_input_mux ad1983_capture_source = {
1415         .num_items = 4,
1416         .items = {
1417                 { "Mic", 0x0 },
1418                 { "Line", 0x1 },
1419                 { "Mix", 0x2 },
1420                 { "Mix Mono", 0x3 },
1421         },
1422 };
1423
1424 /*
1425  * SPDIF playback route
1426  */
1427 static int ad1983_spdif_route_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1428 {
1429         static const char * const texts[] = { "PCM", "ADC" };
1430
1431         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1432         uinfo->count = 1;
1433         uinfo->value.enumerated.items = 2;
1434         if (uinfo->value.enumerated.item > 1)
1435                 uinfo->value.enumerated.item = 1;
1436         strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1437         return 0;
1438 }
1439
1440 static int ad1983_spdif_route_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1441 {
1442         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1443         struct ad198x_spec *spec = codec->spec;
1444
1445         ucontrol->value.enumerated.item[0] = spec->spdif_route;
1446         return 0;
1447 }
1448
1449 static int ad1983_spdif_route_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1450 {
1451         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1452         struct ad198x_spec *spec = codec->spec;
1453
1454         if (ucontrol->value.enumerated.item[0] > 1)
1455                 return -EINVAL;
1456         if (spec->spdif_route != ucontrol->value.enumerated.item[0]) {
1457                 spec->spdif_route = ucontrol->value.enumerated.item[0];
1458                 snd_hda_codec_write_cache(codec, spec->multiout.dig_out_nid, 0,
1459                                           AC_VERB_SET_CONNECT_SEL,
1460                                           spec->spdif_route);
1461                 return 1;
1462         }
1463         return 0;
1464 }
1465
1466 static const struct snd_kcontrol_new ad1983_mixers[] = {
1467         HDA_CODEC_VOLUME("Front Playback Volume", 0x05, 0x0, HDA_OUTPUT),
1468         HDA_CODEC_MUTE("Front Playback Switch", 0x05, 0x0, HDA_OUTPUT),
1469         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x06, 0x0, HDA_OUTPUT),
1470         HDA_CODEC_MUTE("Headphone Playback Switch", 0x06, 0x0, HDA_OUTPUT),
1471         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x07, 1, 0x0, HDA_OUTPUT),
1472         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x07, 1, 0x0, HDA_OUTPUT),
1473         HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
1474         HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT),
1475         HDA_CODEC_VOLUME("Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
1476         HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
1477         HDA_CODEC_VOLUME("Line Playback Volume", 0x13, 0x0, HDA_OUTPUT),
1478         HDA_CODEC_MUTE("Line Playback Switch", 0x13, 0x0, HDA_OUTPUT),
1479         HDA_CODEC_VOLUME("Mic Boost Volume", 0x0c, 0x0, HDA_OUTPUT),
1480         HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
1481         HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
1482         {
1483                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1484                 .name = "Capture Source",
1485                 .info = ad198x_mux_enum_info,
1486                 .get = ad198x_mux_enum_get,
1487                 .put = ad198x_mux_enum_put,
1488         },
1489         {
1490                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1491                 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
1492                 .info = ad1983_spdif_route_info,
1493                 .get = ad1983_spdif_route_get,
1494                 .put = ad1983_spdif_route_put,
1495         },
1496         { } /* end */
1497 };
1498
1499 static const struct hda_verb ad1983_init_verbs[] = {
1500         /* Front, HP, Mono; mute as default */
1501         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1502         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1503         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1504         /* Beep, PCM, Mic, Line-In: mute */
1505         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1506         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1507         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1508         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1509         /* Front, HP selectors; from Mix */
1510         {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
1511         {0x06, AC_VERB_SET_CONNECT_SEL, 0x01},
1512         /* Mono selector; from Mix */
1513         {0x0b, AC_VERB_SET_CONNECT_SEL, 0x03},
1514         /* Mic selector; Mic */
1515         {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0},
1516         /* Line-in selector: Line-in */
1517         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
1518         /* Mic boost: 0dB */
1519         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1520         /* Record selector: mic */
1521         {0x15, AC_VERB_SET_CONNECT_SEL, 0x0},
1522         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1523         /* SPDIF route: PCM */
1524         {0x02, AC_VERB_SET_CONNECT_SEL, 0x0},
1525         /* Front Pin */
1526         {0x05, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
1527         /* HP Pin */
1528         {0x06, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
1529         /* Mono Pin */
1530         {0x07, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
1531         /* Mic Pin */
1532         {0x08, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
1533         /* Line Pin */
1534         {0x09, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
1535         { } /* end */
1536 };
1537
1538 #ifdef CONFIG_PM
1539 static const struct hda_amp_list ad1983_loopbacks[] = {
1540         { 0x12, HDA_OUTPUT, 0 }, /* Mic */
1541         { 0x13, HDA_OUTPUT, 0 }, /* Line */
1542         { } /* end */
1543 };
1544 #endif
1545
1546 static int patch_ad1983(struct hda_codec *codec)
1547 {
1548         struct ad198x_spec *spec;
1549         int err;
1550
1551         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1552         if (spec == NULL)
1553                 return -ENOMEM;
1554
1555         codec->spec = spec;
1556
1557         err = snd_hda_attach_beep_device(codec, 0x10);
1558         if (err < 0) {
1559                 ad198x_free(codec);
1560                 return err;
1561         }
1562         set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
1563
1564         spec->multiout.max_channels = 2;
1565         spec->multiout.num_dacs = ARRAY_SIZE(ad1983_dac_nids);
1566         spec->multiout.dac_nids = ad1983_dac_nids;
1567         spec->multiout.dig_out_nid = AD1983_SPDIF_OUT;
1568         spec->num_adc_nids = 1;
1569         spec->adc_nids = ad1983_adc_nids;
1570         spec->capsrc_nids = ad1983_capsrc_nids;
1571         spec->input_mux = &ad1983_capture_source;
1572         spec->num_mixers = 1;
1573         spec->mixers[0] = ad1983_mixers;
1574         spec->num_init_verbs = 1;
1575         spec->init_verbs[0] = ad1983_init_verbs;
1576         spec->spdif_route = 0;
1577 #ifdef CONFIG_PM
1578         spec->loopback.amplist = ad1983_loopbacks;
1579 #endif
1580         spec->vmaster_nid = 0x05;
1581
1582         codec->patch_ops = ad198x_patch_ops;
1583
1584         codec->no_trigger_sense = 1;
1585         codec->no_sticky_stream = 1;
1586
1587         return 0;
1588 }
1589
1590
1591 /*
1592  * AD1981 HD specific
1593  */
1594
1595 #define AD1981_SPDIF_OUT        0x02
1596 #define AD1981_DAC              0x03
1597 #define AD1981_ADC              0x04
1598
1599 static const hda_nid_t ad1981_dac_nids[1] = { AD1981_DAC };
1600 static const hda_nid_t ad1981_adc_nids[1] = { AD1981_ADC };
1601 static const hda_nid_t ad1981_capsrc_nids[1] = { 0x15 };
1602
1603 /* 0x0c, 0x09, 0x0e, 0x0f, 0x19, 0x05, 0x18, 0x17 */
1604 static const struct hda_input_mux ad1981_capture_source = {
1605         .num_items = 7,
1606         .items = {
1607                 { "Front Mic", 0x0 },
1608                 { "Line", 0x1 },
1609                 { "Mix", 0x2 },
1610                 { "Mix Mono", 0x3 },
1611                 { "CD", 0x4 },
1612                 { "Mic", 0x6 },
1613                 { "Aux", 0x7 },
1614         },
1615 };
1616
1617 static const struct snd_kcontrol_new ad1981_mixers[] = {
1618         HDA_CODEC_VOLUME("Front Playback Volume", 0x05, 0x0, HDA_OUTPUT),
1619         HDA_CODEC_MUTE("Front Playback Switch", 0x05, 0x0, HDA_OUTPUT),
1620         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x06, 0x0, HDA_OUTPUT),
1621         HDA_CODEC_MUTE("Headphone Playback Switch", 0x06, 0x0, HDA_OUTPUT),
1622         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x07, 1, 0x0, HDA_OUTPUT),
1623         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x07, 1, 0x0, HDA_OUTPUT),
1624         HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
1625         HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT),
1626         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
1627         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
1628         HDA_CODEC_VOLUME("Line Playback Volume", 0x13, 0x0, HDA_OUTPUT),
1629         HDA_CODEC_MUTE("Line Playback Switch", 0x13, 0x0, HDA_OUTPUT),
1630         HDA_CODEC_VOLUME("Aux Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
1631         HDA_CODEC_MUTE("Aux Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1632         HDA_CODEC_VOLUME("Mic Playback Volume", 0x1c, 0x0, HDA_OUTPUT),
1633         HDA_CODEC_MUTE("Mic Playback Switch", 0x1c, 0x0, HDA_OUTPUT),
1634         HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
1635         HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
1636         HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x08, 0x0, HDA_INPUT),
1637         HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x0, HDA_INPUT),
1638         HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
1639         HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
1640         {
1641                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1642                 .name = "Capture Source",
1643                 .info = ad198x_mux_enum_info,
1644                 .get = ad198x_mux_enum_get,
1645                 .put = ad198x_mux_enum_put,
1646         },
1647         /* identical with AD1983 */
1648         {
1649                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1650                 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
1651                 .info = ad1983_spdif_route_info,
1652                 .get = ad1983_spdif_route_get,
1653                 .put = ad1983_spdif_route_put,
1654         },
1655         { } /* end */
1656 };
1657
1658 static const struct hda_verb ad1981_init_verbs[] = {
1659         /* Front, HP, Mono; mute as default */
1660         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1661         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1662         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1663         /* Beep, PCM, Front Mic, Line, Rear Mic, Aux, CD-In: mute */
1664         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1665         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1666         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1667         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1668         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1669         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1670         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1671         /* Front, HP selectors; from Mix */
1672         {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
1673         {0x06, AC_VERB_SET_CONNECT_SEL, 0x01},
1674         /* Mono selector; from Mix */
1675         {0x0b, AC_VERB_SET_CONNECT_SEL, 0x03},
1676         /* Mic Mixer; select Front Mic */
1677         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1678         {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1679         /* Mic boost: 0dB */
1680         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1681         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1682         /* Record selector: Front mic */
1683         {0x15, AC_VERB_SET_CONNECT_SEL, 0x0},
1684         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1685         /* SPDIF route: PCM */
1686         {0x02, AC_VERB_SET_CONNECT_SEL, 0x0},
1687         /* Front Pin */
1688         {0x05, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
1689         /* HP Pin */
1690         {0x06, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
1691         /* Mono Pin */
1692         {0x07, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
1693         /* Front & Rear Mic Pins */
1694         {0x08, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
1695         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
1696         /* Line Pin */
1697         {0x09, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
1698         /* Digital Beep */
1699         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
1700         /* Line-Out as Input: disabled */
1701         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1702         { } /* end */
1703 };
1704
1705 #ifdef CONFIG_PM
1706 static const struct hda_amp_list ad1981_loopbacks[] = {
1707         { 0x12, HDA_OUTPUT, 0 }, /* Front Mic */
1708         { 0x13, HDA_OUTPUT, 0 }, /* Line */
1709         { 0x1b, HDA_OUTPUT, 0 }, /* Aux */
1710         { 0x1c, HDA_OUTPUT, 0 }, /* Mic */
1711         { 0x1d, HDA_OUTPUT, 0 }, /* CD */
1712         { } /* end */
1713 };
1714 #endif
1715
1716 /*
1717  * Patch for HP nx6320
1718  *
1719  * nx6320 uses EAPD in the reverse way - EAPD-on means the internal
1720  * speaker output enabled _and_ mute-LED off.
1721  */
1722
1723 #define AD1981_HP_EVENT         0x37
1724 #define AD1981_MIC_EVENT        0x38
1725
1726 static const struct hda_verb ad1981_hp_init_verbs[] = {
1727         {0x05, AC_VERB_SET_EAPD_BTLENABLE, 0x00 }, /* default off */
1728         /* pin sensing on HP and Mic jacks */
1729         {0x06, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_HP_EVENT},
1730         {0x08, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_MIC_EVENT},
1731         {}
1732 };
1733
1734 /* turn on/off EAPD (+ mute HP) as a master switch */
1735 static int ad1981_hp_master_sw_put(struct snd_kcontrol *kcontrol,
1736                                    struct snd_ctl_elem_value *ucontrol)
1737 {
1738         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1739         struct ad198x_spec *spec = codec->spec;
1740
1741         if (! ad198x_eapd_put(kcontrol, ucontrol))
1742                 return 0;
1743         /* change speaker pin appropriately */
1744         snd_hda_set_pin_ctl(codec, 0x05, spec->cur_eapd ? PIN_OUT : 0);
1745         /* toggle HP mute appropriately */
1746         snd_hda_codec_amp_stereo(codec, 0x06, HDA_OUTPUT, 0,
1747                                  HDA_AMP_MUTE,
1748                                  spec->cur_eapd ? 0 : HDA_AMP_MUTE);
1749         return 1;
1750 }
1751
1752 /* bind volumes of both NID 0x05 and 0x06 */
1753 static const struct hda_bind_ctls ad1981_hp_bind_master_vol = {
1754         .ops = &snd_hda_bind_vol,
1755         .values = {
1756                 HDA_COMPOSE_AMP_VAL(0x05, 3, 0, HDA_OUTPUT),
1757                 HDA_COMPOSE_AMP_VAL(0x06, 3, 0, HDA_OUTPUT),
1758                 0
1759         },
1760 };
1761
1762 /* mute internal speaker if HP is plugged */
1763 static void ad1981_hp_automute(struct hda_codec *codec)
1764 {
1765         unsigned int present;
1766
1767         present = snd_hda_jack_detect(codec, 0x06);
1768         snd_hda_codec_amp_stereo(codec, 0x05, HDA_OUTPUT, 0,
1769                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
1770 }
1771
1772 /* toggle input of built-in and mic jack appropriately */
1773 static void ad1981_hp_automic(struct hda_codec *codec)
1774 {
1775         static const struct hda_verb mic_jack_on[] = {
1776                 {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1777                 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1778                 {}
1779         };
1780         static const struct hda_verb mic_jack_off[] = {
1781                 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1782                 {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1783                 {}
1784         };
1785         unsigned int present;
1786
1787         present = snd_hda_jack_detect(codec, 0x08);
1788         if (present)
1789                 snd_hda_sequence_write(codec, mic_jack_on);
1790         else
1791                 snd_hda_sequence_write(codec, mic_jack_off);
1792 }
1793
1794 /* unsolicited event for HP jack sensing */
1795 static void ad1981_hp_unsol_event(struct hda_codec *codec,
1796                                   unsigned int res)
1797 {
1798         res >>= 26;
1799         switch (res) {
1800         case AD1981_HP_EVENT:
1801                 ad1981_hp_automute(codec);
1802                 break;
1803         case AD1981_MIC_EVENT:
1804                 ad1981_hp_automic(codec);
1805                 break;
1806         }
1807 }
1808
1809 static const struct hda_input_mux ad1981_hp_capture_source = {
1810         .num_items = 3,
1811         .items = {
1812                 { "Mic", 0x0 },
1813                 { "Dock Mic", 0x1 },
1814                 { "Mix", 0x2 },
1815         },
1816 };
1817
1818 static const struct snd_kcontrol_new ad1981_hp_mixers[] = {
1819         HDA_BIND_VOL("Master Playback Volume", &ad1981_hp_bind_master_vol),
1820         {
1821                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1822                 .subdevice = HDA_SUBDEV_NID_FLAG | 0x05,
1823                 .name = "Master Playback Switch",
1824                 .info = ad198x_eapd_info,
1825                 .get = ad198x_eapd_get,
1826                 .put = ad1981_hp_master_sw_put,
1827                 .private_value = 0x05,
1828         },
1829         HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
1830         HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT),
1831 #if 0
1832         /* FIXME: analog mic/line loopback doesn't work with my tests...
1833          *        (although recording is OK)
1834          */
1835         HDA_CODEC_VOLUME("Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
1836         HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
1837         HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
1838         HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
1839         HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x1c, 0x0, HDA_OUTPUT),
1840         HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x1c, 0x0, HDA_OUTPUT),
1841         /* FIXME: does this laptop have analog CD connection? */
1842         HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
1843         HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
1844 #endif
1845         HDA_CODEC_VOLUME("Mic Boost Volume", 0x08, 0x0, HDA_INPUT),
1846         HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x18, 0x0, HDA_INPUT),
1847         HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
1848         HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
1849         {
1850                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1851                 .name = "Capture Source",
1852                 .info = ad198x_mux_enum_info,
1853                 .get = ad198x_mux_enum_get,
1854                 .put = ad198x_mux_enum_put,
1855         },
1856         { } /* end */
1857 };
1858
1859 /* initialize jack-sensing, too */
1860 static int ad1981_hp_init(struct hda_codec *codec)
1861 {
1862         ad198x_init(codec);
1863         ad1981_hp_automute(codec);
1864         ad1981_hp_automic(codec);
1865         return 0;
1866 }
1867
1868 /* configuration for Toshiba Laptops */
1869 static const struct hda_verb ad1981_toshiba_init_verbs[] = {
1870         {0x05, AC_VERB_SET_EAPD_BTLENABLE, 0x01 }, /* default on */
1871         /* pin sensing on HP and Mic jacks */
1872         {0x06, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_HP_EVENT},
1873         {0x08, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_MIC_EVENT},
1874         {}
1875 };
1876
1877 static const struct snd_kcontrol_new ad1981_toshiba_mixers[] = {
1878         HDA_CODEC_VOLUME("Amp Volume", 0x1a, 0x0, HDA_OUTPUT),
1879         HDA_CODEC_MUTE("Amp Switch", 0x1a, 0x0, HDA_OUTPUT),
1880         { }
1881 };
1882
1883 /* configuration for Lenovo Thinkpad T60 */
1884 static const struct snd_kcontrol_new ad1981_thinkpad_mixers[] = {
1885         HDA_CODEC_VOLUME("Master Playback Volume", 0x05, 0x0, HDA_OUTPUT),
1886         HDA_CODEC_MUTE("Master Playback Switch", 0x05, 0x0, HDA_OUTPUT),
1887         HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
1888         HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT),
1889         HDA_CODEC_VOLUME("Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
1890         HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
1891         HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
1892         HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
1893         HDA_CODEC_VOLUME("Mic Boost Volume", 0x08, 0x0, HDA_INPUT),
1894         HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
1895         HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
1896         {
1897                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1898                 .name = "Capture Source",
1899                 .info = ad198x_mux_enum_info,
1900                 .get = ad198x_mux_enum_get,
1901                 .put = ad198x_mux_enum_put,
1902         },
1903         /* identical with AD1983 */
1904         {
1905                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1906                 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
1907                 .info = ad1983_spdif_route_info,
1908                 .get = ad1983_spdif_route_get,
1909                 .put = ad1983_spdif_route_put,
1910         },
1911         { } /* end */
1912 };
1913
1914 static const struct hda_input_mux ad1981_thinkpad_capture_source = {
1915         .num_items = 3,
1916         .items = {
1917                 { "Mic", 0x0 },
1918                 { "Mix", 0x2 },
1919                 { "CD", 0x4 },
1920         },
1921 };
1922
1923 /* models */
1924 enum {
1925         AD1981_BASIC,
1926         AD1981_HP,
1927         AD1981_THINKPAD,
1928         AD1981_TOSHIBA,
1929         AD1981_MODELS
1930 };
1931
1932 static const char * const ad1981_models[AD1981_MODELS] = {
1933         [AD1981_HP]             = "hp",
1934         [AD1981_THINKPAD]       = "thinkpad",
1935         [AD1981_BASIC]          = "basic",
1936         [AD1981_TOSHIBA]        = "toshiba"
1937 };
1938
1939 static const struct snd_pci_quirk ad1981_cfg_tbl[] = {
1940         SND_PCI_QUIRK(0x1014, 0x0597, "Lenovo Z60", AD1981_THINKPAD),
1941         SND_PCI_QUIRK(0x1014, 0x05b7, "Lenovo Z60m", AD1981_THINKPAD),
1942         /* All HP models */
1943         SND_PCI_QUIRK_VENDOR(0x103c, "HP nx", AD1981_HP),
1944         SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba U205", AD1981_TOSHIBA),
1945         /* Lenovo Thinkpad T60/X60/Z6xx */
1946         SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo Thinkpad", AD1981_THINKPAD),
1947         /* HP nx6320 (reversed SSID, H/W bug) */
1948         SND_PCI_QUIRK(0x30b0, 0x103c, "HP nx6320", AD1981_HP),
1949         {}
1950 };
1951
1952 static int patch_ad1981(struct hda_codec *codec)
1953 {
1954         struct ad198x_spec *spec;
1955         int err, board_config;
1956
1957         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1958         if (spec == NULL)
1959                 return -ENOMEM;
1960
1961         codec->spec = spec;
1962
1963         err = snd_hda_attach_beep_device(codec, 0x10);
1964         if (err < 0) {
1965                 ad198x_free(codec);
1966                 return err;
1967         }
1968         set_beep_amp(spec, 0x0d, 0, HDA_OUTPUT);
1969
1970         spec->multiout.max_channels = 2;
1971         spec->multiout.num_dacs = ARRAY_SIZE(ad1981_dac_nids);
1972         spec->multiout.dac_nids = ad1981_dac_nids;
1973         spec->multiout.dig_out_nid = AD1981_SPDIF_OUT;
1974         spec->num_adc_nids = 1;
1975         spec->adc_nids = ad1981_adc_nids;
1976         spec->capsrc_nids = ad1981_capsrc_nids;
1977         spec->input_mux = &ad1981_capture_source;
1978         spec->num_mixers = 1;
1979         spec->mixers[0] = ad1981_mixers;
1980         spec->num_init_verbs = 1;
1981         spec->init_verbs[0] = ad1981_init_verbs;
1982         spec->spdif_route = 0;
1983 #ifdef CONFIG_PM
1984         spec->loopback.amplist = ad1981_loopbacks;
1985 #endif
1986         spec->vmaster_nid = 0x05;
1987
1988         codec->patch_ops = ad198x_patch_ops;
1989
1990         /* override some parameters */
1991         board_config = snd_hda_check_board_config(codec, AD1981_MODELS,
1992                                                   ad1981_models,
1993                                                   ad1981_cfg_tbl);
1994         switch (board_config) {
1995         case AD1981_HP:
1996                 spec->mixers[0] = ad1981_hp_mixers;
1997                 spec->num_init_verbs = 2;
1998                 spec->init_verbs[1] = ad1981_hp_init_verbs;
1999                 if (!is_jack_available(codec, 0x0a))
2000                         spec->multiout.dig_out_nid = 0;
2001                 spec->input_mux = &ad1981_hp_capture_source;
2002
2003                 codec->patch_ops.init = ad1981_hp_init;
2004                 codec->patch_ops.unsol_event = ad1981_hp_unsol_event;
2005                 /* set the upper-limit for mixer amp to 0dB for avoiding the
2006                  * possible damage by overloading
2007                  */
2008                 snd_hda_override_amp_caps(codec, 0x11, HDA_INPUT,
2009                                           (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
2010                                           (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
2011                                           (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
2012                                           (1 << AC_AMPCAP_MUTE_SHIFT));
2013                 break;
2014         case AD1981_THINKPAD:
2015                 spec->mixers[0] = ad1981_thinkpad_mixers;
2016                 spec->input_mux = &ad1981_thinkpad_capture_source;
2017                 /* set the upper-limit for mixer amp to 0dB for avoiding the
2018                  * possible damage by overloading
2019                  */
2020                 snd_hda_override_amp_caps(codec, 0x11, HDA_INPUT,
2021                                           (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
2022                                           (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
2023                                           (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
2024                                           (1 << AC_AMPCAP_MUTE_SHIFT));
2025                 break;
2026         case AD1981_TOSHIBA:
2027                 spec->mixers[0] = ad1981_hp_mixers;
2028                 spec->mixers[1] = ad1981_toshiba_mixers;
2029                 spec->num_init_verbs = 2;
2030                 spec->init_verbs[1] = ad1981_toshiba_init_verbs;
2031                 spec->multiout.dig_out_nid = 0;
2032                 spec->input_mux = &ad1981_hp_capture_source;
2033                 codec->patch_ops.init = ad1981_hp_init;
2034                 codec->patch_ops.unsol_event = ad1981_hp_unsol_event;
2035                 break;
2036         }
2037
2038         codec->no_trigger_sense = 1;
2039         codec->no_sticky_stream = 1;
2040
2041         return 0;
2042 }
2043
2044
2045 /*
2046  * AD1988
2047  *
2048  * Output pins and routes
2049  *
2050  *        Pin               Mix     Sel     DAC (*)
2051  * port-A 0x11 (mute/hp) <- 0x22 <- 0x37 <- 03/04/06
2052  * port-B 0x14 (mute/hp) <- 0x2b <- 0x30 <- 03/04/06
2053  * port-C 0x15 (mute)    <- 0x2c <- 0x31 <- 05/0a
2054  * port-D 0x12 (mute/hp) <- 0x29         <- 04
2055  * port-E 0x17 (mute/hp) <- 0x26 <- 0x32 <- 05/0a
2056  * port-F 0x16 (mute)    <- 0x2a         <- 06
2057  * port-G 0x24 (mute)    <- 0x27         <- 05
2058  * port-H 0x25 (mute)    <- 0x28         <- 0a
2059  * mono   0x13 (mute/amp)<- 0x1e <- 0x36 <- 03/04/06
2060  *
2061  * DAC0 = 03h, DAC1 = 04h, DAC2 = 05h, DAC3 = 06h, DAC4 = 0ah
2062  * (*) DAC2/3/4 are swapped to DAC3/4/2 on AD198A rev.2 due to a h/w bug.
2063  *
2064  * Input pins and routes
2065  *
2066  *        pin     boost   mix input # / adc input #
2067  * port-A 0x11 -> 0x38 -> mix 2, ADC 0
2068  * port-B 0x14 -> 0x39 -> mix 0, ADC 1
2069  * port-C 0x15 -> 0x3a -> 33:0 - mix 1, ADC 2
2070  * port-D 0x12 -> 0x3d -> mix 3, ADC 8
2071  * port-E 0x17 -> 0x3c -> 34:0 - mix 4, ADC 4
2072  * port-F 0x16 -> 0x3b -> mix 5, ADC 3
2073  * port-G 0x24 -> N/A  -> 33:1 - mix 1, 34:1 - mix 4, ADC 6
2074  * port-H 0x25 -> N/A  -> 33:2 - mix 1, 34:2 - mix 4, ADC 7
2075  *
2076  *
2077  * DAC assignment
2078  *   6stack - front/surr/CLFE/side/opt DACs - 04/06/05/0a/03
2079  *   3stack - front/surr/CLFE/opt DACs - 04/05/0a/03
2080  *
2081  * Inputs of Analog Mix (0x20)
2082  *   0:Port-B (front mic)
2083  *   1:Port-C/G/H (line-in)
2084  *   2:Port-A
2085  *   3:Port-D (line-in/2)
2086  *   4:Port-E/G/H (mic-in)
2087  *   5:Port-F (mic2-in)
2088  *   6:CD
2089  *   7:Beep
2090  *
2091  * ADC selection
2092  *   0:Port-A
2093  *   1:Port-B (front mic-in)
2094  *   2:Port-C (line-in)
2095  *   3:Port-F (mic2-in)
2096  *   4:Port-E (mic-in)
2097  *   5:CD
2098  *   6:Port-G
2099  *   7:Port-H
2100  *   8:Port-D (line-in/2)
2101  *   9:Mix
2102  *
2103  * Proposed pin assignments by the datasheet
2104  *
2105  * 6-stack
2106  * Port-A front headphone
2107  *      B front mic-in
2108  *      C rear line-in
2109  *      D rear front-out
2110  *      E rear mic-in
2111  *      F rear surround
2112  *      G rear CLFE
2113  *      H rear side
2114  *
2115  * 3-stack
2116  * Port-A front headphone
2117  *      B front mic
2118  *      C rear line-in/surround
2119  *      D rear front-out
2120  *      E rear mic-in/CLFE
2121  *
2122  * laptop
2123  * Port-A headphone
2124  *      B mic-in
2125  *      C docking station
2126  *      D internal speaker (with EAPD)
2127  *      E/F quad mic array
2128  */
2129
2130
2131 /* models */
2132 enum {
2133         AD1988_6STACK,
2134         AD1988_6STACK_DIG,
2135         AD1988_3STACK,
2136         AD1988_3STACK_DIG,
2137         AD1988_LAPTOP,
2138         AD1988_LAPTOP_DIG,
2139         AD1988_AUTO,
2140         AD1988_MODEL_LAST,
2141 };
2142
2143 /* reivision id to check workarounds */
2144 #define AD1988A_REV2            0x100200
2145
2146 #define is_rev2(codec) \
2147         ((codec)->vendor_id == 0x11d41988 && \
2148          (codec)->revision_id == AD1988A_REV2)
2149
2150 /*
2151  * mixers
2152  */
2153
2154 static const hda_nid_t ad1988_6stack_dac_nids[4] = {
2155         0x04, 0x06, 0x05, 0x0a
2156 };
2157
2158 static const hda_nid_t ad1988_3stack_dac_nids[3] = {
2159         0x04, 0x05, 0x0a
2160 };
2161
2162 /* for AD1988A revision-2, DAC2-4 are swapped */
2163 static const hda_nid_t ad1988_6stack_dac_nids_rev2[4] = {
2164         0x04, 0x05, 0x0a, 0x06
2165 };
2166
2167 static const hda_nid_t ad1988_alt_dac_nid[1] = {
2168         0x03
2169 };
2170
2171 static const hda_nid_t ad1988_3stack_dac_nids_rev2[3] = {
2172         0x04, 0x0a, 0x06
2173 };
2174
2175 static const hda_nid_t ad1988_adc_nids[3] = {
2176         0x08, 0x09, 0x0f
2177 };
2178
2179 static const hda_nid_t ad1988_capsrc_nids[3] = {
2180         0x0c, 0x0d, 0x0e
2181 };
2182
2183 #define AD1988_SPDIF_OUT                0x02
2184 #define AD1988_SPDIF_OUT_HDMI   0x0b
2185 #define AD1988_SPDIF_IN         0x07
2186
2187 static const hda_nid_t ad1989b_slave_dig_outs[] = {
2188         AD1988_SPDIF_OUT, AD1988_SPDIF_OUT_HDMI, 0
2189 };
2190
2191 static const struct hda_input_mux ad1988_6stack_capture_source = {
2192         .num_items = 5,
2193         .items = {
2194                 { "Front Mic", 0x1 },   /* port-B */
2195                 { "Line", 0x2 },        /* port-C */
2196                 { "Mic", 0x4 },         /* port-E */
2197                 { "CD", 0x5 },
2198                 { "Mix", 0x9 },
2199         },
2200 };
2201
2202 static const struct hda_input_mux ad1988_laptop_capture_source = {
2203         .num_items = 3,
2204         .items = {
2205                 { "Mic/Line", 0x1 },    /* port-B */
2206                 { "CD", 0x5 },
2207                 { "Mix", 0x9 },
2208         },
2209 };
2210
2211 /*
2212  */
2213 static int ad198x_ch_mode_info(struct snd_kcontrol *kcontrol,
2214                                struct snd_ctl_elem_info *uinfo)
2215 {
2216         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2217         struct ad198x_spec *spec = codec->spec;
2218         return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
2219                                     spec->num_channel_mode);
2220 }
2221
2222 static int ad198x_ch_mode_get(struct snd_kcontrol *kcontrol,
2223                               struct snd_ctl_elem_value *ucontrol)
2224 {
2225         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2226         struct ad198x_spec *spec = codec->spec;
2227         return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
2228                                    spec->num_channel_mode, spec->multiout.max_channels);
2229 }
2230
2231 static int ad198x_ch_mode_put(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         int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
2237                                       spec->num_channel_mode,
2238                                       &spec->multiout.max_channels);
2239         if (err >= 0 && spec->need_dac_fix)
2240                 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
2241         return err;
2242 }
2243
2244 static const struct snd_kcontrol_new ad1988_hp_mixers[] = {
2245         {
2246                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2247                 .name = "Independent HP",
2248                 .info = ad1988_independent_hp_info,
2249                 .get = ad1988_independent_hp_get,
2250                 .put = ad1988_independent_hp_put,
2251         },
2252         { } /* end */
2253 };
2254
2255 /* 6-stack mode */
2256 static const struct snd_kcontrol_new ad1988_6stack_mixers1[] = {
2257         HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
2258         HDA_CODEC_VOLUME("Surround Playback Volume", 0x06, 0x0, HDA_OUTPUT),
2259         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT),
2260         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT),
2261         HDA_CODEC_VOLUME("Side Playback Volume", 0x0a, 0x0, HDA_OUTPUT),
2262         { } /* end */
2263 };
2264
2265 static const struct snd_kcontrol_new ad1988_6stack_mixers1_rev2[] = {
2266         HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
2267         HDA_CODEC_VOLUME("Surround Playback Volume", 0x05, 0x0, HDA_OUTPUT),
2268         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
2269         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0a, 2, 0x0, HDA_OUTPUT),
2270         HDA_CODEC_VOLUME("Side Playback Volume", 0x06, 0x0, HDA_OUTPUT),
2271         { } /* end */
2272 };
2273
2274 static const struct snd_kcontrol_new ad1988_6stack_mixers2[] = {
2275         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
2276         HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT),
2277         HDA_BIND_MUTE("Surround Playback Switch", 0x2a, 2, HDA_INPUT),
2278         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x27, 1, 2, HDA_INPUT),
2279         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x27, 2, 2, HDA_INPUT),
2280         HDA_BIND_MUTE("Side Playback Switch", 0x28, 2, HDA_INPUT),
2281         HDA_BIND_MUTE("Headphone Playback Switch", 0x22, 2, HDA_INPUT),
2282         HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT),
2283
2284         HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x6, HDA_INPUT),
2285         HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x6, HDA_INPUT),
2286         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x0, HDA_INPUT),
2287         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x0, HDA_INPUT),
2288         HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT),
2289         HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT),
2290         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x4, HDA_INPUT),
2291         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x4, HDA_INPUT),
2292
2293         HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT),
2294         HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT),
2295
2296         HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x39, 0x0, HDA_OUTPUT),
2297         HDA_CODEC_VOLUME("Mic Boost Volume", 0x3c, 0x0, HDA_OUTPUT),
2298         { } /* end */
2299 };
2300
2301 /* 3-stack mode */
2302 static const struct snd_kcontrol_new ad1988_3stack_mixers1[] = {
2303         HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
2304         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0a, 0x0, HDA_OUTPUT),
2305         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT),
2306         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT),
2307         { } /* end */
2308 };
2309
2310 static const struct snd_kcontrol_new ad1988_3stack_mixers1_rev2[] = {
2311         HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
2312         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0a, 0x0, HDA_OUTPUT),
2313         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x06, 1, 0x0, HDA_OUTPUT),
2314         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x06, 2, 0x0, HDA_OUTPUT),
2315         { } /* end */
2316 };
2317
2318 static const struct snd_kcontrol_new ad1988_3stack_mixers2[] = {
2319         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
2320         HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT),
2321         HDA_BIND_MUTE("Surround Playback Switch", 0x2c, 2, HDA_INPUT),
2322         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x26, 1, 2, HDA_INPUT),
2323         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x26, 2, 2, HDA_INPUT),
2324         HDA_BIND_MUTE("Headphone Playback Switch", 0x22, 2, HDA_INPUT),
2325         HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT),
2326
2327         HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x6, HDA_INPUT),
2328         HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x6, HDA_INPUT),
2329         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x0, HDA_INPUT),
2330         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x0, HDA_INPUT),
2331         HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT),
2332         HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT),
2333         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x4, HDA_INPUT),
2334         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x4, HDA_INPUT),
2335
2336         HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT),
2337         HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT),
2338
2339         HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x39, 0x0, HDA_OUTPUT),
2340         HDA_CODEC_VOLUME("Mic Boost Volume", 0x3c, 0x0, HDA_OUTPUT),
2341         {
2342                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2343                 .name = "Channel Mode",
2344                 .info = ad198x_ch_mode_info,
2345                 .get = ad198x_ch_mode_get,
2346                 .put = ad198x_ch_mode_put,
2347         },
2348
2349         { } /* end */
2350 };
2351
2352 /* laptop mode */
2353 static const struct snd_kcontrol_new ad1988_laptop_mixers[] = {
2354         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
2355         HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
2356         HDA_CODEC_MUTE("PCM Playback Switch", 0x29, 0x0, HDA_INPUT),
2357         HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT),
2358
2359         HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x6, HDA_INPUT),
2360         HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x6, HDA_INPUT),
2361         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x0, HDA_INPUT),
2362         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x0, HDA_INPUT),
2363         HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT),
2364         HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT),
2365
2366         HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT),
2367         HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT),
2368
2369         HDA_CODEC_VOLUME("Mic Boost Volume", 0x39, 0x0, HDA_OUTPUT),
2370
2371         {
2372                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2373                 .name = "External Amplifier",
2374                 .subdevice = HDA_SUBDEV_NID_FLAG | 0x12,
2375                 .info = ad198x_eapd_info,
2376                 .get = ad198x_eapd_get,
2377                 .put = ad198x_eapd_put,
2378                 .private_value = 0x12, /* port-D */
2379         },
2380
2381         { } /* end */
2382 };
2383
2384 /* capture */
2385 static const struct snd_kcontrol_new ad1988_capture_mixers[] = {
2386         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
2387         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
2388         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
2389         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
2390         HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x0e, 0x0, HDA_OUTPUT),
2391         HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x0e, 0x0, HDA_OUTPUT),
2392         {
2393                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2394                 /* The multiple "Capture Source" controls confuse alsamixer
2395                  * So call somewhat different..
2396                  */
2397                 /* .name = "Capture Source", */
2398                 .name = "Input Source",
2399                 .count = 3,
2400                 .info = ad198x_mux_enum_info,
2401                 .get = ad198x_mux_enum_get,
2402                 .put = ad198x_mux_enum_put,
2403         },
2404         { } /* end */
2405 };
2406
2407 static int ad1988_spdif_playback_source_info(struct snd_kcontrol *kcontrol,
2408                                              struct snd_ctl_elem_info *uinfo)
2409 {
2410         static const char * const texts[] = {
2411                 "PCM", "ADC1", "ADC2", "ADC3"
2412         };
2413         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2414         uinfo->count = 1;
2415         uinfo->value.enumerated.items = 4;
2416         if (uinfo->value.enumerated.item >= 4)
2417                 uinfo->value.enumerated.item = 3;
2418         strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2419         return 0;
2420 }
2421
2422 static int ad1988_spdif_playback_source_get(struct snd_kcontrol *kcontrol,
2423                                             struct snd_ctl_elem_value *ucontrol)
2424 {
2425         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2426         unsigned int sel;
2427
2428         sel = snd_hda_codec_read(codec, 0x1d, 0, AC_VERB_GET_AMP_GAIN_MUTE,
2429                                  AC_AMP_GET_INPUT);
2430         if (!(sel & 0x80))
2431                 ucontrol->value.enumerated.item[0] = 0;
2432         else {
2433                 sel = snd_hda_codec_read(codec, 0x0b, 0,
2434                                          AC_VERB_GET_CONNECT_SEL, 0);
2435                 if (sel < 3)
2436                         sel++;
2437                 else
2438                         sel = 0;
2439                 ucontrol->value.enumerated.item[0] = sel;
2440         }
2441         return 0;
2442 }
2443
2444 static int ad1988_spdif_playback_source_put(struct snd_kcontrol *kcontrol,
2445                                             struct snd_ctl_elem_value *ucontrol)
2446 {
2447         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2448         unsigned int val, sel;
2449         int change;
2450
2451         val = ucontrol->value.enumerated.item[0];
2452         if (val > 3)
2453                 return -EINVAL;
2454         if (!val) {
2455                 sel = snd_hda_codec_read(codec, 0x1d, 0,
2456                                          AC_VERB_GET_AMP_GAIN_MUTE,
2457                                          AC_AMP_GET_INPUT);
2458                 change = sel & 0x80;
2459                 if (change) {
2460                         snd_hda_codec_write_cache(codec, 0x1d, 0,
2461                                                   AC_VERB_SET_AMP_GAIN_MUTE,
2462                                                   AMP_IN_UNMUTE(0));
2463                         snd_hda_codec_write_cache(codec, 0x1d, 0,
2464                                                   AC_VERB_SET_AMP_GAIN_MUTE,
2465                                                   AMP_IN_MUTE(1));
2466                 }
2467         } else {
2468                 sel = snd_hda_codec_read(codec, 0x1d, 0,
2469                                          AC_VERB_GET_AMP_GAIN_MUTE,
2470                                          AC_AMP_GET_INPUT | 0x01);
2471                 change = sel & 0x80;
2472                 if (change) {
2473                         snd_hda_codec_write_cache(codec, 0x1d, 0,
2474                                                   AC_VERB_SET_AMP_GAIN_MUTE,
2475                                                   AMP_IN_MUTE(0));
2476                         snd_hda_codec_write_cache(codec, 0x1d, 0,
2477                                                   AC_VERB_SET_AMP_GAIN_MUTE,
2478                                                   AMP_IN_UNMUTE(1));
2479                 }
2480                 sel = snd_hda_codec_read(codec, 0x0b, 0,
2481                                          AC_VERB_GET_CONNECT_SEL, 0) + 1;
2482                 change |= sel != val;
2483                 if (change)
2484                         snd_hda_codec_write_cache(codec, 0x0b, 0,
2485                                                   AC_VERB_SET_CONNECT_SEL,
2486                                                   val - 1);
2487         }
2488         return change;
2489 }
2490
2491 static const struct snd_kcontrol_new ad1988_spdif_out_mixers[] = {
2492         HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
2493         {
2494                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2495                 .name = "IEC958 Playback Source",
2496                 .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b,
2497                 .info = ad1988_spdif_playback_source_info,
2498                 .get = ad1988_spdif_playback_source_get,
2499                 .put = ad1988_spdif_playback_source_put,
2500         },
2501         { } /* end */
2502 };
2503
2504 static const struct snd_kcontrol_new ad1988_spdif_in_mixers[] = {
2505         HDA_CODEC_VOLUME("IEC958 Capture Volume", 0x1c, 0x0, HDA_INPUT),
2506         { } /* end */
2507 };
2508
2509 static const struct snd_kcontrol_new ad1989_spdif_out_mixers[] = {
2510         HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
2511         HDA_CODEC_VOLUME("HDMI Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
2512         { } /* end */
2513 };
2514
2515 /*
2516  * initialization verbs
2517  */
2518
2519 /*
2520  * for 6-stack (+dig)
2521  */
2522 static const struct hda_verb ad1988_6stack_init_verbs[] = {
2523         /* Front, Surround, CLFE, side DAC; unmute as default */
2524         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2525         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2526         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2527         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2528         /* Port-A front headphon path */
2529         {0x37, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC0:03h */
2530         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2531         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2532         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2533         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2534         /* Port-D line-out path */
2535         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2536         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2537         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2538         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2539         /* Port-F surround path */
2540         {0x2a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2541         {0x2a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2542         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2543         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2544         /* Port-G CLFE path */
2545         {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2546         {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2547         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2548         {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2549         /* Port-H side path */
2550         {0x28, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2551         {0x28, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2552         {0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2553         {0x25, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2554         /* Mono out path */
2555         {0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */
2556         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2557         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2558         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2559         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */
2560         /* Port-B front mic-in path */
2561         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2562         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2563         {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2564         /* Port-C line-in path */
2565         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2566         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2567         {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2568         {0x33, AC_VERB_SET_CONNECT_SEL, 0x0},
2569         /* Port-E mic-in path */
2570         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2571         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2572         {0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2573         {0x34, AC_VERB_SET_CONNECT_SEL, 0x0},
2574         /* Analog CD Input */
2575         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2576         /* Analog Mix output amp */
2577         {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
2578
2579         { }
2580 };
2581
2582 static const struct hda_verb ad1988_6stack_fp_init_verbs[] = {
2583         /* Headphone; unmute as default */
2584         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2585         /* Port-A front headphon path */
2586         {0x37, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC0:03h */
2587         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2588         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2589         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2590         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2591
2592         { }
2593 };
2594
2595 static const struct hda_verb ad1988_capture_init_verbs[] = {
2596         /* mute analog mix */
2597         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2598         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2599         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2600         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2601         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2602         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
2603         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2604         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2605         /* select ADCs - front-mic */
2606         {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1},
2607         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x1},
2608         {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
2609
2610         { }
2611 };
2612
2613 static const struct hda_verb ad1988_spdif_init_verbs[] = {
2614         /* SPDIF out sel */
2615         {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */
2616         {0x0b, AC_VERB_SET_CONNECT_SEL, 0x0}, /* ADC1 */
2617         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2618         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2619         /* SPDIF out pin */
2620         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
2621
2622         { }
2623 };
2624
2625 static const struct hda_verb ad1988_spdif_in_init_verbs[] = {
2626         /* unmute SPDIF input pin */
2627         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2628         { }
2629 };
2630
2631 /* AD1989 has no ADC -> SPDIF route */
2632 static const struct hda_verb ad1989_spdif_init_verbs[] = {
2633         /* SPDIF-1 out pin */
2634         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2635         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
2636         /* SPDIF-2/HDMI out pin */
2637         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2638         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
2639         { }
2640 };
2641
2642 /*
2643  * verbs for 3stack (+dig)
2644  */
2645 static const struct hda_verb ad1988_3stack_ch2_init[] = {
2646         /* set port-C to line-in */
2647         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2648         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2649         /* set port-E to mic-in */
2650         { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2651         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2652         { } /* end */
2653 };
2654
2655 static const struct hda_verb ad1988_3stack_ch6_init[] = {
2656         /* set port-C to surround out */
2657         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2658         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2659         /* set port-E to CLFE out */
2660         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2661         { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2662         { } /* end */
2663 };
2664
2665 static const struct hda_channel_mode ad1988_3stack_modes[2] = {
2666         { 2, ad1988_3stack_ch2_init },
2667         { 6, ad1988_3stack_ch6_init },
2668 };
2669
2670 static const struct hda_verb ad1988_3stack_init_verbs[] = {
2671         /* Front, Surround, CLFE, side DAC; unmute as default */
2672         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2673         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2674         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2675         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2676         /* Port-A front headphon path */
2677         {0x37, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC0:03h */
2678         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2679         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2680         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2681         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2682         /* Port-D line-out path */
2683         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2684         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2685         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2686         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2687         /* Mono out path */
2688         {0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */
2689         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2690         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2691         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2692         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */
2693         /* Port-B front mic-in path */
2694         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2695         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2696         {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2697         /* Port-C line-in/surround path - 6ch mode as default */
2698         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2699         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2700         {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2701         {0x31, AC_VERB_SET_CONNECT_SEL, 0x0}, /* output sel: DAC 0x05 */
2702         {0x33, AC_VERB_SET_CONNECT_SEL, 0x0},
2703         /* Port-E mic-in/CLFE path - 6ch mode as default */
2704         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2705         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2706         {0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2707         {0x32, AC_VERB_SET_CONNECT_SEL, 0x1}, /* output sel: DAC 0x0a */
2708         {0x34, AC_VERB_SET_CONNECT_SEL, 0x0},
2709         /* mute analog mix */
2710         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2711         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2712         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2713         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2714         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2715         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
2716         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2717         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2718         /* select ADCs - front-mic */
2719         {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1},
2720         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x1},
2721         {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
2722         /* Analog Mix output amp */
2723         {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
2724         { }
2725 };
2726
2727 /*
2728  * verbs for laptop mode (+dig)
2729  */
2730 static const struct hda_verb ad1988_laptop_hp_on[] = {
2731         /* unmute port-A and mute port-D */
2732         { 0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2733         { 0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2734         { } /* end */
2735 };
2736 static const struct hda_verb ad1988_laptop_hp_off[] = {
2737         /* mute port-A and unmute port-D */
2738         { 0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2739         { 0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2740         { } /* end */
2741 };
2742
2743 #define AD1988_HP_EVENT 0x01
2744
2745 static const struct hda_verb ad1988_laptop_init_verbs[] = {
2746         /* Front, Surround, CLFE, side DAC; unmute as default */
2747         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2748         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2749         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2750         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2751         /* Port-A front headphon path */
2752         {0x37, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC0:03h */
2753         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2754         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2755         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2756         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2757         /* unsolicited event for pin-sense */
2758         {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1988_HP_EVENT },
2759         /* Port-D line-out path + EAPD */
2760         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2761         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2762         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2763         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2764         {0x12, AC_VERB_SET_EAPD_BTLENABLE, 0x00}, /* EAPD-off */
2765         /* Mono out path */
2766         {0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */
2767         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2768         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2769         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2770         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */
2771         /* Port-B mic-in path */
2772         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2773         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2774         {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2775         /* Port-C docking station - try to output */
2776         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2777         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2778         {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2779         {0x33, AC_VERB_SET_CONNECT_SEL, 0x0},
2780         /* mute analog mix */
2781         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2782         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2783         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2784         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2785         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2786         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
2787         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2788         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2789         /* select ADCs - mic */
2790         {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1},
2791         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x1},
2792         {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
2793         /* Analog Mix output amp */
2794         {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
2795         { }
2796 };
2797
2798 static void ad1988_laptop_unsol_event(struct hda_codec *codec, unsigned int res)
2799 {
2800         if ((res >> 26) != AD1988_HP_EVENT)
2801                 return;
2802         if (snd_hda_jack_detect(codec, 0x11))
2803                 snd_hda_sequence_write(codec, ad1988_laptop_hp_on);
2804         else
2805                 snd_hda_sequence_write(codec, ad1988_laptop_hp_off);
2806
2807
2808 #ifdef CONFIG_PM
2809 static const struct hda_amp_list ad1988_loopbacks[] = {
2810         { 0x20, HDA_INPUT, 0 }, /* Front Mic */
2811         { 0x20, HDA_INPUT, 1 }, /* Line */
2812         { 0x20, HDA_INPUT, 4 }, /* Mic */
2813         { 0x20, HDA_INPUT, 6 }, /* CD */
2814         { } /* end */
2815 };
2816 #endif
2817
2818 /*
2819  * Automatic parse of I/O pins from the BIOS configuration
2820  */
2821
2822 enum {
2823         AD_CTL_WIDGET_VOL,
2824         AD_CTL_WIDGET_MUTE,
2825         AD_CTL_BIND_MUTE,
2826 };
2827 static const struct snd_kcontrol_new ad1988_control_templates[] = {
2828         HDA_CODEC_VOLUME(NULL, 0, 0, 0),
2829         HDA_CODEC_MUTE(NULL, 0, 0, 0),
2830         HDA_BIND_MUTE(NULL, 0, 0, 0),
2831 };
2832
2833 /* add dynamic controls */
2834 static int add_control(struct ad198x_spec *spec, int type, const char *name,
2835                        unsigned long val)
2836 {
2837         struct snd_kcontrol_new *knew;
2838
2839         snd_array_init(&spec->kctls, sizeof(*knew), 32);
2840         knew = snd_array_new(&spec->kctls);
2841         if (!knew)
2842                 return -ENOMEM;
2843         *knew = ad1988_control_templates[type];
2844         knew->name = kstrdup(name, GFP_KERNEL);
2845         if (! knew->name)
2846                 return -ENOMEM;
2847         if (get_amp_nid_(val))
2848                 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
2849         knew->private_value = val;
2850         return 0;
2851 }
2852
2853 #define AD1988_PIN_CD_NID               0x18
2854 #define AD1988_PIN_BEEP_NID             0x10
2855
2856 static const hda_nid_t ad1988_mixer_nids[8] = {
2857         /* A     B     C     D     E     F     G     H */
2858         0x22, 0x2b, 0x2c, 0x29, 0x26, 0x2a, 0x27, 0x28
2859 };
2860
2861 static inline hda_nid_t ad1988_idx_to_dac(struct hda_codec *codec, int idx)
2862 {
2863         static const hda_nid_t idx_to_dac[8] = {
2864                 /* A     B     C     D     E     F     G     H */
2865                 0x03, 0x06, 0x05, 0x04, 0x0a, 0x06, 0x05, 0x0a
2866         };
2867         static const hda_nid_t idx_to_dac_rev2[8] = {
2868                 /* A     B     C     D     E     F     G     H */
2869                 0x03, 0x05, 0x0a, 0x04, 0x06, 0x05, 0x0a, 0x06
2870         };
2871         if (is_rev2(codec))
2872                 return idx_to_dac_rev2[idx];
2873         else
2874                 return idx_to_dac[idx];
2875 }
2876
2877 static const hda_nid_t ad1988_boost_nids[8] = {
2878         0x38, 0x39, 0x3a, 0x3d, 0x3c, 0x3b, 0, 0
2879 };
2880
2881 static int ad1988_pin_idx(hda_nid_t nid)
2882 {
2883         static const hda_nid_t ad1988_io_pins[8] = {
2884                 0x11, 0x14, 0x15, 0x12, 0x17, 0x16, 0x24, 0x25
2885         };
2886         int i;
2887         for (i = 0; i < ARRAY_SIZE(ad1988_io_pins); i++)
2888                 if (ad1988_io_pins[i] == nid)
2889                         return i;
2890         return 0; /* should be -1 */
2891 }
2892
2893 static int ad1988_pin_to_loopback_idx(hda_nid_t nid)
2894 {
2895         static const int loopback_idx[8] = {
2896                 2, 0, 1, 3, 4, 5, 1, 4
2897         };
2898         switch (nid) {
2899         case AD1988_PIN_CD_NID:
2900                 return 6;
2901         default:
2902                 return loopback_idx[ad1988_pin_idx(nid)];
2903         }
2904 }
2905
2906 static int ad1988_pin_to_adc_idx(hda_nid_t nid)
2907 {
2908         static const int adc_idx[8] = {
2909                 0, 1, 2, 8, 4, 3, 6, 7
2910         };
2911         switch (nid) {
2912         case AD1988_PIN_CD_NID:
2913                 return 5;
2914         default:
2915                 return adc_idx[ad1988_pin_idx(nid)];
2916         }
2917 }
2918
2919 /* fill in the dac_nids table from the parsed pin configuration */
2920 static int ad1988_auto_fill_dac_nids(struct hda_codec *codec,
2921                                      const struct auto_pin_cfg *cfg)
2922 {
2923         struct ad198x_spec *spec = codec->spec;
2924         int i, idx;
2925
2926         spec->multiout.dac_nids = spec->private_dac_nids;
2927
2928         /* check the pins hardwired to audio widget */
2929         for (i = 0; i < cfg->line_outs; i++) {
2930                 idx = ad1988_pin_idx(cfg->line_out_pins[i]);
2931                 spec->private_dac_nids[i] = ad1988_idx_to_dac(codec, idx);
2932         }
2933         spec->multiout.num_dacs = cfg->line_outs;
2934         return 0;
2935 }
2936
2937 /* add playback controls from the parsed DAC table */
2938 static int ad1988_auto_create_multi_out_ctls(struct ad198x_spec *spec,
2939                                              const struct auto_pin_cfg *cfg)
2940 {
2941         char name[32];
2942         static const char * const chname[4] = {
2943                 "Front", "Surround", NULL /*CLFE*/, "Side"
2944         };
2945         hda_nid_t nid;
2946         int i, err;
2947
2948         for (i = 0; i < cfg->line_outs; i++) {
2949                 hda_nid_t dac = spec->multiout.dac_nids[i];
2950                 if (! dac)
2951                         continue;
2952                 nid = ad1988_mixer_nids[ad1988_pin_idx(cfg->line_out_pins[i])];
2953                 if (i == 2) {
2954                         /* Center/LFE */
2955                         err = add_control(spec, AD_CTL_WIDGET_VOL,
2956                                           "Center Playback Volume",
2957                                           HDA_COMPOSE_AMP_VAL(dac, 1, 0, HDA_OUTPUT));
2958                         if (err < 0)
2959                                 return err;
2960                         err = add_control(spec, AD_CTL_WIDGET_VOL,
2961                                           "LFE Playback Volume",
2962                                           HDA_COMPOSE_AMP_VAL(dac, 2, 0, HDA_OUTPUT));
2963                         if (err < 0)
2964                                 return err;
2965                         err = add_control(spec, AD_CTL_BIND_MUTE,
2966                                           "Center Playback Switch",
2967                                           HDA_COMPOSE_AMP_VAL(nid, 1, 2, HDA_INPUT));
2968                         if (err < 0)
2969                                 return err;
2970                         err = add_control(spec, AD_CTL_BIND_MUTE,
2971                                           "LFE Playback Switch",
2972                                           HDA_COMPOSE_AMP_VAL(nid, 2, 2, HDA_INPUT));
2973                         if (err < 0)
2974                                 return err;
2975                 } else {
2976                         sprintf(name, "%s Playback Volume", chname[i]);
2977                         err = add_control(spec, AD_CTL_WIDGET_VOL, name,
2978                                           HDA_COMPOSE_AMP_VAL(dac, 3, 0, HDA_OUTPUT));
2979                         if (err < 0)
2980                                 return err;
2981                         sprintf(name, "%s Playback Switch", chname[i]);
2982                         err = add_control(spec, AD_CTL_BIND_MUTE, name,
2983                                           HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
2984                         if (err < 0)
2985                                 return err;
2986                 }
2987         }
2988         return 0;
2989 }
2990
2991 /* add playback controls for speaker and HP outputs */
2992 static int ad1988_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
2993                                         const char *pfx)
2994 {
2995         struct ad198x_spec *spec = codec->spec;
2996         hda_nid_t nid;
2997         int i, idx, err;
2998         char name[32];
2999
3000         if (! pin)
3001                 return 0;
3002
3003         idx = ad1988_pin_idx(pin);
3004         nid = ad1988_idx_to_dac(codec, idx);
3005         /* check whether the corresponding DAC was already taken */
3006         for (i = 0; i < spec->autocfg.line_outs; i++) {
3007                 hda_nid_t pin = spec->autocfg.line_out_pins[i];
3008                 hda_nid_t dac = ad1988_idx_to_dac(codec, ad1988_pin_idx(pin));
3009                 if (dac == nid)
3010                         break;
3011         }
3012         if (i >= spec->autocfg.line_outs) {
3013                 /* specify the DAC as the extra output */
3014                 if (!spec->multiout.hp_nid)
3015                         spec->multiout.hp_nid = nid;
3016                 else
3017                         spec->multiout.extra_out_nid[0] = nid;
3018                 /* control HP volume/switch on the output mixer amp */
3019                 sprintf(name, "%s Playback Volume", pfx);
3020                 err = add_control(spec, AD_CTL_WIDGET_VOL, name,
3021                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
3022                 if (err < 0)
3023                         return err;
3024         }
3025         nid = ad1988_mixer_nids[idx];
3026         sprintf(name, "%s Playback Switch", pfx);
3027         if ((err = add_control(spec, AD_CTL_BIND_MUTE, name,
3028                                HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT))) < 0)
3029                 return err;
3030         return 0;
3031 }
3032
3033 /* create input playback/capture controls for the given pin */
3034 static int new_analog_input(struct ad198x_spec *spec, hda_nid_t pin,
3035                             const char *ctlname, int ctlidx, int boost)
3036 {
3037         char name[32];
3038         int err, idx;
3039
3040         sprintf(name, "%s Playback Volume", ctlname);
3041         idx = ad1988_pin_to_loopback_idx(pin);
3042         if ((err = add_control(spec, AD_CTL_WIDGET_VOL, name,
3043                                HDA_COMPOSE_AMP_VAL(0x20, 3, idx, HDA_INPUT))) < 0)
3044                 return err;
3045         sprintf(name, "%s Playback Switch", ctlname);
3046         if ((err = add_control(spec, AD_CTL_WIDGET_MUTE, name,
3047                                HDA_COMPOSE_AMP_VAL(0x20, 3, idx, HDA_INPUT))) < 0)
3048                 return err;
3049         if (boost) {
3050                 hda_nid_t bnid;
3051                 idx = ad1988_pin_idx(pin);
3052                 bnid = ad1988_boost_nids[idx];
3053                 if (bnid) {
3054                         sprintf(name, "%s Boost Volume", ctlname);
3055                         return add_control(spec, AD_CTL_WIDGET_VOL, name,
3056                                            HDA_COMPOSE_AMP_VAL(bnid, 3, idx, HDA_OUTPUT));
3057
3058                 }
3059         }
3060         return 0;
3061 }
3062
3063 /* create playback/capture controls for input pins */
3064 static int ad1988_auto_create_analog_input_ctls(struct hda_codec *codec,
3065                                                 const struct auto_pin_cfg *cfg)
3066 {
3067         struct ad198x_spec *spec = codec->spec;
3068         struct hda_input_mux *imux = &spec->private_imux;
3069         int i, err, type, type_idx;
3070
3071         for (i = 0; i < cfg->num_inputs; i++) {
3072                 const char *label;
3073                 type = cfg->inputs[i].type;
3074                 label = hda_get_autocfg_input_label(codec, cfg, i);
3075                 snd_hda_add_imux_item(imux, label,
3076                                       ad1988_pin_to_adc_idx(cfg->inputs[i].pin),
3077                                       &type_idx);
3078                 err = new_analog_input(spec, cfg->inputs[i].pin,
3079                                        label, type_idx,
3080                                        type == AUTO_PIN_MIC);
3081                 if (err < 0)
3082                         return err;
3083         }
3084         snd_hda_add_imux_item(imux, "Mix", 9, NULL);
3085
3086         if ((err = add_control(spec, AD_CTL_WIDGET_VOL,
3087                                "Analog Mix Playback Volume",
3088                                HDA_COMPOSE_AMP_VAL(0x21, 3, 0x0, HDA_OUTPUT))) < 0)
3089                 return err;
3090         if ((err = add_control(spec, AD_CTL_WIDGET_MUTE,
3091                                "Analog Mix Playback Switch",
3092                                HDA_COMPOSE_AMP_VAL(0x21, 3, 0x0, HDA_OUTPUT))) < 0)
3093                 return err;
3094
3095         return 0;
3096 }
3097
3098 static void ad1988_auto_set_output_and_unmute(struct hda_codec *codec,
3099                                               hda_nid_t nid, int pin_type,
3100                                               int dac_idx)
3101 {
3102         /* set as output */
3103         snd_hda_set_pin_ctl(codec, nid, pin_type);
3104         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
3105         switch (nid) {
3106         case 0x11: /* port-A - DAC 03 */
3107                 snd_hda_codec_write(codec, 0x37, 0, AC_VERB_SET_CONNECT_SEL, 0x00);
3108                 break;
3109         case 0x14: /* port-B - DAC 06 */
3110                 snd_hda_codec_write(codec, 0x30, 0, AC_VERB_SET_CONNECT_SEL, 0x02);
3111                 break;
3112         case 0x15: /* port-C - DAC 05 */
3113                 snd_hda_codec_write(codec, 0x31, 0, AC_VERB_SET_CONNECT_SEL, 0x00);
3114                 break;
3115         case 0x17: /* port-E - DAC 0a */
3116                 snd_hda_codec_write(codec, 0x32, 0, AC_VERB_SET_CONNECT_SEL, 0x01);
3117                 break;
3118         case 0x13: /* mono - DAC 04 */
3119                 snd_hda_codec_write(codec, 0x36, 0, AC_VERB_SET_CONNECT_SEL, 0x01);
3120                 break;
3121         }
3122 }
3123
3124 static void ad1988_auto_init_multi_out(struct hda_codec *codec)
3125 {
3126         struct ad198x_spec *spec = codec->spec;
3127         int i;
3128
3129         for (i = 0; i < spec->autocfg.line_outs; i++) {
3130                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
3131                 ad1988_auto_set_output_and_unmute(codec, nid, PIN_OUT, i);
3132         }
3133 }
3134
3135 static void ad1988_auto_init_extra_out(struct hda_codec *codec)
3136 {
3137         struct ad198x_spec *spec = codec->spec;
3138         hda_nid_t pin;
3139
3140         pin = spec->autocfg.speaker_pins[0];
3141         if (pin) /* connect to front */
3142                 ad1988_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
3143         pin = spec->autocfg.hp_pins[0];
3144         if (pin) /* connect to front */
3145                 ad1988_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
3146 }
3147
3148 static void ad1988_auto_init_analog_input(struct hda_codec *codec)
3149 {
3150         struct ad198x_spec *spec = codec->spec;
3151         const struct auto_pin_cfg *cfg = &spec->autocfg;
3152         int i, idx;
3153
3154         for (i = 0; i < cfg->num_inputs; i++) {
3155                 hda_nid_t nid = cfg->inputs[i].pin;
3156                 int type = cfg->inputs[i].type;
3157                 int val;
3158                 switch (nid) {
3159                 case 0x15: /* port-C */
3160                         snd_hda_codec_write(codec, 0x33, 0, AC_VERB_SET_CONNECT_SEL, 0x0);
3161                         break;
3162                 case 0x17: /* port-E */
3163                         snd_hda_codec_write(codec, 0x34, 0, AC_VERB_SET_CONNECT_SEL, 0x0);
3164                         break;
3165                 }
3166                 val = PIN_IN;
3167                 if (type == AUTO_PIN_MIC)
3168                         val |= snd_hda_get_default_vref(codec, nid);
3169                 snd_hda_set_pin_ctl(codec, nid, val);
3170                 if (nid != AD1988_PIN_CD_NID)
3171                         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3172                                             AMP_OUT_MUTE);
3173                 idx = ad1988_pin_idx(nid);
3174                 if (ad1988_boost_nids[idx])
3175                         snd_hda_codec_write(codec, ad1988_boost_nids[idx], 0,
3176                                             AC_VERB_SET_AMP_GAIN_MUTE,
3177                                             AMP_OUT_ZERO);
3178         }
3179 }
3180
3181 /* parse the BIOS configuration and set up the alc_spec */
3182 /* return 1 if successful, 0 if the proper config is not found, or a negative error code */
3183 static int ad1988_parse_auto_config(struct hda_codec *codec)
3184 {
3185         struct ad198x_spec *spec = codec->spec;
3186         int err;
3187
3188         if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL)) < 0)
3189                 return err;
3190         if ((err = ad1988_auto_fill_dac_nids(codec, &spec->autocfg)) < 0)
3191                 return err;
3192         if (! spec->autocfg.line_outs)
3193                 return 0; /* can't find valid BIOS pin config */
3194         if ((err = ad1988_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 ||
3195             (err = ad1988_auto_create_extra_out(codec,
3196                                                 spec->autocfg.speaker_pins[0],
3197                                                 "Speaker")) < 0 ||
3198             (err = ad1988_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
3199                                                 "Headphone")) < 0 ||
3200             (err = ad1988_auto_create_analog_input_ctls(codec, &spec->autocfg)) < 0)
3201                 return err;
3202
3203         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3204
3205         if (spec->autocfg.dig_outs)
3206                 spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
3207         if (spec->autocfg.dig_in_pin)
3208                 spec->dig_in_nid = AD1988_SPDIF_IN;
3209
3210         if (spec->kctls.list)
3211                 spec->mixers[spec->num_mixers++] = spec->kctls.list;
3212
3213         spec->init_verbs[spec->num_init_verbs++] = ad1988_6stack_init_verbs;
3214
3215         spec->input_mux = &spec->private_imux;
3216
3217         return 1;
3218 }
3219
3220 /* init callback for auto-configuration model -- overriding the default init */
3221 static int ad1988_auto_init(struct hda_codec *codec)
3222 {
3223         ad198x_init(codec);
3224         ad1988_auto_init_multi_out(codec);
3225         ad1988_auto_init_extra_out(codec);
3226         ad1988_auto_init_analog_input(codec);
3227         return 0;
3228 }
3229
3230 /*
3231  */
3232
3233 static const char * const ad1988_models[AD1988_MODEL_LAST] = {
3234         [AD1988_6STACK]         = "6stack",
3235         [AD1988_6STACK_DIG]     = "6stack-dig",
3236         [AD1988_3STACK]         = "3stack",
3237         [AD1988_3STACK_DIG]     = "3stack-dig",
3238         [AD1988_LAPTOP]         = "laptop",
3239         [AD1988_LAPTOP_DIG]     = "laptop-dig",
3240         [AD1988_AUTO]           = "auto",
3241 };
3242
3243 static const struct snd_pci_quirk ad1988_cfg_tbl[] = {
3244         SND_PCI_QUIRK(0x1043, 0x81ec, "Asus P5B-DLX", AD1988_6STACK_DIG),
3245         SND_PCI_QUIRK(0x1043, 0x81f6, "Asus M2N-SLI", AD1988_6STACK_DIG),
3246         SND_PCI_QUIRK(0x1043, 0x8277, "Asus P5K-E/WIFI-AP", AD1988_6STACK_DIG),
3247         SND_PCI_QUIRK(0x1043, 0x82c0, "Asus M3N-HT Deluxe", AD1988_6STACK_DIG),
3248         SND_PCI_QUIRK(0x1043, 0x8311, "Asus P5Q-Premium/Pro", AD1988_6STACK_DIG),
3249         {}
3250 };
3251
3252 static int patch_ad1988(struct hda_codec *codec)
3253 {
3254         struct ad198x_spec *spec;
3255         int err, board_config;
3256
3257         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3258         if (spec == NULL)
3259                 return -ENOMEM;
3260
3261         codec->spec = spec;
3262
3263         if (is_rev2(codec))
3264                 snd_printk(KERN_INFO "patch_analog: AD1988A rev.2 is detected, enable workarounds\n");
3265
3266         board_config = snd_hda_check_board_config(codec, AD1988_MODEL_LAST,
3267                                                   ad1988_models, ad1988_cfg_tbl);
3268         if (board_config < 0) {
3269                 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
3270                        codec->chip_name);
3271                 board_config = AD1988_AUTO;
3272         }
3273
3274         if (board_config == AD1988_AUTO) {
3275                 /* automatic parse from the BIOS config */
3276                 err = ad1988_parse_auto_config(codec);
3277                 if (err < 0) {
3278                         ad198x_free(codec);
3279                         return err;
3280                 } else if (! err) {
3281                         printk(KERN_INFO "hda_codec: Cannot set up configuration from BIOS.  Using 6-stack mode...\n");
3282                         board_config = AD1988_6STACK;
3283                 }
3284         }
3285
3286         err = snd_hda_attach_beep_device(codec, 0x10);
3287         if (err < 0) {
3288                 ad198x_free(codec);
3289                 return err;
3290         }
3291         set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
3292
3293         if (!spec->multiout.hp_nid)
3294                 spec->multiout.hp_nid = ad1988_alt_dac_nid[0];
3295         switch (board_config) {
3296         case AD1988_6STACK:
3297         case AD1988_6STACK_DIG:
3298                 spec->multiout.max_channels = 8;
3299                 spec->multiout.num_dacs = 4;
3300                 if (is_rev2(codec))
3301                         spec->multiout.dac_nids = ad1988_6stack_dac_nids_rev2;
3302                 else
3303                         spec->multiout.dac_nids = ad1988_6stack_dac_nids;
3304                 spec->input_mux = &ad1988_6stack_capture_source;
3305                 spec->num_mixers = 2;
3306                 if (is_rev2(codec))
3307                         spec->mixers[0] = ad1988_6stack_mixers1_rev2;
3308                 else
3309                         spec->mixers[0] = ad1988_6stack_mixers1;
3310                 spec->mixers[1] = ad1988_6stack_mixers2;
3311                 spec->num_init_verbs = 1;
3312                 spec->init_verbs[0] = ad1988_6stack_init_verbs;
3313                 if (board_config == AD1988_6STACK_DIG) {
3314                         spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
3315                         spec->dig_in_nid = AD1988_SPDIF_IN;
3316                 }
3317                 break;
3318         case AD1988_3STACK:
3319         case AD1988_3STACK_DIG:
3320                 spec->multiout.max_channels = 6;
3321                 spec->multiout.num_dacs = 3;
3322                 if (is_rev2(codec))
3323                         spec->multiout.dac_nids = ad1988_3stack_dac_nids_rev2;
3324                 else
3325                         spec->multiout.dac_nids = ad1988_3stack_dac_nids;
3326                 spec->input_mux = &ad1988_6stack_capture_source;
3327                 spec->channel_mode = ad1988_3stack_modes;
3328                 spec->num_channel_mode = ARRAY_SIZE(ad1988_3stack_modes);
3329                 spec->num_mixers = 2;
3330                 if (is_rev2(codec))
3331                         spec->mixers[0] = ad1988_3stack_mixers1_rev2;
3332                 else
3333                         spec->mixers[0] = ad1988_3stack_mixers1;
3334                 spec->mixers[1] = ad1988_3stack_mixers2;
3335                 spec->num_init_verbs = 1;
3336                 spec->init_verbs[0] = ad1988_3stack_init_verbs;
3337                 if (board_config == AD1988_3STACK_DIG)
3338                         spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
3339                 break;
3340         case AD1988_LAPTOP:
3341         case AD1988_LAPTOP_DIG:
3342                 spec->multiout.max_channels = 2;
3343                 spec->multiout.num_dacs = 1;
3344                 spec->multiout.dac_nids = ad1988_3stack_dac_nids;
3345                 spec->input_mux = &ad1988_laptop_capture_source;
3346                 spec->num_mixers = 1;
3347                 spec->mixers[0] = ad1988_laptop_mixers;
3348                 spec->inv_eapd = 1; /* inverted EAPD */
3349                 spec->num_init_verbs = 1;
3350                 spec->init_verbs[0] = ad1988_laptop_init_verbs;
3351                 if (board_config == AD1988_LAPTOP_DIG)
3352                         spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
3353                 break;
3354         }
3355
3356         if (spec->autocfg.hp_pins[0]) {
3357                 spec->mixers[spec->num_mixers++] = ad1988_hp_mixers;
3358                 spec->slave_vols = ad1988_6stack_fp_slave_pfxs;
3359                 spec->slave_sws = ad1988_6stack_fp_slave_pfxs;
3360                 spec->alt_dac_nid = ad1988_alt_dac_nid;
3361                 spec->stream_analog_alt_playback =
3362                         &ad198x_pcm_analog_alt_playback;
3363         }
3364
3365         spec->num_adc_nids = ARRAY_SIZE(ad1988_adc_nids);
3366         spec->adc_nids = ad1988_adc_nids;
3367         spec->capsrc_nids = ad1988_capsrc_nids;
3368         spec->mixers[spec->num_mixers++] = ad1988_capture_mixers;
3369         spec->init_verbs[spec->num_init_verbs++] = ad1988_capture_init_verbs;
3370         if (spec->multiout.dig_out_nid) {
3371                 if (codec->vendor_id >= 0x11d4989a) {
3372                         spec->mixers[spec->num_mixers++] =
3373                                 ad1989_spdif_out_mixers;
3374                         spec->init_verbs[spec->num_init_verbs++] =
3375                                 ad1989_spdif_init_verbs;
3376                         codec->slave_dig_outs = ad1989b_slave_dig_outs;
3377                 } else {
3378                         spec->mixers[spec->num_mixers++] =
3379                                 ad1988_spdif_out_mixers;
3380                         spec->init_verbs[spec->num_init_verbs++] =
3381                                 ad1988_spdif_init_verbs;
3382                 }
3383         }
3384         if (spec->dig_in_nid && codec->vendor_id < 0x11d4989a) {
3385                 spec->mixers[spec->num_mixers++] = ad1988_spdif_in_mixers;
3386                 spec->init_verbs[spec->num_init_verbs++] =
3387                         ad1988_spdif_in_init_verbs;
3388         }
3389
3390         codec->patch_ops = ad198x_patch_ops;
3391         switch (board_config) {
3392         case AD1988_AUTO:
3393                 codec->patch_ops.init = ad1988_auto_init;
3394                 break;
3395         case AD1988_LAPTOP:
3396         case AD1988_LAPTOP_DIG:
3397                 codec->patch_ops.unsol_event = ad1988_laptop_unsol_event;
3398                 break;
3399         }
3400 #ifdef CONFIG_PM
3401         spec->loopback.amplist = ad1988_loopbacks;
3402 #endif
3403         spec->vmaster_nid = 0x04;
3404
3405         codec->no_trigger_sense = 1;
3406         codec->no_sticky_stream = 1;
3407
3408         return 0;
3409 }
3410
3411
3412 /*
3413  * AD1884 / AD1984
3414  *
3415  * port-B - front line/mic-in
3416  * port-E - aux in/out
3417  * port-F - aux in/out
3418  * port-C - rear line/mic-in
3419  * port-D - rear line/hp-out
3420  * port-A - front line/hp-out
3421  *
3422  * AD1984 = AD1884 + two digital mic-ins
3423  *
3424  * FIXME:
3425  * For simplicity, we share the single DAC for both HP and line-outs
3426  * right now.  The inidividual playbacks could be easily implemented,
3427  * but no build-up framework is given, so far.
3428  */
3429
3430 static const hda_nid_t ad1884_dac_nids[1] = {
3431         0x04,
3432 };
3433
3434 static const hda_nid_t ad1884_adc_nids[2] = {
3435         0x08, 0x09,
3436 };
3437
3438 static const hda_nid_t ad1884_capsrc_nids[2] = {
3439         0x0c, 0x0d,
3440 };
3441
3442 #define AD1884_SPDIF_OUT        0x02
3443
3444 static const struct hda_input_mux ad1884_capture_source = {
3445         .num_items = 4,
3446         .items = {
3447                 { "Front Mic", 0x0 },
3448                 { "Mic", 0x1 },
3449                 { "CD", 0x2 },
3450                 { "Mix", 0x3 },
3451         },
3452 };
3453
3454 static const struct snd_kcontrol_new ad1884_base_mixers[] = {
3455         HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
3456         /* HDA_CODEC_VOLUME_IDX("PCM Playback Volume", 1, 0x03, 0x0, HDA_OUTPUT), */
3457         HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
3458         HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT),
3459         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
3460         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
3461         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
3462         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3463         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
3464         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
3465         HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x02, HDA_INPUT),
3466         HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x02, HDA_INPUT),
3467         HDA_CODEC_VOLUME("Mic Boost Volume", 0x15, 0x0, HDA_INPUT),
3468         HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
3469         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3470         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3471         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
3472         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
3473         {
3474                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3475                 /* The multiple "Capture Source" controls confuse alsamixer
3476                  * So call somewhat different..
3477                  */
3478                 /* .name = "Capture Source", */
3479                 .name = "Input Source",
3480                 .count = 2,
3481                 .info = ad198x_mux_enum_info,
3482                 .get = ad198x_mux_enum_get,
3483                 .put = ad198x_mux_enum_put,
3484         },
3485         /* SPDIF controls */
3486         HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
3487         {
3488                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3489                 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
3490                 /* identical with ad1983 */
3491                 .info = ad1983_spdif_route_info,
3492                 .get = ad1983_spdif_route_get,
3493                 .put = ad1983_spdif_route_put,
3494         },
3495         { } /* end */
3496 };
3497
3498 static const struct snd_kcontrol_new ad1984_dmic_mixers[] = {
3499         HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x05, 0x0, HDA_INPUT),
3500         HDA_CODEC_MUTE("Digital Mic Capture Switch", 0x05, 0x0, HDA_INPUT),
3501         HDA_CODEC_VOLUME_IDX("Digital Mic Capture Volume", 1, 0x06, 0x0,
3502                              HDA_INPUT),
3503         HDA_CODEC_MUTE_IDX("Digital Mic Capture Switch", 1, 0x06, 0x0,
3504                            HDA_INPUT),
3505         { } /* end */
3506 };
3507
3508 /*
3509  * initialization verbs
3510  */
3511 static const struct hda_verb ad1884_init_verbs[] = {
3512         /* DACs; mute as default */
3513         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3514         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3515         /* Port-A (HP) mixer */
3516         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3517         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3518         /* Port-A pin */
3519         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3520         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3521         /* HP selector - select DAC2 */
3522         {0x22, AC_VERB_SET_CONNECT_SEL, 0x1},
3523         /* Port-D (Line-out) mixer */
3524         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3525         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3526         /* Port-D pin */
3527         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3528         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3529         /* Mono-out mixer */
3530         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3531         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3532         /* Mono-out pin */
3533         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3534         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3535         /* Mono selector */
3536         {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
3537         /* Port-B (front mic) pin */
3538         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3539         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3540         /* Port-C (rear mic) pin */
3541         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3542         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3543         /* Analog mixer; mute as default */
3544         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3545         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3546         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3547         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3548         /* Analog Mix output amp */
3549         {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
3550         /* SPDIF output selector */
3551         {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */
3552         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
3553         { } /* end */
3554 };
3555
3556 #ifdef CONFIG_PM
3557 static const struct hda_amp_list ad1884_loopbacks[] = {
3558         { 0x20, HDA_INPUT, 0 }, /* Front Mic */
3559         { 0x20, HDA_INPUT, 1 }, /* Mic */
3560         { 0x20, HDA_INPUT, 2 }, /* CD */
3561         { 0x20, HDA_INPUT, 4 }, /* Docking */
3562         { } /* end */
3563 };
3564 #endif
3565
3566 static const char * const ad1884_slave_vols[] = {
3567         "PCM", "Mic", "Mono", "Front Mic", "Mic", "CD",
3568         "Internal Mic", "Dock Mic", /* "Beep", */ "IEC958",
3569         NULL
3570 };
3571
3572 static int patch_ad1884(struct hda_codec *codec)
3573 {
3574         struct ad198x_spec *spec;
3575         int err;
3576
3577         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3578         if (spec == NULL)
3579                 return -ENOMEM;
3580
3581         codec->spec = spec;
3582
3583         err = snd_hda_attach_beep_device(codec, 0x10);
3584         if (err < 0) {
3585                 ad198x_free(codec);
3586                 return err;
3587         }
3588         set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
3589
3590         spec->multiout.max_channels = 2;
3591         spec->multiout.num_dacs = ARRAY_SIZE(ad1884_dac_nids);
3592         spec->multiout.dac_nids = ad1884_dac_nids;
3593         spec->multiout.dig_out_nid = AD1884_SPDIF_OUT;
3594         spec->num_adc_nids = ARRAY_SIZE(ad1884_adc_nids);
3595         spec->adc_nids = ad1884_adc_nids;
3596         spec->capsrc_nids = ad1884_capsrc_nids;
3597         spec->input_mux = &ad1884_capture_source;
3598         spec->num_mixers = 1;
3599         spec->mixers[0] = ad1884_base_mixers;
3600         spec->num_init_verbs = 1;
3601         spec->init_verbs[0] = ad1884_init_verbs;
3602         spec->spdif_route = 0;
3603 #ifdef CONFIG_PM
3604         spec->loopback.amplist = ad1884_loopbacks;
3605 #endif
3606         spec->vmaster_nid = 0x04;
3607         /* we need to cover all playback volumes */
3608         spec->slave_vols = ad1884_slave_vols;
3609         /* slaves may contain input volumes, so we can't raise to 0dB blindly */
3610         spec->avoid_init_slave_vol = 1;
3611
3612         codec->patch_ops = ad198x_patch_ops;
3613
3614         codec->no_trigger_sense = 1;
3615         codec->no_sticky_stream = 1;
3616
3617         return 0;
3618 }
3619
3620 /*
3621  * Lenovo Thinkpad T61/X61
3622  */
3623 static const struct hda_input_mux ad1984_thinkpad_capture_source = {
3624         .num_items = 4,
3625         .items = {
3626                 { "Mic", 0x0 },
3627                 { "Internal Mic", 0x1 },
3628                 { "Mix", 0x3 },
3629                 { "Dock Mic", 0x4 },
3630         },
3631 };
3632
3633
3634 /*
3635  * Dell Precision T3400
3636  */
3637 static const struct hda_input_mux ad1984_dell_desktop_capture_source = {
3638         .num_items = 3,
3639         .items = {
3640                 { "Front Mic", 0x0 },
3641                 { "Line-In", 0x1 },
3642                 { "Mix", 0x3 },
3643         },
3644 };
3645
3646
3647 static const struct snd_kcontrol_new ad1984_thinkpad_mixers[] = {
3648         HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
3649         /* HDA_CODEC_VOLUME_IDX("PCM Playback Volume", 1, 0x03, 0x0, HDA_OUTPUT), */
3650         HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
3651         HDA_CODEC_MUTE("Speaker Playback Switch", 0x12, 0x0, HDA_OUTPUT),
3652         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
3653         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3654         HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
3655         HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
3656         HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x03, HDA_INPUT),
3657         HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x03, HDA_INPUT),
3658         HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
3659         HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
3660         HDA_CODEC_VOLUME("Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
3661         HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x15, 0x0, HDA_INPUT),
3662         HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x25, 0x0, HDA_OUTPUT),
3663         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3664         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3665         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
3666         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
3667         {
3668                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3669                 /* The multiple "Capture Source" controls confuse alsamixer
3670                  * So call somewhat different..
3671                  */
3672                 /* .name = "Capture Source", */
3673                 .name = "Input Source",
3674                 .count = 2,
3675                 .info = ad198x_mux_enum_info,
3676                 .get = ad198x_mux_enum_get,
3677                 .put = ad198x_mux_enum_put,
3678         },
3679         /* SPDIF controls */
3680         HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
3681         {
3682                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3683                 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
3684                 /* identical with ad1983 */
3685                 .info = ad1983_spdif_route_info,
3686                 .get = ad1983_spdif_route_get,
3687                 .put = ad1983_spdif_route_put,
3688         },
3689         { } /* end */
3690 };
3691
3692 /* additional verbs */
3693 static const struct hda_verb ad1984_thinkpad_init_verbs[] = {
3694         /* Port-E (docking station mic) pin */
3695         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3696         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3697         /* docking mic boost */
3698         {0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3699         /* Analog PC Beeper - allow firmware/ACPI beeps */
3700         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3) | 0x1a},
3701         /* Analog mixer - docking mic; mute as default */
3702         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3703         /* enable EAPD bit */
3704         {0x12, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
3705         { } /* end */
3706 };
3707
3708 /*
3709  * Dell Precision T3400
3710  */
3711 static const struct snd_kcontrol_new ad1984_dell_desktop_mixers[] = {
3712         HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
3713         HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
3714         HDA_CODEC_MUTE("Speaker Playback Switch", 0x12, 0x0, HDA_OUTPUT),
3715         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
3716         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
3717         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
3718         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3719         HDA_CODEC_VOLUME("Line-In Playback Volume", 0x20, 0x01, HDA_INPUT),
3720         HDA_CODEC_MUTE("Line-In Playback Switch", 0x20, 0x01, HDA_INPUT),
3721         HDA_CODEC_VOLUME("Line-In Boost Volume", 0x15, 0x0, HDA_INPUT),
3722         HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
3723         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3724         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3725         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
3726         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
3727         {
3728                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3729                 /* The multiple "Capture Source" controls confuse alsamixer
3730                  * So call somewhat different..
3731                  */
3732                 /* .name = "Capture Source", */
3733                 .name = "Input Source",
3734                 .count = 2,
3735                 .info = ad198x_mux_enum_info,
3736                 .get = ad198x_mux_enum_get,
3737                 .put = ad198x_mux_enum_put,
3738         },
3739         { } /* end */
3740 };
3741
3742 /* Digial MIC ADC NID 0x05 + 0x06 */
3743 static int ad1984_pcm_dmic_prepare(struct hda_pcm_stream *hinfo,
3744                                    struct hda_codec *codec,
3745                                    unsigned int stream_tag,
3746                                    unsigned int format,
3747                                    struct snd_pcm_substream *substream)
3748 {
3749         snd_hda_codec_setup_stream(codec, 0x05 + substream->number,
3750                                    stream_tag, 0, format);
3751         return 0;
3752 }
3753
3754 static int ad1984_pcm_dmic_cleanup(struct hda_pcm_stream *hinfo,
3755                                    struct hda_codec *codec,
3756                                    struct snd_pcm_substream *substream)
3757 {
3758         snd_hda_codec_cleanup_stream(codec, 0x05 + substream->number);
3759         return 0;
3760 }
3761
3762 static const struct hda_pcm_stream ad1984_pcm_dmic_capture = {
3763         .substreams = 2,
3764         .channels_min = 2,
3765         .channels_max = 2,
3766         .nid = 0x05,
3767         .ops = {
3768                 .prepare = ad1984_pcm_dmic_prepare,
3769                 .cleanup = ad1984_pcm_dmic_cleanup
3770         },
3771 };
3772
3773 static int ad1984_build_pcms(struct hda_codec *codec)
3774 {
3775         struct ad198x_spec *spec = codec->spec;
3776         struct hda_pcm *info;
3777         int err;
3778
3779         err = ad198x_build_pcms(codec);
3780         if (err < 0)
3781                 return err;
3782
3783         info = spec->pcm_rec + codec->num_pcms;
3784         codec->num_pcms++;
3785         info->name = "AD1984 Digital Mic";
3786         info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad1984_pcm_dmic_capture;
3787         return 0;
3788 }
3789
3790 /* models */
3791 enum {
3792         AD1984_BASIC,
3793         AD1984_THINKPAD,
3794         AD1984_DELL_DESKTOP,
3795         AD1984_MODELS
3796 };
3797
3798 static const char * const ad1984_models[AD1984_MODELS] = {
3799         [AD1984_BASIC]          = "basic",
3800         [AD1984_THINKPAD]       = "thinkpad",
3801         [AD1984_DELL_DESKTOP]   = "dell_desktop",
3802 };
3803
3804 static const struct snd_pci_quirk ad1984_cfg_tbl[] = {
3805         /* Lenovo Thinkpad T61/X61 */
3806         SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo Thinkpad", AD1984_THINKPAD),
3807         SND_PCI_QUIRK(0x1028, 0x0214, "Dell T3400", AD1984_DELL_DESKTOP),
3808         SND_PCI_QUIRK(0x1028, 0x0233, "Dell Latitude E6400", AD1984_DELL_DESKTOP),
3809         {}
3810 };
3811
3812 static int patch_ad1984(struct hda_codec *codec)
3813 {
3814         struct ad198x_spec *spec;
3815         int board_config, err;
3816
3817         err = patch_ad1884(codec);
3818         if (err < 0)
3819                 return err;
3820         spec = codec->spec;
3821         board_config = snd_hda_check_board_config(codec, AD1984_MODELS,
3822                                                   ad1984_models, ad1984_cfg_tbl);
3823         switch (board_config) {
3824         case AD1984_BASIC:
3825                 /* additional digital mics */
3826                 spec->mixers[spec->num_mixers++] = ad1984_dmic_mixers;
3827                 codec->patch_ops.build_pcms = ad1984_build_pcms;
3828                 break;
3829         case AD1984_THINKPAD:
3830                 if (codec->subsystem_id == 0x17aa20fb) {
3831                         /* Thinpad X300 does not have the ability to do SPDIF,
3832                            or attach to docking station to use SPDIF */
3833                         spec->multiout.dig_out_nid = 0;
3834                 } else
3835                         spec->multiout.dig_out_nid = AD1884_SPDIF_OUT;
3836                 spec->input_mux = &ad1984_thinkpad_capture_source;
3837                 spec->mixers[0] = ad1984_thinkpad_mixers;
3838                 spec->init_verbs[spec->num_init_verbs++] = ad1984_thinkpad_init_verbs;
3839                 spec->analog_beep = 1;
3840                 break;
3841         case AD1984_DELL_DESKTOP:
3842                 spec->multiout.dig_out_nid = 0;
3843                 spec->input_mux = &ad1984_dell_desktop_capture_source;
3844                 spec->mixers[0] = ad1984_dell_desktop_mixers;
3845                 break;
3846         }
3847         return 0;
3848 }
3849
3850
3851 /*
3852  * AD1883 / AD1884A / AD1984A / AD1984B
3853  *
3854  * port-B (0x14) - front mic-in
3855  * port-E (0x1c) - rear mic-in
3856  * port-F (0x16) - CD / ext out
3857  * port-C (0x15) - rear line-in
3858  * port-D (0x12) - rear line-out
3859  * port-A (0x11) - front hp-out
3860  *
3861  * AD1984A = AD1884A + digital-mic
3862  * AD1883 = equivalent with AD1984A
3863  * AD1984B = AD1984A + extra SPDIF-out
3864  *
3865  * FIXME:
3866  * We share the single DAC for both HP and line-outs (see AD1884/1984).
3867  */
3868
3869 static const hda_nid_t ad1884a_dac_nids[1] = {
3870         0x03,
3871 };
3872
3873 #define ad1884a_adc_nids        ad1884_adc_nids
3874 #define ad1884a_capsrc_nids     ad1884_capsrc_nids
3875
3876 #define AD1884A_SPDIF_OUT       0x02
3877
3878 static const struct hda_input_mux ad1884a_capture_source = {
3879         .num_items = 5,
3880         .items = {
3881                 { "Front Mic", 0x0 },
3882                 { "Mic", 0x4 },
3883                 { "Line", 0x1 },
3884                 { "CD", 0x2 },
3885                 { "Mix", 0x3 },
3886         },
3887 };
3888
3889 static const struct snd_kcontrol_new ad1884a_base_mixers[] = {
3890         HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
3891         HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),
3892         HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
3893         HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT),
3894         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
3895         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
3896         HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
3897         HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
3898         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
3899         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3900         HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x01, HDA_INPUT),
3901         HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x01, HDA_INPUT),
3902         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
3903         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
3904         HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x02, HDA_INPUT),
3905         HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x02, HDA_INPUT),
3906         HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
3907         HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x0, HDA_INPUT),
3908         HDA_CODEC_VOLUME("Mic Boost Volume", 0x25, 0x0, HDA_OUTPUT),
3909         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3910         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3911         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
3912         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
3913         {
3914                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3915                 /* The multiple "Capture Source" controls confuse alsamixer
3916                  * So call somewhat different..
3917                  */
3918                 /* .name = "Capture Source", */
3919                 .name = "Input Source",
3920                 .count = 2,
3921                 .info = ad198x_mux_enum_info,
3922                 .get = ad198x_mux_enum_get,
3923                 .put = ad198x_mux_enum_put,
3924         },
3925         /* SPDIF controls */
3926         HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
3927         {
3928                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3929                 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
3930                 /* identical with ad1983 */
3931                 .info = ad1983_spdif_route_info,
3932                 .get = ad1983_spdif_route_get,
3933                 .put = ad1983_spdif_route_put,
3934         },
3935         { } /* end */
3936 };
3937
3938 /*
3939  * initialization verbs
3940  */
3941 static const struct hda_verb ad1884a_init_verbs[] = {
3942         /* DACs; unmute as default */
3943         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
3944         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
3945         /* Port-A (HP) mixer - route only from analog mixer */
3946         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3947         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3948         /* Port-A pin */
3949         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3950         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3951         /* Port-D (Line-out) mixer - route only from analog mixer */
3952         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3953         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3954         /* Port-D pin */
3955         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3956         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3957         /* Mono-out mixer - route only from analog mixer */
3958         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3959         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3960         /* Mono-out pin */
3961         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3962         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3963         /* Port-B (front mic) pin */
3964         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3965         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3966         /* Port-C (rear line-in) pin */
3967         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3968         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3969         /* Port-E (rear mic) pin */
3970         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3971         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3972         {0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* no boost */
3973         /* Port-F (CD) pin */
3974         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3975         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3976         /* Analog mixer; mute as default */
3977         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3978         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3979         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3980         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3981         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, /* aux */
3982         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
3983         /* Analog Mix output amp */
3984         {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3985         /* capture sources */
3986         {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0},
3987         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3988         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
3989         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3990         /* SPDIF output amp */
3991         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
3992         { } /* end */
3993 };
3994
3995 #ifdef CONFIG_PM
3996 static const struct hda_amp_list ad1884a_loopbacks[] = {
3997         { 0x20, HDA_INPUT, 0 }, /* Front Mic */
3998         { 0x20, HDA_INPUT, 1 }, /* Mic */
3999         { 0x20, HDA_INPUT, 2 }, /* CD */
4000         { 0x20, HDA_INPUT, 4 }, /* Docking */
4001         { } /* end */
4002 };
4003 #endif
4004
4005 /*
4006  * Laptop model
4007  *
4008  * Port A: Headphone jack
4009  * Port B: MIC jack
4010  * Port C: Internal MIC
4011  * Port D: Dock Line Out (if enabled)
4012  * Port E: Dock Line In (if enabled)
4013  * Port F: Internal speakers
4014  */
4015
4016 static int ad1884a_mobile_master_sw_put(struct snd_kcontrol *kcontrol,
4017                                         struct snd_ctl_elem_value *ucontrol)
4018 {
4019         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4020         int ret = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
4021         int mute = (!ucontrol->value.integer.value[0] &&
4022                     !ucontrol->value.integer.value[1]);
4023         /* toggle GPIO1 according to the mute state */
4024         snd_hda_codec_write_cache(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
4025                             mute ? 0x02 : 0x0);
4026         return ret;
4027 }
4028
4029 static const struct snd_kcontrol_new ad1884a_laptop_mixers[] = {
4030         HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
4031         {
4032                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4033                 .name = "Master Playback Switch",
4034                 .subdevice = HDA_SUBDEV_AMP_FLAG,
4035                 .info = snd_hda_mixer_amp_switch_info,
4036                 .get = snd_hda_mixer_amp_switch_get,
4037                 .put = ad1884a_mobile_master_sw_put,
4038                 .private_value = HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
4039         },
4040         HDA_CODEC_MUTE("Dock Playback Switch", 0x12, 0x0, HDA_OUTPUT),
4041         HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
4042         HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
4043         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
4044         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
4045         HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
4046         HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
4047         HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
4048         HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
4049         HDA_CODEC_VOLUME("Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
4050         HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x15, 0x0, HDA_INPUT),
4051         HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x25, 0x0, HDA_OUTPUT),
4052         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
4053         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
4054         { } /* end */
4055 };
4056
4057 static const struct snd_kcontrol_new ad1884a_mobile_mixers[] = {
4058         HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
4059         /*HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/
4060         {
4061                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4062                 .name = "Master Playback Switch",
4063                 .subdevice = HDA_SUBDEV_AMP_FLAG,
4064                 .info = snd_hda_mixer_amp_switch_info,
4065                 .get = snd_hda_mixer_amp_switch_get,
4066                 .put = ad1884a_mobile_master_sw_put,
4067                 .private_value = HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
4068         },
4069         HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
4070         HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
4071         HDA_CODEC_VOLUME("Mic Capture Volume", 0x14, 0x0, HDA_INPUT),
4072         HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x15, 0x0, HDA_INPUT),
4073         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
4074         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
4075         { } /* end */
4076 };
4077
4078 /* mute internal speaker if HP is plugged */
4079 static void ad1884a_hp_automute(struct hda_codec *codec)
4080 {
4081         unsigned int present;
4082
4083         present = snd_hda_jack_detect(codec, 0x11);
4084         snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
4085                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
4086         snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_EAPD_BTLENABLE,
4087                             present ? 0x00 : 0x02);
4088 }
4089
4090 /* switch to external mic if plugged */
4091 static void ad1884a_hp_automic(struct hda_codec *codec)
4092 {
4093         unsigned int present;
4094
4095         present = snd_hda_jack_detect(codec, 0x14);
4096         snd_hda_codec_write(codec, 0x0c, 0, AC_VERB_SET_CONNECT_SEL,
4097                             present ? 0 : 1);
4098 }
4099
4100 #define AD1884A_HP_EVENT                0x37
4101 #define AD1884A_MIC_EVENT               0x36
4102
4103 /* unsolicited event for HP jack sensing */
4104 static void ad1884a_hp_unsol_event(struct hda_codec *codec, unsigned int res)
4105 {
4106         switch (res >> 26) {
4107         case AD1884A_HP_EVENT:
4108                 ad1884a_hp_automute(codec);
4109                 break;
4110         case AD1884A_MIC_EVENT:
4111                 ad1884a_hp_automic(codec);
4112                 break;
4113         }
4114 }
4115
4116 /* initialize jack-sensing, too */
4117 static int ad1884a_hp_init(struct hda_codec *codec)
4118 {
4119         ad198x_init(codec);
4120         ad1884a_hp_automute(codec);
4121         ad1884a_hp_automic(codec);
4122         return 0;
4123 }
4124
4125 /* mute internal speaker if HP or docking HP is plugged */
4126 static void ad1884a_laptop_automute(struct hda_codec *codec)
4127 {
4128         unsigned int present;
4129
4130         present = snd_hda_jack_detect(codec, 0x11);
4131         if (!present)
4132                 present = snd_hda_jack_detect(codec, 0x12);
4133         snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
4134                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
4135         snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_EAPD_BTLENABLE,
4136                             present ? 0x00 : 0x02);
4137 }
4138
4139 /* switch to external mic if plugged */
4140 static void ad1884a_laptop_automic(struct hda_codec *codec)
4141 {
4142         unsigned int idx;
4143
4144         if (snd_hda_jack_detect(codec, 0x14))
4145                 idx = 0;
4146         else if (snd_hda_jack_detect(codec, 0x1c))
4147                 idx = 4;
4148         else
4149                 idx = 1;
4150         snd_hda_codec_write(codec, 0x0c, 0, AC_VERB_SET_CONNECT_SEL, idx);
4151 }
4152
4153 /* unsolicited event for HP jack sensing */
4154 static void ad1884a_laptop_unsol_event(struct hda_codec *codec,
4155                                        unsigned int res)
4156 {
4157         switch (res >> 26) {
4158         case AD1884A_HP_EVENT:
4159                 ad1884a_laptop_automute(codec);
4160                 break;
4161         case AD1884A_MIC_EVENT:
4162                 ad1884a_laptop_automic(codec);
4163                 break;
4164         }
4165 }
4166
4167 /* initialize jack-sensing, too */
4168 static int ad1884a_laptop_init(struct hda_codec *codec)
4169 {
4170         ad198x_init(codec);
4171         ad1884a_laptop_automute(codec);
4172         ad1884a_laptop_automic(codec);
4173         return 0;
4174 }
4175
4176 /* additional verbs for laptop model */
4177 static const struct hda_verb ad1884a_laptop_verbs[] = {
4178         /* Port-A (HP) pin - always unmuted */
4179         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4180         /* Port-F (int speaker) mixer - route only from analog mixer */
4181         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4182         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4183         /* Port-F (int speaker) pin */
4184         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4185         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4186         /* required for compaq 6530s/6531s speaker output */
4187         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4188         /* Port-C pin - internal mic-in */
4189         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4190         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
4191         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
4192         /* Port-D (docking line-out) pin - default unmuted */
4193         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4194         /* analog mix */
4195         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4196         /* unsolicited event for pin-sense */
4197         {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
4198         {0x12, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
4199         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT},
4200         {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT},
4201         /* allow to touch GPIO1 (for mute control) */
4202         {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
4203         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
4204         {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, /* first muted */
4205         { } /* end */
4206 };
4207
4208 static const struct hda_verb ad1884a_mobile_verbs[] = {
4209         /* DACs; unmute as default */
4210         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
4211         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
4212         /* Port-A (HP) mixer - route only from analog mixer */
4213         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4214         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4215         /* Port-A pin */
4216         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4217         /* Port-A (HP) pin - always unmuted */
4218         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4219         /* Port-B (mic jack) pin */
4220         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4221         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
4222         /* Port-C (int mic) pin */
4223         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4224         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
4225         /* Port-F (int speaker) mixer - route only from analog mixer */
4226         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4227         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4228         /* Port-F pin */
4229         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4230         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4231         /* Analog mixer; mute as default */
4232         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4233         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4234         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4235         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4236         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4237         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
4238         /* Analog Mix output amp */
4239         {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4240         /* capture sources */
4241         /* {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0}, */ /* set via unsol */
4242         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4243         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
4244         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4245         /* unsolicited event for pin-sense */
4246         {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
4247         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT},
4248         /* allow to touch GPIO1 (for mute control) */
4249         {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
4250         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
4251         {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, /* first muted */
4252         { } /* end */
4253 };
4254
4255 /*
4256  * Thinkpad X300
4257  * 0x11 - HP
4258  * 0x12 - speaker
4259  * 0x14 - mic-in
4260  * 0x17 - built-in mic
4261  */
4262
4263 static const struct hda_verb ad1984a_thinkpad_verbs[] = {
4264         /* HP unmute */
4265         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4266         /* analog mix */
4267         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4268         /* turn on EAPD */
4269         {0x12, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4270         /* unsolicited event for pin-sense */
4271         {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
4272         /* internal mic - dmic */
4273         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4274         /* set magic COEFs for dmic */
4275         {0x01, AC_VERB_SET_COEF_INDEX, 0x13f7},
4276         {0x01, AC_VERB_SET_PROC_COEF, 0x08},
4277         { } /* end */
4278 };
4279
4280 static const struct snd_kcontrol_new ad1984a_thinkpad_mixers[] = {
4281         HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
4282         HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),
4283         HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
4284         HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
4285         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
4286         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
4287         HDA_CODEC_VOLUME("Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
4288         HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x17, 0x0, HDA_INPUT),
4289         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
4290         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
4291         {
4292                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4293                 .name = "Capture Source",
4294                 .info = ad198x_mux_enum_info,
4295                 .get = ad198x_mux_enum_get,
4296                 .put = ad198x_mux_enum_put,
4297         },
4298         { } /* end */
4299 };
4300
4301 static const struct hda_input_mux ad1984a_thinkpad_capture_source = {
4302         .num_items = 3,
4303         .items = {
4304                 { "Mic", 0x0 },
4305                 { "Internal Mic", 0x5 },
4306                 { "Mix", 0x3 },
4307         },
4308 };
4309
4310 /* mute internal speaker if HP is plugged */
4311 static void ad1984a_thinkpad_automute(struct hda_codec *codec)
4312 {
4313         unsigned int present;
4314
4315         present = snd_hda_jack_detect(codec, 0x11);
4316         snd_hda_codec_amp_stereo(codec, 0x12, HDA_OUTPUT, 0,
4317                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
4318 }
4319
4320 /* unsolicited event for HP jack sensing */
4321 static void ad1984a_thinkpad_unsol_event(struct hda_codec *codec,
4322                                          unsigned int res)
4323 {
4324         if ((res >> 26) != AD1884A_HP_EVENT)
4325                 return;
4326         ad1984a_thinkpad_automute(codec);
4327 }
4328
4329 /* initialize jack-sensing, too */
4330 static int ad1984a_thinkpad_init(struct hda_codec *codec)
4331 {
4332         ad198x_init(codec);
4333         ad1984a_thinkpad_automute(codec);
4334         return 0;
4335 }
4336
4337 /*
4338  * Precision R5500
4339  * 0x12 - HP/line-out
4340  * 0x13 - speaker (mono)
4341  * 0x15 - mic-in
4342  */
4343
4344 static const struct hda_verb ad1984a_precision_verbs[] = {
4345         /* Unmute main output path */
4346         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
4347         {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE + 0x1f}, /* 0dB */
4348         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) + 0x17}, /* 0dB */
4349         /* Analog mixer; mute as default */
4350         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4351         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4352         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4353         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4354         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4355         /* Select mic as input */
4356         {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1},
4357         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE + 0x27}, /* 0dB */
4358         /* Configure as mic */
4359         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4360         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
4361         /* HP unmute */
4362         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4363         /* turn on EAPD */
4364         {0x13, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4365         /* unsolicited event for pin-sense */
4366         {0x12, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
4367         { } /* end */
4368 };
4369
4370 static const struct snd_kcontrol_new ad1984a_precision_mixers[] = {
4371         HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
4372         HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),
4373         HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
4374         HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
4375         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
4376         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
4377         HDA_CODEC_VOLUME("Mic Boost Volume", 0x15, 0x0, HDA_INPUT),
4378         HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT),
4379         HDA_CODEC_VOLUME("Speaker Playback Volume", 0x13, 0x0, HDA_OUTPUT),
4380         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
4381         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
4382         { } /* end */
4383 };
4384
4385
4386 /* mute internal speaker if HP is plugged */
4387 static void ad1984a_precision_automute(struct hda_codec *codec)
4388 {
4389         unsigned int present;
4390
4391         present = snd_hda_jack_detect(codec, 0x12);
4392         snd_hda_codec_amp_stereo(codec, 0x13, HDA_OUTPUT, 0,
4393                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
4394 }
4395
4396
4397 /* unsolicited event for HP jack sensing */
4398 static void ad1984a_precision_unsol_event(struct hda_codec *codec,
4399                                          unsigned int res)
4400 {
4401         if ((res >> 26) != AD1884A_HP_EVENT)
4402                 return;
4403         ad1984a_precision_automute(codec);
4404 }
4405
4406 /* initialize jack-sensing, too */
4407 static int ad1984a_precision_init(struct hda_codec *codec)
4408 {
4409         ad198x_init(codec);
4410         ad1984a_precision_automute(codec);
4411         return 0;
4412 }
4413
4414
4415 /*
4416  * HP Touchsmart
4417  * port-A (0x11)      - front hp-out
4418  * port-B (0x14)      - unused
4419  * port-C (0x15)      - unused
4420  * port-D (0x12)      - rear line out
4421  * port-E (0x1c)      - front mic-in
4422  * port-F (0x16)      - Internal speakers
4423  * digital-mic (0x17) - Internal mic
4424  */
4425
4426 static const struct hda_verb ad1984a_touchsmart_verbs[] = {
4427         /* DACs; unmute as default */
4428         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
4429         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
4430         /* Port-A (HP) mixer - route only from analog mixer */
4431         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4432         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4433         /* Port-A pin */
4434         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4435         /* Port-A (HP) pin - always unmuted */
4436         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4437         /* Port-E (int speaker) mixer - route only from analog mixer */
4438         {0x25, AC_VERB_SET_AMP_GAIN_MUTE, 0x03},
4439         /* Port-E pin */
4440         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4441         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4442         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4443         /* Port-F (int speaker) mixer - route only from analog mixer */
4444         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4445         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4446         /* Port-F pin */
4447         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4448         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4449         /* Analog mixer; mute as default */
4450         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4451         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4452         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4453         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4454         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4455         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
4456         /* Analog Mix output amp */
4457         {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4458         /* capture sources */
4459         /* {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0}, */ /* set via unsol */
4460         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4461         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
4462         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4463         /* unsolicited event for pin-sense */
4464         {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
4465         {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT},
4466         /* allow to touch GPIO1 (for mute control) */
4467         {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
4468         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
4469         {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, /* first muted */
4470         /* internal mic - dmic */
4471         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4472         /* set magic COEFs for dmic */
4473         {0x01, AC_VERB_SET_COEF_INDEX, 0x13f7},
4474         {0x01, AC_VERB_SET_PROC_COEF, 0x08},
4475         { } /* end */
4476 };
4477
4478 static const struct snd_kcontrol_new ad1984a_touchsmart_mixers[] = {
4479         HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
4480 /*      HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/
4481         {
4482                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4483                 .subdevice = HDA_SUBDEV_AMP_FLAG,
4484                 .name = "Master Playback Switch",
4485                 .info = snd_hda_mixer_amp_switch_info,
4486                 .get = snd_hda_mixer_amp_switch_get,
4487                 .put = ad1884a_mobile_master_sw_put,
4488                 .private_value = HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
4489         },
4490         HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
4491         HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
4492         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
4493         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
4494         HDA_CODEC_VOLUME("Mic Boost Volume", 0x25, 0x0, HDA_OUTPUT),
4495         HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x17, 0x0, HDA_INPUT),
4496         { } /* end */
4497 };
4498
4499 /* switch to external mic if plugged */
4500 static void ad1984a_touchsmart_automic(struct hda_codec *codec)
4501 {
4502         if (snd_hda_jack_detect(codec, 0x1c))
4503                 snd_hda_codec_write(codec, 0x0c, 0,
4504                                      AC_VERB_SET_CONNECT_SEL, 0x4);
4505         else
4506                 snd_hda_codec_write(codec, 0x0c, 0,
4507                                      AC_VERB_SET_CONNECT_SEL, 0x5);
4508 }
4509
4510
4511 /* unsolicited event for HP jack sensing */
4512 static void ad1984a_touchsmart_unsol_event(struct hda_codec *codec,
4513         unsigned int res)
4514 {
4515         switch (res >> 26) {
4516         case AD1884A_HP_EVENT:
4517                 ad1884a_hp_automute(codec);
4518                 break;
4519         case AD1884A_MIC_EVENT:
4520                 ad1984a_touchsmart_automic(codec);
4521                 break;
4522         }
4523 }
4524
4525 /* initialize jack-sensing, too */
4526 static int ad1984a_touchsmart_init(struct hda_codec *codec)
4527 {
4528         ad198x_init(codec);
4529         ad1884a_hp_automute(codec);
4530         ad1984a_touchsmart_automic(codec);
4531         return 0;
4532 }
4533
4534
4535 /*
4536  */
4537
4538 enum {
4539         AD1884A_DESKTOP,
4540         AD1884A_LAPTOP,
4541         AD1884A_MOBILE,
4542         AD1884A_THINKPAD,
4543         AD1984A_TOUCHSMART,
4544         AD1984A_PRECISION,
4545         AD1884A_MODELS
4546 };
4547
4548 static const char * const ad1884a_models[AD1884A_MODELS] = {
4549         [AD1884A_DESKTOP]       = "desktop",
4550         [AD1884A_LAPTOP]        = "laptop",
4551         [AD1884A_MOBILE]        = "mobile",
4552         [AD1884A_THINKPAD]      = "thinkpad",
4553         [AD1984A_TOUCHSMART]    = "touchsmart",
4554         [AD1984A_PRECISION]     = "precision",
4555 };
4556
4557 static const struct snd_pci_quirk ad1884a_cfg_tbl[] = {
4558         SND_PCI_QUIRK(0x1028, 0x04ac, "Precision R5500", AD1984A_PRECISION),
4559         SND_PCI_QUIRK(0x103c, 0x3030, "HP", AD1884A_MOBILE),
4560         SND_PCI_QUIRK(0x103c, 0x3037, "HP 2230s", AD1884A_LAPTOP),
4561         SND_PCI_QUIRK(0x103c, 0x3056, "HP", AD1884A_MOBILE),
4562         SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x3070, "HP", AD1884A_MOBILE),
4563         SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x30d0, "HP laptop", AD1884A_LAPTOP),
4564         SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x30e0, "HP laptop", AD1884A_LAPTOP),
4565         SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3600, "HP laptop", AD1884A_LAPTOP),
4566         SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x7010, "HP laptop", AD1884A_MOBILE),
4567         SND_PCI_QUIRK(0x17aa, 0x20ac, "Thinkpad X300", AD1884A_THINKPAD),
4568         SND_PCI_QUIRK(0x103c, 0x2a82, "Touchsmart", AD1984A_TOUCHSMART),
4569         {}
4570 };
4571
4572 static int patch_ad1884a(struct hda_codec *codec)
4573 {
4574         struct ad198x_spec *spec;
4575         int err, board_config;
4576
4577         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4578         if (spec == NULL)
4579                 return -ENOMEM;
4580
4581         codec->spec = spec;
4582
4583         err = snd_hda_attach_beep_device(codec, 0x10);
4584         if (err < 0) {
4585                 ad198x_free(codec);
4586                 return err;
4587         }
4588         set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
4589
4590         spec->multiout.max_channels = 2;
4591         spec->multiout.num_dacs = ARRAY_SIZE(ad1884a_dac_nids);
4592         spec->multiout.dac_nids = ad1884a_dac_nids;
4593         spec->multiout.dig_out_nid = AD1884A_SPDIF_OUT;
4594         spec->num_adc_nids = ARRAY_SIZE(ad1884a_adc_nids);
4595         spec->adc_nids = ad1884a_adc_nids;
4596         spec->capsrc_nids = ad1884a_capsrc_nids;
4597         spec->input_mux = &ad1884a_capture_source;
4598         spec->num_mixers = 1;
4599         spec->mixers[0] = ad1884a_base_mixers;
4600         spec->num_init_verbs = 1;
4601         spec->init_verbs[0] = ad1884a_init_verbs;
4602         spec->spdif_route = 0;
4603 #ifdef CONFIG_PM
4604         spec->loopback.amplist = ad1884a_loopbacks;
4605 #endif
4606         codec->patch_ops = ad198x_patch_ops;
4607
4608         /* override some parameters */
4609         board_config = snd_hda_check_board_config(codec, AD1884A_MODELS,
4610                                                   ad1884a_models,
4611                                                   ad1884a_cfg_tbl);
4612         switch (board_config) {
4613         case AD1884A_LAPTOP:
4614                 spec->mixers[0] = ad1884a_laptop_mixers;
4615                 spec->init_verbs[spec->num_init_verbs++] = ad1884a_laptop_verbs;
4616                 spec->multiout.dig_out_nid = 0;
4617                 codec->patch_ops.unsol_event = ad1884a_laptop_unsol_event;
4618                 codec->patch_ops.init = ad1884a_laptop_init;
4619                 /* set the upper-limit for mixer amp to 0dB for avoiding the
4620                  * possible damage by overloading
4621                  */
4622                 snd_hda_override_amp_caps(codec, 0x20, HDA_INPUT,
4623                                           (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
4624                                           (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
4625                                           (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
4626                                           (1 << AC_AMPCAP_MUTE_SHIFT));
4627                 break;
4628         case AD1884A_MOBILE:
4629                 spec->mixers[0] = ad1884a_mobile_mixers;
4630                 spec->init_verbs[0] = ad1884a_mobile_verbs;
4631                 spec->multiout.dig_out_nid = 0;
4632                 codec->patch_ops.unsol_event = ad1884a_hp_unsol_event;
4633                 codec->patch_ops.init = ad1884a_hp_init;
4634                 /* set the upper-limit for mixer amp to 0dB for avoiding the
4635                  * possible damage by overloading
4636                  */
4637                 snd_hda_override_amp_caps(codec, 0x20, HDA_INPUT,
4638                                           (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
4639                                           (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
4640                                           (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
4641                                           (1 << AC_AMPCAP_MUTE_SHIFT));
4642                 break;
4643         case AD1884A_THINKPAD:
4644                 spec->mixers[0] = ad1984a_thinkpad_mixers;
4645                 spec->init_verbs[spec->num_init_verbs++] =
4646                         ad1984a_thinkpad_verbs;
4647                 spec->multiout.dig_out_nid = 0;
4648                 spec->input_mux = &ad1984a_thinkpad_capture_source;
4649                 codec->patch_ops.unsol_event = ad1984a_thinkpad_unsol_event;
4650                 codec->patch_ops.init = ad1984a_thinkpad_init;
4651                 break;
4652         case AD1984A_PRECISION:
4653                 spec->mixers[0] = ad1984a_precision_mixers;
4654                 spec->init_verbs[spec->num_init_verbs++] =
4655                         ad1984a_precision_verbs;
4656                 spec->multiout.dig_out_nid = 0;
4657                 codec->patch_ops.unsol_event = ad1984a_precision_unsol_event;
4658                 codec->patch_ops.init = ad1984a_precision_init;
4659                 break;
4660         case AD1984A_TOUCHSMART:
4661                 spec->mixers[0] = ad1984a_touchsmart_mixers;
4662                 spec->init_verbs[0] = ad1984a_touchsmart_verbs;
4663                 spec->multiout.dig_out_nid = 0;
4664                 codec->patch_ops.unsol_event = ad1984a_touchsmart_unsol_event;
4665                 codec->patch_ops.init = ad1984a_touchsmart_init;
4666                 /* set the upper-limit for mixer amp to 0dB for avoiding the
4667                  * possible damage by overloading
4668                  */
4669                 snd_hda_override_amp_caps(codec, 0x20, HDA_INPUT,
4670                                           (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
4671                                           (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
4672                                           (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
4673                                           (1 << AC_AMPCAP_MUTE_SHIFT));
4674                 break;
4675         }
4676
4677         codec->no_trigger_sense = 1;
4678         codec->no_sticky_stream = 1;
4679
4680         return 0;
4681 }
4682
4683
4684 /*
4685  * AD1882 / AD1882A
4686  *
4687  * port-A - front hp-out
4688  * port-B - front mic-in
4689  * port-C - rear line-in, shared surr-out (3stack)
4690  * port-D - rear line-out
4691  * port-E - rear mic-in, shared clfe-out (3stack)
4692  * port-F - rear surr-out (6stack)
4693  * port-G - rear clfe-out (6stack)
4694  */
4695
4696 static const hda_nid_t ad1882_dac_nids[3] = {
4697         0x04, 0x03, 0x05
4698 };
4699
4700 static const hda_nid_t ad1882_adc_nids[2] = {
4701         0x08, 0x09,
4702 };
4703
4704 static const hda_nid_t ad1882_capsrc_nids[2] = {
4705         0x0c, 0x0d,
4706 };
4707
4708 #define AD1882_SPDIF_OUT        0x02
4709
4710 /* list: 0x11, 0x39, 0x3a, 0x18, 0x3c, 0x3b, 0x12, 0x20 */
4711 static const struct hda_input_mux ad1882_capture_source = {
4712         .num_items = 5,
4713         .items = {
4714                 { "Front Mic", 0x1 },
4715                 { "Mic", 0x4 },
4716                 { "Line", 0x2 },
4717                 { "CD", 0x3 },
4718                 { "Mix", 0x7 },
4719         },
4720 };
4721
4722 /* list: 0x11, 0x39, 0x3a, 0x3c, 0x18, 0x1f, 0x12, 0x20 */
4723 static const struct hda_input_mux ad1882a_capture_source = {
4724         .num_items = 5,
4725         .items = {
4726                 { "Front Mic", 0x1 },
4727                 { "Mic", 0x4},
4728                 { "Line", 0x2 },
4729                 { "Digital Mic", 0x06 },
4730                 { "Mix", 0x7 },
4731         },
4732 };
4733
4734 static const struct snd_kcontrol_new ad1882_base_mixers[] = {
4735         HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
4736         HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
4737         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT),
4738         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT),
4739         HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
4740         HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT),
4741         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
4742         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
4743
4744         HDA_CODEC_VOLUME("Mic Boost Volume", 0x3c, 0x0, HDA_OUTPUT),
4745         HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x39, 0x0, HDA_OUTPUT),
4746         HDA_CODEC_VOLUME("Line-In Boost Volume", 0x3a, 0x0, HDA_OUTPUT),
4747         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
4748         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
4749         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
4750         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
4751         {
4752                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4753                 /* The multiple "Capture Source" controls confuse alsamixer
4754                  * So call somewhat different..
4755                  */
4756                 /* .name = "Capture Source", */
4757                 .name = "Input Source",
4758                 .count = 2,
4759                 .info = ad198x_mux_enum_info,
4760                 .get = ad198x_mux_enum_get,
4761                 .put = ad198x_mux_enum_put,
4762         },
4763         /* SPDIF controls */
4764         HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
4765         {
4766                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4767                 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
4768                 /* identical with ad1983 */
4769                 .info = ad1983_spdif_route_info,
4770                 .get = ad1983_spdif_route_get,
4771                 .put = ad1983_spdif_route_put,
4772         },
4773         { } /* end */
4774 };
4775
4776 static const struct snd_kcontrol_new ad1882_loopback_mixers[] = {
4777         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
4778         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
4779         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
4780         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
4781         HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x04, HDA_INPUT),
4782         HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x04, HDA_INPUT),
4783         HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x06, HDA_INPUT),
4784         HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x06, HDA_INPUT),
4785         { } /* end */
4786 };
4787
4788 static const struct snd_kcontrol_new ad1882a_loopback_mixers[] = {
4789         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
4790         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
4791         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
4792         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
4793         HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x01, HDA_INPUT),
4794         HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x01, HDA_INPUT),
4795         HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x06, HDA_INPUT),
4796         HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x06, HDA_INPUT),
4797         HDA_CODEC_VOLUME("Digital Mic Boost Volume", 0x1f, 0x0, HDA_INPUT),
4798         { } /* end */
4799 };
4800
4801 static const struct snd_kcontrol_new ad1882_3stack_mixers[] = {
4802         HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
4803         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x17, 1, 0x0, HDA_OUTPUT),
4804         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x17, 2, 0x0, HDA_OUTPUT),
4805         {
4806                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4807                 .name = "Channel Mode",
4808                 .info = ad198x_ch_mode_info,
4809                 .get = ad198x_ch_mode_get,
4810                 .put = ad198x_ch_mode_put,
4811         },
4812         { } /* end */
4813 };
4814
4815 /* simple auto-mute control for AD1882 3-stack board */
4816 #define AD1882_HP_EVENT 0x01
4817
4818 static void ad1882_3stack_automute(struct hda_codec *codec)
4819 {
4820         bool mute = snd_hda_jack_detect(codec, 0x11);
4821         snd_hda_codec_write(codec, 0x12, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4822                             mute ? 0 : PIN_OUT);
4823 }
4824
4825 static int ad1882_3stack_automute_init(struct hda_codec *codec)
4826 {
4827         ad198x_init(codec);
4828         ad1882_3stack_automute(codec);
4829         return 0;
4830 }
4831
4832 static void ad1882_3stack_unsol_event(struct hda_codec *codec, unsigned int res)
4833 {
4834         switch (res >> 26) {
4835         case AD1882_HP_EVENT:
4836                 ad1882_3stack_automute(codec);
4837                 break;
4838         }
4839 }
4840
4841 static const struct snd_kcontrol_new ad1882_6stack_mixers[] = {
4842         HDA_CODEC_MUTE("Surround Playback Switch", 0x16, 0x0, HDA_OUTPUT),
4843         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x24, 1, 0x0, HDA_OUTPUT),
4844         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x24, 2, 0x0, HDA_OUTPUT),
4845         { } /* end */
4846 };
4847
4848 static const struct hda_verb ad1882_ch2_init[] = {
4849         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4850         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4851         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4852         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4853         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4854         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4855         { } /* end */
4856 };
4857
4858 static const struct hda_verb ad1882_ch4_init[] = {
4859         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4860         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4861         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4862         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4863         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4864         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4865         { } /* end */
4866 };
4867
4868 static const struct hda_verb ad1882_ch6_init[] = {
4869         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4870         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4871         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4872         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4873         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4874         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4875         { } /* end */
4876 };
4877
4878 static const struct hda_channel_mode ad1882_modes[3] = {
4879         { 2, ad1882_ch2_init },
4880         { 4, ad1882_ch4_init },
4881         { 6, ad1882_ch6_init },
4882 };
4883
4884 /*
4885  * initialization verbs
4886  */
4887 static const struct hda_verb ad1882_init_verbs[] = {
4888         /* DACs; mute as default */
4889         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4890         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4891         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4892         /* Port-A (HP) mixer */
4893         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4894         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4895         /* Port-A pin */
4896         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4897         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4898         /* HP selector - select DAC2 */
4899         {0x37, AC_VERB_SET_CONNECT_SEL, 0x1},
4900         /* Port-D (Line-out) mixer */
4901         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4902         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4903         /* Port-D pin */
4904         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4905         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4906         /* Mono-out mixer */
4907         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4908         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4909         /* Mono-out pin */
4910         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4911         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4912         /* Port-B (front mic) pin */
4913         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4914         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4915         {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */
4916         /* Port-C (line-in) pin */
4917         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4918         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4919         {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */
4920         /* Port-C mixer - mute as input */
4921         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4922         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4923         /* Port-E (mic-in) pin */
4924         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4925         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4926         {0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */
4927         /* Port-E mixer - mute as input */
4928         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4929         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4930         /* Port-F (surround) */
4931         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4932         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4933         /* Port-G (CLFE) */
4934         {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4935         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4936         /* Analog mixer; mute as default */
4937         /* list: 0x39, 0x3a, 0x11, 0x12, 0x3c, 0x3b, 0x18, 0x1a */
4938         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4939         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4940         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4941         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4942         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4943         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
4944         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
4945         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
4946         /* Analog Mix output amp */
4947         {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
4948         /* SPDIF output selector */
4949         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
4950         {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */
4951         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
4952         { } /* end */
4953 };
4954
4955 static const struct hda_verb ad1882_3stack_automute_verbs[] = {
4956         {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1882_HP_EVENT},
4957         { } /* end */
4958 };
4959
4960 #ifdef CONFIG_PM
4961 static const struct hda_amp_list ad1882_loopbacks[] = {
4962         { 0x20, HDA_INPUT, 0 }, /* Front Mic */
4963         { 0x20, HDA_INPUT, 1 }, /* Mic */
4964         { 0x20, HDA_INPUT, 4 }, /* Line */
4965         { 0x20, HDA_INPUT, 6 }, /* CD */
4966         { } /* end */
4967 };
4968 #endif
4969
4970 /* models */
4971 enum {
4972         AD1882_3STACK,
4973         AD1882_6STACK,
4974         AD1882_3STACK_AUTOMUTE,
4975         AD1882_MODELS
4976 };
4977
4978 static const char * const ad1882_models[AD1986A_MODELS] = {
4979         [AD1882_3STACK]         = "3stack",
4980         [AD1882_6STACK]         = "6stack",
4981         [AD1882_3STACK_AUTOMUTE] = "3stack-automute",
4982 };
4983
4984
4985 static int patch_ad1882(struct hda_codec *codec)
4986 {
4987         struct ad198x_spec *spec;
4988         int err, board_config;
4989
4990         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4991         if (spec == NULL)
4992                 return -ENOMEM;
4993
4994         codec->spec = spec;
4995
4996         err = snd_hda_attach_beep_device(codec, 0x10);
4997         if (err < 0) {
4998                 ad198x_free(codec);
4999                 return err;
5000         }
5001         set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
5002
5003         spec->multiout.max_channels = 6;
5004         spec->multiout.num_dacs = 3;
5005         spec->multiout.dac_nids = ad1882_dac_nids;
5006         spec->multiout.dig_out_nid = AD1882_SPDIF_OUT;
5007         spec->num_adc_nids = ARRAY_SIZE(ad1882_adc_nids);
5008         spec->adc_nids = ad1882_adc_nids;
5009         spec->capsrc_nids = ad1882_capsrc_nids;
5010         if (codec->vendor_id == 0x11d41882)
5011                 spec->input_mux = &ad1882_capture_source;
5012         else
5013                 spec->input_mux = &ad1882a_capture_source;
5014         spec->num_mixers = 2;
5015         spec->mixers[0] = ad1882_base_mixers;
5016         if (codec->vendor_id == 0x11d41882)
5017                 spec->mixers[1] = ad1882_loopback_mixers;
5018         else
5019                 spec->mixers[1] = ad1882a_loopback_mixers;
5020         spec->num_init_verbs = 1;
5021         spec->init_verbs[0] = ad1882_init_verbs;
5022         spec->spdif_route = 0;
5023 #ifdef CONFIG_PM
5024         spec->loopback.amplist = ad1882_loopbacks;
5025 #endif
5026         spec->vmaster_nid = 0x04;
5027
5028         codec->patch_ops = ad198x_patch_ops;
5029
5030         /* override some parameters */
5031         board_config = snd_hda_check_board_config(codec, AD1882_MODELS,
5032                                                   ad1882_models, NULL);
5033         switch (board_config) {
5034         default:
5035         case AD1882_3STACK:
5036         case AD1882_3STACK_AUTOMUTE:
5037                 spec->num_mixers = 3;
5038                 spec->mixers[2] = ad1882_3stack_mixers;
5039                 spec->channel_mode = ad1882_modes;
5040                 spec->num_channel_mode = ARRAY_SIZE(ad1882_modes);
5041                 spec->need_dac_fix = 1;
5042                 spec->multiout.max_channels = 2;
5043                 spec->multiout.num_dacs = 1;
5044                 if (board_config != AD1882_3STACK) {
5045                         spec->init_verbs[spec->num_init_verbs++] =
5046                                 ad1882_3stack_automute_verbs;
5047                         codec->patch_ops.unsol_event = ad1882_3stack_unsol_event;
5048                         codec->patch_ops.init = ad1882_3stack_automute_init;
5049                 }
5050                 break;
5051         case AD1882_6STACK:
5052                 spec->num_mixers = 3;
5053                 spec->mixers[2] = ad1882_6stack_mixers;
5054                 break;
5055         }
5056
5057         codec->no_trigger_sense = 1;
5058         codec->no_sticky_stream = 1;
5059
5060         return 0;
5061 }
5062
5063
5064 /*
5065  * patch entries
5066  */
5067 static const struct hda_codec_preset snd_hda_preset_analog[] = {
5068         { .id = 0x11d4184a, .name = "AD1884A", .patch = patch_ad1884a },
5069         { .id = 0x11d41882, .name = "AD1882", .patch = patch_ad1882 },
5070         { .id = 0x11d41883, .name = "AD1883", .patch = patch_ad1884a },
5071         { .id = 0x11d41884, .name = "AD1884", .patch = patch_ad1884 },
5072         { .id = 0x11d4194a, .name = "AD1984A", .patch = patch_ad1884a },
5073         { .id = 0x11d4194b, .name = "AD1984B", .patch = patch_ad1884a },
5074         { .id = 0x11d41981, .name = "AD1981", .patch = patch_ad1981 },
5075         { .id = 0x11d41983, .name = "AD1983", .patch = patch_ad1983 },
5076         { .id = 0x11d41984, .name = "AD1984", .patch = patch_ad1984 },
5077         { .id = 0x11d41986, .name = "AD1986A", .patch = patch_ad1986a },
5078         { .id = 0x11d41988, .name = "AD1988", .patch = patch_ad1988 },
5079         { .id = 0x11d4198b, .name = "AD1988B", .patch = patch_ad1988 },
5080         { .id = 0x11d4882a, .name = "AD1882A", .patch = patch_ad1882 },
5081         { .id = 0x11d4989a, .name = "AD1989A", .patch = patch_ad1988 },
5082         { .id = 0x11d4989b, .name = "AD1989B", .patch = patch_ad1988 },
5083         {} /* terminator */
5084 };
5085
5086 MODULE_ALIAS("snd-hda-codec-id:11d4*");
5087
5088 MODULE_LICENSE("GPL");
5089 MODULE_DESCRIPTION("Analog Devices HD-audio codec");
5090
5091 static struct hda_codec_preset_list analog_list = {
5092         .preset = snd_hda_preset_analog,
5093         .owner = THIS_MODULE,
5094 };
5095
5096 static int __init patch_analog_init(void)
5097 {
5098         return snd_hda_add_codec_preset(&analog_list);
5099 }
5100
5101 static void __exit patch_analog_exit(void)
5102 {
5103         snd_hda_delete_codec_preset(&analog_list);
5104 }
5105
5106 module_init(patch_analog_init)
5107 module_exit(patch_analog_exit)