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