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