]> bbs.cooldavid.org Git - net-next-2.6.git/blob - sound/pci/hda/patch_analog.c
ALSA: hda - AD1988 codec - fix SPDIF-input mixer initialization (unmute)
[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 static struct hda_verb ad1988_spdif_in_init_verbs[] = {
2462         /* unmute SPDIF input pin */
2463         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2464         { }
2465 };
2466
2467 /* AD1989 has no ADC -> SPDIF route */
2468 static struct hda_verb ad1989_spdif_init_verbs[] = {
2469         /* SPDIF-1 out pin */
2470         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2471         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
2472         /* SPDIF-2/HDMI out pin */
2473         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2474         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
2475         { }
2476 };
2477
2478 /*
2479  * verbs for 3stack (+dig)
2480  */
2481 static struct hda_verb ad1988_3stack_ch2_init[] = {
2482         /* set port-C to line-in */
2483         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2484         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2485         /* set port-E to mic-in */
2486         { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2487         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2488         { } /* end */
2489 };
2490
2491 static struct hda_verb ad1988_3stack_ch6_init[] = {
2492         /* set port-C to surround out */
2493         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2494         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2495         /* set port-E to CLFE out */
2496         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2497         { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2498         { } /* end */
2499 };
2500
2501 static struct hda_channel_mode ad1988_3stack_modes[2] = {
2502         { 2, ad1988_3stack_ch2_init },
2503         { 6, ad1988_3stack_ch6_init },
2504 };
2505
2506 static struct hda_verb ad1988_3stack_init_verbs[] = {
2507         /* Front, Surround, CLFE, side DAC; unmute as default */
2508         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2509         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2510         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2511         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2512         /* Port-A front headphon path */
2513         {0x37, AC_VERB_SET_CONNECT_SEL, 0x01}, /* DAC1:04h */
2514         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2515         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2516         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2517         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2518         /* Port-D line-out path */
2519         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2520         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2521         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2522         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2523         /* Mono out path */
2524         {0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */
2525         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2526         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2527         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2528         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */
2529         /* Port-B front mic-in path */
2530         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2531         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2532         {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2533         /* Port-C line-in/surround path - 6ch mode as default */
2534         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2535         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2536         {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2537         {0x31, AC_VERB_SET_CONNECT_SEL, 0x0}, /* output sel: DAC 0x05 */
2538         {0x33, AC_VERB_SET_CONNECT_SEL, 0x0},
2539         /* Port-E mic-in/CLFE path - 6ch mode as default */
2540         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2541         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2542         {0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2543         {0x32, AC_VERB_SET_CONNECT_SEL, 0x1}, /* output sel: DAC 0x0a */
2544         {0x34, AC_VERB_SET_CONNECT_SEL, 0x0},
2545         /* mute analog mix */
2546         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2547         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2548         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2549         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2550         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2551         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
2552         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2553         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2554         /* select ADCs - front-mic */
2555         {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1},
2556         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x1},
2557         {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
2558         /* Analog Mix output amp */
2559         {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
2560         { }
2561 };
2562
2563 /*
2564  * verbs for laptop mode (+dig)
2565  */
2566 static struct hda_verb ad1988_laptop_hp_on[] = {
2567         /* unmute port-A and mute port-D */
2568         { 0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2569         { 0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2570         { } /* end */
2571 };
2572 static struct hda_verb ad1988_laptop_hp_off[] = {
2573         /* mute port-A and unmute port-D */
2574         { 0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2575         { 0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2576         { } /* end */
2577 };
2578
2579 #define AD1988_HP_EVENT 0x01
2580
2581 static struct hda_verb ad1988_laptop_init_verbs[] = {
2582         /* Front, Surround, CLFE, side DAC; unmute as default */
2583         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2584         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2585         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2586         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2587         /* Port-A front headphon path */
2588         {0x37, AC_VERB_SET_CONNECT_SEL, 0x01}, /* DAC1:04h */
2589         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2590         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2591         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2592         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2593         /* unsolicited event for pin-sense */
2594         {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1988_HP_EVENT },
2595         /* Port-D line-out path + EAPD */
2596         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2597         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2598         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2599         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2600         {0x12, AC_VERB_SET_EAPD_BTLENABLE, 0x00}, /* EAPD-off */
2601         /* Mono out path */
2602         {0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */
2603         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2604         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2605         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2606         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */
2607         /* Port-B mic-in path */
2608         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2609         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2610         {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2611         /* Port-C docking station - try to output */
2612         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2613         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2614         {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2615         {0x33, AC_VERB_SET_CONNECT_SEL, 0x0},
2616         /* mute analog mix */
2617         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2618         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2619         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2620         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2621         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2622         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
2623         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2624         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2625         /* select ADCs - mic */
2626         {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1},
2627         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x1},
2628         {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
2629         /* Analog Mix output amp */
2630         {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
2631         { }
2632 };
2633
2634 static void ad1988_laptop_unsol_event(struct hda_codec *codec, unsigned int res)
2635 {
2636         if ((res >> 26) != AD1988_HP_EVENT)
2637                 return;
2638         if (snd_hda_jack_detect(codec, 0x11))
2639                 snd_hda_sequence_write(codec, ad1988_laptop_hp_on);
2640         else
2641                 snd_hda_sequence_write(codec, ad1988_laptop_hp_off);
2642
2643
2644 #ifdef CONFIG_SND_HDA_POWER_SAVE
2645 static struct hda_amp_list ad1988_loopbacks[] = {
2646         { 0x20, HDA_INPUT, 0 }, /* Front Mic */
2647         { 0x20, HDA_INPUT, 1 }, /* Line */
2648         { 0x20, HDA_INPUT, 4 }, /* Mic */
2649         { 0x20, HDA_INPUT, 6 }, /* CD */
2650         { } /* end */
2651 };
2652 #endif
2653
2654 /*
2655  * Automatic parse of I/O pins from the BIOS configuration
2656  */
2657
2658 enum {
2659         AD_CTL_WIDGET_VOL,
2660         AD_CTL_WIDGET_MUTE,
2661         AD_CTL_BIND_MUTE,
2662 };
2663 static struct snd_kcontrol_new ad1988_control_templates[] = {
2664         HDA_CODEC_VOLUME(NULL, 0, 0, 0),
2665         HDA_CODEC_MUTE(NULL, 0, 0, 0),
2666         HDA_BIND_MUTE(NULL, 0, 0, 0),
2667 };
2668
2669 /* add dynamic controls */
2670 static int add_control(struct ad198x_spec *spec, int type, const char *name,
2671                        unsigned long val)
2672 {
2673         struct snd_kcontrol_new *knew;
2674
2675         snd_array_init(&spec->kctls, sizeof(*knew), 32);
2676         knew = snd_array_new(&spec->kctls);
2677         if (!knew)
2678                 return -ENOMEM;
2679         *knew = ad1988_control_templates[type];
2680         knew->name = kstrdup(name, GFP_KERNEL);
2681         if (! knew->name)
2682                 return -ENOMEM;
2683         if (get_amp_nid_(val))
2684                 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
2685         knew->private_value = val;
2686         return 0;
2687 }
2688
2689 #define AD1988_PIN_CD_NID               0x18
2690 #define AD1988_PIN_BEEP_NID             0x10
2691
2692 static hda_nid_t ad1988_mixer_nids[8] = {
2693         /* A     B     C     D     E     F     G     H */
2694         0x22, 0x2b, 0x2c, 0x29, 0x26, 0x2a, 0x27, 0x28
2695 };
2696
2697 static inline hda_nid_t ad1988_idx_to_dac(struct hda_codec *codec, int idx)
2698 {
2699         static hda_nid_t idx_to_dac[8] = {
2700                 /* A     B     C     D     E     F     G     H */
2701                 0x04, 0x06, 0x05, 0x04, 0x0a, 0x06, 0x05, 0x0a
2702         };
2703         static hda_nid_t idx_to_dac_rev2[8] = {
2704                 /* A     B     C     D     E     F     G     H */
2705                 0x04, 0x05, 0x0a, 0x04, 0x06, 0x05, 0x0a, 0x06
2706         };
2707         if (is_rev2(codec))
2708                 return idx_to_dac_rev2[idx];
2709         else
2710                 return idx_to_dac[idx];
2711 }
2712
2713 static hda_nid_t ad1988_boost_nids[8] = {
2714         0x38, 0x39, 0x3a, 0x3d, 0x3c, 0x3b, 0, 0
2715 };
2716
2717 static int ad1988_pin_idx(hda_nid_t nid)
2718 {
2719         static hda_nid_t ad1988_io_pins[8] = {
2720                 0x11, 0x14, 0x15, 0x12, 0x17, 0x16, 0x24, 0x25
2721         };
2722         int i;
2723         for (i = 0; i < ARRAY_SIZE(ad1988_io_pins); i++)
2724                 if (ad1988_io_pins[i] == nid)
2725                         return i;
2726         return 0; /* should be -1 */
2727 }
2728
2729 static int ad1988_pin_to_loopback_idx(hda_nid_t nid)
2730 {
2731         static int loopback_idx[8] = {
2732                 2, 0, 1, 3, 4, 5, 1, 4
2733         };
2734         switch (nid) {
2735         case AD1988_PIN_CD_NID:
2736                 return 6;
2737         default:
2738                 return loopback_idx[ad1988_pin_idx(nid)];
2739         }
2740 }
2741
2742 static int ad1988_pin_to_adc_idx(hda_nid_t nid)
2743 {
2744         static int adc_idx[8] = {
2745                 0, 1, 2, 8, 4, 3, 6, 7
2746         };
2747         switch (nid) {
2748         case AD1988_PIN_CD_NID:
2749                 return 5;
2750         default:
2751                 return adc_idx[ad1988_pin_idx(nid)];
2752         }
2753 }
2754
2755 /* fill in the dac_nids table from the parsed pin configuration */
2756 static int ad1988_auto_fill_dac_nids(struct hda_codec *codec,
2757                                      const struct auto_pin_cfg *cfg)
2758 {
2759         struct ad198x_spec *spec = codec->spec;
2760         int i, idx;
2761
2762         spec->multiout.dac_nids = spec->private_dac_nids;
2763
2764         /* check the pins hardwired to audio widget */
2765         for (i = 0; i < cfg->line_outs; i++) {
2766                 idx = ad1988_pin_idx(cfg->line_out_pins[i]);
2767                 spec->multiout.dac_nids[i] = ad1988_idx_to_dac(codec, idx);
2768         }
2769         spec->multiout.num_dacs = cfg->line_outs;
2770         return 0;
2771 }
2772
2773 /* add playback controls from the parsed DAC table */
2774 static int ad1988_auto_create_multi_out_ctls(struct ad198x_spec *spec,
2775                                              const struct auto_pin_cfg *cfg)
2776 {
2777         char name[32];
2778         static const char *chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" };
2779         hda_nid_t nid;
2780         int i, err;
2781
2782         for (i = 0; i < cfg->line_outs; i++) {
2783                 hda_nid_t dac = spec->multiout.dac_nids[i];
2784                 if (! dac)
2785                         continue;
2786                 nid = ad1988_mixer_nids[ad1988_pin_idx(cfg->line_out_pins[i])];
2787                 if (i == 2) {
2788                         /* Center/LFE */
2789                         err = add_control(spec, AD_CTL_WIDGET_VOL,
2790                                           "Center Playback Volume",
2791                                           HDA_COMPOSE_AMP_VAL(dac, 1, 0, HDA_OUTPUT));
2792                         if (err < 0)
2793                                 return err;
2794                         err = add_control(spec, AD_CTL_WIDGET_VOL,
2795                                           "LFE Playback Volume",
2796                                           HDA_COMPOSE_AMP_VAL(dac, 2, 0, HDA_OUTPUT));
2797                         if (err < 0)
2798                                 return err;
2799                         err = add_control(spec, AD_CTL_BIND_MUTE,
2800                                           "Center Playback Switch",
2801                                           HDA_COMPOSE_AMP_VAL(nid, 1, 2, HDA_INPUT));
2802                         if (err < 0)
2803                                 return err;
2804                         err = add_control(spec, AD_CTL_BIND_MUTE,
2805                                           "LFE Playback Switch",
2806                                           HDA_COMPOSE_AMP_VAL(nid, 2, 2, HDA_INPUT));
2807                         if (err < 0)
2808                                 return err;
2809                 } else {
2810                         sprintf(name, "%s Playback Volume", chname[i]);
2811                         err = add_control(spec, AD_CTL_WIDGET_VOL, name,
2812                                           HDA_COMPOSE_AMP_VAL(dac, 3, 0, HDA_OUTPUT));
2813                         if (err < 0)
2814                                 return err;
2815                         sprintf(name, "%s Playback Switch", chname[i]);
2816                         err = add_control(spec, AD_CTL_BIND_MUTE, name,
2817                                           HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
2818                         if (err < 0)
2819                                 return err;
2820                 }
2821         }
2822         return 0;
2823 }
2824
2825 /* add playback controls for speaker and HP outputs */
2826 static int ad1988_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
2827                                         const char *pfx)
2828 {
2829         struct ad198x_spec *spec = codec->spec;
2830         hda_nid_t nid;
2831         int i, idx, err;
2832         char name[32];
2833
2834         if (! pin)
2835                 return 0;
2836
2837         idx = ad1988_pin_idx(pin);
2838         nid = ad1988_idx_to_dac(codec, idx);
2839         /* check whether the corresponding DAC was already taken */
2840         for (i = 0; i < spec->autocfg.line_outs; i++) {
2841                 hda_nid_t pin = spec->autocfg.line_out_pins[i];
2842                 hda_nid_t dac = ad1988_idx_to_dac(codec, ad1988_pin_idx(pin));
2843                 if (dac == nid)
2844                         break;
2845         }
2846         if (i >= spec->autocfg.line_outs) {
2847                 /* specify the DAC as the extra output */
2848                 if (!spec->multiout.hp_nid)
2849                         spec->multiout.hp_nid = nid;
2850                 else
2851                         spec->multiout.extra_out_nid[0] = nid;
2852                 /* control HP volume/switch on the output mixer amp */
2853                 sprintf(name, "%s Playback Volume", pfx);
2854                 err = add_control(spec, AD_CTL_WIDGET_VOL, name,
2855                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
2856                 if (err < 0)
2857                         return err;
2858         }
2859         nid = ad1988_mixer_nids[idx];
2860         sprintf(name, "%s Playback Switch", pfx);
2861         if ((err = add_control(spec, AD_CTL_BIND_MUTE, name,
2862                                HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT))) < 0)
2863                 return err;
2864         return 0;
2865 }
2866
2867 /* create input playback/capture controls for the given pin */
2868 static int new_analog_input(struct ad198x_spec *spec, hda_nid_t pin,
2869                             const char *ctlname, int boost)
2870 {
2871         char name[32];
2872         int err, idx;
2873
2874         sprintf(name, "%s Playback Volume", ctlname);
2875         idx = ad1988_pin_to_loopback_idx(pin);
2876         if ((err = add_control(spec, AD_CTL_WIDGET_VOL, name,
2877                                HDA_COMPOSE_AMP_VAL(0x20, 3, idx, HDA_INPUT))) < 0)
2878                 return err;
2879         sprintf(name, "%s Playback Switch", ctlname);
2880         if ((err = add_control(spec, AD_CTL_WIDGET_MUTE, name,
2881                                HDA_COMPOSE_AMP_VAL(0x20, 3, idx, HDA_INPUT))) < 0)
2882                 return err;
2883         if (boost) {
2884                 hda_nid_t bnid;
2885                 idx = ad1988_pin_idx(pin);
2886                 bnid = ad1988_boost_nids[idx];
2887                 if (bnid) {
2888                         sprintf(name, "%s Boost", ctlname);
2889                         return add_control(spec, AD_CTL_WIDGET_VOL, name,
2890                                            HDA_COMPOSE_AMP_VAL(bnid, 3, idx, HDA_OUTPUT));
2891
2892                 }
2893         }
2894         return 0;
2895 }
2896
2897 /* create playback/capture controls for input pins */
2898 static int ad1988_auto_create_analog_input_ctls(struct ad198x_spec *spec,
2899                                                 const struct auto_pin_cfg *cfg)
2900 {
2901         struct hda_input_mux *imux = &spec->private_imux;
2902         int i, err;
2903
2904         for (i = 0; i < AUTO_PIN_LAST; i++) {
2905                 err = new_analog_input(spec, cfg->input_pins[i],
2906                                        auto_pin_cfg_labels[i],
2907                                        i <= AUTO_PIN_FRONT_MIC);
2908                 if (err < 0)
2909                         return err;
2910                 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
2911                 imux->items[imux->num_items].index = ad1988_pin_to_adc_idx(cfg->input_pins[i]);
2912                 imux->num_items++;
2913         }
2914         imux->items[imux->num_items].label = "Mix";
2915         imux->items[imux->num_items].index = 9;
2916         imux->num_items++;
2917
2918         if ((err = add_control(spec, AD_CTL_WIDGET_VOL,
2919                                "Analog Mix Playback Volume",
2920                                HDA_COMPOSE_AMP_VAL(0x21, 3, 0x0, HDA_OUTPUT))) < 0)
2921                 return err;
2922         if ((err = add_control(spec, AD_CTL_WIDGET_MUTE,
2923                                "Analog Mix Playback Switch",
2924                                HDA_COMPOSE_AMP_VAL(0x21, 3, 0x0, HDA_OUTPUT))) < 0)
2925                 return err;
2926
2927         return 0;
2928 }
2929
2930 static void ad1988_auto_set_output_and_unmute(struct hda_codec *codec,
2931                                               hda_nid_t nid, int pin_type,
2932                                               int dac_idx)
2933 {
2934         /* set as output */
2935         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
2936         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
2937         switch (nid) {
2938         case 0x11: /* port-A - DAC 04 */
2939                 snd_hda_codec_write(codec, 0x37, 0, AC_VERB_SET_CONNECT_SEL, 0x01);
2940                 break;
2941         case 0x14: /* port-B - DAC 06 */
2942                 snd_hda_codec_write(codec, 0x30, 0, AC_VERB_SET_CONNECT_SEL, 0x02);
2943                 break;
2944         case 0x15: /* port-C - DAC 05 */
2945                 snd_hda_codec_write(codec, 0x31, 0, AC_VERB_SET_CONNECT_SEL, 0x00);
2946                 break;
2947         case 0x17: /* port-E - DAC 0a */
2948                 snd_hda_codec_write(codec, 0x32, 0, AC_VERB_SET_CONNECT_SEL, 0x01);
2949                 break;
2950         case 0x13: /* mono - DAC 04 */
2951                 snd_hda_codec_write(codec, 0x36, 0, AC_VERB_SET_CONNECT_SEL, 0x01);
2952                 break;
2953         }
2954 }
2955
2956 static void ad1988_auto_init_multi_out(struct hda_codec *codec)
2957 {
2958         struct ad198x_spec *spec = codec->spec;
2959         int i;
2960
2961         for (i = 0; i < spec->autocfg.line_outs; i++) {
2962                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
2963                 ad1988_auto_set_output_and_unmute(codec, nid, PIN_OUT, i);
2964         }
2965 }
2966
2967 static void ad1988_auto_init_extra_out(struct hda_codec *codec)
2968 {
2969         struct ad198x_spec *spec = codec->spec;
2970         hda_nid_t pin;
2971
2972         pin = spec->autocfg.speaker_pins[0];
2973         if (pin) /* connect to front */
2974                 ad1988_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
2975         pin = spec->autocfg.hp_pins[0];
2976         if (pin) /* connect to front */
2977                 ad1988_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
2978 }
2979
2980 static void ad1988_auto_init_analog_input(struct hda_codec *codec)
2981 {
2982         struct ad198x_spec *spec = codec->spec;
2983         int i, idx;
2984
2985         for (i = 0; i < AUTO_PIN_LAST; i++) {
2986                 hda_nid_t nid = spec->autocfg.input_pins[i];
2987                 if (! nid)
2988                         continue;
2989                 switch (nid) {
2990                 case 0x15: /* port-C */
2991                         snd_hda_codec_write(codec, 0x33, 0, AC_VERB_SET_CONNECT_SEL, 0x0);
2992                         break;
2993                 case 0x17: /* port-E */
2994                         snd_hda_codec_write(codec, 0x34, 0, AC_VERB_SET_CONNECT_SEL, 0x0);
2995                         break;
2996                 }
2997                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
2998                                     i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN);
2999                 if (nid != AD1988_PIN_CD_NID)
3000                         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3001                                             AMP_OUT_MUTE);
3002                 idx = ad1988_pin_idx(nid);
3003                 if (ad1988_boost_nids[idx])
3004                         snd_hda_codec_write(codec, ad1988_boost_nids[idx], 0,
3005                                             AC_VERB_SET_AMP_GAIN_MUTE,
3006                                             AMP_OUT_ZERO);
3007         }
3008 }
3009
3010 /* parse the BIOS configuration and set up the alc_spec */
3011 /* return 1 if successful, 0 if the proper config is not found, or a negative error code */
3012 static int ad1988_parse_auto_config(struct hda_codec *codec)
3013 {
3014         struct ad198x_spec *spec = codec->spec;
3015         int err;
3016
3017         if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL)) < 0)
3018                 return err;
3019         if ((err = ad1988_auto_fill_dac_nids(codec, &spec->autocfg)) < 0)
3020                 return err;
3021         if (! spec->autocfg.line_outs)
3022                 return 0; /* can't find valid BIOS pin config */
3023         if ((err = ad1988_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 ||
3024             (err = ad1988_auto_create_extra_out(codec,
3025                                                 spec->autocfg.speaker_pins[0],
3026                                                 "Speaker")) < 0 ||
3027             (err = ad1988_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
3028                                                 "Headphone")) < 0 ||
3029             (err = ad1988_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0)
3030                 return err;
3031
3032         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3033
3034         if (spec->autocfg.dig_outs)
3035                 spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
3036         if (spec->autocfg.dig_in_pin)
3037                 spec->dig_in_nid = AD1988_SPDIF_IN;
3038
3039         if (spec->kctls.list)
3040                 spec->mixers[spec->num_mixers++] = spec->kctls.list;
3041
3042         spec->init_verbs[spec->num_init_verbs++] = ad1988_6stack_init_verbs;
3043
3044         spec->input_mux = &spec->private_imux;
3045
3046         return 1;
3047 }
3048
3049 /* init callback for auto-configuration model -- overriding the default init */
3050 static int ad1988_auto_init(struct hda_codec *codec)
3051 {
3052         ad198x_init(codec);
3053         ad1988_auto_init_multi_out(codec);
3054         ad1988_auto_init_extra_out(codec);
3055         ad1988_auto_init_analog_input(codec);
3056         return 0;
3057 }
3058
3059
3060 /*
3061  */
3062
3063 static const char *ad1988_models[AD1988_MODEL_LAST] = {
3064         [AD1988_6STACK]         = "6stack",
3065         [AD1988_6STACK_DIG]     = "6stack-dig",
3066         [AD1988_3STACK]         = "3stack",
3067         [AD1988_3STACK_DIG]     = "3stack-dig",
3068         [AD1988_LAPTOP]         = "laptop",
3069         [AD1988_LAPTOP_DIG]     = "laptop-dig",
3070         [AD1988_AUTO]           = "auto",
3071 };
3072
3073 static struct snd_pci_quirk ad1988_cfg_tbl[] = {
3074         SND_PCI_QUIRK(0x1043, 0x81ec, "Asus P5B-DLX", AD1988_6STACK_DIG),
3075         SND_PCI_QUIRK(0x1043, 0x81f6, "Asus M2N-SLI", AD1988_6STACK_DIG),
3076         SND_PCI_QUIRK(0x1043, 0x8277, "Asus P5K-E/WIFI-AP", AD1988_6STACK_DIG),
3077         SND_PCI_QUIRK(0x1043, 0x8311, "Asus P5Q-Premium/Pro", AD1988_6STACK_DIG),
3078         {}
3079 };
3080
3081 static int patch_ad1988(struct hda_codec *codec)
3082 {
3083         struct ad198x_spec *spec;
3084         int err, board_config;
3085
3086         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3087         if (spec == NULL)
3088                 return -ENOMEM;
3089
3090         codec->spec = spec;
3091
3092         if (is_rev2(codec))
3093                 snd_printk(KERN_INFO "patch_analog: AD1988A rev.2 is detected, enable workarounds\n");
3094
3095         board_config = snd_hda_check_board_config(codec, AD1988_MODEL_LAST,
3096                                                   ad1988_models, ad1988_cfg_tbl);
3097         if (board_config < 0) {
3098                 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
3099                        codec->chip_name);
3100                 board_config = AD1988_AUTO;
3101         }
3102
3103         if (board_config == AD1988_AUTO) {
3104                 /* automatic parse from the BIOS config */
3105                 err = ad1988_parse_auto_config(codec);
3106                 if (err < 0) {
3107                         ad198x_free(codec);
3108                         return err;
3109                 } else if (! err) {
3110                         printk(KERN_INFO "hda_codec: Cannot set up configuration from BIOS.  Using 6-stack mode...\n");
3111                         board_config = AD1988_6STACK;
3112                 }
3113         }
3114
3115         err = snd_hda_attach_beep_device(codec, 0x10);
3116         if (err < 0) {
3117                 ad198x_free(codec);
3118                 return err;
3119         }
3120         set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
3121
3122         switch (board_config) {
3123         case AD1988_6STACK:
3124         case AD1988_6STACK_DIG:
3125                 spec->multiout.max_channels = 8;
3126                 spec->multiout.num_dacs = 4;
3127                 if (is_rev2(codec))
3128                         spec->multiout.dac_nids = ad1988_6stack_dac_nids_rev2;
3129                 else
3130                         spec->multiout.dac_nids = ad1988_6stack_dac_nids;
3131                 spec->input_mux = &ad1988_6stack_capture_source;
3132                 spec->num_mixers = 2;
3133                 if (is_rev2(codec))
3134                         spec->mixers[0] = ad1988_6stack_mixers1_rev2;
3135                 else
3136                         spec->mixers[0] = ad1988_6stack_mixers1;
3137                 spec->mixers[1] = ad1988_6stack_mixers2;
3138                 spec->num_init_verbs = 1;
3139                 spec->init_verbs[0] = ad1988_6stack_init_verbs;
3140                 if (board_config == AD1988_6STACK_DIG) {
3141                         spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
3142                         spec->dig_in_nid = AD1988_SPDIF_IN;
3143                 }
3144                 break;
3145         case AD1988_3STACK:
3146         case AD1988_3STACK_DIG:
3147                 spec->multiout.max_channels = 6;
3148                 spec->multiout.num_dacs = 3;
3149                 if (is_rev2(codec))
3150                         spec->multiout.dac_nids = ad1988_3stack_dac_nids_rev2;
3151                 else
3152                         spec->multiout.dac_nids = ad1988_3stack_dac_nids;
3153                 spec->input_mux = &ad1988_6stack_capture_source;
3154                 spec->channel_mode = ad1988_3stack_modes;
3155                 spec->num_channel_mode = ARRAY_SIZE(ad1988_3stack_modes);
3156                 spec->num_mixers = 2;
3157                 if (is_rev2(codec))
3158                         spec->mixers[0] = ad1988_3stack_mixers1_rev2;
3159                 else
3160                         spec->mixers[0] = ad1988_3stack_mixers1;
3161                 spec->mixers[1] = ad1988_3stack_mixers2;
3162                 spec->num_init_verbs = 1;
3163                 spec->init_verbs[0] = ad1988_3stack_init_verbs;
3164                 if (board_config == AD1988_3STACK_DIG)
3165                         spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
3166                 break;
3167         case AD1988_LAPTOP:
3168         case AD1988_LAPTOP_DIG:
3169                 spec->multiout.max_channels = 2;
3170                 spec->multiout.num_dacs = 1;
3171                 spec->multiout.dac_nids = ad1988_3stack_dac_nids;
3172                 spec->input_mux = &ad1988_laptop_capture_source;
3173                 spec->num_mixers = 1;
3174                 spec->mixers[0] = ad1988_laptop_mixers;
3175                 spec->inv_eapd = 1; /* inverted EAPD */
3176                 spec->num_init_verbs = 1;
3177                 spec->init_verbs[0] = ad1988_laptop_init_verbs;
3178                 if (board_config == AD1988_LAPTOP_DIG)
3179                         spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
3180                 break;
3181         }
3182
3183         spec->num_adc_nids = ARRAY_SIZE(ad1988_adc_nids);
3184         spec->adc_nids = ad1988_adc_nids;
3185         spec->capsrc_nids = ad1988_capsrc_nids;
3186         spec->mixers[spec->num_mixers++] = ad1988_capture_mixers;
3187         spec->init_verbs[spec->num_init_verbs++] = ad1988_capture_init_verbs;
3188         if (spec->multiout.dig_out_nid) {
3189                 if (codec->vendor_id >= 0x11d4989a) {
3190                         spec->mixers[spec->num_mixers++] =
3191                                 ad1989_spdif_out_mixers;
3192                         spec->init_verbs[spec->num_init_verbs++] =
3193                                 ad1989_spdif_init_verbs;
3194                         codec->slave_dig_outs = ad1989b_slave_dig_outs;
3195                 } else {
3196                         spec->mixers[spec->num_mixers++] =
3197                                 ad1988_spdif_out_mixers;
3198                         spec->init_verbs[spec->num_init_verbs++] =
3199                                 ad1988_spdif_init_verbs;
3200                 }
3201         }
3202         if (spec->dig_in_nid && codec->vendor_id < 0x11d4989a) {
3203                 spec->mixers[spec->num_mixers++] = ad1988_spdif_in_mixers;
3204                 spec->init_verbs[spec->num_init_verbs++] =
3205                         ad1988_spdif_in_init_verbs;
3206         }
3207
3208         codec->patch_ops = ad198x_patch_ops;
3209         switch (board_config) {
3210         case AD1988_AUTO:
3211                 codec->patch_ops.init = ad1988_auto_init;
3212                 break;
3213         case AD1988_LAPTOP:
3214         case AD1988_LAPTOP_DIG:
3215                 codec->patch_ops.unsol_event = ad1988_laptop_unsol_event;
3216                 break;
3217         }
3218 #ifdef CONFIG_SND_HDA_POWER_SAVE
3219         spec->loopback.amplist = ad1988_loopbacks;
3220 #endif
3221         spec->vmaster_nid = 0x04;
3222
3223         return 0;
3224 }
3225
3226
3227 /*
3228  * AD1884 / AD1984
3229  *
3230  * port-B - front line/mic-in
3231  * port-E - aux in/out
3232  * port-F - aux in/out
3233  * port-C - rear line/mic-in
3234  * port-D - rear line/hp-out
3235  * port-A - front line/hp-out
3236  *
3237  * AD1984 = AD1884 + two digital mic-ins
3238  *
3239  * FIXME:
3240  * For simplicity, we share the single DAC for both HP and line-outs
3241  * right now.  The inidividual playbacks could be easily implemented,
3242  * but no build-up framework is given, so far.
3243  */
3244
3245 static hda_nid_t ad1884_dac_nids[1] = {
3246         0x04,
3247 };
3248
3249 static hda_nid_t ad1884_adc_nids[2] = {
3250         0x08, 0x09,
3251 };
3252
3253 static hda_nid_t ad1884_capsrc_nids[2] = {
3254         0x0c, 0x0d,
3255 };
3256
3257 #define AD1884_SPDIF_OUT        0x02
3258
3259 static struct hda_input_mux ad1884_capture_source = {
3260         .num_items = 4,
3261         .items = {
3262                 { "Front Mic", 0x0 },
3263                 { "Mic", 0x1 },
3264                 { "CD", 0x2 },
3265                 { "Mix", 0x3 },
3266         },
3267 };
3268
3269 static struct snd_kcontrol_new ad1884_base_mixers[] = {
3270         HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
3271         /* HDA_CODEC_VOLUME_IDX("PCM Playback Volume", 1, 0x03, 0x0, HDA_OUTPUT), */
3272         HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
3273         HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT),
3274         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
3275         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
3276         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
3277         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3278         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
3279         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
3280         HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x02, HDA_INPUT),
3281         HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x02, HDA_INPUT),
3282         HDA_CODEC_VOLUME("Mic Boost", 0x15, 0x0, HDA_INPUT),
3283         HDA_CODEC_VOLUME("Front Mic Boost", 0x14, 0x0, HDA_INPUT),
3284         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3285         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3286         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
3287         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
3288         {
3289                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3290                 /* The multiple "Capture Source" controls confuse alsamixer
3291                  * So call somewhat different..
3292                  */
3293                 /* .name = "Capture Source", */
3294                 .name = "Input Source",
3295                 .count = 2,
3296                 .info = ad198x_mux_enum_info,
3297                 .get = ad198x_mux_enum_get,
3298                 .put = ad198x_mux_enum_put,
3299         },
3300         /* SPDIF controls */
3301         HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
3302         {
3303                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3304                 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
3305                 /* identical with ad1983 */
3306                 .info = ad1983_spdif_route_info,
3307                 .get = ad1983_spdif_route_get,
3308                 .put = ad1983_spdif_route_put,
3309         },
3310         { } /* end */
3311 };
3312
3313 static struct snd_kcontrol_new ad1984_dmic_mixers[] = {
3314         HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x05, 0x0, HDA_INPUT),
3315         HDA_CODEC_MUTE("Digital Mic Capture Switch", 0x05, 0x0, HDA_INPUT),
3316         HDA_CODEC_VOLUME_IDX("Digital Mic Capture Volume", 1, 0x06, 0x0,
3317                              HDA_INPUT),
3318         HDA_CODEC_MUTE_IDX("Digital Mic Capture Switch", 1, 0x06, 0x0,
3319                            HDA_INPUT),
3320         { } /* end */
3321 };
3322
3323 /*
3324  * initialization verbs
3325  */
3326 static struct hda_verb ad1884_init_verbs[] = {
3327         /* DACs; mute as default */
3328         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3329         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3330         /* Port-A (HP) mixer */
3331         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3332         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3333         /* Port-A pin */
3334         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3335         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3336         /* HP selector - select DAC2 */
3337         {0x22, AC_VERB_SET_CONNECT_SEL, 0x1},
3338         /* Port-D (Line-out) mixer */
3339         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3340         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3341         /* Port-D pin */
3342         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3343         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3344         /* Mono-out mixer */
3345         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3346         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3347         /* Mono-out pin */
3348         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3349         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3350         /* Mono selector */
3351         {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
3352         /* Port-B (front mic) pin */
3353         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3354         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3355         /* Port-C (rear mic) pin */
3356         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3357         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3358         /* Analog mixer; mute as default */
3359         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3360         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3361         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3362         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3363         /* Analog Mix output amp */
3364         {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
3365         /* SPDIF output selector */
3366         {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */
3367         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
3368         { } /* end */
3369 };
3370
3371 #ifdef CONFIG_SND_HDA_POWER_SAVE
3372 static struct hda_amp_list ad1884_loopbacks[] = {
3373         { 0x20, HDA_INPUT, 0 }, /* Front Mic */
3374         { 0x20, HDA_INPUT, 1 }, /* Mic */
3375         { 0x20, HDA_INPUT, 2 }, /* CD */
3376         { 0x20, HDA_INPUT, 4 }, /* Docking */
3377         { } /* end */
3378 };
3379 #endif
3380
3381 static const char *ad1884_slave_vols[] = {
3382         "PCM Playback Volume",
3383         "Mic Playback Volume",
3384         "Mono Playback Volume",
3385         "Front Mic Playback Volume",
3386         "Mic Playback Volume",
3387         "CD Playback Volume",
3388         "Internal Mic Playback Volume",
3389         "Docking Mic Playback Volume",
3390         /* "Beep Playback Volume", */
3391         "IEC958 Playback Volume",
3392         NULL
3393 };
3394
3395 static int patch_ad1884(struct hda_codec *codec)
3396 {
3397         struct ad198x_spec *spec;
3398         int err;
3399
3400         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3401         if (spec == NULL)
3402                 return -ENOMEM;
3403
3404         codec->spec = spec;
3405
3406         err = snd_hda_attach_beep_device(codec, 0x10);
3407         if (err < 0) {
3408                 ad198x_free(codec);
3409                 return err;
3410         }
3411         set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
3412
3413         spec->multiout.max_channels = 2;
3414         spec->multiout.num_dacs = ARRAY_SIZE(ad1884_dac_nids);
3415         spec->multiout.dac_nids = ad1884_dac_nids;
3416         spec->multiout.dig_out_nid = AD1884_SPDIF_OUT;
3417         spec->num_adc_nids = ARRAY_SIZE(ad1884_adc_nids);
3418         spec->adc_nids = ad1884_adc_nids;
3419         spec->capsrc_nids = ad1884_capsrc_nids;
3420         spec->input_mux = &ad1884_capture_source;
3421         spec->num_mixers = 1;
3422         spec->mixers[0] = ad1884_base_mixers;
3423         spec->num_init_verbs = 1;
3424         spec->init_verbs[0] = ad1884_init_verbs;
3425         spec->spdif_route = 0;
3426 #ifdef CONFIG_SND_HDA_POWER_SAVE
3427         spec->loopback.amplist = ad1884_loopbacks;
3428 #endif
3429         spec->vmaster_nid = 0x04;
3430         /* we need to cover all playback volumes */
3431         spec->slave_vols = ad1884_slave_vols;
3432
3433         codec->patch_ops = ad198x_patch_ops;
3434
3435         return 0;
3436 }
3437
3438 /*
3439  * Lenovo Thinkpad T61/X61
3440  */
3441 static struct hda_input_mux ad1984_thinkpad_capture_source = {
3442         .num_items = 4,
3443         .items = {
3444                 { "Mic", 0x0 },
3445                 { "Internal Mic", 0x1 },
3446                 { "Mix", 0x3 },
3447                 { "Docking-Station", 0x4 },
3448         },
3449 };
3450
3451
3452 /*
3453  * Dell Precision T3400
3454  */
3455 static struct hda_input_mux ad1984_dell_desktop_capture_source = {
3456         .num_items = 3,
3457         .items = {
3458                 { "Front Mic", 0x0 },
3459                 { "Line-In", 0x1 },
3460                 { "Mix", 0x3 },
3461         },
3462 };
3463
3464
3465 static struct snd_kcontrol_new ad1984_thinkpad_mixers[] = {
3466         HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
3467         /* HDA_CODEC_VOLUME_IDX("PCM Playback Volume", 1, 0x03, 0x0, HDA_OUTPUT), */
3468         HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
3469         HDA_CODEC_MUTE("Speaker Playback Switch", 0x12, 0x0, HDA_OUTPUT),
3470         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
3471         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3472         HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
3473         HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
3474         HDA_CODEC_VOLUME("Docking Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
3475         HDA_CODEC_MUTE("Docking Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
3476         HDA_CODEC_VOLUME("Mic Boost", 0x14, 0x0, HDA_INPUT),
3477         HDA_CODEC_VOLUME("Internal Mic Boost", 0x15, 0x0, HDA_INPUT),
3478         HDA_CODEC_VOLUME("Docking Mic Boost", 0x25, 0x0, HDA_OUTPUT),
3479         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3480         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3481         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
3482         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
3483         {
3484                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3485                 /* The multiple "Capture Source" controls confuse alsamixer
3486                  * So call somewhat different..
3487                  */
3488                 /* .name = "Capture Source", */
3489                 .name = "Input Source",
3490                 .count = 2,
3491                 .info = ad198x_mux_enum_info,
3492                 .get = ad198x_mux_enum_get,
3493                 .put = ad198x_mux_enum_put,
3494         },
3495         /* SPDIF controls */
3496         HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
3497         {
3498                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3499                 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
3500                 /* identical with ad1983 */
3501                 .info = ad1983_spdif_route_info,
3502                 .get = ad1983_spdif_route_get,
3503                 .put = ad1983_spdif_route_put,
3504         },
3505         { } /* end */
3506 };
3507
3508 /* additional verbs */
3509 static struct hda_verb ad1984_thinkpad_init_verbs[] = {
3510         /* Port-E (docking station mic) pin */
3511         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3512         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3513         /* docking mic boost */
3514         {0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3515         /* Analog mixer - docking mic; mute as default */
3516         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3517         /* enable EAPD bit */
3518         {0x12, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
3519         { } /* end */
3520 };
3521
3522 /*
3523  * Dell Precision T3400
3524  */
3525 static struct snd_kcontrol_new ad1984_dell_desktop_mixers[] = {
3526         HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
3527         HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
3528         HDA_CODEC_MUTE("Speaker Playback Switch", 0x12, 0x0, HDA_OUTPUT),
3529         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
3530         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
3531         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
3532         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3533         HDA_CODEC_VOLUME("Line-In Playback Volume", 0x20, 0x01, HDA_INPUT),
3534         HDA_CODEC_MUTE("Line-In Playback Switch", 0x20, 0x01, HDA_INPUT),
3535         HDA_CODEC_VOLUME("Line-In Boost", 0x15, 0x0, HDA_INPUT),
3536         HDA_CODEC_VOLUME("Front Mic Boost", 0x14, 0x0, HDA_INPUT),
3537         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3538         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3539         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
3540         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
3541         {
3542                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3543                 /* The multiple "Capture Source" controls confuse alsamixer
3544                  * So call somewhat different..
3545                  */
3546                 /* .name = "Capture Source", */
3547                 .name = "Input Source",
3548                 .count = 2,
3549                 .info = ad198x_mux_enum_info,
3550                 .get = ad198x_mux_enum_get,
3551                 .put = ad198x_mux_enum_put,
3552         },
3553         { } /* end */
3554 };
3555
3556 /* Digial MIC ADC NID 0x05 + 0x06 */
3557 static int ad1984_pcm_dmic_prepare(struct hda_pcm_stream *hinfo,
3558                                    struct hda_codec *codec,
3559                                    unsigned int stream_tag,
3560                                    unsigned int format,
3561                                    struct snd_pcm_substream *substream)
3562 {
3563         snd_hda_codec_setup_stream(codec, 0x05 + substream->number,
3564                                    stream_tag, 0, format);
3565         return 0;
3566 }
3567
3568 static int ad1984_pcm_dmic_cleanup(struct hda_pcm_stream *hinfo,
3569                                    struct hda_codec *codec,
3570                                    struct snd_pcm_substream *substream)
3571 {
3572         snd_hda_codec_cleanup_stream(codec, 0x05 + substream->number);
3573         return 0;
3574 }
3575
3576 static struct hda_pcm_stream ad1984_pcm_dmic_capture = {
3577         .substreams = 2,
3578         .channels_min = 2,
3579         .channels_max = 2,
3580         .nid = 0x05,
3581         .ops = {
3582                 .prepare = ad1984_pcm_dmic_prepare,
3583                 .cleanup = ad1984_pcm_dmic_cleanup
3584         },
3585 };
3586
3587 static int ad1984_build_pcms(struct hda_codec *codec)
3588 {
3589         struct ad198x_spec *spec = codec->spec;
3590         struct hda_pcm *info;
3591         int err;
3592
3593         err = ad198x_build_pcms(codec);
3594         if (err < 0)
3595                 return err;
3596
3597         info = spec->pcm_rec + codec->num_pcms;
3598         codec->num_pcms++;
3599         info->name = "AD1984 Digital Mic";
3600         info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad1984_pcm_dmic_capture;
3601         return 0;
3602 }
3603
3604 /* models */
3605 enum {
3606         AD1984_BASIC,
3607         AD1984_THINKPAD,
3608         AD1984_DELL_DESKTOP,
3609         AD1984_MODELS
3610 };
3611
3612 static const char *ad1984_models[AD1984_MODELS] = {
3613         [AD1984_BASIC]          = "basic",
3614         [AD1984_THINKPAD]       = "thinkpad",
3615         [AD1984_DELL_DESKTOP]   = "dell_desktop",
3616 };
3617
3618 static struct snd_pci_quirk ad1984_cfg_tbl[] = {
3619         /* Lenovo Thinkpad T61/X61 */
3620         SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo Thinkpad", AD1984_THINKPAD),
3621         SND_PCI_QUIRK(0x1028, 0x0214, "Dell T3400", AD1984_DELL_DESKTOP),
3622         {}
3623 };
3624
3625 static int patch_ad1984(struct hda_codec *codec)
3626 {
3627         struct ad198x_spec *spec;
3628         int board_config, err;
3629
3630         err = patch_ad1884(codec);
3631         if (err < 0)
3632                 return err;
3633         spec = codec->spec;
3634         board_config = snd_hda_check_board_config(codec, AD1984_MODELS,
3635                                                   ad1984_models, ad1984_cfg_tbl);
3636         switch (board_config) {
3637         case AD1984_BASIC:
3638                 /* additional digital mics */
3639                 spec->mixers[spec->num_mixers++] = ad1984_dmic_mixers;
3640                 codec->patch_ops.build_pcms = ad1984_build_pcms;
3641                 break;
3642         case AD1984_THINKPAD:
3643                 spec->multiout.dig_out_nid = AD1884_SPDIF_OUT;
3644                 spec->input_mux = &ad1984_thinkpad_capture_source;
3645                 spec->mixers[0] = ad1984_thinkpad_mixers;
3646                 spec->init_verbs[spec->num_init_verbs++] = ad1984_thinkpad_init_verbs;
3647                 break;
3648         case AD1984_DELL_DESKTOP:
3649                 spec->multiout.dig_out_nid = 0;
3650                 spec->input_mux = &ad1984_dell_desktop_capture_source;
3651                 spec->mixers[0] = ad1984_dell_desktop_mixers;
3652                 break;
3653         }
3654         return 0;
3655 }
3656
3657
3658 /*
3659  * AD1883 / AD1884A / AD1984A / AD1984B
3660  *
3661  * port-B (0x14) - front mic-in
3662  * port-E (0x1c) - rear mic-in
3663  * port-F (0x16) - CD / ext out
3664  * port-C (0x15) - rear line-in
3665  * port-D (0x12) - rear line-out
3666  * port-A (0x11) - front hp-out
3667  *
3668  * AD1984A = AD1884A + digital-mic
3669  * AD1883 = equivalent with AD1984A
3670  * AD1984B = AD1984A + extra SPDIF-out
3671  *
3672  * FIXME:
3673  * We share the single DAC for both HP and line-outs (see AD1884/1984).
3674  */
3675
3676 static hda_nid_t ad1884a_dac_nids[1] = {
3677         0x03,
3678 };
3679
3680 #define ad1884a_adc_nids        ad1884_adc_nids
3681 #define ad1884a_capsrc_nids     ad1884_capsrc_nids
3682
3683 #define AD1884A_SPDIF_OUT       0x02
3684
3685 static struct hda_input_mux ad1884a_capture_source = {
3686         .num_items = 5,
3687         .items = {
3688                 { "Front Mic", 0x0 },
3689                 { "Mic", 0x4 },
3690                 { "Line", 0x1 },
3691                 { "CD", 0x2 },
3692                 { "Mix", 0x3 },
3693         },
3694 };
3695
3696 static struct snd_kcontrol_new ad1884a_base_mixers[] = {
3697         HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
3698         HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),
3699         HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
3700         HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT),
3701         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
3702         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
3703         HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
3704         HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
3705         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
3706         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3707         HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x01, HDA_INPUT),
3708         HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x01, HDA_INPUT),
3709         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
3710         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
3711         HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x02, HDA_INPUT),
3712         HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x02, HDA_INPUT),
3713         HDA_CODEC_VOLUME("Front Mic Boost", 0x14, 0x0, HDA_INPUT),
3714         HDA_CODEC_VOLUME("Line Boost", 0x15, 0x0, HDA_INPUT),
3715         HDA_CODEC_VOLUME("Mic Boost", 0x25, 0x0, HDA_OUTPUT),
3716         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3717         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3718         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
3719         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
3720         {
3721                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3722                 /* The multiple "Capture Source" controls confuse alsamixer
3723                  * So call somewhat different..
3724                  */
3725                 /* .name = "Capture Source", */
3726                 .name = "Input Source",
3727                 .count = 2,
3728                 .info = ad198x_mux_enum_info,
3729                 .get = ad198x_mux_enum_get,
3730                 .put = ad198x_mux_enum_put,
3731         },
3732         /* SPDIF controls */
3733         HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
3734         {
3735                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3736                 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
3737                 /* identical with ad1983 */
3738                 .info = ad1983_spdif_route_info,
3739                 .get = ad1983_spdif_route_get,
3740                 .put = ad1983_spdif_route_put,
3741         },
3742         { } /* end */
3743 };
3744
3745 /*
3746  * initialization verbs
3747  */
3748 static struct hda_verb ad1884a_init_verbs[] = {
3749         /* DACs; unmute as default */
3750         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
3751         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
3752         /* Port-A (HP) mixer - route only from analog mixer */
3753         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3754         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3755         /* Port-A pin */
3756         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3757         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3758         /* Port-D (Line-out) mixer - route only from analog mixer */
3759         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3760         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3761         /* Port-D pin */
3762         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3763         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3764         /* Mono-out mixer - route only from analog mixer */
3765         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3766         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3767         /* Mono-out pin */
3768         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3769         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3770         /* Port-B (front mic) pin */
3771         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3772         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3773         /* Port-C (rear line-in) pin */
3774         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3775         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3776         /* Port-E (rear mic) pin */
3777         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3778         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3779         {0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* no boost */
3780         /* Port-F (CD) pin */
3781         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3782         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3783         /* Analog mixer; mute as default */
3784         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3785         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3786         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3787         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3788         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, /* aux */
3789         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
3790         /* Analog Mix output amp */
3791         {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3792         /* capture sources */
3793         {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0},
3794         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3795         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
3796         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3797         /* SPDIF output amp */
3798         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
3799         { } /* end */
3800 };
3801
3802 #ifdef CONFIG_SND_HDA_POWER_SAVE
3803 static struct hda_amp_list ad1884a_loopbacks[] = {
3804         { 0x20, HDA_INPUT, 0 }, /* Front Mic */
3805         { 0x20, HDA_INPUT, 1 }, /* Mic */
3806         { 0x20, HDA_INPUT, 2 }, /* CD */
3807         { 0x20, HDA_INPUT, 4 }, /* Docking */
3808         { } /* end */
3809 };
3810 #endif
3811
3812 /*
3813  * Laptop model
3814  *
3815  * Port A: Headphone jack
3816  * Port B: MIC jack
3817  * Port C: Internal MIC
3818  * Port D: Dock Line Out (if enabled)
3819  * Port E: Dock Line In (if enabled)
3820  * Port F: Internal speakers
3821  */
3822
3823 static int ad1884a_mobile_master_sw_put(struct snd_kcontrol *kcontrol,
3824                                         struct snd_ctl_elem_value *ucontrol)
3825 {
3826         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3827         int ret = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
3828         int mute = (!ucontrol->value.integer.value[0] &&
3829                     !ucontrol->value.integer.value[1]);
3830         /* toggle GPIO1 according to the mute state */
3831         snd_hda_codec_write_cache(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
3832                             mute ? 0x02 : 0x0);
3833         return ret;
3834 }
3835
3836 static struct snd_kcontrol_new ad1884a_laptop_mixers[] = {
3837         HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
3838         {
3839                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3840                 .name = "Master Playback Switch",
3841                 .subdevice = HDA_SUBDEV_AMP_FLAG,
3842                 .info = snd_hda_mixer_amp_switch_info,
3843                 .get = snd_hda_mixer_amp_switch_get,
3844                 .put = ad1884a_mobile_master_sw_put,
3845                 .private_value = HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
3846         },
3847         HDA_CODEC_MUTE("Dock Playback Switch", 0x12, 0x0, HDA_OUTPUT),
3848         HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
3849         HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
3850         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
3851         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3852         HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
3853         HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
3854         HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
3855         HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
3856         HDA_CODEC_VOLUME("Mic Boost", 0x14, 0x0, HDA_INPUT),
3857         HDA_CODEC_VOLUME("Internal Mic Boost", 0x15, 0x0, HDA_INPUT),
3858         HDA_CODEC_VOLUME("Dock Mic Boost", 0x25, 0x0, HDA_OUTPUT),
3859         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3860         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3861         { } /* end */
3862 };
3863
3864 static struct snd_kcontrol_new ad1884a_mobile_mixers[] = {
3865         HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
3866         /*HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/
3867         {
3868                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3869                 .name = "Master Playback Switch",
3870                 .subdevice = HDA_SUBDEV_AMP_FLAG,
3871                 .info = snd_hda_mixer_amp_switch_info,
3872                 .get = snd_hda_mixer_amp_switch_get,
3873                 .put = ad1884a_mobile_master_sw_put,
3874                 .private_value = HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
3875         },
3876         HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
3877         HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
3878         HDA_CODEC_VOLUME("Mic Capture Volume", 0x14, 0x0, HDA_INPUT),
3879         HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x15, 0x0, HDA_INPUT),
3880         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3881         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3882         { } /* end */
3883 };
3884
3885 /* mute internal speaker if HP is plugged */
3886 static void ad1884a_hp_automute(struct hda_codec *codec)
3887 {
3888         unsigned int present;
3889
3890         present = snd_hda_jack_detect(codec, 0x11);
3891         snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
3892                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
3893         snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_EAPD_BTLENABLE,
3894                             present ? 0x00 : 0x02);
3895 }
3896
3897 /* switch to external mic if plugged */
3898 static void ad1884a_hp_automic(struct hda_codec *codec)
3899 {
3900         unsigned int present;
3901
3902         present = snd_hda_jack_detect(codec, 0x14);
3903         snd_hda_codec_write(codec, 0x0c, 0, AC_VERB_SET_CONNECT_SEL,
3904                             present ? 0 : 1);
3905 }
3906
3907 #define AD1884A_HP_EVENT                0x37
3908 #define AD1884A_MIC_EVENT               0x36
3909
3910 /* unsolicited event for HP jack sensing */
3911 static void ad1884a_hp_unsol_event(struct hda_codec *codec, unsigned int res)
3912 {
3913         switch (res >> 26) {
3914         case AD1884A_HP_EVENT:
3915                 ad1884a_hp_automute(codec);
3916                 break;
3917         case AD1884A_MIC_EVENT:
3918                 ad1884a_hp_automic(codec);
3919                 break;
3920         }
3921 }
3922
3923 /* initialize jack-sensing, too */
3924 static int ad1884a_hp_init(struct hda_codec *codec)
3925 {
3926         ad198x_init(codec);
3927         ad1884a_hp_automute(codec);
3928         ad1884a_hp_automic(codec);
3929         return 0;
3930 }
3931
3932 /* mute internal speaker if HP or docking HP is plugged */
3933 static void ad1884a_laptop_automute(struct hda_codec *codec)
3934 {
3935         unsigned int present;
3936
3937         present = snd_hda_jack_detect(codec, 0x11);
3938         if (!present)
3939                 present = snd_hda_jack_detect(codec, 0x12);
3940         snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
3941                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
3942         snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_EAPD_BTLENABLE,
3943                             present ? 0x00 : 0x02);
3944 }
3945
3946 /* switch to external mic if plugged */
3947 static void ad1884a_laptop_automic(struct hda_codec *codec)
3948 {
3949         unsigned int idx;
3950
3951         if (snd_hda_jack_detect(codec, 0x14))
3952                 idx = 0;
3953         else if (snd_hda_jack_detect(codec, 0x1c))
3954                 idx = 4;
3955         else
3956                 idx = 1;
3957         snd_hda_codec_write(codec, 0x0c, 0, AC_VERB_SET_CONNECT_SEL, idx);
3958 }
3959
3960 /* unsolicited event for HP jack sensing */
3961 static void ad1884a_laptop_unsol_event(struct hda_codec *codec,
3962                                        unsigned int res)
3963 {
3964         switch (res >> 26) {
3965         case AD1884A_HP_EVENT:
3966                 ad1884a_laptop_automute(codec);
3967                 break;
3968         case AD1884A_MIC_EVENT:
3969                 ad1884a_laptop_automic(codec);
3970                 break;
3971         }
3972 }
3973
3974 /* initialize jack-sensing, too */
3975 static int ad1884a_laptop_init(struct hda_codec *codec)
3976 {
3977         ad198x_init(codec);
3978         ad1884a_laptop_automute(codec);
3979         ad1884a_laptop_automic(codec);
3980         return 0;
3981 }
3982
3983 /* additional verbs for laptop model */
3984 static struct hda_verb ad1884a_laptop_verbs[] = {
3985         /* Port-A (HP) pin - always unmuted */
3986         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3987         /* Port-F (int speaker) mixer - route only from analog mixer */
3988         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3989         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3990         /* Port-F (int speaker) pin */
3991         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3992         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3993         /* required for compaq 6530s/6531s speaker output */
3994         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3995         /* Port-C pin - internal mic-in */
3996         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3997         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
3998         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
3999         /* Port-D (docking line-out) pin - default unmuted */
4000         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4001         /* analog mix */
4002         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4003         /* unsolicited event for pin-sense */
4004         {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
4005         {0x12, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
4006         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT},
4007         {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT},
4008         /* allow to touch GPIO1 (for mute control) */
4009         {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
4010         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
4011         {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, /* first muted */
4012         { } /* end */
4013 };
4014
4015 static struct hda_verb ad1884a_mobile_verbs[] = {
4016         /* DACs; unmute as default */
4017         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
4018         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
4019         /* Port-A (HP) mixer - route only from analog mixer */
4020         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4021         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4022         /* Port-A pin */
4023         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4024         /* Port-A (HP) pin - always unmuted */
4025         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4026         /* Port-B (mic jack) pin */
4027         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4028         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
4029         /* Port-C (int mic) pin */
4030         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4031         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
4032         /* Port-F (int speaker) mixer - route only from analog mixer */
4033         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4034         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4035         /* Port-F pin */
4036         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4037         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4038         /* Analog mixer; mute as default */
4039         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4040         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4041         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4042         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4043         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4044         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
4045         /* Analog Mix output amp */
4046         {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4047         /* capture sources */
4048         /* {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0}, */ /* set via unsol */
4049         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4050         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
4051         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4052         /* unsolicited event for pin-sense */
4053         {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
4054         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT},
4055         /* allow to touch GPIO1 (for mute control) */
4056         {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
4057         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
4058         {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, /* first muted */
4059         { } /* end */
4060 };
4061
4062 /*
4063  * Thinkpad X300
4064  * 0x11 - HP
4065  * 0x12 - speaker
4066  * 0x14 - mic-in
4067  * 0x17 - built-in mic
4068  */
4069
4070 static struct hda_verb ad1984a_thinkpad_verbs[] = {
4071         /* HP unmute */
4072         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4073         /* analog mix */
4074         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4075         /* turn on EAPD */
4076         {0x12, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4077         /* unsolicited event for pin-sense */
4078         {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
4079         /* internal mic - dmic */
4080         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4081         /* set magic COEFs for dmic */
4082         {0x01, AC_VERB_SET_COEF_INDEX, 0x13f7},
4083         {0x01, AC_VERB_SET_PROC_COEF, 0x08},
4084         { } /* end */
4085 };
4086
4087 static struct snd_kcontrol_new ad1984a_thinkpad_mixers[] = {
4088         HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
4089         HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),
4090         HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
4091         HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
4092         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
4093         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
4094         HDA_CODEC_VOLUME("Mic Boost", 0x14, 0x0, HDA_INPUT),
4095         HDA_CODEC_VOLUME("Internal Mic Boost", 0x17, 0x0, HDA_INPUT),
4096         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
4097         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
4098         {
4099                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4100                 .name = "Capture Source",
4101                 .info = ad198x_mux_enum_info,
4102                 .get = ad198x_mux_enum_get,
4103                 .put = ad198x_mux_enum_put,
4104         },
4105         { } /* end */
4106 };
4107
4108 static struct hda_input_mux ad1984a_thinkpad_capture_source = {
4109         .num_items = 3,
4110         .items = {
4111                 { "Mic", 0x0 },
4112                 { "Internal Mic", 0x5 },
4113                 { "Mix", 0x3 },
4114         },
4115 };
4116
4117 /* mute internal speaker if HP is plugged */
4118 static void ad1984a_thinkpad_automute(struct hda_codec *codec)
4119 {
4120         unsigned int present;
4121
4122         present = snd_hda_jack_detect(codec, 0x11);
4123         snd_hda_codec_amp_stereo(codec, 0x12, HDA_OUTPUT, 0,
4124                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
4125 }
4126
4127 /* unsolicited event for HP jack sensing */
4128 static void ad1984a_thinkpad_unsol_event(struct hda_codec *codec,
4129                                          unsigned int res)
4130 {
4131         if ((res >> 26) != AD1884A_HP_EVENT)
4132                 return;
4133         ad1984a_thinkpad_automute(codec);
4134 }
4135
4136 /* initialize jack-sensing, too */
4137 static int ad1984a_thinkpad_init(struct hda_codec *codec)
4138 {
4139         ad198x_init(codec);
4140         ad1984a_thinkpad_automute(codec);
4141         return 0;
4142 }
4143
4144 /*
4145  * HP Touchsmart
4146  * port-A (0x11)      - front hp-out
4147  * port-B (0x14)      - unused
4148  * port-C (0x15)      - unused
4149  * port-D (0x12)      - rear line out
4150  * port-E (0x1c)      - front mic-in
4151  * port-F (0x16)      - Internal speakers
4152  * digital-mic (0x17) - Internal mic
4153  */
4154
4155 static struct hda_verb ad1984a_touchsmart_verbs[] = {
4156         /* DACs; unmute as default */
4157         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
4158         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
4159         /* Port-A (HP) mixer - route only from analog mixer */
4160         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4161         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4162         /* Port-A pin */
4163         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4164         /* Port-A (HP) pin - always unmuted */
4165         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4166         /* Port-E (int speaker) mixer - route only from analog mixer */
4167         {0x25, AC_VERB_SET_AMP_GAIN_MUTE, 0x03},
4168         /* Port-E pin */
4169         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4170         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4171         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4172         /* Port-F (int speaker) mixer - route only from analog mixer */
4173         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4174         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4175         /* Port-F pin */
4176         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4177         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4178         /* Analog mixer; mute as default */
4179         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4180         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4181         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4182         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4183         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4184         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
4185         /* Analog Mix output amp */
4186         {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4187         /* capture sources */
4188         /* {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0}, */ /* set via unsol */
4189         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4190         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
4191         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4192         /* unsolicited event for pin-sense */
4193         {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
4194         {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT},
4195         /* allow to touch GPIO1 (for mute control) */
4196         {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
4197         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
4198         {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, /* first muted */
4199         /* internal mic - dmic */
4200         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4201         /* set magic COEFs for dmic */
4202         {0x01, AC_VERB_SET_COEF_INDEX, 0x13f7},
4203         {0x01, AC_VERB_SET_PROC_COEF, 0x08},
4204         { } /* end */
4205 };
4206
4207 static struct snd_kcontrol_new ad1984a_touchsmart_mixers[] = {
4208         HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
4209 /*      HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/
4210         {
4211                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4212                 .subdevice = HDA_SUBDEV_AMP_FLAG,
4213                 .name = "Master Playback Switch",
4214                 .info = snd_hda_mixer_amp_switch_info,
4215                 .get = snd_hda_mixer_amp_switch_get,
4216                 .put = ad1884a_mobile_master_sw_put,
4217                 .private_value = HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
4218         },
4219         HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
4220         HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
4221         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
4222         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
4223         HDA_CODEC_VOLUME("Mic Boost", 0x25, 0x0, HDA_OUTPUT),
4224         HDA_CODEC_VOLUME("Internal Mic Boost", 0x17, 0x0, HDA_INPUT),
4225         { } /* end */
4226 };
4227
4228 /* switch to external mic if plugged */
4229 static void ad1984a_touchsmart_automic(struct hda_codec *codec)
4230 {
4231         if (snd_hda_jack_detect(codec, 0x1c))
4232                 snd_hda_codec_write(codec, 0x0c, 0,
4233                                      AC_VERB_SET_CONNECT_SEL, 0x4);
4234         else
4235                 snd_hda_codec_write(codec, 0x0c, 0,
4236                                      AC_VERB_SET_CONNECT_SEL, 0x5);
4237 }
4238
4239
4240 /* unsolicited event for HP jack sensing */
4241 static void ad1984a_touchsmart_unsol_event(struct hda_codec *codec,
4242         unsigned int res)
4243 {
4244         switch (res >> 26) {
4245         case AD1884A_HP_EVENT:
4246                 ad1884a_hp_automute(codec);
4247                 break;
4248         case AD1884A_MIC_EVENT:
4249                 ad1984a_touchsmart_automic(codec);
4250                 break;
4251         }
4252 }
4253
4254 /* initialize jack-sensing, too */
4255 static int ad1984a_touchsmart_init(struct hda_codec *codec)
4256 {
4257         ad198x_init(codec);
4258         ad1884a_hp_automute(codec);
4259         ad1984a_touchsmart_automic(codec);
4260         return 0;
4261 }
4262
4263
4264 /*
4265  */
4266
4267 enum {
4268         AD1884A_DESKTOP,
4269         AD1884A_LAPTOP,
4270         AD1884A_MOBILE,
4271         AD1884A_THINKPAD,
4272         AD1984A_TOUCHSMART,
4273         AD1884A_MODELS
4274 };
4275
4276 static const char *ad1884a_models[AD1884A_MODELS] = {
4277         [AD1884A_DESKTOP]       = "desktop",
4278         [AD1884A_LAPTOP]        = "laptop",
4279         [AD1884A_MOBILE]        = "mobile",
4280         [AD1884A_THINKPAD]      = "thinkpad",
4281         [AD1984A_TOUCHSMART]    = "touchsmart",
4282 };
4283
4284 static struct snd_pci_quirk ad1884a_cfg_tbl[] = {
4285         SND_PCI_QUIRK(0x103c, 0x3030, "HP", AD1884A_MOBILE),
4286         SND_PCI_QUIRK(0x103c, 0x3037, "HP 2230s", AD1884A_LAPTOP),
4287         SND_PCI_QUIRK(0x103c, 0x3056, "HP", AD1884A_MOBILE),
4288         SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x3070, "HP", AD1884A_MOBILE),
4289         SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x30d0, "HP laptop", AD1884A_LAPTOP),
4290         SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x30e0, "HP laptop", AD1884A_LAPTOP),
4291         SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3600, "HP laptop", AD1884A_LAPTOP),
4292         SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x7010, "HP laptop", AD1884A_MOBILE),
4293         SND_PCI_QUIRK(0x17aa, 0x20ac, "Thinkpad X300", AD1884A_THINKPAD),
4294         SND_PCI_QUIRK(0x103c, 0x2a82, "Touchsmart", AD1984A_TOUCHSMART),
4295         {}
4296 };
4297
4298 static int patch_ad1884a(struct hda_codec *codec)
4299 {
4300         struct ad198x_spec *spec;
4301         int err, board_config;
4302
4303         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4304         if (spec == NULL)
4305                 return -ENOMEM;
4306
4307         codec->spec = spec;
4308
4309         err = snd_hda_attach_beep_device(codec, 0x10);
4310         if (err < 0) {
4311                 ad198x_free(codec);
4312                 return err;
4313         }
4314         set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
4315
4316         spec->multiout.max_channels = 2;
4317         spec->multiout.num_dacs = ARRAY_SIZE(ad1884a_dac_nids);
4318         spec->multiout.dac_nids = ad1884a_dac_nids;
4319         spec->multiout.dig_out_nid = AD1884A_SPDIF_OUT;
4320         spec->num_adc_nids = ARRAY_SIZE(ad1884a_adc_nids);
4321         spec->adc_nids = ad1884a_adc_nids;
4322         spec->capsrc_nids = ad1884a_capsrc_nids;
4323         spec->input_mux = &ad1884a_capture_source;
4324         spec->num_mixers = 1;
4325         spec->mixers[0] = ad1884a_base_mixers;
4326         spec->num_init_verbs = 1;
4327         spec->init_verbs[0] = ad1884a_init_verbs;
4328         spec->spdif_route = 0;
4329 #ifdef CONFIG_SND_HDA_POWER_SAVE
4330         spec->loopback.amplist = ad1884a_loopbacks;
4331 #endif
4332         codec->patch_ops = ad198x_patch_ops;
4333
4334         /* override some parameters */
4335         board_config = snd_hda_check_board_config(codec, AD1884A_MODELS,
4336                                                   ad1884a_models,
4337                                                   ad1884a_cfg_tbl);
4338         switch (board_config) {
4339         case AD1884A_LAPTOP:
4340                 spec->mixers[0] = ad1884a_laptop_mixers;
4341                 spec->init_verbs[spec->num_init_verbs++] = ad1884a_laptop_verbs;
4342                 spec->multiout.dig_out_nid = 0;
4343                 codec->patch_ops.unsol_event = ad1884a_laptop_unsol_event;
4344                 codec->patch_ops.init = ad1884a_laptop_init;
4345                 /* set the upper-limit for mixer amp to 0dB for avoiding the
4346                  * possible damage by overloading
4347                  */
4348                 snd_hda_override_amp_caps(codec, 0x20, HDA_INPUT,
4349                                           (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
4350                                           (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
4351                                           (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
4352                                           (1 << AC_AMPCAP_MUTE_SHIFT));
4353                 break;
4354         case AD1884A_MOBILE:
4355                 spec->mixers[0] = ad1884a_mobile_mixers;
4356                 spec->init_verbs[0] = ad1884a_mobile_verbs;
4357                 spec->multiout.dig_out_nid = 0;
4358                 codec->patch_ops.unsol_event = ad1884a_hp_unsol_event;
4359                 codec->patch_ops.init = ad1884a_hp_init;
4360                 /* set the upper-limit for mixer amp to 0dB for avoiding the
4361                  * possible damage by overloading
4362                  */
4363                 snd_hda_override_amp_caps(codec, 0x20, HDA_INPUT,
4364                                           (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
4365                                           (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
4366                                           (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
4367                                           (1 << AC_AMPCAP_MUTE_SHIFT));
4368                 break;
4369         case AD1884A_THINKPAD:
4370                 spec->mixers[0] = ad1984a_thinkpad_mixers;
4371                 spec->init_verbs[spec->num_init_verbs++] =
4372                         ad1984a_thinkpad_verbs;
4373                 spec->multiout.dig_out_nid = 0;
4374                 spec->input_mux = &ad1984a_thinkpad_capture_source;
4375                 codec->patch_ops.unsol_event = ad1984a_thinkpad_unsol_event;
4376                 codec->patch_ops.init = ad1984a_thinkpad_init;
4377                 break;
4378         case AD1984A_TOUCHSMART:
4379                 spec->mixers[0] = ad1984a_touchsmart_mixers;
4380                 spec->init_verbs[0] = ad1984a_touchsmart_verbs;
4381                 spec->multiout.dig_out_nid = 0;
4382                 codec->patch_ops.unsol_event = ad1984a_touchsmart_unsol_event;
4383                 codec->patch_ops.init = ad1984a_touchsmart_init;
4384                 /* set the upper-limit for mixer amp to 0dB for avoiding the
4385                  * possible damage by overloading
4386                  */
4387                 snd_hda_override_amp_caps(codec, 0x20, HDA_INPUT,
4388                                           (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
4389                                           (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
4390                                           (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
4391                                           (1 << AC_AMPCAP_MUTE_SHIFT));
4392                 break;
4393         }
4394
4395         return 0;
4396 }
4397
4398
4399 /*
4400  * AD1882 / AD1882A
4401  *
4402  * port-A - front hp-out
4403  * port-B - front mic-in
4404  * port-C - rear line-in, shared surr-out (3stack)
4405  * port-D - rear line-out
4406  * port-E - rear mic-in, shared clfe-out (3stack)
4407  * port-F - rear surr-out (6stack)
4408  * port-G - rear clfe-out (6stack)
4409  */
4410
4411 static hda_nid_t ad1882_dac_nids[3] = {
4412         0x04, 0x03, 0x05
4413 };
4414
4415 static hda_nid_t ad1882_adc_nids[2] = {
4416         0x08, 0x09,
4417 };
4418
4419 static hda_nid_t ad1882_capsrc_nids[2] = {
4420         0x0c, 0x0d,
4421 };
4422
4423 #define AD1882_SPDIF_OUT        0x02
4424
4425 /* list: 0x11, 0x39, 0x3a, 0x18, 0x3c, 0x3b, 0x12, 0x20 */
4426 static struct hda_input_mux ad1882_capture_source = {
4427         .num_items = 5,
4428         .items = {
4429                 { "Front Mic", 0x1 },
4430                 { "Mic", 0x4 },
4431                 { "Line", 0x2 },
4432                 { "CD", 0x3 },
4433                 { "Mix", 0x7 },
4434         },
4435 };
4436
4437 /* list: 0x11, 0x39, 0x3a, 0x3c, 0x18, 0x1f, 0x12, 0x20 */
4438 static struct hda_input_mux ad1882a_capture_source = {
4439         .num_items = 5,
4440         .items = {
4441                 { "Front Mic", 0x1 },
4442                 { "Mic", 0x4},
4443                 { "Line", 0x2 },
4444                 { "Digital Mic", 0x06 },
4445                 { "Mix", 0x7 },
4446         },
4447 };
4448
4449 static struct snd_kcontrol_new ad1882_base_mixers[] = {
4450         HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
4451         HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
4452         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT),
4453         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT),
4454         HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
4455         HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT),
4456         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
4457         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
4458
4459         HDA_CODEC_VOLUME("Mic Boost", 0x3c, 0x0, HDA_OUTPUT),
4460         HDA_CODEC_VOLUME("Front Mic Boost", 0x39, 0x0, HDA_OUTPUT),
4461         HDA_CODEC_VOLUME("Line-In Boost", 0x3a, 0x0, HDA_OUTPUT),
4462         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
4463         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
4464         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
4465         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
4466         {
4467                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4468                 /* The multiple "Capture Source" controls confuse alsamixer
4469                  * So call somewhat different..
4470                  */
4471                 /* .name = "Capture Source", */
4472                 .name = "Input Source",
4473                 .count = 2,
4474                 .info = ad198x_mux_enum_info,
4475                 .get = ad198x_mux_enum_get,
4476                 .put = ad198x_mux_enum_put,
4477         },
4478         /* SPDIF controls */
4479         HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
4480         {
4481                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4482                 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
4483                 /* identical with ad1983 */
4484                 .info = ad1983_spdif_route_info,
4485                 .get = ad1983_spdif_route_get,
4486                 .put = ad1983_spdif_route_put,
4487         },
4488         { } /* end */
4489 };
4490
4491 static struct snd_kcontrol_new ad1882_loopback_mixers[] = {
4492         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
4493         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
4494         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
4495         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
4496         HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x04, HDA_INPUT),
4497         HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x04, HDA_INPUT),
4498         HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x06, HDA_INPUT),
4499         HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x06, HDA_INPUT),
4500         { } /* end */
4501 };
4502
4503 static struct snd_kcontrol_new ad1882a_loopback_mixers[] = {
4504         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
4505         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
4506         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
4507         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
4508         HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x01, HDA_INPUT),
4509         HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x01, HDA_INPUT),
4510         HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x06, HDA_INPUT),
4511         HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x06, HDA_INPUT),
4512         HDA_CODEC_VOLUME("Digital Mic Boost", 0x1f, 0x0, HDA_INPUT),
4513         { } /* end */
4514 };
4515
4516 static struct snd_kcontrol_new ad1882_3stack_mixers[] = {
4517         HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
4518         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x17, 1, 0x0, HDA_OUTPUT),
4519         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x17, 2, 0x0, HDA_OUTPUT),
4520         {
4521                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4522                 .name = "Channel Mode",
4523                 .info = ad198x_ch_mode_info,
4524                 .get = ad198x_ch_mode_get,
4525                 .put = ad198x_ch_mode_put,
4526         },
4527         { } /* end */
4528 };
4529
4530 static struct snd_kcontrol_new ad1882_6stack_mixers[] = {
4531         HDA_CODEC_MUTE("Surround Playback Switch", 0x16, 0x0, HDA_OUTPUT),
4532         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x24, 1, 0x0, HDA_OUTPUT),
4533         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x24, 2, 0x0, HDA_OUTPUT),
4534         { } /* end */
4535 };
4536
4537 static struct hda_verb ad1882_ch2_init[] = {
4538         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4539         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4540         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4541         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4542         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4543         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4544         { } /* end */
4545 };
4546
4547 static struct hda_verb ad1882_ch4_init[] = {
4548         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4549         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4550         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4551         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4552         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4553         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4554         { } /* end */
4555 };
4556
4557 static struct hda_verb ad1882_ch6_init[] = {
4558         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4559         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4560         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4561         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4562         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4563         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4564         { } /* end */
4565 };
4566
4567 static struct hda_channel_mode ad1882_modes[3] = {
4568         { 2, ad1882_ch2_init },
4569         { 4, ad1882_ch4_init },
4570         { 6, ad1882_ch6_init },
4571 };
4572
4573 /*
4574  * initialization verbs
4575  */
4576 static struct hda_verb ad1882_init_verbs[] = {
4577         /* DACs; mute as default */
4578         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4579         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4580         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4581         /* Port-A (HP) mixer */
4582         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4583         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4584         /* Port-A pin */
4585         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4586         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4587         /* HP selector - select DAC2 */
4588         {0x37, AC_VERB_SET_CONNECT_SEL, 0x1},
4589         /* Port-D (Line-out) mixer */
4590         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4591         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4592         /* Port-D pin */
4593         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4594         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4595         /* Mono-out mixer */
4596         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4597         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4598         /* Mono-out pin */
4599         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4600         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4601         /* Port-B (front mic) pin */
4602         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4603         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4604         {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */
4605         /* Port-C (line-in) pin */
4606         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4607         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4608         {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */
4609         /* Port-C mixer - mute as input */
4610         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4611         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4612         /* Port-E (mic-in) pin */
4613         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4614         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4615         {0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */
4616         /* Port-E mixer - mute as input */
4617         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4618         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4619         /* Port-F (surround) */
4620         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4621         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4622         /* Port-G (CLFE) */
4623         {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4624         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4625         /* Analog mixer; mute as default */
4626         /* list: 0x39, 0x3a, 0x11, 0x12, 0x3c, 0x3b, 0x18, 0x1a */
4627         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4628         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4629         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4630         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4631         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4632         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
4633         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
4634         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
4635         /* Analog Mix output amp */
4636         {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
4637         /* SPDIF output selector */
4638         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
4639         {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */
4640         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
4641         { } /* end */
4642 };
4643
4644 #ifdef CONFIG_SND_HDA_POWER_SAVE
4645 static struct hda_amp_list ad1882_loopbacks[] = {
4646         { 0x20, HDA_INPUT, 0 }, /* Front Mic */
4647         { 0x20, HDA_INPUT, 1 }, /* Mic */
4648         { 0x20, HDA_INPUT, 4 }, /* Line */
4649         { 0x20, HDA_INPUT, 6 }, /* CD */
4650         { } /* end */
4651 };
4652 #endif
4653
4654 /* models */
4655 enum {
4656         AD1882_3STACK,
4657         AD1882_6STACK,
4658         AD1882_MODELS
4659 };
4660
4661 static const char *ad1882_models[AD1986A_MODELS] = {
4662         [AD1882_3STACK]         = "3stack",
4663         [AD1882_6STACK]         = "6stack",
4664 };
4665
4666
4667 static int patch_ad1882(struct hda_codec *codec)
4668 {
4669         struct ad198x_spec *spec;
4670         int err, board_config;
4671
4672         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4673         if (spec == NULL)
4674                 return -ENOMEM;
4675
4676         codec->spec = spec;
4677
4678         err = snd_hda_attach_beep_device(codec, 0x10);
4679         if (err < 0) {
4680                 ad198x_free(codec);
4681                 return err;
4682         }
4683         set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
4684
4685         spec->multiout.max_channels = 6;
4686         spec->multiout.num_dacs = 3;
4687         spec->multiout.dac_nids = ad1882_dac_nids;
4688         spec->multiout.dig_out_nid = AD1882_SPDIF_OUT;
4689         spec->num_adc_nids = ARRAY_SIZE(ad1882_adc_nids);
4690         spec->adc_nids = ad1882_adc_nids;
4691         spec->capsrc_nids = ad1882_capsrc_nids;
4692         if (codec->vendor_id == 0x11d41882)
4693                 spec->input_mux = &ad1882_capture_source;
4694         else
4695                 spec->input_mux = &ad1882a_capture_source;
4696         spec->num_mixers = 2;
4697         spec->mixers[0] = ad1882_base_mixers;
4698         if (codec->vendor_id == 0x11d41882)
4699                 spec->mixers[1] = ad1882_loopback_mixers;
4700         else
4701                 spec->mixers[1] = ad1882a_loopback_mixers;
4702         spec->num_init_verbs = 1;
4703         spec->init_verbs[0] = ad1882_init_verbs;
4704         spec->spdif_route = 0;
4705 #ifdef CONFIG_SND_HDA_POWER_SAVE
4706         spec->loopback.amplist = ad1882_loopbacks;
4707 #endif
4708         spec->vmaster_nid = 0x04;
4709
4710         codec->patch_ops = ad198x_patch_ops;
4711
4712         /* override some parameters */
4713         board_config = snd_hda_check_board_config(codec, AD1882_MODELS,
4714                                                   ad1882_models, NULL);
4715         switch (board_config) {
4716         default:
4717         case AD1882_3STACK:
4718                 spec->num_mixers = 3;
4719                 spec->mixers[2] = ad1882_3stack_mixers;
4720                 spec->channel_mode = ad1882_modes;
4721                 spec->num_channel_mode = ARRAY_SIZE(ad1882_modes);
4722                 spec->need_dac_fix = 1;
4723                 spec->multiout.max_channels = 2;
4724                 spec->multiout.num_dacs = 1;
4725                 break;
4726         case AD1882_6STACK:
4727                 spec->num_mixers = 3;
4728                 spec->mixers[2] = ad1882_6stack_mixers;
4729                 break;
4730         }
4731         return 0;
4732 }
4733
4734
4735 /*
4736  * patch entries
4737  */
4738 static struct hda_codec_preset snd_hda_preset_analog[] = {
4739         { .id = 0x11d4184a, .name = "AD1884A", .patch = patch_ad1884a },
4740         { .id = 0x11d41882, .name = "AD1882", .patch = patch_ad1882 },
4741         { .id = 0x11d41883, .name = "AD1883", .patch = patch_ad1884a },
4742         { .id = 0x11d41884, .name = "AD1884", .patch = patch_ad1884 },
4743         { .id = 0x11d4194a, .name = "AD1984A", .patch = patch_ad1884a },
4744         { .id = 0x11d4194b, .name = "AD1984B", .patch = patch_ad1884a },
4745         { .id = 0x11d41981, .name = "AD1981", .patch = patch_ad1981 },
4746         { .id = 0x11d41983, .name = "AD1983", .patch = patch_ad1983 },
4747         { .id = 0x11d41984, .name = "AD1984", .patch = patch_ad1984 },
4748         { .id = 0x11d41986, .name = "AD1986A", .patch = patch_ad1986a },
4749         { .id = 0x11d41988, .name = "AD1988", .patch = patch_ad1988 },
4750         { .id = 0x11d4198b, .name = "AD1988B", .patch = patch_ad1988 },
4751         { .id = 0x11d4882a, .name = "AD1882A", .patch = patch_ad1882 },
4752         { .id = 0x11d4989a, .name = "AD1989A", .patch = patch_ad1988 },
4753         { .id = 0x11d4989b, .name = "AD1989B", .patch = patch_ad1988 },
4754         {} /* terminator */
4755 };
4756
4757 MODULE_ALIAS("snd-hda-codec-id:11d4*");
4758
4759 MODULE_LICENSE("GPL");
4760 MODULE_DESCRIPTION("Analog Devices HD-audio codec");
4761
4762 static struct hda_codec_preset_list analog_list = {
4763         .preset = snd_hda_preset_analog,
4764         .owner = THIS_MODULE,
4765 };
4766
4767 static int __init patch_analog_init(void)
4768 {
4769         return snd_hda_add_codec_preset(&analog_list);
4770 }
4771
4772 static void __exit patch_analog_exit(void)
4773 {
4774         snd_hda_delete_codec_preset(&analog_list);
4775 }
4776
4777 module_init(patch_analog_init)
4778 module_exit(patch_analog_exit)