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