ALSA: hda - Improve the input source name labels
[linux-2.6.git] / sound / pci / hda / patch_analog.c
1 /*
2  * HD audio interface patch for AD1882, AD1884, AD1981HD, AD1983, AD1984,
3  *   AD1986A, AD1988
4  *
5  * Copyright (c) 2005-2007 Takashi Iwai <tiwai@suse.de>
6  *
7  *  This driver is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation; either version 2 of the License, or
10  *  (at your option) any later version.
11  *
12  *  This driver is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with this program; if not, write to the Free Software
19  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
20  */
21
22 #include <linux/init.h>
23 #include <linux/delay.h>
24 #include <linux/slab.h>
25 #include <linux/pci.h>
26
27 #include <sound/core.h>
28 #include "hda_codec.h"
29 #include "hda_local.h"
30 #include "hda_beep.h"
31
32 struct ad198x_spec {
33         struct snd_kcontrol_new *mixers[5];
34         int num_mixers;
35         unsigned int beep_amp;  /* beep amp value, set via set_beep_amp() */
36         const struct hda_verb *init_verbs[5];   /* initialization verbs
37                                                  * don't forget NULL termination!
38                                                  */
39         unsigned int num_init_verbs;
40
41         /* playback */
42         struct hda_multi_out multiout;  /* playback set-up
43                                          * max_channels, dacs must be set
44                                          * dig_out_nid and hp_nid are optional
45                                          */
46         unsigned int cur_eapd;
47         unsigned int need_dac_fix;
48
49         /* capture */
50         unsigned int num_adc_nids;
51         hda_nid_t *adc_nids;
52         hda_nid_t dig_in_nid;           /* digital-in NID; optional */
53
54         /* capture source */
55         const struct hda_input_mux *input_mux;
56         hda_nid_t *capsrc_nids;
57         unsigned int cur_mux[3];
58
59         /* channel model */
60         const struct hda_channel_mode *channel_mode;
61         int num_channel_mode;
62
63         /* PCM information */
64         struct hda_pcm pcm_rec[3];      /* used in alc_build_pcms() */
65
66         unsigned int spdif_route;
67
68         /* dynamic controls, init_verbs and input_mux */
69         struct auto_pin_cfg autocfg;
70         struct snd_array kctls;
71         struct hda_input_mux private_imux;
72         hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
73
74         unsigned int jack_present: 1;
75         unsigned int inv_jack_detect: 1;/* inverted jack-detection */
76         unsigned int inv_eapd: 1;       /* inverted EAPD implementation */
77         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         {}
3646 };
3647
3648 static int patch_ad1984(struct hda_codec *codec)
3649 {
3650         struct ad198x_spec *spec;
3651         int board_config, err;
3652
3653         err = patch_ad1884(codec);
3654         if (err < 0)
3655                 return err;
3656         spec = codec->spec;
3657         board_config = snd_hda_check_board_config(codec, AD1984_MODELS,
3658                                                   ad1984_models, ad1984_cfg_tbl);
3659         switch (board_config) {
3660         case AD1984_BASIC:
3661                 /* additional digital mics */
3662                 spec->mixers[spec->num_mixers++] = ad1984_dmic_mixers;
3663                 codec->patch_ops.build_pcms = ad1984_build_pcms;
3664                 break;
3665         case AD1984_THINKPAD:
3666                 if (codec->subsystem_id == 0x17aa20fb) {
3667                         /* Thinpad X300 does not have the ability to do SPDIF,
3668                            or attach to docking station to use SPDIF */
3669                         spec->multiout.dig_out_nid = 0;
3670                 } else
3671                         spec->multiout.dig_out_nid = AD1884_SPDIF_OUT;
3672                 spec->input_mux = &ad1984_thinkpad_capture_source;
3673                 spec->mixers[0] = ad1984_thinkpad_mixers;
3674                 spec->init_verbs[spec->num_init_verbs++] = ad1984_thinkpad_init_verbs;
3675                 spec->analog_beep = 1;
3676                 break;
3677         case AD1984_DELL_DESKTOP:
3678                 spec->multiout.dig_out_nid = 0;
3679                 spec->input_mux = &ad1984_dell_desktop_capture_source;
3680                 spec->mixers[0] = ad1984_dell_desktop_mixers;
3681                 break;
3682         }
3683         return 0;
3684 }
3685
3686
3687 /*
3688  * AD1883 / AD1884A / AD1984A / AD1984B
3689  *
3690  * port-B (0x14) - front mic-in
3691  * port-E (0x1c) - rear mic-in
3692  * port-F (0x16) - CD / ext out
3693  * port-C (0x15) - rear line-in
3694  * port-D (0x12) - rear line-out
3695  * port-A (0x11) - front hp-out
3696  *
3697  * AD1984A = AD1884A + digital-mic
3698  * AD1883 = equivalent with AD1984A
3699  * AD1984B = AD1984A + extra SPDIF-out
3700  *
3701  * FIXME:
3702  * We share the single DAC for both HP and line-outs (see AD1884/1984).
3703  */
3704
3705 static hda_nid_t ad1884a_dac_nids[1] = {
3706         0x03,
3707 };
3708
3709 #define ad1884a_adc_nids        ad1884_adc_nids
3710 #define ad1884a_capsrc_nids     ad1884_capsrc_nids
3711
3712 #define AD1884A_SPDIF_OUT       0x02
3713
3714 static struct hda_input_mux ad1884a_capture_source = {
3715         .num_items = 5,
3716         .items = {
3717                 { "Front Mic", 0x0 },
3718                 { "Mic", 0x4 },
3719                 { "Line", 0x1 },
3720                 { "CD", 0x2 },
3721                 { "Mix", 0x3 },
3722         },
3723 };
3724
3725 static struct snd_kcontrol_new ad1884a_base_mixers[] = {
3726         HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
3727         HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),
3728         HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
3729         HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT),
3730         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
3731         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
3732         HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
3733         HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
3734         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
3735         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3736         HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x01, HDA_INPUT),
3737         HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x01, HDA_INPUT),
3738         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
3739         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
3740         HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x02, HDA_INPUT),
3741         HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x02, HDA_INPUT),
3742         HDA_CODEC_VOLUME("Front Mic Boost", 0x14, 0x0, HDA_INPUT),
3743         HDA_CODEC_VOLUME("Line Boost", 0x15, 0x0, HDA_INPUT),
3744         HDA_CODEC_VOLUME("Mic Boost", 0x25, 0x0, HDA_OUTPUT),
3745         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3746         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3747         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
3748         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
3749         {
3750                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3751                 /* The multiple "Capture Source" controls confuse alsamixer
3752                  * So call somewhat different..
3753                  */
3754                 /* .name = "Capture Source", */
3755                 .name = "Input Source",
3756                 .count = 2,
3757                 .info = ad198x_mux_enum_info,
3758                 .get = ad198x_mux_enum_get,
3759                 .put = ad198x_mux_enum_put,
3760         },
3761         /* SPDIF controls */
3762         HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
3763         {
3764                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3765                 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
3766                 /* identical with ad1983 */
3767                 .info = ad1983_spdif_route_info,
3768                 .get = ad1983_spdif_route_get,
3769                 .put = ad1983_spdif_route_put,
3770         },
3771         { } /* end */
3772 };
3773
3774 /*
3775  * initialization verbs
3776  */
3777 static struct hda_verb ad1884a_init_verbs[] = {
3778         /* DACs; unmute as default */
3779         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
3780         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
3781         /* Port-A (HP) mixer - route only from analog mixer */
3782         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3783         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3784         /* Port-A pin */
3785         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3786         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3787         /* Port-D (Line-out) mixer - route only from analog mixer */
3788         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3789         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3790         /* Port-D pin */
3791         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3792         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3793         /* Mono-out mixer - route only from analog mixer */
3794         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3795         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3796         /* Mono-out pin */
3797         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3798         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3799         /* Port-B (front mic) pin */
3800         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3801         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3802         /* Port-C (rear line-in) pin */
3803         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3804         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3805         /* Port-E (rear mic) pin */
3806         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3807         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3808         {0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* no boost */
3809         /* Port-F (CD) pin */
3810         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3811         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3812         /* Analog mixer; mute as default */
3813         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3814         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3815         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3816         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3817         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, /* aux */
3818         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
3819         /* Analog Mix output amp */
3820         {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3821         /* capture sources */
3822         {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0},
3823         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3824         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
3825         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3826         /* SPDIF output amp */
3827         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
3828         { } /* end */
3829 };
3830
3831 #ifdef CONFIG_SND_HDA_POWER_SAVE
3832 static struct hda_amp_list ad1884a_loopbacks[] = {
3833         { 0x20, HDA_INPUT, 0 }, /* Front Mic */
3834         { 0x20, HDA_INPUT, 1 }, /* Mic */
3835         { 0x20, HDA_INPUT, 2 }, /* CD */
3836         { 0x20, HDA_INPUT, 4 }, /* Docking */
3837         { } /* end */
3838 };
3839 #endif
3840
3841 /*
3842  * Laptop model
3843  *
3844  * Port A: Headphone jack
3845  * Port B: MIC jack
3846  * Port C: Internal MIC
3847  * Port D: Dock Line Out (if enabled)
3848  * Port E: Dock Line In (if enabled)
3849  * Port F: Internal speakers
3850  */
3851
3852 static int ad1884a_mobile_master_sw_put(struct snd_kcontrol *kcontrol,
3853                                         struct snd_ctl_elem_value *ucontrol)
3854 {
3855         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3856         int ret = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
3857         int mute = (!ucontrol->value.integer.value[0] &&
3858                     !ucontrol->value.integer.value[1]);
3859         /* toggle GPIO1 according to the mute state */
3860         snd_hda_codec_write_cache(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
3861                             mute ? 0x02 : 0x0);
3862         return ret;
3863 }
3864
3865 static struct snd_kcontrol_new ad1884a_laptop_mixers[] = {
3866         HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
3867         {
3868                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3869                 .name = "Master Playback Switch",
3870                 .subdevice = HDA_SUBDEV_AMP_FLAG,
3871                 .info = snd_hda_mixer_amp_switch_info,
3872                 .get = snd_hda_mixer_amp_switch_get,
3873                 .put = ad1884a_mobile_master_sw_put,
3874                 .private_value = HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
3875         },
3876         HDA_CODEC_MUTE("Dock Playback Switch", 0x12, 0x0, HDA_OUTPUT),
3877         HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
3878         HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
3879         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
3880         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3881         HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
3882         HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
3883         HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
3884         HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
3885         HDA_CODEC_VOLUME("Mic Boost", 0x14, 0x0, HDA_INPUT),
3886         HDA_CODEC_VOLUME("Internal Mic Boost", 0x15, 0x0, HDA_INPUT),
3887         HDA_CODEC_VOLUME("Dock Mic Boost", 0x25, 0x0, HDA_OUTPUT),
3888         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3889         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3890         { } /* end */
3891 };
3892
3893 static struct snd_kcontrol_new ad1884a_mobile_mixers[] = {
3894         HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
3895         /*HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/
3896         {
3897                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3898                 .name = "Master Playback Switch",
3899                 .subdevice = HDA_SUBDEV_AMP_FLAG,
3900                 .info = snd_hda_mixer_amp_switch_info,
3901                 .get = snd_hda_mixer_amp_switch_get,
3902                 .put = ad1884a_mobile_master_sw_put,
3903                 .private_value = HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
3904         },
3905         HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
3906         HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
3907         HDA_CODEC_VOLUME("Mic Capture Volume", 0x14, 0x0, HDA_INPUT),
3908         HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x15, 0x0, HDA_INPUT),
3909         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3910         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3911         { } /* end */
3912 };
3913
3914 /* mute internal speaker if HP is plugged */
3915 static void ad1884a_hp_automute(struct hda_codec *codec)
3916 {
3917         unsigned int present;
3918
3919         present = snd_hda_jack_detect(codec, 0x11);
3920         snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
3921                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
3922         snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_EAPD_BTLENABLE,
3923                             present ? 0x00 : 0x02);
3924 }
3925
3926 /* switch to external mic if plugged */
3927 static void ad1884a_hp_automic(struct hda_codec *codec)
3928 {
3929         unsigned int present;
3930
3931         present = snd_hda_jack_detect(codec, 0x14);
3932         snd_hda_codec_write(codec, 0x0c, 0, AC_VERB_SET_CONNECT_SEL,
3933                             present ? 0 : 1);
3934 }
3935
3936 #define AD1884A_HP_EVENT                0x37
3937 #define AD1884A_MIC_EVENT               0x36
3938
3939 /* unsolicited event for HP jack sensing */
3940 static void ad1884a_hp_unsol_event(struct hda_codec *codec, unsigned int res)
3941 {
3942         switch (res >> 26) {
3943         case AD1884A_HP_EVENT:
3944                 ad1884a_hp_automute(codec);
3945                 break;
3946         case AD1884A_MIC_EVENT:
3947                 ad1884a_hp_automic(codec);
3948                 break;
3949         }
3950 }
3951
3952 /* initialize jack-sensing, too */
3953 static int ad1884a_hp_init(struct hda_codec *codec)
3954 {
3955         ad198x_init(codec);
3956         ad1884a_hp_automute(codec);
3957         ad1884a_hp_automic(codec);
3958         return 0;
3959 }
3960
3961 /* mute internal speaker if HP or docking HP is plugged */
3962 static void ad1884a_laptop_automute(struct hda_codec *codec)
3963 {
3964         unsigned int present;
3965
3966         present = snd_hda_jack_detect(codec, 0x11);
3967         if (!present)
3968                 present = snd_hda_jack_detect(codec, 0x12);
3969         snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
3970                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
3971         snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_EAPD_BTLENABLE,
3972                             present ? 0x00 : 0x02);
3973 }
3974
3975 /* switch to external mic if plugged */
3976 static void ad1884a_laptop_automic(struct hda_codec *codec)
3977 {
3978         unsigned int idx;
3979
3980         if (snd_hda_jack_detect(codec, 0x14))
3981                 idx = 0;
3982         else if (snd_hda_jack_detect(codec, 0x1c))
3983                 idx = 4;
3984         else
3985                 idx = 1;
3986         snd_hda_codec_write(codec, 0x0c, 0, AC_VERB_SET_CONNECT_SEL, idx);
3987 }
3988
3989 /* unsolicited event for HP jack sensing */
3990 static void ad1884a_laptop_unsol_event(struct hda_codec *codec,
3991                                        unsigned int res)
3992 {
3993         switch (res >> 26) {
3994         case AD1884A_HP_EVENT:
3995                 ad1884a_laptop_automute(codec);
3996                 break;
3997         case AD1884A_MIC_EVENT:
3998                 ad1884a_laptop_automic(codec);
3999                 break;
4000         }
4001 }
4002
4003 /* initialize jack-sensing, too */
4004 static int ad1884a_laptop_init(struct hda_codec *codec)
4005 {
4006         ad198x_init(codec);
4007         ad1884a_laptop_automute(codec);
4008         ad1884a_laptop_automic(codec);
4009         return 0;
4010 }
4011
4012 /* additional verbs for laptop model */
4013 static struct hda_verb ad1884a_laptop_verbs[] = {
4014         /* Port-A (HP) pin - always unmuted */
4015         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4016         /* Port-F (int speaker) mixer - route only from analog mixer */
4017         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4018         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4019         /* Port-F (int speaker) pin */
4020         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4021         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4022         /* required for compaq 6530s/6531s speaker output */
4023         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4024         /* Port-C pin - internal mic-in */
4025         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4026         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
4027         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
4028         /* Port-D (docking line-out) pin - default unmuted */
4029         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4030         /* analog mix */
4031         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4032         /* unsolicited event for pin-sense */
4033         {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
4034         {0x12, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
4035         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT},
4036         {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT},
4037         /* allow to touch GPIO1 (for mute control) */
4038         {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
4039         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
4040         {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, /* first muted */
4041         { } /* end */
4042 };
4043
4044 static struct hda_verb ad1884a_mobile_verbs[] = {
4045         /* DACs; unmute as default */
4046         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
4047         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
4048         /* Port-A (HP) mixer - route only from analog mixer */
4049         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4050         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4051         /* Port-A pin */
4052         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4053         /* Port-A (HP) pin - always unmuted */
4054         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4055         /* Port-B (mic jack) pin */
4056         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4057         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
4058         /* Port-C (int mic) pin */
4059         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4060         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
4061         /* Port-F (int speaker) mixer - route only from analog mixer */
4062         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4063         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4064         /* Port-F pin */
4065         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4066         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4067         /* Analog mixer; mute as default */
4068         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4069         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4070         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4071         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4072         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4073         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
4074         /* Analog Mix output amp */
4075         {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4076         /* capture sources */
4077         /* {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0}, */ /* set via unsol */
4078         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4079         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
4080         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4081         /* unsolicited event for pin-sense */
4082         {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
4083         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT},
4084         /* allow to touch GPIO1 (for mute control) */
4085         {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
4086         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
4087         {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, /* first muted */
4088         { } /* end */
4089 };
4090
4091 /*
4092  * Thinkpad X300
4093  * 0x11 - HP
4094  * 0x12 - speaker
4095  * 0x14 - mic-in
4096  * 0x17 - built-in mic
4097  */
4098
4099 static struct hda_verb ad1984a_thinkpad_verbs[] = {
4100         /* HP unmute */
4101         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4102         /* analog mix */
4103         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4104         /* turn on EAPD */
4105         {0x12, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4106         /* unsolicited event for pin-sense */
4107         {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
4108         /* internal mic - dmic */
4109         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4110         /* set magic COEFs for dmic */
4111         {0x01, AC_VERB_SET_COEF_INDEX, 0x13f7},
4112         {0x01, AC_VERB_SET_PROC_COEF, 0x08},
4113         { } /* end */
4114 };
4115
4116 static struct snd_kcontrol_new ad1984a_thinkpad_mixers[] = {
4117         HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
4118         HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),
4119         HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
4120         HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
4121         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
4122         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
4123         HDA_CODEC_VOLUME("Mic Boost", 0x14, 0x0, HDA_INPUT),
4124         HDA_CODEC_VOLUME("Internal Mic Boost", 0x17, 0x0, HDA_INPUT),
4125         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
4126         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
4127         {
4128                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4129                 .name = "Capture Source",
4130                 .info = ad198x_mux_enum_info,
4131                 .get = ad198x_mux_enum_get,
4132                 .put = ad198x_mux_enum_put,
4133         },
4134         { } /* end */
4135 };
4136
4137 static struct hda_input_mux ad1984a_thinkpad_capture_source = {
4138         .num_items = 3,
4139         .items = {
4140                 { "Mic", 0x0 },
4141                 { "Internal Mic", 0x5 },
4142                 { "Mix", 0x3 },
4143         },
4144 };
4145
4146 /* mute internal speaker if HP is plugged */
4147 static void ad1984a_thinkpad_automute(struct hda_codec *codec)
4148 {
4149         unsigned int present;
4150
4151         present = snd_hda_jack_detect(codec, 0x11);
4152         snd_hda_codec_amp_stereo(codec, 0x12, HDA_OUTPUT, 0,
4153                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
4154 }
4155
4156 /* unsolicited event for HP jack sensing */
4157 static void ad1984a_thinkpad_unsol_event(struct hda_codec *codec,
4158                                          unsigned int res)
4159 {
4160         if ((res >> 26) != AD1884A_HP_EVENT)
4161                 return;
4162         ad1984a_thinkpad_automute(codec);
4163 }
4164
4165 /* initialize jack-sensing, too */
4166 static int ad1984a_thinkpad_init(struct hda_codec *codec)
4167 {
4168         ad198x_init(codec);
4169         ad1984a_thinkpad_automute(codec);
4170         return 0;
4171 }
4172
4173 /*
4174  * HP Touchsmart
4175  * port-A (0x11)      - front hp-out
4176  * port-B (0x14)      - unused
4177  * port-C (0x15)      - unused
4178  * port-D (0x12)      - rear line out
4179  * port-E (0x1c)      - front mic-in
4180  * port-F (0x16)      - Internal speakers
4181  * digital-mic (0x17) - Internal mic
4182  */
4183
4184 static struct hda_verb ad1984a_touchsmart_verbs[] = {
4185         /* DACs; unmute as default */
4186         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
4187         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
4188         /* Port-A (HP) mixer - route only from analog mixer */
4189         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4190         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4191         /* Port-A pin */
4192         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4193         /* Port-A (HP) pin - always unmuted */
4194         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4195         /* Port-E (int speaker) mixer - route only from analog mixer */
4196         {0x25, AC_VERB_SET_AMP_GAIN_MUTE, 0x03},
4197         /* Port-E pin */
4198         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4199         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4200         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4201         /* Port-F (int speaker) mixer - route only from analog mixer */
4202         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4203         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4204         /* Port-F pin */
4205         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4206         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4207         /* Analog mixer; mute as default */
4208         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4209         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4210         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4211         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4212         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4213         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
4214         /* Analog Mix output amp */
4215         {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4216         /* capture sources */
4217         /* {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0}, */ /* set via unsol */
4218         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4219         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
4220         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4221         /* unsolicited event for pin-sense */
4222         {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
4223         {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT},
4224         /* allow to touch GPIO1 (for mute control) */
4225         {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
4226         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
4227         {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, /* first muted */
4228         /* internal mic - dmic */
4229         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4230         /* set magic COEFs for dmic */
4231         {0x01, AC_VERB_SET_COEF_INDEX, 0x13f7},
4232         {0x01, AC_VERB_SET_PROC_COEF, 0x08},
4233         { } /* end */
4234 };
4235
4236 static struct snd_kcontrol_new ad1984a_touchsmart_mixers[] = {
4237         HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
4238 /*      HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/
4239         {
4240                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4241                 .subdevice = HDA_SUBDEV_AMP_FLAG,
4242                 .name = "Master Playback Switch",
4243                 .info = snd_hda_mixer_amp_switch_info,
4244                 .get = snd_hda_mixer_amp_switch_get,
4245                 .put = ad1884a_mobile_master_sw_put,
4246                 .private_value = HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
4247         },
4248         HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
4249         HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
4250         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
4251         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
4252         HDA_CODEC_VOLUME("Mic Boost", 0x25, 0x0, HDA_OUTPUT),
4253         HDA_CODEC_VOLUME("Internal Mic Boost", 0x17, 0x0, HDA_INPUT),
4254         { } /* end */
4255 };
4256
4257 /* switch to external mic if plugged */
4258 static void ad1984a_touchsmart_automic(struct hda_codec *codec)
4259 {
4260         if (snd_hda_jack_detect(codec, 0x1c))
4261                 snd_hda_codec_write(codec, 0x0c, 0,
4262                                      AC_VERB_SET_CONNECT_SEL, 0x4);
4263         else
4264                 snd_hda_codec_write(codec, 0x0c, 0,
4265                                      AC_VERB_SET_CONNECT_SEL, 0x5);
4266 }
4267
4268
4269 /* unsolicited event for HP jack sensing */
4270 static void ad1984a_touchsmart_unsol_event(struct hda_codec *codec,
4271         unsigned int res)
4272 {
4273         switch (res >> 26) {
4274         case AD1884A_HP_EVENT:
4275                 ad1884a_hp_automute(codec);
4276                 break;
4277         case AD1884A_MIC_EVENT:
4278                 ad1984a_touchsmart_automic(codec);
4279                 break;
4280         }
4281 }
4282
4283 /* initialize jack-sensing, too */
4284 static int ad1984a_touchsmart_init(struct hda_codec *codec)
4285 {
4286         ad198x_init(codec);
4287         ad1884a_hp_automute(codec);
4288         ad1984a_touchsmart_automic(codec);
4289         return 0;
4290 }
4291
4292
4293 /*
4294  */
4295
4296 enum {
4297         AD1884A_DESKTOP,
4298         AD1884A_LAPTOP,
4299         AD1884A_MOBILE,
4300         AD1884A_THINKPAD,
4301         AD1984A_TOUCHSMART,
4302         AD1884A_MODELS
4303 };
4304
4305 static const char *ad1884a_models[AD1884A_MODELS] = {
4306         [AD1884A_DESKTOP]       = "desktop",
4307         [AD1884A_LAPTOP]        = "laptop",
4308         [AD1884A_MOBILE]        = "mobile",
4309         [AD1884A_THINKPAD]      = "thinkpad",
4310         [AD1984A_TOUCHSMART]    = "touchsmart",
4311 };
4312
4313 static struct snd_pci_quirk ad1884a_cfg_tbl[] = {
4314         SND_PCI_QUIRK(0x103c, 0x3030, "HP", AD1884A_MOBILE),
4315         SND_PCI_QUIRK(0x103c, 0x3037, "HP 2230s", AD1884A_LAPTOP),
4316         SND_PCI_QUIRK(0x103c, 0x3056, "HP", AD1884A_MOBILE),
4317         SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x3070, "HP", AD1884A_MOBILE),
4318         SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x30d0, "HP laptop", AD1884A_LAPTOP),
4319         SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x30e0, "HP laptop", AD1884A_LAPTOP),
4320         SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3600, "HP laptop", AD1884A_LAPTOP),
4321         SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x7010, "HP laptop", AD1884A_MOBILE),
4322         SND_PCI_QUIRK(0x17aa, 0x20ac, "Thinkpad X300", AD1884A_THINKPAD),
4323         SND_PCI_QUIRK(0x103c, 0x2a82, "Touchsmart", AD1984A_TOUCHSMART),
4324         {}
4325 };
4326
4327 static int patch_ad1884a(struct hda_codec *codec)
4328 {
4329         struct ad198x_spec *spec;
4330         int err, board_config;
4331
4332         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4333         if (spec == NULL)
4334                 return -ENOMEM;
4335
4336         codec->spec = spec;
4337
4338         err = snd_hda_attach_beep_device(codec, 0x10);
4339         if (err < 0) {
4340                 ad198x_free(codec);
4341                 return err;
4342         }
4343         set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
4344
4345         spec->multiout.max_channels = 2;
4346         spec->multiout.num_dacs = ARRAY_SIZE(ad1884a_dac_nids);
4347         spec->multiout.dac_nids = ad1884a_dac_nids;
4348         spec->multiout.dig_out_nid = AD1884A_SPDIF_OUT;
4349         spec->num_adc_nids = ARRAY_SIZE(ad1884a_adc_nids);
4350         spec->adc_nids = ad1884a_adc_nids;
4351         spec->capsrc_nids = ad1884a_capsrc_nids;
4352         spec->input_mux = &ad1884a_capture_source;
4353         spec->num_mixers = 1;
4354         spec->mixers[0] = ad1884a_base_mixers;
4355         spec->num_init_verbs = 1;
4356         spec->init_verbs[0] = ad1884a_init_verbs;
4357         spec->spdif_route = 0;
4358 #ifdef CONFIG_SND_HDA_POWER_SAVE
4359         spec->loopback.amplist = ad1884a_loopbacks;
4360 #endif
4361         codec->patch_ops = ad198x_patch_ops;
4362
4363         /* override some parameters */
4364         board_config = snd_hda_check_board_config(codec, AD1884A_MODELS,
4365                                                   ad1884a_models,
4366                                                   ad1884a_cfg_tbl);
4367         switch (board_config) {
4368         case AD1884A_LAPTOP:
4369                 spec->mixers[0] = ad1884a_laptop_mixers;
4370                 spec->init_verbs[spec->num_init_verbs++] = ad1884a_laptop_verbs;
4371                 spec->multiout.dig_out_nid = 0;
4372                 codec->patch_ops.unsol_event = ad1884a_laptop_unsol_event;
4373                 codec->patch_ops.init = ad1884a_laptop_init;
4374                 /* set the upper-limit for mixer amp to 0dB for avoiding the
4375                  * possible damage by overloading
4376                  */
4377                 snd_hda_override_amp_caps(codec, 0x20, HDA_INPUT,
4378                                           (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
4379                                           (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
4380                                           (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
4381                                           (1 << AC_AMPCAP_MUTE_SHIFT));
4382                 break;
4383         case AD1884A_MOBILE:
4384                 spec->mixers[0] = ad1884a_mobile_mixers;
4385                 spec->init_verbs[0] = ad1884a_mobile_verbs;
4386                 spec->multiout.dig_out_nid = 0;
4387                 codec->patch_ops.unsol_event = ad1884a_hp_unsol_event;
4388                 codec->patch_ops.init = ad1884a_hp_init;
4389                 /* set the upper-limit for mixer amp to 0dB for avoiding the
4390                  * possible damage by overloading
4391                  */
4392                 snd_hda_override_amp_caps(codec, 0x20, HDA_INPUT,
4393                                           (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
4394                                           (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
4395                                           (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
4396                                           (1 << AC_AMPCAP_MUTE_SHIFT));
4397                 break;
4398         case AD1884A_THINKPAD:
4399                 spec->mixers[0] = ad1984a_thinkpad_mixers;
4400                 spec->init_verbs[spec->num_init_verbs++] =
4401                         ad1984a_thinkpad_verbs;
4402                 spec->multiout.dig_out_nid = 0;
4403                 spec->input_mux = &ad1984a_thinkpad_capture_source;
4404                 codec->patch_ops.unsol_event = ad1984a_thinkpad_unsol_event;
4405                 codec->patch_ops.init = ad1984a_thinkpad_init;
4406                 break;
4407         case AD1984A_TOUCHSMART:
4408                 spec->mixers[0] = ad1984a_touchsmart_mixers;
4409                 spec->init_verbs[0] = ad1984a_touchsmart_verbs;
4410                 spec->multiout.dig_out_nid = 0;
4411                 codec->patch_ops.unsol_event = ad1984a_touchsmart_unsol_event;
4412                 codec->patch_ops.init = ad1984a_touchsmart_init;
4413                 /* set the upper-limit for mixer amp to 0dB for avoiding the
4414                  * possible damage by overloading
4415                  */
4416                 snd_hda_override_amp_caps(codec, 0x20, HDA_INPUT,
4417                                           (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
4418                                           (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
4419                                           (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
4420                                           (1 << AC_AMPCAP_MUTE_SHIFT));
4421                 break;
4422         }
4423
4424         codec->no_trigger_sense = 1;
4425
4426         return 0;
4427 }
4428
4429
4430 /*
4431  * AD1882 / AD1882A
4432  *
4433  * port-A - front hp-out
4434  * port-B - front mic-in
4435  * port-C - rear line-in, shared surr-out (3stack)
4436  * port-D - rear line-out
4437  * port-E - rear mic-in, shared clfe-out (3stack)
4438  * port-F - rear surr-out (6stack)
4439  * port-G - rear clfe-out (6stack)
4440  */
4441
4442 static hda_nid_t ad1882_dac_nids[3] = {
4443         0x04, 0x03, 0x05
4444 };
4445
4446 static hda_nid_t ad1882_adc_nids[2] = {
4447         0x08, 0x09,
4448 };
4449
4450 static hda_nid_t ad1882_capsrc_nids[2] = {
4451         0x0c, 0x0d,
4452 };
4453
4454 #define AD1882_SPDIF_OUT        0x02
4455
4456 /* list: 0x11, 0x39, 0x3a, 0x18, 0x3c, 0x3b, 0x12, 0x20 */
4457 static struct hda_input_mux ad1882_capture_source = {
4458         .num_items = 5,
4459         .items = {
4460                 { "Front Mic", 0x1 },
4461                 { "Mic", 0x4 },
4462                 { "Line", 0x2 },
4463                 { "CD", 0x3 },
4464                 { "Mix", 0x7 },
4465         },
4466 };
4467
4468 /* list: 0x11, 0x39, 0x3a, 0x3c, 0x18, 0x1f, 0x12, 0x20 */
4469 static struct hda_input_mux ad1882a_capture_source = {
4470         .num_items = 5,
4471         .items = {
4472                 { "Front Mic", 0x1 },
4473                 { "Mic", 0x4},
4474                 { "Line", 0x2 },
4475                 { "Digital Mic", 0x06 },
4476                 { "Mix", 0x7 },
4477         },
4478 };
4479
4480 static struct snd_kcontrol_new ad1882_base_mixers[] = {
4481         HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
4482         HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
4483         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT),
4484         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT),
4485         HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
4486         HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT),
4487         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
4488         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
4489
4490         HDA_CODEC_VOLUME("Mic Boost", 0x3c, 0x0, HDA_OUTPUT),
4491         HDA_CODEC_VOLUME("Front Mic Boost", 0x39, 0x0, HDA_OUTPUT),
4492         HDA_CODEC_VOLUME("Line-In Boost", 0x3a, 0x0, HDA_OUTPUT),
4493         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
4494         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
4495         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
4496         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
4497         {
4498                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4499                 /* The multiple "Capture Source" controls confuse alsamixer
4500                  * So call somewhat different..
4501                  */
4502                 /* .name = "Capture Source", */
4503                 .name = "Input Source",
4504                 .count = 2,
4505                 .info = ad198x_mux_enum_info,
4506                 .get = ad198x_mux_enum_get,
4507                 .put = ad198x_mux_enum_put,
4508         },
4509         /* SPDIF controls */
4510         HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
4511         {
4512                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4513                 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
4514                 /* identical with ad1983 */
4515                 .info = ad1983_spdif_route_info,
4516                 .get = ad1983_spdif_route_get,
4517                 .put = ad1983_spdif_route_put,
4518         },
4519         { } /* end */
4520 };
4521
4522 static struct snd_kcontrol_new ad1882_loopback_mixers[] = {
4523         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
4524         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
4525         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
4526         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
4527         HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x04, HDA_INPUT),
4528         HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x04, HDA_INPUT),
4529         HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x06, HDA_INPUT),
4530         HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x06, HDA_INPUT),
4531         { } /* end */
4532 };
4533
4534 static struct snd_kcontrol_new ad1882a_loopback_mixers[] = {
4535         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
4536         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
4537         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
4538         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
4539         HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x01, HDA_INPUT),
4540         HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x01, HDA_INPUT),
4541         HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x06, HDA_INPUT),
4542         HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x06, HDA_INPUT),
4543         HDA_CODEC_VOLUME("Digital Mic Boost", 0x1f, 0x0, HDA_INPUT),
4544         { } /* end */
4545 };
4546
4547 static struct snd_kcontrol_new ad1882_3stack_mixers[] = {
4548         HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
4549         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x17, 1, 0x0, HDA_OUTPUT),
4550         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x17, 2, 0x0, HDA_OUTPUT),
4551         {
4552                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4553                 .name = "Channel Mode",
4554                 .info = ad198x_ch_mode_info,
4555                 .get = ad198x_ch_mode_get,
4556                 .put = ad198x_ch_mode_put,
4557         },
4558         { } /* end */
4559 };
4560
4561 static struct snd_kcontrol_new ad1882_6stack_mixers[] = {
4562         HDA_CODEC_MUTE("Surround Playback Switch", 0x16, 0x0, HDA_OUTPUT),
4563         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x24, 1, 0x0, HDA_OUTPUT),
4564         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x24, 2, 0x0, HDA_OUTPUT),
4565         { } /* end */
4566 };
4567
4568 static struct hda_verb ad1882_ch2_init[] = {
4569         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4570         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4571         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4572         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4573         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4574         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4575         { } /* end */
4576 };
4577
4578 static struct hda_verb ad1882_ch4_init[] = {
4579         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4580         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4581         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4582         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4583         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4584         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4585         { } /* end */
4586 };
4587
4588 static struct hda_verb ad1882_ch6_init[] = {
4589         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4590         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4591         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4592         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4593         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4594         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4595         { } /* end */
4596 };
4597
4598 static struct hda_channel_mode ad1882_modes[3] = {
4599         { 2, ad1882_ch2_init },
4600         { 4, ad1882_ch4_init },
4601         { 6, ad1882_ch6_init },
4602 };
4603
4604 /*
4605  * initialization verbs
4606  */
4607 static struct hda_verb ad1882_init_verbs[] = {
4608         /* DACs; mute as default */
4609         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4610         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4611         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4612         /* Port-A (HP) mixer */
4613         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4614         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4615         /* Port-A pin */
4616         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4617         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4618         /* HP selector - select DAC2 */
4619         {0x37, AC_VERB_SET_CONNECT_SEL, 0x1},
4620         /* Port-D (Line-out) mixer */
4621         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4622         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4623         /* Port-D pin */
4624         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4625         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4626         /* Mono-out mixer */
4627         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4628         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4629         /* Mono-out pin */
4630         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4631         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4632         /* Port-B (front mic) pin */
4633         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4634         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4635         {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */
4636         /* Port-C (line-in) pin */
4637         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4638         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4639         {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */
4640         /* Port-C mixer - mute as input */
4641         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4642         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4643         /* Port-E (mic-in) pin */
4644         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4645         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4646         {0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */
4647         /* Port-E mixer - mute as input */
4648         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4649         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4650         /* Port-F (surround) */
4651         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4652         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4653         /* Port-G (CLFE) */
4654         {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4655         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4656         /* Analog mixer; mute as default */
4657         /* list: 0x39, 0x3a, 0x11, 0x12, 0x3c, 0x3b, 0x18, 0x1a */
4658         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4659         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4660         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4661         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4662         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4663         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
4664         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
4665         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
4666         /* Analog Mix output amp */
4667         {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
4668         /* SPDIF output selector */
4669         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
4670         {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */
4671         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
4672         { } /* end */
4673 };
4674
4675 #ifdef CONFIG_SND_HDA_POWER_SAVE
4676 static struct hda_amp_list ad1882_loopbacks[] = {
4677         { 0x20, HDA_INPUT, 0 }, /* Front Mic */
4678         { 0x20, HDA_INPUT, 1 }, /* Mic */
4679         { 0x20, HDA_INPUT, 4 }, /* Line */
4680         { 0x20, HDA_INPUT, 6 }, /* CD */
4681         { } /* end */
4682 };
4683 #endif
4684
4685 /* models */
4686 enum {
4687         AD1882_3STACK,
4688         AD1882_6STACK,
4689         AD1882_MODELS
4690 };
4691
4692 static const char *ad1882_models[AD1986A_MODELS] = {
4693         [AD1882_3STACK]         = "3stack",
4694         [AD1882_6STACK]         = "6stack",
4695 };
4696
4697
4698 static int patch_ad1882(struct hda_codec *codec)
4699 {
4700         struct ad198x_spec *spec;
4701         int err, board_config;
4702
4703         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4704         if (spec == NULL)
4705                 return -ENOMEM;
4706
4707         codec->spec = spec;
4708
4709         err = snd_hda_attach_beep_device(codec, 0x10);
4710         if (err < 0) {
4711                 ad198x_free(codec);
4712                 return err;
4713         }
4714         set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
4715
4716         spec->multiout.max_channels = 6;
4717         spec->multiout.num_dacs = 3;
4718         spec->multiout.dac_nids = ad1882_dac_nids;
4719         spec->multiout.dig_out_nid = AD1882_SPDIF_OUT;
4720         spec->num_adc_nids = ARRAY_SIZE(ad1882_adc_nids);
4721         spec->adc_nids = ad1882_adc_nids;
4722         spec->capsrc_nids = ad1882_capsrc_nids;
4723         if (codec->vendor_id == 0x11d41882)
4724                 spec->input_mux = &ad1882_capture_source;
4725         else
4726                 spec->input_mux = &ad1882a_capture_source;
4727         spec->num_mixers = 2;
4728         spec->mixers[0] = ad1882_base_mixers;
4729         if (codec->vendor_id == 0x11d41882)
4730                 spec->mixers[1] = ad1882_loopback_mixers;
4731         else
4732                 spec->mixers[1] = ad1882a_loopback_mixers;
4733         spec->num_init_verbs = 1;
4734         spec->init_verbs[0] = ad1882_init_verbs;
4735         spec->spdif_route = 0;
4736 #ifdef CONFIG_SND_HDA_POWER_SAVE
4737         spec->loopback.amplist = ad1882_loopbacks;
4738 #endif
4739         spec->vmaster_nid = 0x04;
4740
4741         codec->patch_ops = ad198x_patch_ops;
4742
4743         /* override some parameters */
4744         board_config = snd_hda_check_board_config(codec, AD1882_MODELS,
4745                                                   ad1882_models, NULL);
4746         switch (board_config) {
4747         default:
4748         case AD1882_3STACK:
4749                 spec->num_mixers = 3;
4750                 spec->mixers[2] = ad1882_3stack_mixers;
4751                 spec->channel_mode = ad1882_modes;
4752                 spec->num_channel_mode = ARRAY_SIZE(ad1882_modes);
4753                 spec->need_dac_fix = 1;
4754                 spec->multiout.max_channels = 2;
4755                 spec->multiout.num_dacs = 1;
4756                 break;
4757         case AD1882_6STACK:
4758                 spec->num_mixers = 3;
4759                 spec->mixers[2] = ad1882_6stack_mixers;
4760                 break;
4761         }
4762
4763         codec->no_trigger_sense = 1;
4764
4765         return 0;
4766 }
4767
4768
4769 /*
4770  * patch entries
4771  */
4772 static struct hda_codec_preset snd_hda_preset_analog[] = {
4773         { .id = 0x11d4184a, .name = "AD1884A", .patch = patch_ad1884a },
4774         { .id = 0x11d41882, .name = "AD1882", .patch = patch_ad1882 },
4775         { .id = 0x11d41883, .name = "AD1883", .patch = patch_ad1884a },
4776         { .id = 0x11d41884, .name = "AD1884", .patch = patch_ad1884 },
4777         { .id = 0x11d4194a, .name = "AD1984A", .patch = patch_ad1884a },
4778         { .id = 0x11d4194b, .name = "AD1984B", .patch = patch_ad1884a },
4779         { .id = 0x11d41981, .name = "AD1981", .patch = patch_ad1981 },
4780         { .id = 0x11d41983, .name = "AD1983", .patch = patch_ad1983 },
4781         { .id = 0x11d41984, .name = "AD1984", .patch = patch_ad1984 },
4782         { .id = 0x11d41986, .name = "AD1986A", .patch = patch_ad1986a },
4783         { .id = 0x11d41988, .name = "AD1988", .patch = patch_ad1988 },
4784         { .id = 0x11d4198b, .name = "AD1988B", .patch = patch_ad1988 },
4785         { .id = 0x11d4882a, .name = "AD1882A", .patch = patch_ad1882 },
4786         { .id = 0x11d4989a, .name = "AD1989A", .patch = patch_ad1988 },
4787         { .id = 0x11d4989b, .name = "AD1989B", .patch = patch_ad1988 },
4788         {} /* terminator */
4789 };
4790
4791 MODULE_ALIAS("snd-hda-codec-id:11d4*");
4792
4793 MODULE_LICENSE("GPL");
4794 MODULE_DESCRIPTION("Analog Devices HD-audio codec");
4795
4796 static struct hda_codec_preset_list analog_list = {
4797         .preset = snd_hda_preset_analog,
4798         .owner = THIS_MODULE,
4799 };
4800
4801 static int __init patch_analog_init(void)
4802 {
4803         return snd_hda_add_codec_preset(&analog_list);
4804 }
4805
4806 static void __exit patch_analog_exit(void)
4807 {
4808         snd_hda_delete_codec_preset(&analog_list);
4809 }
4810
4811 module_init(patch_analog_init)
4812 module_exit(patch_analog_exit)