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