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