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