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