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