]> bbs.cooldavid.org Git - net-next-2.6.git/blob - sound/pci/hda/patch_analog.c
ALSA: hda - Disable sticky PCM stream assignment for AD codecs
[net-next-2.6.git] / sound / pci / hda / patch_analog.c
1 /*
2  * HD audio interface patch for AD1882, AD1884, AD1981HD, AD1983, AD1984,
3  *   AD1986A, AD1988
4  *
5  * Copyright (c) 2005-2007 Takashi Iwai <tiwai@suse.de>
6  *
7  *  This driver is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation; either version 2 of the License, or
10  *  (at your option) any later version.
11  *
12  *  This driver is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with this program; if not, write to the Free Software
19  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
20  */
21
22 #include <linux/init.h>
23 #include <linux/delay.h>
24 #include <linux/slab.h>
25 #include <linux/pci.h>
26
27 #include <sound/core.h>
28 #include "hda_codec.h"
29 #include "hda_local.h"
30 #include "hda_beep.h"
31
32 struct ad198x_spec {
33         struct snd_kcontrol_new *mixers[5];
34         int num_mixers;
35         unsigned int beep_amp;  /* beep amp value, set via set_beep_amp() */
36         const struct hda_verb *init_verbs[5];   /* initialization verbs
37                                                  * don't forget NULL termination!
38                                                  */
39         unsigned int num_init_verbs;
40
41         /* playback */
42         struct hda_multi_out multiout;  /* playback set-up
43                                          * max_channels, dacs must be set
44                                          * dig_out_nid and hp_nid are optional
45                                          */
46         unsigned int cur_eapd;
47         unsigned int need_dac_fix;
48
49         /* capture */
50         unsigned int num_adc_nids;
51         hda_nid_t *adc_nids;
52         hda_nid_t dig_in_nid;           /* digital-in NID; optional */
53
54         /* capture source */
55         const struct hda_input_mux *input_mux;
56         hda_nid_t *capsrc_nids;
57         unsigned int cur_mux[3];
58
59         /* channel model */
60         const struct hda_channel_mode *channel_mode;
61         int num_channel_mode;
62
63         /* PCM information */
64         struct hda_pcm pcm_rec[3];      /* used in alc_build_pcms() */
65
66         unsigned int spdif_route;
67
68         /* dynamic controls, init_verbs and input_mux */
69         struct auto_pin_cfg autocfg;
70         struct snd_array kctls;
71         struct hda_input_mux private_imux;
72         hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
73
74         unsigned int jack_present: 1;
75         unsigned int inv_jack_detect: 1;/* inverted jack-detection */
76         unsigned int inv_eapd: 1;       /* inverted EAPD implementation */
77         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         codec->no_sticky_stream = 1;
1280
1281         return 0;
1282 }
1283
1284 /*
1285  * AD1983 specific
1286  */
1287
1288 #define AD1983_SPDIF_OUT        0x02
1289 #define AD1983_DAC              0x03
1290 #define AD1983_ADC              0x04
1291
1292 static hda_nid_t ad1983_dac_nids[1] = { AD1983_DAC };
1293 static hda_nid_t ad1983_adc_nids[1] = { AD1983_ADC };
1294 static hda_nid_t ad1983_capsrc_nids[1] = { 0x15 };
1295
1296 static struct hda_input_mux ad1983_capture_source = {
1297         .num_items = 4,
1298         .items = {
1299                 { "Mic", 0x0 },
1300                 { "Line", 0x1 },
1301                 { "Mix", 0x2 },
1302                 { "Mix Mono", 0x3 },
1303         },
1304 };
1305
1306 /*
1307  * SPDIF playback route
1308  */
1309 static int ad1983_spdif_route_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1310 {
1311         static char *texts[] = { "PCM", "ADC" };
1312
1313         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1314         uinfo->count = 1;
1315         uinfo->value.enumerated.items = 2;
1316         if (uinfo->value.enumerated.item > 1)
1317                 uinfo->value.enumerated.item = 1;
1318         strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1319         return 0;
1320 }
1321
1322 static int ad1983_spdif_route_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1323 {
1324         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1325         struct ad198x_spec *spec = codec->spec;
1326
1327         ucontrol->value.enumerated.item[0] = spec->spdif_route;
1328         return 0;
1329 }
1330
1331 static int ad1983_spdif_route_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1332 {
1333         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1334         struct ad198x_spec *spec = codec->spec;
1335
1336         if (ucontrol->value.enumerated.item[0] > 1)
1337                 return -EINVAL;
1338         if (spec->spdif_route != ucontrol->value.enumerated.item[0]) {
1339                 spec->spdif_route = ucontrol->value.enumerated.item[0];
1340                 snd_hda_codec_write_cache(codec, spec->multiout.dig_out_nid, 0,
1341                                           AC_VERB_SET_CONNECT_SEL,
1342                                           spec->spdif_route);
1343                 return 1;
1344         }
1345         return 0;
1346 }
1347
1348 static struct snd_kcontrol_new ad1983_mixers[] = {
1349         HDA_CODEC_VOLUME("Front Playback Volume", 0x05, 0x0, HDA_OUTPUT),
1350         HDA_CODEC_MUTE("Front Playback Switch", 0x05, 0x0, HDA_OUTPUT),
1351         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x06, 0x0, HDA_OUTPUT),
1352         HDA_CODEC_MUTE("Headphone Playback Switch", 0x06, 0x0, HDA_OUTPUT),
1353         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x07, 1, 0x0, HDA_OUTPUT),
1354         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x07, 1, 0x0, HDA_OUTPUT),
1355         HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
1356         HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT),
1357         HDA_CODEC_VOLUME("Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
1358         HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
1359         HDA_CODEC_VOLUME("Line Playback Volume", 0x13, 0x0, HDA_OUTPUT),
1360         HDA_CODEC_MUTE("Line Playback Switch", 0x13, 0x0, HDA_OUTPUT),
1361         HDA_CODEC_VOLUME("Mic Boost", 0x0c, 0x0, HDA_OUTPUT),
1362         HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
1363         HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
1364         {
1365                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1366                 .name = "Capture Source",
1367                 .info = ad198x_mux_enum_info,
1368                 .get = ad198x_mux_enum_get,
1369                 .put = ad198x_mux_enum_put,
1370         },
1371         {
1372                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1373                 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
1374                 .info = ad1983_spdif_route_info,
1375                 .get = ad1983_spdif_route_get,
1376                 .put = ad1983_spdif_route_put,
1377         },
1378         { } /* end */
1379 };
1380
1381 static struct hda_verb ad1983_init_verbs[] = {
1382         /* Front, HP, Mono; mute as default */
1383         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1384         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1385         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1386         /* Beep, PCM, Mic, Line-In: mute */
1387         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1388         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1389         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1390         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1391         /* Front, HP selectors; from Mix */
1392         {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
1393         {0x06, AC_VERB_SET_CONNECT_SEL, 0x01},
1394         /* Mono selector; from Mix */
1395         {0x0b, AC_VERB_SET_CONNECT_SEL, 0x03},
1396         /* Mic selector; Mic */
1397         {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0},
1398         /* Line-in selector: Line-in */
1399         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
1400         /* Mic boost: 0dB */
1401         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1402         /* Record selector: mic */
1403         {0x15, AC_VERB_SET_CONNECT_SEL, 0x0},
1404         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1405         /* SPDIF route: PCM */
1406         {0x02, AC_VERB_SET_CONNECT_SEL, 0x0},
1407         /* Front Pin */
1408         {0x05, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
1409         /* HP Pin */
1410         {0x06, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
1411         /* Mono Pin */
1412         {0x07, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
1413         /* Mic Pin */
1414         {0x08, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
1415         /* Line Pin */
1416         {0x09, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
1417         { } /* end */
1418 };
1419
1420 #ifdef CONFIG_SND_HDA_POWER_SAVE
1421 static struct hda_amp_list ad1983_loopbacks[] = {
1422         { 0x12, HDA_OUTPUT, 0 }, /* Mic */
1423         { 0x13, HDA_OUTPUT, 0 }, /* Line */
1424         { } /* end */
1425 };
1426 #endif
1427
1428 static int patch_ad1983(struct hda_codec *codec)
1429 {
1430         struct ad198x_spec *spec;
1431         int err;
1432
1433         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1434         if (spec == NULL)
1435                 return -ENOMEM;
1436
1437         codec->spec = spec;
1438
1439         err = snd_hda_attach_beep_device(codec, 0x10);
1440         if (err < 0) {
1441                 ad198x_free(codec);
1442                 return err;
1443         }
1444         set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
1445
1446         spec->multiout.max_channels = 2;
1447         spec->multiout.num_dacs = ARRAY_SIZE(ad1983_dac_nids);
1448         spec->multiout.dac_nids = ad1983_dac_nids;
1449         spec->multiout.dig_out_nid = AD1983_SPDIF_OUT;
1450         spec->num_adc_nids = 1;
1451         spec->adc_nids = ad1983_adc_nids;
1452         spec->capsrc_nids = ad1983_capsrc_nids;
1453         spec->input_mux = &ad1983_capture_source;
1454         spec->num_mixers = 1;
1455         spec->mixers[0] = ad1983_mixers;
1456         spec->num_init_verbs = 1;
1457         spec->init_verbs[0] = ad1983_init_verbs;
1458         spec->spdif_route = 0;
1459 #ifdef CONFIG_SND_HDA_POWER_SAVE
1460         spec->loopback.amplist = ad1983_loopbacks;
1461 #endif
1462         spec->vmaster_nid = 0x05;
1463
1464         codec->patch_ops = ad198x_patch_ops;
1465
1466         codec->no_trigger_sense = 1;
1467         codec->no_sticky_stream = 1;
1468
1469         return 0;
1470 }
1471
1472
1473 /*
1474  * AD1981 HD specific
1475  */
1476
1477 #define AD1981_SPDIF_OUT        0x02
1478 #define AD1981_DAC              0x03
1479 #define AD1981_ADC              0x04
1480
1481 static hda_nid_t ad1981_dac_nids[1] = { AD1981_DAC };
1482 static hda_nid_t ad1981_adc_nids[1] = { AD1981_ADC };
1483 static hda_nid_t ad1981_capsrc_nids[1] = { 0x15 };
1484
1485 /* 0x0c, 0x09, 0x0e, 0x0f, 0x19, 0x05, 0x18, 0x17 */
1486 static struct hda_input_mux ad1981_capture_source = {
1487         .num_items = 7,
1488         .items = {
1489                 { "Front Mic", 0x0 },
1490                 { "Line", 0x1 },
1491                 { "Mix", 0x2 },
1492                 { "Mix Mono", 0x3 },
1493                 { "CD", 0x4 },
1494                 { "Mic", 0x6 },
1495                 { "Aux", 0x7 },
1496         },
1497 };
1498
1499 static struct snd_kcontrol_new ad1981_mixers[] = {
1500         HDA_CODEC_VOLUME("Front Playback Volume", 0x05, 0x0, HDA_OUTPUT),
1501         HDA_CODEC_MUTE("Front Playback Switch", 0x05, 0x0, HDA_OUTPUT),
1502         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x06, 0x0, HDA_OUTPUT),
1503         HDA_CODEC_MUTE("Headphone Playback Switch", 0x06, 0x0, HDA_OUTPUT),
1504         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x07, 1, 0x0, HDA_OUTPUT),
1505         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x07, 1, 0x0, HDA_OUTPUT),
1506         HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
1507         HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT),
1508         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
1509         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
1510         HDA_CODEC_VOLUME("Line Playback Volume", 0x13, 0x0, HDA_OUTPUT),
1511         HDA_CODEC_MUTE("Line Playback Switch", 0x13, 0x0, HDA_OUTPUT),
1512         HDA_CODEC_VOLUME("Aux Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
1513         HDA_CODEC_MUTE("Aux Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1514         HDA_CODEC_VOLUME("Mic Playback Volume", 0x1c, 0x0, HDA_OUTPUT),
1515         HDA_CODEC_MUTE("Mic Playback Switch", 0x1c, 0x0, HDA_OUTPUT),
1516         HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
1517         HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
1518         HDA_CODEC_VOLUME("Front Mic Boost", 0x08, 0x0, HDA_INPUT),
1519         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x0, HDA_INPUT),
1520         HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
1521         HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
1522         {
1523                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1524                 .name = "Capture Source",
1525                 .info = ad198x_mux_enum_info,
1526                 .get = ad198x_mux_enum_get,
1527                 .put = ad198x_mux_enum_put,
1528         },
1529         /* identical with AD1983 */
1530         {
1531                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1532                 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
1533                 .info = ad1983_spdif_route_info,
1534                 .get = ad1983_spdif_route_get,
1535                 .put = ad1983_spdif_route_put,
1536         },
1537         { } /* end */
1538 };
1539
1540 static struct hda_verb ad1981_init_verbs[] = {
1541         /* Front, HP, Mono; mute as default */
1542         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1543         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1544         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1545         /* Beep, PCM, Front Mic, Line, Rear Mic, Aux, CD-In: mute */
1546         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1547         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1548         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1549         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1550         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1551         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1552         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1553         /* Front, HP selectors; from Mix */
1554         {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
1555         {0x06, AC_VERB_SET_CONNECT_SEL, 0x01},
1556         /* Mono selector; from Mix */
1557         {0x0b, AC_VERB_SET_CONNECT_SEL, 0x03},
1558         /* Mic Mixer; select Front Mic */
1559         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1560         {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1561         /* Mic boost: 0dB */
1562         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1563         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1564         /* Record selector: Front mic */
1565         {0x15, AC_VERB_SET_CONNECT_SEL, 0x0},
1566         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1567         /* SPDIF route: PCM */
1568         {0x02, AC_VERB_SET_CONNECT_SEL, 0x0},
1569         /* Front Pin */
1570         {0x05, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
1571         /* HP Pin */
1572         {0x06, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
1573         /* Mono Pin */
1574         {0x07, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
1575         /* Front & Rear Mic Pins */
1576         {0x08, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
1577         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
1578         /* Line Pin */
1579         {0x09, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
1580         /* Digital Beep */
1581         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
1582         /* Line-Out as Input: disabled */
1583         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1584         { } /* end */
1585 };
1586
1587 #ifdef CONFIG_SND_HDA_POWER_SAVE
1588 static struct hda_amp_list ad1981_loopbacks[] = {
1589         { 0x12, HDA_OUTPUT, 0 }, /* Front Mic */
1590         { 0x13, HDA_OUTPUT, 0 }, /* Line */
1591         { 0x1b, HDA_OUTPUT, 0 }, /* Aux */
1592         { 0x1c, HDA_OUTPUT, 0 }, /* Mic */
1593         { 0x1d, HDA_OUTPUT, 0 }, /* CD */
1594         { } /* end */
1595 };
1596 #endif
1597
1598 /*
1599  * Patch for HP nx6320
1600  *
1601  * nx6320 uses EAPD in the reverse way - EAPD-on means the internal
1602  * speaker output enabled _and_ mute-LED off.
1603  */
1604
1605 #define AD1981_HP_EVENT         0x37
1606 #define AD1981_MIC_EVENT        0x38
1607
1608 static struct hda_verb ad1981_hp_init_verbs[] = {
1609         {0x05, AC_VERB_SET_EAPD_BTLENABLE, 0x00 }, /* default off */
1610         /* pin sensing on HP and Mic jacks */
1611         {0x06, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_HP_EVENT},
1612         {0x08, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_MIC_EVENT},
1613         {}
1614 };
1615
1616 /* turn on/off EAPD (+ mute HP) as a master switch */
1617 static int ad1981_hp_master_sw_put(struct snd_kcontrol *kcontrol,
1618                                    struct snd_ctl_elem_value *ucontrol)
1619 {
1620         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1621         struct ad198x_spec *spec = codec->spec;
1622
1623         if (! ad198x_eapd_put(kcontrol, ucontrol))
1624                 return 0;
1625         /* change speaker pin appropriately */
1626         snd_hda_codec_write(codec, 0x05, 0,
1627                             AC_VERB_SET_PIN_WIDGET_CONTROL,
1628                             spec->cur_eapd ? PIN_OUT : 0);
1629         /* toggle HP mute appropriately */
1630         snd_hda_codec_amp_stereo(codec, 0x06, HDA_OUTPUT, 0,
1631                                  HDA_AMP_MUTE,
1632                                  spec->cur_eapd ? 0 : HDA_AMP_MUTE);
1633         return 1;
1634 }
1635
1636 /* bind volumes of both NID 0x05 and 0x06 */
1637 static struct hda_bind_ctls ad1981_hp_bind_master_vol = {
1638         .ops = &snd_hda_bind_vol,
1639         .values = {
1640                 HDA_COMPOSE_AMP_VAL(0x05, 3, 0, HDA_OUTPUT),
1641                 HDA_COMPOSE_AMP_VAL(0x06, 3, 0, HDA_OUTPUT),
1642                 0
1643         },
1644 };
1645
1646 /* mute internal speaker if HP is plugged */
1647 static void ad1981_hp_automute(struct hda_codec *codec)
1648 {
1649         unsigned int present;
1650
1651         present = snd_hda_jack_detect(codec, 0x06);
1652         snd_hda_codec_amp_stereo(codec, 0x05, HDA_OUTPUT, 0,
1653                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
1654 }
1655
1656 /* toggle input of built-in and mic jack appropriately */
1657 static void ad1981_hp_automic(struct hda_codec *codec)
1658 {
1659         static struct hda_verb mic_jack_on[] = {
1660                 {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1661                 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1662                 {}
1663         };
1664         static struct hda_verb mic_jack_off[] = {
1665                 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1666                 {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1667                 {}
1668         };
1669         unsigned int present;
1670
1671         present = snd_hda_jack_detect(codec, 0x08);
1672         if (present)
1673                 snd_hda_sequence_write(codec, mic_jack_on);
1674         else
1675                 snd_hda_sequence_write(codec, mic_jack_off);
1676 }
1677
1678 /* unsolicited event for HP jack sensing */
1679 static void ad1981_hp_unsol_event(struct hda_codec *codec,
1680                                   unsigned int res)
1681 {
1682         res >>= 26;
1683         switch (res) {
1684         case AD1981_HP_EVENT:
1685                 ad1981_hp_automute(codec);
1686                 break;
1687         case AD1981_MIC_EVENT:
1688                 ad1981_hp_automic(codec);
1689                 break;
1690         }
1691 }
1692
1693 static struct hda_input_mux ad1981_hp_capture_source = {
1694         .num_items = 3,
1695         .items = {
1696                 { "Mic", 0x0 },
1697                 { "Docking-Station", 0x1 },
1698                 { "Mix", 0x2 },
1699         },
1700 };
1701
1702 static struct snd_kcontrol_new ad1981_hp_mixers[] = {
1703         HDA_BIND_VOL("Master Playback Volume", &ad1981_hp_bind_master_vol),
1704         {
1705                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1706                 .subdevice = HDA_SUBDEV_NID_FLAG | 0x05,
1707                 .name = "Master Playback Switch",
1708                 .info = ad198x_eapd_info,
1709                 .get = ad198x_eapd_get,
1710                 .put = ad1981_hp_master_sw_put,
1711                 .private_value = 0x05,
1712         },
1713         HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
1714         HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT),
1715 #if 0
1716         /* FIXME: analog mic/line loopback doesn't work with my tests...
1717          *        (although recording is OK)
1718          */
1719         HDA_CODEC_VOLUME("Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
1720         HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
1721         HDA_CODEC_VOLUME("Docking-Station Playback Volume", 0x13, 0x0, HDA_OUTPUT),
1722         HDA_CODEC_MUTE("Docking-Station Playback Switch", 0x13, 0x0, HDA_OUTPUT),
1723         HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x1c, 0x0, HDA_OUTPUT),
1724         HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x1c, 0x0, HDA_OUTPUT),
1725         /* FIXME: does this laptop have analog CD connection? */
1726         HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
1727         HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
1728 #endif
1729         HDA_CODEC_VOLUME("Mic Boost", 0x08, 0x0, HDA_INPUT),
1730         HDA_CODEC_VOLUME("Internal Mic Boost", 0x18, 0x0, HDA_INPUT),
1731         HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
1732         HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
1733         {
1734                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1735                 .name = "Capture Source",
1736                 .info = ad198x_mux_enum_info,
1737                 .get = ad198x_mux_enum_get,
1738                 .put = ad198x_mux_enum_put,
1739         },
1740         { } /* end */
1741 };
1742
1743 /* initialize jack-sensing, too */
1744 static int ad1981_hp_init(struct hda_codec *codec)
1745 {
1746         ad198x_init(codec);
1747         ad1981_hp_automute(codec);
1748         ad1981_hp_automic(codec);
1749         return 0;
1750 }
1751
1752 /* configuration for Toshiba Laptops */
1753 static struct hda_verb ad1981_toshiba_init_verbs[] = {
1754         {0x05, AC_VERB_SET_EAPD_BTLENABLE, 0x01 }, /* default on */
1755         /* pin sensing on HP and Mic jacks */
1756         {0x06, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_HP_EVENT},
1757         {0x08, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_MIC_EVENT},
1758         {}
1759 };
1760
1761 static struct snd_kcontrol_new ad1981_toshiba_mixers[] = {
1762         HDA_CODEC_VOLUME("Amp Volume", 0x1a, 0x0, HDA_OUTPUT),
1763         HDA_CODEC_MUTE("Amp Switch", 0x1a, 0x0, HDA_OUTPUT),
1764         { }
1765 };
1766
1767 /* configuration for Lenovo Thinkpad T60 */
1768 static struct snd_kcontrol_new ad1981_thinkpad_mixers[] = {
1769         HDA_CODEC_VOLUME("Master Playback Volume", 0x05, 0x0, HDA_OUTPUT),
1770         HDA_CODEC_MUTE("Master Playback Switch", 0x05, 0x0, HDA_OUTPUT),
1771         HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
1772         HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT),
1773         HDA_CODEC_VOLUME("Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
1774         HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
1775         HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
1776         HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
1777         HDA_CODEC_VOLUME("Mic Boost", 0x08, 0x0, HDA_INPUT),
1778         HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
1779         HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
1780         {
1781                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1782                 .name = "Capture Source",
1783                 .info = ad198x_mux_enum_info,
1784                 .get = ad198x_mux_enum_get,
1785                 .put = ad198x_mux_enum_put,
1786         },
1787         /* identical with AD1983 */
1788         {
1789                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1790                 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
1791                 .info = ad1983_spdif_route_info,
1792                 .get = ad1983_spdif_route_get,
1793                 .put = ad1983_spdif_route_put,
1794         },
1795         { } /* end */
1796 };
1797
1798 static struct hda_input_mux ad1981_thinkpad_capture_source = {
1799         .num_items = 3,
1800         .items = {
1801                 { "Mic", 0x0 },
1802                 { "Mix", 0x2 },
1803                 { "CD", 0x4 },
1804         },
1805 };
1806
1807 /* models */
1808 enum {
1809         AD1981_BASIC,
1810         AD1981_HP,
1811         AD1981_THINKPAD,
1812         AD1981_TOSHIBA,
1813         AD1981_MODELS
1814 };
1815
1816 static const char *ad1981_models[AD1981_MODELS] = {
1817         [AD1981_HP]             = "hp",
1818         [AD1981_THINKPAD]       = "thinkpad",
1819         [AD1981_BASIC]          = "basic",
1820         [AD1981_TOSHIBA]        = "toshiba"
1821 };
1822
1823 static struct snd_pci_quirk ad1981_cfg_tbl[] = {
1824         SND_PCI_QUIRK(0x1014, 0x0597, "Lenovo Z60", AD1981_THINKPAD),
1825         SND_PCI_QUIRK(0x1014, 0x05b7, "Lenovo Z60m", AD1981_THINKPAD),
1826         /* All HP models */
1827         SND_PCI_QUIRK_VENDOR(0x103c, "HP nx", AD1981_HP),
1828         SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba U205", AD1981_TOSHIBA),
1829         /* Lenovo Thinkpad T60/X60/Z6xx */
1830         SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo Thinkpad", AD1981_THINKPAD),
1831         /* HP nx6320 (reversed SSID, H/W bug) */
1832         SND_PCI_QUIRK(0x30b0, 0x103c, "HP nx6320", AD1981_HP),
1833         {}
1834 };
1835
1836 static int patch_ad1981(struct hda_codec *codec)
1837 {
1838         struct ad198x_spec *spec;
1839         int err, board_config;
1840
1841         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1842         if (spec == NULL)
1843                 return -ENOMEM;
1844
1845         codec->spec = spec;
1846
1847         err = snd_hda_attach_beep_device(codec, 0x10);
1848         if (err < 0) {
1849                 ad198x_free(codec);
1850                 return err;
1851         }
1852         set_beep_amp(spec, 0x0d, 0, HDA_OUTPUT);
1853
1854         spec->multiout.max_channels = 2;
1855         spec->multiout.num_dacs = ARRAY_SIZE(ad1981_dac_nids);
1856         spec->multiout.dac_nids = ad1981_dac_nids;
1857         spec->multiout.dig_out_nid = AD1981_SPDIF_OUT;
1858         spec->num_adc_nids = 1;
1859         spec->adc_nids = ad1981_adc_nids;
1860         spec->capsrc_nids = ad1981_capsrc_nids;
1861         spec->input_mux = &ad1981_capture_source;
1862         spec->num_mixers = 1;
1863         spec->mixers[0] = ad1981_mixers;
1864         spec->num_init_verbs = 1;
1865         spec->init_verbs[0] = ad1981_init_verbs;
1866         spec->spdif_route = 0;
1867 #ifdef CONFIG_SND_HDA_POWER_SAVE
1868         spec->loopback.amplist = ad1981_loopbacks;
1869 #endif
1870         spec->vmaster_nid = 0x05;
1871
1872         codec->patch_ops = ad198x_patch_ops;
1873
1874         /* override some parameters */
1875         board_config = snd_hda_check_board_config(codec, AD1981_MODELS,
1876                                                   ad1981_models,
1877                                                   ad1981_cfg_tbl);
1878         switch (board_config) {
1879         case AD1981_HP:
1880                 spec->mixers[0] = ad1981_hp_mixers;
1881                 spec->num_init_verbs = 2;
1882                 spec->init_verbs[1] = ad1981_hp_init_verbs;
1883                 spec->multiout.dig_out_nid = 0;
1884                 spec->input_mux = &ad1981_hp_capture_source;
1885
1886                 codec->patch_ops.init = ad1981_hp_init;
1887                 codec->patch_ops.unsol_event = ad1981_hp_unsol_event;
1888                 /* set the upper-limit for mixer amp to 0dB for avoiding the
1889                  * possible damage by overloading
1890                  */
1891                 snd_hda_override_amp_caps(codec, 0x11, HDA_INPUT,
1892                                           (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
1893                                           (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
1894                                           (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
1895                                           (1 << AC_AMPCAP_MUTE_SHIFT));
1896                 break;
1897         case AD1981_THINKPAD:
1898                 spec->mixers[0] = ad1981_thinkpad_mixers;
1899                 spec->input_mux = &ad1981_thinkpad_capture_source;
1900                 /* set the upper-limit for mixer amp to 0dB for avoiding the
1901                  * possible damage by overloading
1902                  */
1903                 snd_hda_override_amp_caps(codec, 0x11, HDA_INPUT,
1904                                           (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
1905                                           (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
1906                                           (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
1907                                           (1 << AC_AMPCAP_MUTE_SHIFT));
1908                 break;
1909         case AD1981_TOSHIBA:
1910                 spec->mixers[0] = ad1981_hp_mixers;
1911                 spec->mixers[1] = ad1981_toshiba_mixers;
1912                 spec->num_init_verbs = 2;
1913                 spec->init_verbs[1] = ad1981_toshiba_init_verbs;
1914                 spec->multiout.dig_out_nid = 0;
1915                 spec->input_mux = &ad1981_hp_capture_source;
1916                 codec->patch_ops.init = ad1981_hp_init;
1917                 codec->patch_ops.unsol_event = ad1981_hp_unsol_event;
1918                 break;
1919         }
1920
1921         codec->no_trigger_sense = 1;
1922         codec->no_sticky_stream = 1;
1923
1924         return 0;
1925 }
1926
1927
1928 /*
1929  * AD1988
1930  *
1931  * Output pins and routes
1932  *
1933  *        Pin               Mix     Sel     DAC (*)
1934  * port-A 0x11 (mute/hp) <- 0x22 <- 0x37 <- 03/04/06
1935  * port-B 0x14 (mute/hp) <- 0x2b <- 0x30 <- 03/04/06
1936  * port-C 0x15 (mute)    <- 0x2c <- 0x31 <- 05/0a
1937  * port-D 0x12 (mute/hp) <- 0x29         <- 04
1938  * port-E 0x17 (mute/hp) <- 0x26 <- 0x32 <- 05/0a
1939  * port-F 0x16 (mute)    <- 0x2a         <- 06
1940  * port-G 0x24 (mute)    <- 0x27         <- 05
1941  * port-H 0x25 (mute)    <- 0x28         <- 0a
1942  * mono   0x13 (mute/amp)<- 0x1e <- 0x36 <- 03/04/06
1943  *
1944  * DAC0 = 03h, DAC1 = 04h, DAC2 = 05h, DAC3 = 06h, DAC4 = 0ah
1945  * (*) DAC2/3/4 are swapped to DAC3/4/2 on AD198A rev.2 due to a h/w bug.
1946  *
1947  * Input pins and routes
1948  *
1949  *        pin     boost   mix input # / adc input #
1950  * port-A 0x11 -> 0x38 -> mix 2, ADC 0
1951  * port-B 0x14 -> 0x39 -> mix 0, ADC 1
1952  * port-C 0x15 -> 0x3a -> 33:0 - mix 1, ADC 2
1953  * port-D 0x12 -> 0x3d -> mix 3, ADC 8
1954  * port-E 0x17 -> 0x3c -> 34:0 - mix 4, ADC 4
1955  * port-F 0x16 -> 0x3b -> mix 5, ADC 3
1956  * port-G 0x24 -> N/A  -> 33:1 - mix 1, 34:1 - mix 4, ADC 6
1957  * port-H 0x25 -> N/A  -> 33:2 - mix 1, 34:2 - mix 4, ADC 7
1958  *
1959  *
1960  * DAC assignment
1961  *   6stack - front/surr/CLFE/side/opt DACs - 04/06/05/0a/03
1962  *   3stack - front/surr/CLFE/opt DACs - 04/05/0a/03
1963  *
1964  * Inputs of Analog Mix (0x20)
1965  *   0:Port-B (front mic)
1966  *   1:Port-C/G/H (line-in)
1967  *   2:Port-A
1968  *   3:Port-D (line-in/2)
1969  *   4:Port-E/G/H (mic-in)
1970  *   5:Port-F (mic2-in)
1971  *   6:CD
1972  *   7:Beep
1973  *
1974  * ADC selection
1975  *   0:Port-A
1976  *   1:Port-B (front mic-in)
1977  *   2:Port-C (line-in)
1978  *   3:Port-F (mic2-in)
1979  *   4:Port-E (mic-in)
1980  *   5:CD
1981  *   6:Port-G
1982  *   7:Port-H
1983  *   8:Port-D (line-in/2)
1984  *   9:Mix
1985  *
1986  * Proposed pin assignments by the datasheet
1987  *
1988  * 6-stack
1989  * Port-A front headphone
1990  *      B front mic-in
1991  *      C rear line-in
1992  *      D rear front-out
1993  *      E rear mic-in
1994  *      F rear surround
1995  *      G rear CLFE
1996  *      H rear side
1997  *
1998  * 3-stack
1999  * Port-A front headphone
2000  *      B front mic
2001  *      C rear line-in/surround
2002  *      D rear front-out
2003  *      E rear mic-in/CLFE
2004  *
2005  * laptop
2006  * Port-A headphone
2007  *      B mic-in
2008  *      C docking station
2009  *      D internal speaker (with EAPD)
2010  *      E/F quad mic array
2011  */
2012
2013
2014 /* models */
2015 enum {
2016         AD1988_6STACK,
2017         AD1988_6STACK_DIG,
2018         AD1988_3STACK,
2019         AD1988_3STACK_DIG,
2020         AD1988_LAPTOP,
2021         AD1988_LAPTOP_DIG,
2022         AD1988_AUTO,
2023         AD1988_MODEL_LAST,
2024 };
2025
2026 /* reivision id to check workarounds */
2027 #define AD1988A_REV2            0x100200
2028
2029 #define is_rev2(codec) \
2030         ((codec)->vendor_id == 0x11d41988 && \
2031          (codec)->revision_id == AD1988A_REV2)
2032
2033 /*
2034  * mixers
2035  */
2036
2037 static hda_nid_t ad1988_6stack_dac_nids[4] = {
2038         0x04, 0x06, 0x05, 0x0a
2039 };
2040
2041 static hda_nid_t ad1988_3stack_dac_nids[3] = {
2042         0x04, 0x05, 0x0a
2043 };
2044
2045 /* for AD1988A revision-2, DAC2-4 are swapped */
2046 static hda_nid_t ad1988_6stack_dac_nids_rev2[4] = {
2047         0x04, 0x05, 0x0a, 0x06
2048 };
2049
2050 static hda_nid_t ad1988_3stack_dac_nids_rev2[3] = {
2051         0x04, 0x0a, 0x06
2052 };
2053
2054 static hda_nid_t ad1988_adc_nids[3] = {
2055         0x08, 0x09, 0x0f
2056 };
2057
2058 static hda_nid_t ad1988_capsrc_nids[3] = {
2059         0x0c, 0x0d, 0x0e
2060 };
2061
2062 #define AD1988_SPDIF_OUT                0x02
2063 #define AD1988_SPDIF_OUT_HDMI   0x0b
2064 #define AD1988_SPDIF_IN         0x07
2065
2066 static hda_nid_t ad1989b_slave_dig_outs[] = {
2067         AD1988_SPDIF_OUT, AD1988_SPDIF_OUT_HDMI, 0
2068 };
2069
2070 static struct hda_input_mux ad1988_6stack_capture_source = {
2071         .num_items = 5,
2072         .items = {
2073                 { "Front Mic", 0x1 },   /* port-B */
2074                 { "Line", 0x2 },        /* port-C */
2075                 { "Mic", 0x4 },         /* port-E */
2076                 { "CD", 0x5 },
2077                 { "Mix", 0x9 },
2078         },
2079 };
2080
2081 static struct hda_input_mux ad1988_laptop_capture_source = {
2082         .num_items = 3,
2083         .items = {
2084                 { "Mic/Line", 0x1 },    /* port-B */
2085                 { "CD", 0x5 },
2086                 { "Mix", 0x9 },
2087         },
2088 };
2089
2090 /*
2091  */
2092 static int ad198x_ch_mode_info(struct snd_kcontrol *kcontrol,
2093                                struct snd_ctl_elem_info *uinfo)
2094 {
2095         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2096         struct ad198x_spec *spec = codec->spec;
2097         return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
2098                                     spec->num_channel_mode);
2099 }
2100
2101 static int ad198x_ch_mode_get(struct snd_kcontrol *kcontrol,
2102                               struct snd_ctl_elem_value *ucontrol)
2103 {
2104         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2105         struct ad198x_spec *spec = codec->spec;
2106         return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
2107                                    spec->num_channel_mode, spec->multiout.max_channels);
2108 }
2109
2110 static int ad198x_ch_mode_put(struct snd_kcontrol *kcontrol,
2111                               struct snd_ctl_elem_value *ucontrol)
2112 {
2113         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2114         struct ad198x_spec *spec = codec->spec;
2115         int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
2116                                       spec->num_channel_mode,
2117                                       &spec->multiout.max_channels);
2118         if (err >= 0 && spec->need_dac_fix)
2119                 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
2120         return err;
2121 }
2122
2123 /* 6-stack mode */
2124 static struct snd_kcontrol_new ad1988_6stack_mixers1[] = {
2125         HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
2126         HDA_CODEC_VOLUME("Surround Playback Volume", 0x06, 0x0, HDA_OUTPUT),
2127         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT),
2128         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT),
2129         HDA_CODEC_VOLUME("Side Playback Volume", 0x0a, 0x0, HDA_OUTPUT),
2130         { } /* end */
2131 };
2132
2133 static struct snd_kcontrol_new ad1988_6stack_mixers1_rev2[] = {
2134         HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
2135         HDA_CODEC_VOLUME("Surround Playback Volume", 0x05, 0x0, HDA_OUTPUT),
2136         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
2137         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0a, 2, 0x0, HDA_OUTPUT),
2138         HDA_CODEC_VOLUME("Side Playback Volume", 0x06, 0x0, HDA_OUTPUT),
2139         { } /* end */
2140 };
2141
2142 static struct snd_kcontrol_new ad1988_6stack_mixers2[] = {
2143         HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT),
2144         HDA_BIND_MUTE("Surround Playback Switch", 0x2a, 2, HDA_INPUT),
2145         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x27, 1, 2, HDA_INPUT),
2146         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x27, 2, 2, HDA_INPUT),
2147         HDA_BIND_MUTE("Side Playback Switch", 0x28, 2, HDA_INPUT),
2148         HDA_BIND_MUTE("Headphone Playback Switch", 0x22, 2, HDA_INPUT),
2149         HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT),
2150
2151         HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x6, HDA_INPUT),
2152         HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x6, HDA_INPUT),
2153         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x0, HDA_INPUT),
2154         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x0, HDA_INPUT),
2155         HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT),
2156         HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT),
2157         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x4, HDA_INPUT),
2158         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x4, HDA_INPUT),
2159
2160         HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT),
2161         HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT),
2162
2163         HDA_CODEC_VOLUME("Front Mic Boost", 0x39, 0x0, HDA_OUTPUT),
2164         HDA_CODEC_VOLUME("Mic Boost", 0x3c, 0x0, HDA_OUTPUT),
2165
2166         { } /* end */
2167 };
2168
2169 /* 3-stack mode */
2170 static struct snd_kcontrol_new ad1988_3stack_mixers1[] = {
2171         HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
2172         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0a, 0x0, HDA_OUTPUT),
2173         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT),
2174         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT),
2175         { } /* end */
2176 };
2177
2178 static struct snd_kcontrol_new ad1988_3stack_mixers1_rev2[] = {
2179         HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
2180         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0a, 0x0, HDA_OUTPUT),
2181         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x06, 1, 0x0, HDA_OUTPUT),
2182         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x06, 2, 0x0, HDA_OUTPUT),
2183         { } /* end */
2184 };
2185
2186 static struct snd_kcontrol_new ad1988_3stack_mixers2[] = {
2187         HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT),
2188         HDA_BIND_MUTE("Surround Playback Switch", 0x2c, 2, HDA_INPUT),
2189         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x26, 1, 2, HDA_INPUT),
2190         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x26, 2, 2, HDA_INPUT),
2191         HDA_BIND_MUTE("Headphone Playback Switch", 0x22, 2, HDA_INPUT),
2192         HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT),
2193
2194         HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x6, HDA_INPUT),
2195         HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x6, HDA_INPUT),
2196         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x0, HDA_INPUT),
2197         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x0, HDA_INPUT),
2198         HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT),
2199         HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT),
2200         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x4, HDA_INPUT),
2201         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x4, HDA_INPUT),
2202
2203         HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT),
2204         HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT),
2205
2206         HDA_CODEC_VOLUME("Front Mic Boost", 0x39, 0x0, HDA_OUTPUT),
2207         HDA_CODEC_VOLUME("Mic Boost", 0x3c, 0x0, HDA_OUTPUT),
2208         {
2209                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2210                 .name = "Channel Mode",
2211                 .info = ad198x_ch_mode_info,
2212                 .get = ad198x_ch_mode_get,
2213                 .put = ad198x_ch_mode_put,
2214         },
2215
2216         { } /* end */
2217 };
2218
2219 /* laptop mode */
2220 static struct snd_kcontrol_new ad1988_laptop_mixers[] = {
2221         HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
2222         HDA_CODEC_MUTE("PCM Playback Switch", 0x29, 0x0, HDA_INPUT),
2223         HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT),
2224
2225         HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x6, HDA_INPUT),
2226         HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x6, HDA_INPUT),
2227         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x0, HDA_INPUT),
2228         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x0, HDA_INPUT),
2229         HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT),
2230         HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT),
2231
2232         HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT),
2233         HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT),
2234
2235         HDA_CODEC_VOLUME("Mic Boost", 0x39, 0x0, HDA_OUTPUT),
2236
2237         {
2238                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2239                 .name = "External Amplifier",
2240                 .subdevice = HDA_SUBDEV_NID_FLAG | 0x12,
2241                 .info = ad198x_eapd_info,
2242                 .get = ad198x_eapd_get,
2243                 .put = ad198x_eapd_put,
2244                 .private_value = 0x12, /* port-D */
2245         },
2246
2247         { } /* end */
2248 };
2249
2250 /* capture */
2251 static struct snd_kcontrol_new ad1988_capture_mixers[] = {
2252         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
2253         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
2254         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
2255         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
2256         HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x0e, 0x0, HDA_OUTPUT),
2257         HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x0e, 0x0, HDA_OUTPUT),
2258         {
2259                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2260                 /* The multiple "Capture Source" controls confuse alsamixer
2261                  * So call somewhat different..
2262                  */
2263                 /* .name = "Capture Source", */
2264                 .name = "Input Source",
2265                 .count = 3,
2266                 .info = ad198x_mux_enum_info,
2267                 .get = ad198x_mux_enum_get,
2268                 .put = ad198x_mux_enum_put,
2269         },
2270         { } /* end */
2271 };
2272
2273 static int ad1988_spdif_playback_source_info(struct snd_kcontrol *kcontrol,
2274                                              struct snd_ctl_elem_info *uinfo)
2275 {
2276         static char *texts[] = {
2277                 "PCM", "ADC1", "ADC2", "ADC3"
2278         };
2279         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2280         uinfo->count = 1;
2281         uinfo->value.enumerated.items = 4;
2282         if (uinfo->value.enumerated.item >= 4)
2283                 uinfo->value.enumerated.item = 3;
2284         strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2285         return 0;
2286 }
2287
2288 static int ad1988_spdif_playback_source_get(struct snd_kcontrol *kcontrol,
2289                                             struct snd_ctl_elem_value *ucontrol)
2290 {
2291         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2292         unsigned int sel;
2293
2294         sel = snd_hda_codec_read(codec, 0x1d, 0, AC_VERB_GET_AMP_GAIN_MUTE,
2295                                  AC_AMP_GET_INPUT);
2296         if (!(sel & 0x80))
2297                 ucontrol->value.enumerated.item[0] = 0;
2298         else {
2299                 sel = snd_hda_codec_read(codec, 0x0b, 0,
2300                                          AC_VERB_GET_CONNECT_SEL, 0);
2301                 if (sel < 3)
2302                         sel++;
2303                 else
2304                         sel = 0;
2305                 ucontrol->value.enumerated.item[0] = sel;
2306         }
2307         return 0;
2308 }
2309
2310 static int ad1988_spdif_playback_source_put(struct snd_kcontrol *kcontrol,
2311                                             struct snd_ctl_elem_value *ucontrol)
2312 {
2313         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2314         unsigned int val, sel;
2315         int change;
2316
2317         val = ucontrol->value.enumerated.item[0];
2318         if (val > 3)
2319                 return -EINVAL;
2320         if (!val) {
2321                 sel = snd_hda_codec_read(codec, 0x1d, 0,
2322                                          AC_VERB_GET_AMP_GAIN_MUTE,
2323                                          AC_AMP_GET_INPUT);
2324                 change = sel & 0x80;
2325                 if (change) {
2326                         snd_hda_codec_write_cache(codec, 0x1d, 0,
2327                                                   AC_VERB_SET_AMP_GAIN_MUTE,
2328                                                   AMP_IN_UNMUTE(0));
2329                         snd_hda_codec_write_cache(codec, 0x1d, 0,
2330                                                   AC_VERB_SET_AMP_GAIN_MUTE,
2331                                                   AMP_IN_MUTE(1));
2332                 }
2333         } else {
2334                 sel = snd_hda_codec_read(codec, 0x1d, 0,
2335                                          AC_VERB_GET_AMP_GAIN_MUTE,
2336                                          AC_AMP_GET_INPUT | 0x01);
2337                 change = sel & 0x80;
2338                 if (change) {
2339                         snd_hda_codec_write_cache(codec, 0x1d, 0,
2340                                                   AC_VERB_SET_AMP_GAIN_MUTE,
2341                                                   AMP_IN_MUTE(0));
2342                         snd_hda_codec_write_cache(codec, 0x1d, 0,
2343                                                   AC_VERB_SET_AMP_GAIN_MUTE,
2344                                                   AMP_IN_UNMUTE(1));
2345                 }
2346                 sel = snd_hda_codec_read(codec, 0x0b, 0,
2347                                          AC_VERB_GET_CONNECT_SEL, 0) + 1;
2348                 change |= sel != val;
2349                 if (change)
2350                         snd_hda_codec_write_cache(codec, 0x0b, 0,
2351                                                   AC_VERB_SET_CONNECT_SEL,
2352                                                   val - 1);
2353         }
2354         return change;
2355 }
2356
2357 static struct snd_kcontrol_new ad1988_spdif_out_mixers[] = {
2358         HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
2359         {
2360                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2361                 .name = "IEC958 Playback Source",
2362                 .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b,
2363                 .info = ad1988_spdif_playback_source_info,
2364                 .get = ad1988_spdif_playback_source_get,
2365                 .put = ad1988_spdif_playback_source_put,
2366         },
2367         { } /* end */
2368 };
2369
2370 static struct snd_kcontrol_new ad1988_spdif_in_mixers[] = {
2371         HDA_CODEC_VOLUME("IEC958 Capture Volume", 0x1c, 0x0, HDA_INPUT),
2372         { } /* end */
2373 };
2374
2375 static struct snd_kcontrol_new ad1989_spdif_out_mixers[] = {
2376         HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
2377         HDA_CODEC_VOLUME("HDMI Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
2378         { } /* end */
2379 };
2380
2381 /*
2382  * initialization verbs
2383  */
2384
2385 /*
2386  * for 6-stack (+dig)
2387  */
2388 static struct hda_verb ad1988_6stack_init_verbs[] = {
2389         /* Front, Surround, CLFE, side DAC; unmute as default */
2390         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2391         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2392         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2393         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2394         /* Port-A front headphon path */
2395         {0x37, AC_VERB_SET_CONNECT_SEL, 0x01}, /* DAC1:04h */
2396         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2397         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2398         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2399         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2400         /* Port-D line-out path */
2401         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2402         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2403         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2404         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2405         /* Port-F surround path */
2406         {0x2a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2407         {0x2a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2408         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2409         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2410         /* Port-G CLFE path */
2411         {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2412         {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2413         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2414         {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2415         /* Port-H side path */
2416         {0x28, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2417         {0x28, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2418         {0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2419         {0x25, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2420         /* Mono out path */
2421         {0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */
2422         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2423         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2424         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2425         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */
2426         /* Port-B front mic-in path */
2427         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2428         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2429         {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2430         /* Port-C line-in path */
2431         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2432         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2433         {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2434         {0x33, AC_VERB_SET_CONNECT_SEL, 0x0},
2435         /* Port-E mic-in path */
2436         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2437         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2438         {0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2439         {0x34, AC_VERB_SET_CONNECT_SEL, 0x0},
2440         /* Analog CD Input */
2441         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2442         /* Analog Mix output amp */
2443         {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
2444
2445         { }
2446 };
2447
2448 static struct hda_verb ad1988_capture_init_verbs[] = {
2449         /* mute analog mix */
2450         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2451         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2452         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2453         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2454         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2455         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
2456         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2457         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2458         /* select ADCs - front-mic */
2459         {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1},
2460         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x1},
2461         {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
2462
2463         { }
2464 };
2465
2466 static struct hda_verb ad1988_spdif_init_verbs[] = {
2467         /* SPDIF out sel */
2468         {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */
2469         {0x0b, AC_VERB_SET_CONNECT_SEL, 0x0}, /* ADC1 */
2470         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2471         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2472         /* SPDIF out pin */
2473         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
2474
2475         { }
2476 };
2477
2478 static struct hda_verb ad1988_spdif_in_init_verbs[] = {
2479         /* unmute SPDIF input pin */
2480         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2481         { }
2482 };
2483
2484 /* AD1989 has no ADC -> SPDIF route */
2485 static struct hda_verb ad1989_spdif_init_verbs[] = {
2486         /* SPDIF-1 out pin */
2487         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2488         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
2489         /* SPDIF-2/HDMI out pin */
2490         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2491         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
2492         { }
2493 };
2494
2495 /*
2496  * verbs for 3stack (+dig)
2497  */
2498 static struct hda_verb ad1988_3stack_ch2_init[] = {
2499         /* set port-C to line-in */
2500         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2501         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2502         /* set port-E to mic-in */
2503         { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2504         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2505         { } /* end */
2506 };
2507
2508 static struct hda_verb ad1988_3stack_ch6_init[] = {
2509         /* set port-C to surround out */
2510         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2511         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2512         /* set port-E to CLFE out */
2513         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2514         { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2515         { } /* end */
2516 };
2517
2518 static struct hda_channel_mode ad1988_3stack_modes[2] = {
2519         { 2, ad1988_3stack_ch2_init },
2520         { 6, ad1988_3stack_ch6_init },
2521 };
2522
2523 static struct hda_verb ad1988_3stack_init_verbs[] = {
2524         /* Front, Surround, CLFE, side DAC; unmute as default */
2525         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2526         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2527         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2528         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2529         /* Port-A front headphon path */
2530         {0x37, AC_VERB_SET_CONNECT_SEL, 0x01}, /* DAC1:04h */
2531         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2532         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2533         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2534         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2535         /* Port-D line-out path */
2536         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2537         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2538         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2539         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2540         /* Mono out path */
2541         {0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */
2542         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2543         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2544         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2545         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */
2546         /* Port-B front mic-in path */
2547         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2548         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2549         {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2550         /* Port-C line-in/surround path - 6ch mode as default */
2551         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2552         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2553         {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2554         {0x31, AC_VERB_SET_CONNECT_SEL, 0x0}, /* output sel: DAC 0x05 */
2555         {0x33, AC_VERB_SET_CONNECT_SEL, 0x0},
2556         /* Port-E mic-in/CLFE path - 6ch mode as default */
2557         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2558         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2559         {0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2560         {0x32, AC_VERB_SET_CONNECT_SEL, 0x1}, /* output sel: DAC 0x0a */
2561         {0x34, AC_VERB_SET_CONNECT_SEL, 0x0},
2562         /* mute analog mix */
2563         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2564         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2565         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2566         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2567         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2568         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
2569         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2570         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2571         /* select ADCs - front-mic */
2572         {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1},
2573         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x1},
2574         {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
2575         /* Analog Mix output amp */
2576         {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
2577         { }
2578 };
2579
2580 /*
2581  * verbs for laptop mode (+dig)
2582  */
2583 static struct hda_verb ad1988_laptop_hp_on[] = {
2584         /* unmute port-A and mute port-D */
2585         { 0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2586         { 0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2587         { } /* end */
2588 };
2589 static struct hda_verb ad1988_laptop_hp_off[] = {
2590         /* mute port-A and unmute port-D */
2591         { 0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2592         { 0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2593         { } /* end */
2594 };
2595
2596 #define AD1988_HP_EVENT 0x01
2597
2598 static struct hda_verb ad1988_laptop_init_verbs[] = {
2599         /* Front, Surround, CLFE, side DAC; unmute as default */
2600         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2601         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2602         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2603         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2604         /* Port-A front headphon path */
2605         {0x37, AC_VERB_SET_CONNECT_SEL, 0x01}, /* DAC1:04h */
2606         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2607         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2608         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2609         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2610         /* unsolicited event for pin-sense */
2611         {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1988_HP_EVENT },
2612         /* Port-D line-out path + EAPD */
2613         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2614         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2615         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2616         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2617         {0x12, AC_VERB_SET_EAPD_BTLENABLE, 0x00}, /* EAPD-off */
2618         /* Mono out path */
2619         {0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */
2620         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2621         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2622         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2623         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */
2624         /* Port-B mic-in path */
2625         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2626         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2627         {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2628         /* Port-C docking station - try to output */
2629         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2630         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2631         {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2632         {0x33, AC_VERB_SET_CONNECT_SEL, 0x0},
2633         /* mute analog mix */
2634         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2635         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2636         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2637         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2638         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2639         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
2640         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2641         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2642         /* select ADCs - mic */
2643         {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1},
2644         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x1},
2645         {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
2646         /* Analog Mix output amp */
2647         {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
2648         { }
2649 };
2650
2651 static void ad1988_laptop_unsol_event(struct hda_codec *codec, unsigned int res)
2652 {
2653         if ((res >> 26) != AD1988_HP_EVENT)
2654                 return;
2655         if (snd_hda_jack_detect(codec, 0x11))
2656                 snd_hda_sequence_write(codec, ad1988_laptop_hp_on);
2657         else
2658                 snd_hda_sequence_write(codec, ad1988_laptop_hp_off);
2659
2660
2661 #ifdef CONFIG_SND_HDA_POWER_SAVE
2662 static struct hda_amp_list ad1988_loopbacks[] = {
2663         { 0x20, HDA_INPUT, 0 }, /* Front Mic */
2664         { 0x20, HDA_INPUT, 1 }, /* Line */
2665         { 0x20, HDA_INPUT, 4 }, /* Mic */
2666         { 0x20, HDA_INPUT, 6 }, /* CD */
2667         { } /* end */
2668 };
2669 #endif
2670
2671 /*
2672  * Automatic parse of I/O pins from the BIOS configuration
2673  */
2674
2675 enum {
2676         AD_CTL_WIDGET_VOL,
2677         AD_CTL_WIDGET_MUTE,
2678         AD_CTL_BIND_MUTE,
2679 };
2680 static struct snd_kcontrol_new ad1988_control_templates[] = {
2681         HDA_CODEC_VOLUME(NULL, 0, 0, 0),
2682         HDA_CODEC_MUTE(NULL, 0, 0, 0),
2683         HDA_BIND_MUTE(NULL, 0, 0, 0),
2684 };
2685
2686 /* add dynamic controls */
2687 static int add_control(struct ad198x_spec *spec, int type, const char *name,
2688                        unsigned long val)
2689 {
2690         struct snd_kcontrol_new *knew;
2691
2692         snd_array_init(&spec->kctls, sizeof(*knew), 32);
2693         knew = snd_array_new(&spec->kctls);
2694         if (!knew)
2695                 return -ENOMEM;
2696         *knew = ad1988_control_templates[type];
2697         knew->name = kstrdup(name, GFP_KERNEL);
2698         if (! knew->name)
2699                 return -ENOMEM;
2700         if (get_amp_nid_(val))
2701                 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
2702         knew->private_value = val;
2703         return 0;
2704 }
2705
2706 #define AD1988_PIN_CD_NID               0x18
2707 #define AD1988_PIN_BEEP_NID             0x10
2708
2709 static hda_nid_t ad1988_mixer_nids[8] = {
2710         /* A     B     C     D     E     F     G     H */
2711         0x22, 0x2b, 0x2c, 0x29, 0x26, 0x2a, 0x27, 0x28
2712 };
2713
2714 static inline hda_nid_t ad1988_idx_to_dac(struct hda_codec *codec, int idx)
2715 {
2716         static hda_nid_t idx_to_dac[8] = {
2717                 /* A     B     C     D     E     F     G     H */
2718                 0x04, 0x06, 0x05, 0x04, 0x0a, 0x06, 0x05, 0x0a
2719         };
2720         static hda_nid_t idx_to_dac_rev2[8] = {
2721                 /* A     B     C     D     E     F     G     H */
2722                 0x04, 0x05, 0x0a, 0x04, 0x06, 0x05, 0x0a, 0x06
2723         };
2724         if (is_rev2(codec))
2725                 return idx_to_dac_rev2[idx];
2726         else
2727                 return idx_to_dac[idx];
2728 }
2729
2730 static hda_nid_t ad1988_boost_nids[8] = {
2731         0x38, 0x39, 0x3a, 0x3d, 0x3c, 0x3b, 0, 0
2732 };
2733
2734 static int ad1988_pin_idx(hda_nid_t nid)
2735 {
2736         static hda_nid_t ad1988_io_pins[8] = {
2737                 0x11, 0x14, 0x15, 0x12, 0x17, 0x16, 0x24, 0x25
2738         };
2739         int i;
2740         for (i = 0; i < ARRAY_SIZE(ad1988_io_pins); i++)
2741                 if (ad1988_io_pins[i] == nid)
2742                         return i;
2743         return 0; /* should be -1 */
2744 }
2745
2746 static int ad1988_pin_to_loopback_idx(hda_nid_t nid)
2747 {
2748         static int loopback_idx[8] = {
2749                 2, 0, 1, 3, 4, 5, 1, 4
2750         };
2751         switch (nid) {
2752         case AD1988_PIN_CD_NID:
2753                 return 6;
2754         default:
2755                 return loopback_idx[ad1988_pin_idx(nid)];
2756         }
2757 }
2758
2759 static int ad1988_pin_to_adc_idx(hda_nid_t nid)
2760 {
2761         static int adc_idx[8] = {
2762                 0, 1, 2, 8, 4, 3, 6, 7
2763         };
2764         switch (nid) {
2765         case AD1988_PIN_CD_NID:
2766                 return 5;
2767         default:
2768                 return adc_idx[ad1988_pin_idx(nid)];
2769         }
2770 }
2771
2772 /* fill in the dac_nids table from the parsed pin configuration */
2773 static int ad1988_auto_fill_dac_nids(struct hda_codec *codec,
2774                                      const struct auto_pin_cfg *cfg)
2775 {
2776         struct ad198x_spec *spec = codec->spec;
2777         int i, idx;
2778
2779         spec->multiout.dac_nids = spec->private_dac_nids;
2780
2781         /* check the pins hardwired to audio widget */
2782         for (i = 0; i < cfg->line_outs; i++) {
2783                 idx = ad1988_pin_idx(cfg->line_out_pins[i]);
2784                 spec->multiout.dac_nids[i] = ad1988_idx_to_dac(codec, idx);
2785         }
2786         spec->multiout.num_dacs = cfg->line_outs;
2787         return 0;
2788 }
2789
2790 /* add playback controls from the parsed DAC table */
2791 static int ad1988_auto_create_multi_out_ctls(struct ad198x_spec *spec,
2792                                              const struct auto_pin_cfg *cfg)
2793 {
2794         char name[32];
2795         static const char *chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" };
2796         hda_nid_t nid;
2797         int i, err;
2798
2799         for (i = 0; i < cfg->line_outs; i++) {
2800                 hda_nid_t dac = spec->multiout.dac_nids[i];
2801                 if (! dac)
2802                         continue;
2803                 nid = ad1988_mixer_nids[ad1988_pin_idx(cfg->line_out_pins[i])];
2804                 if (i == 2) {
2805                         /* Center/LFE */
2806                         err = add_control(spec, AD_CTL_WIDGET_VOL,
2807                                           "Center Playback Volume",
2808                                           HDA_COMPOSE_AMP_VAL(dac, 1, 0, HDA_OUTPUT));
2809                         if (err < 0)
2810                                 return err;
2811                         err = add_control(spec, AD_CTL_WIDGET_VOL,
2812                                           "LFE Playback Volume",
2813                                           HDA_COMPOSE_AMP_VAL(dac, 2, 0, HDA_OUTPUT));
2814                         if (err < 0)
2815                                 return err;
2816                         err = add_control(spec, AD_CTL_BIND_MUTE,
2817                                           "Center Playback Switch",
2818                                           HDA_COMPOSE_AMP_VAL(nid, 1, 2, HDA_INPUT));
2819                         if (err < 0)
2820                                 return err;
2821                         err = add_control(spec, AD_CTL_BIND_MUTE,
2822                                           "LFE Playback Switch",
2823                                           HDA_COMPOSE_AMP_VAL(nid, 2, 2, HDA_INPUT));
2824                         if (err < 0)
2825                                 return err;
2826                 } else {
2827                         sprintf(name, "%s Playback Volume", chname[i]);
2828                         err = add_control(spec, AD_CTL_WIDGET_VOL, name,
2829                                           HDA_COMPOSE_AMP_VAL(dac, 3, 0, HDA_OUTPUT));
2830                         if (err < 0)
2831                                 return err;
2832                         sprintf(name, "%s Playback Switch", chname[i]);
2833                         err = add_control(spec, AD_CTL_BIND_MUTE, name,
2834                                           HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
2835                         if (err < 0)
2836                                 return err;
2837                 }
2838         }
2839         return 0;
2840 }
2841
2842 /* add playback controls for speaker and HP outputs */
2843 static int ad1988_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
2844                                         const char *pfx)
2845 {
2846         struct ad198x_spec *spec = codec->spec;
2847         hda_nid_t nid;
2848         int i, idx, err;
2849         char name[32];
2850
2851         if (! pin)
2852                 return 0;
2853
2854         idx = ad1988_pin_idx(pin);
2855         nid = ad1988_idx_to_dac(codec, idx);
2856         /* check whether the corresponding DAC was already taken */
2857         for (i = 0; i < spec->autocfg.line_outs; i++) {
2858                 hda_nid_t pin = spec->autocfg.line_out_pins[i];
2859                 hda_nid_t dac = ad1988_idx_to_dac(codec, ad1988_pin_idx(pin));
2860                 if (dac == nid)
2861                         break;
2862         }
2863         if (i >= spec->autocfg.line_outs) {
2864                 /* specify the DAC as the extra output */
2865                 if (!spec->multiout.hp_nid)
2866                         spec->multiout.hp_nid = nid;
2867                 else
2868                         spec->multiout.extra_out_nid[0] = nid;
2869                 /* control HP volume/switch on the output mixer amp */
2870                 sprintf(name, "%s Playback Volume", pfx);
2871                 err = add_control(spec, AD_CTL_WIDGET_VOL, name,
2872                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
2873                 if (err < 0)
2874                         return err;
2875         }
2876         nid = ad1988_mixer_nids[idx];
2877         sprintf(name, "%s Playback Switch", pfx);
2878         if ((err = add_control(spec, AD_CTL_BIND_MUTE, name,
2879                                HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT))) < 0)
2880                 return err;
2881         return 0;
2882 }
2883
2884 /* create input playback/capture controls for the given pin */
2885 static int new_analog_input(struct ad198x_spec *spec, hda_nid_t pin,
2886                             const char *ctlname, int ctlidx, int boost)
2887 {
2888         char name[32];
2889         int err, idx;
2890
2891         sprintf(name, "%s Playback Volume", ctlname);
2892         idx = ad1988_pin_to_loopback_idx(pin);
2893         if ((err = add_control(spec, AD_CTL_WIDGET_VOL, name,
2894                                HDA_COMPOSE_AMP_VAL(0x20, 3, idx, HDA_INPUT))) < 0)
2895                 return err;
2896         sprintf(name, "%s Playback Switch", ctlname);
2897         if ((err = add_control(spec, AD_CTL_WIDGET_MUTE, name,
2898                                HDA_COMPOSE_AMP_VAL(0x20, 3, idx, HDA_INPUT))) < 0)
2899                 return err;
2900         if (boost) {
2901                 hda_nid_t bnid;
2902                 idx = ad1988_pin_idx(pin);
2903                 bnid = ad1988_boost_nids[idx];
2904                 if (bnid) {
2905                         sprintf(name, "%s Boost", ctlname);
2906                         return add_control(spec, AD_CTL_WIDGET_VOL, name,
2907                                            HDA_COMPOSE_AMP_VAL(bnid, 3, idx, HDA_OUTPUT));
2908
2909                 }
2910         }
2911         return 0;
2912 }
2913
2914 /* create playback/capture controls for input pins */
2915 static int ad1988_auto_create_analog_input_ctls(struct hda_codec *codec,
2916                                                 const struct auto_pin_cfg *cfg)
2917 {
2918         struct ad198x_spec *spec = codec->spec;
2919         struct hda_input_mux *imux = &spec->private_imux;
2920         int i, err, type, type_idx;
2921
2922         for (i = 0; i < cfg->num_inputs; i++) {
2923                 const char *label;
2924                 type = cfg->inputs[i].type;
2925                 label = hda_get_autocfg_input_label(codec, cfg, i);
2926                 snd_hda_add_imux_item(imux, label,
2927                                       ad1988_pin_to_adc_idx(cfg->inputs[i].pin),
2928                                       &type_idx);
2929                 err = new_analog_input(spec, cfg->inputs[i].pin,
2930                                        label, type_idx,
2931                                        type == AUTO_PIN_MIC);
2932                 if (err < 0)
2933                         return err;
2934         }
2935         snd_hda_add_imux_item(imux, "Mix", 9, NULL);
2936
2937         if ((err = add_control(spec, AD_CTL_WIDGET_VOL,
2938                                "Analog Mix Playback Volume",
2939                                HDA_COMPOSE_AMP_VAL(0x21, 3, 0x0, HDA_OUTPUT))) < 0)
2940                 return err;
2941         if ((err = add_control(spec, AD_CTL_WIDGET_MUTE,
2942                                "Analog Mix Playback Switch",
2943                                HDA_COMPOSE_AMP_VAL(0x21, 3, 0x0, HDA_OUTPUT))) < 0)
2944                 return err;
2945
2946         return 0;
2947 }
2948
2949 static void ad1988_auto_set_output_and_unmute(struct hda_codec *codec,
2950                                               hda_nid_t nid, int pin_type,
2951                                               int dac_idx)
2952 {
2953         /* set as output */
2954         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
2955         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
2956         switch (nid) {
2957         case 0x11: /* port-A - DAC 04 */
2958                 snd_hda_codec_write(codec, 0x37, 0, AC_VERB_SET_CONNECT_SEL, 0x01);
2959                 break;
2960         case 0x14: /* port-B - DAC 06 */
2961                 snd_hda_codec_write(codec, 0x30, 0, AC_VERB_SET_CONNECT_SEL, 0x02);
2962                 break;
2963         case 0x15: /* port-C - DAC 05 */
2964                 snd_hda_codec_write(codec, 0x31, 0, AC_VERB_SET_CONNECT_SEL, 0x00);
2965                 break;
2966         case 0x17: /* port-E - DAC 0a */
2967                 snd_hda_codec_write(codec, 0x32, 0, AC_VERB_SET_CONNECT_SEL, 0x01);
2968                 break;
2969         case 0x13: /* mono - DAC 04 */
2970                 snd_hda_codec_write(codec, 0x36, 0, AC_VERB_SET_CONNECT_SEL, 0x01);
2971                 break;
2972         }
2973 }
2974
2975 static void ad1988_auto_init_multi_out(struct hda_codec *codec)
2976 {
2977         struct ad198x_spec *spec = codec->spec;
2978         int i;
2979
2980         for (i = 0; i < spec->autocfg.line_outs; i++) {
2981                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
2982                 ad1988_auto_set_output_and_unmute(codec, nid, PIN_OUT, i);
2983         }
2984 }
2985
2986 static void ad1988_auto_init_extra_out(struct hda_codec *codec)
2987 {
2988         struct ad198x_spec *spec = codec->spec;
2989         hda_nid_t pin;
2990
2991         pin = spec->autocfg.speaker_pins[0];
2992         if (pin) /* connect to front */
2993                 ad1988_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
2994         pin = spec->autocfg.hp_pins[0];
2995         if (pin) /* connect to front */
2996                 ad1988_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
2997 }
2998
2999 static void ad1988_auto_init_analog_input(struct hda_codec *codec)
3000 {
3001         struct ad198x_spec *spec = codec->spec;
3002         const struct auto_pin_cfg *cfg = &spec->autocfg;
3003         int i, idx;
3004
3005         for (i = 0; i < cfg->num_inputs; i++) {
3006                 hda_nid_t nid = cfg->inputs[i].pin;
3007                 switch (nid) {
3008                 case 0x15: /* port-C */
3009                         snd_hda_codec_write(codec, 0x33, 0, AC_VERB_SET_CONNECT_SEL, 0x0);
3010                         break;
3011                 case 0x17: /* port-E */
3012                         snd_hda_codec_write(codec, 0x34, 0, AC_VERB_SET_CONNECT_SEL, 0x0);
3013                         break;
3014                 }
3015                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3016                                     i == AUTO_PIN_MIC ? PIN_VREF80 : PIN_IN);
3017                 if (nid != AD1988_PIN_CD_NID)
3018                         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3019                                             AMP_OUT_MUTE);
3020                 idx = ad1988_pin_idx(nid);
3021                 if (ad1988_boost_nids[idx])
3022                         snd_hda_codec_write(codec, ad1988_boost_nids[idx], 0,
3023                                             AC_VERB_SET_AMP_GAIN_MUTE,
3024                                             AMP_OUT_ZERO);
3025         }
3026 }
3027
3028 /* parse the BIOS configuration and set up the alc_spec */
3029 /* return 1 if successful, 0 if the proper config is not found, or a negative error code */
3030 static int ad1988_parse_auto_config(struct hda_codec *codec)
3031 {
3032         struct ad198x_spec *spec = codec->spec;
3033         int err;
3034
3035         if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL)) < 0)
3036                 return err;
3037         if ((err = ad1988_auto_fill_dac_nids(codec, &spec->autocfg)) < 0)
3038                 return err;
3039         if (! spec->autocfg.line_outs)
3040                 return 0; /* can't find valid BIOS pin config */
3041         if ((err = ad1988_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 ||
3042             (err = ad1988_auto_create_extra_out(codec,
3043                                                 spec->autocfg.speaker_pins[0],
3044                                                 "Speaker")) < 0 ||
3045             (err = ad1988_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
3046                                                 "Headphone")) < 0 ||
3047             (err = ad1988_auto_create_analog_input_ctls(codec, &spec->autocfg)) < 0)
3048                 return err;
3049
3050         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3051
3052         if (spec->autocfg.dig_outs)
3053                 spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
3054         if (spec->autocfg.dig_in_pin)
3055                 spec->dig_in_nid = AD1988_SPDIF_IN;
3056
3057         if (spec->kctls.list)
3058                 spec->mixers[spec->num_mixers++] = spec->kctls.list;
3059
3060         spec->init_verbs[spec->num_init_verbs++] = ad1988_6stack_init_verbs;
3061
3062         spec->input_mux = &spec->private_imux;
3063
3064         return 1;
3065 }
3066
3067 /* init callback for auto-configuration model -- overriding the default init */
3068 static int ad1988_auto_init(struct hda_codec *codec)
3069 {
3070         ad198x_init(codec);
3071         ad1988_auto_init_multi_out(codec);
3072         ad1988_auto_init_extra_out(codec);
3073         ad1988_auto_init_analog_input(codec);
3074         return 0;
3075 }
3076
3077
3078 /*
3079  */
3080
3081 static const char *ad1988_models[AD1988_MODEL_LAST] = {
3082         [AD1988_6STACK]         = "6stack",
3083         [AD1988_6STACK_DIG]     = "6stack-dig",
3084         [AD1988_3STACK]         = "3stack",
3085         [AD1988_3STACK_DIG]     = "3stack-dig",
3086         [AD1988_LAPTOP]         = "laptop",
3087         [AD1988_LAPTOP_DIG]     = "laptop-dig",
3088         [AD1988_AUTO]           = "auto",
3089 };
3090
3091 static struct snd_pci_quirk ad1988_cfg_tbl[] = {
3092         SND_PCI_QUIRK(0x1043, 0x81ec, "Asus P5B-DLX", AD1988_6STACK_DIG),
3093         SND_PCI_QUIRK(0x1043, 0x81f6, "Asus M2N-SLI", AD1988_6STACK_DIG),
3094         SND_PCI_QUIRK(0x1043, 0x8277, "Asus P5K-E/WIFI-AP", AD1988_6STACK_DIG),
3095         SND_PCI_QUIRK(0x1043, 0x8311, "Asus P5Q-Premium/Pro", AD1988_6STACK_DIG),
3096         {}
3097 };
3098
3099 static int patch_ad1988(struct hda_codec *codec)
3100 {
3101         struct ad198x_spec *spec;
3102         int err, board_config;
3103
3104         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3105         if (spec == NULL)
3106                 return -ENOMEM;
3107
3108         codec->spec = spec;
3109
3110         if (is_rev2(codec))
3111                 snd_printk(KERN_INFO "patch_analog: AD1988A rev.2 is detected, enable workarounds\n");
3112
3113         board_config = snd_hda_check_board_config(codec, AD1988_MODEL_LAST,
3114                                                   ad1988_models, ad1988_cfg_tbl);
3115         if (board_config < 0) {
3116                 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
3117                        codec->chip_name);
3118                 board_config = AD1988_AUTO;
3119         }
3120
3121         if (board_config == AD1988_AUTO) {
3122                 /* automatic parse from the BIOS config */
3123                 err = ad1988_parse_auto_config(codec);
3124                 if (err < 0) {
3125                         ad198x_free(codec);
3126                         return err;
3127                 } else if (! err) {
3128                         printk(KERN_INFO "hda_codec: Cannot set up configuration from BIOS.  Using 6-stack mode...\n");
3129                         board_config = AD1988_6STACK;
3130                 }
3131         }
3132
3133         err = snd_hda_attach_beep_device(codec, 0x10);
3134         if (err < 0) {
3135                 ad198x_free(codec);
3136                 return err;
3137         }
3138         set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
3139
3140         switch (board_config) {
3141         case AD1988_6STACK:
3142         case AD1988_6STACK_DIG:
3143                 spec->multiout.max_channels = 8;
3144                 spec->multiout.num_dacs = 4;
3145                 if (is_rev2(codec))
3146                         spec->multiout.dac_nids = ad1988_6stack_dac_nids_rev2;
3147                 else
3148                         spec->multiout.dac_nids = ad1988_6stack_dac_nids;
3149                 spec->input_mux = &ad1988_6stack_capture_source;
3150                 spec->num_mixers = 2;
3151                 if (is_rev2(codec))
3152                         spec->mixers[0] = ad1988_6stack_mixers1_rev2;
3153                 else
3154                         spec->mixers[0] = ad1988_6stack_mixers1;
3155                 spec->mixers[1] = ad1988_6stack_mixers2;
3156                 spec->num_init_verbs = 1;
3157                 spec->init_verbs[0] = ad1988_6stack_init_verbs;
3158                 if (board_config == AD1988_6STACK_DIG) {
3159                         spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
3160                         spec->dig_in_nid = AD1988_SPDIF_IN;
3161                 }
3162                 break;
3163         case AD1988_3STACK:
3164         case AD1988_3STACK_DIG:
3165                 spec->multiout.max_channels = 6;
3166                 spec->multiout.num_dacs = 3;
3167                 if (is_rev2(codec))
3168                         spec->multiout.dac_nids = ad1988_3stack_dac_nids_rev2;
3169                 else
3170                         spec->multiout.dac_nids = ad1988_3stack_dac_nids;
3171                 spec->input_mux = &ad1988_6stack_capture_source;
3172                 spec->channel_mode = ad1988_3stack_modes;
3173                 spec->num_channel_mode = ARRAY_SIZE(ad1988_3stack_modes);
3174                 spec->num_mixers = 2;
3175                 if (is_rev2(codec))
3176                         spec->mixers[0] = ad1988_3stack_mixers1_rev2;
3177                 else
3178                         spec->mixers[0] = ad1988_3stack_mixers1;
3179                 spec->mixers[1] = ad1988_3stack_mixers2;
3180                 spec->num_init_verbs = 1;
3181                 spec->init_verbs[0] = ad1988_3stack_init_verbs;
3182                 if (board_config == AD1988_3STACK_DIG)
3183                         spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
3184                 break;
3185         case AD1988_LAPTOP:
3186         case AD1988_LAPTOP_DIG:
3187                 spec->multiout.max_channels = 2;
3188                 spec->multiout.num_dacs = 1;
3189                 spec->multiout.dac_nids = ad1988_3stack_dac_nids;
3190                 spec->input_mux = &ad1988_laptop_capture_source;
3191                 spec->num_mixers = 1;
3192                 spec->mixers[0] = ad1988_laptop_mixers;
3193                 spec->inv_eapd = 1; /* inverted EAPD */
3194                 spec->num_init_verbs = 1;
3195                 spec->init_verbs[0] = ad1988_laptop_init_verbs;
3196                 if (board_config == AD1988_LAPTOP_DIG)
3197                         spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
3198                 break;
3199         }
3200
3201         spec->num_adc_nids = ARRAY_SIZE(ad1988_adc_nids);
3202         spec->adc_nids = ad1988_adc_nids;
3203         spec->capsrc_nids = ad1988_capsrc_nids;
3204         spec->mixers[spec->num_mixers++] = ad1988_capture_mixers;
3205         spec->init_verbs[spec->num_init_verbs++] = ad1988_capture_init_verbs;
3206         if (spec->multiout.dig_out_nid) {
3207                 if (codec->vendor_id >= 0x11d4989a) {
3208                         spec->mixers[spec->num_mixers++] =
3209                                 ad1989_spdif_out_mixers;
3210                         spec->init_verbs[spec->num_init_verbs++] =
3211                                 ad1989_spdif_init_verbs;
3212                         codec->slave_dig_outs = ad1989b_slave_dig_outs;
3213                 } else {
3214                         spec->mixers[spec->num_mixers++] =
3215                                 ad1988_spdif_out_mixers;
3216                         spec->init_verbs[spec->num_init_verbs++] =
3217                                 ad1988_spdif_init_verbs;
3218                 }
3219         }
3220         if (spec->dig_in_nid && codec->vendor_id < 0x11d4989a) {
3221                 spec->mixers[spec->num_mixers++] = ad1988_spdif_in_mixers;
3222                 spec->init_verbs[spec->num_init_verbs++] =
3223                         ad1988_spdif_in_init_verbs;
3224         }
3225
3226         codec->patch_ops = ad198x_patch_ops;
3227         switch (board_config) {
3228         case AD1988_AUTO:
3229                 codec->patch_ops.init = ad1988_auto_init;
3230                 break;
3231         case AD1988_LAPTOP:
3232         case AD1988_LAPTOP_DIG:
3233                 codec->patch_ops.unsol_event = ad1988_laptop_unsol_event;
3234                 break;
3235         }
3236 #ifdef CONFIG_SND_HDA_POWER_SAVE
3237         spec->loopback.amplist = ad1988_loopbacks;
3238 #endif
3239         spec->vmaster_nid = 0x04;
3240
3241         codec->no_trigger_sense = 1;
3242         codec->no_sticky_stream = 1;
3243
3244         return 0;
3245 }
3246
3247
3248 /*
3249  * AD1884 / AD1984
3250  *
3251  * port-B - front line/mic-in
3252  * port-E - aux in/out
3253  * port-F - aux in/out
3254  * port-C - rear line/mic-in
3255  * port-D - rear line/hp-out
3256  * port-A - front line/hp-out
3257  *
3258  * AD1984 = AD1884 + two digital mic-ins
3259  *
3260  * FIXME:
3261  * For simplicity, we share the single DAC for both HP and line-outs
3262  * right now.  The inidividual playbacks could be easily implemented,
3263  * but no build-up framework is given, so far.
3264  */
3265
3266 static hda_nid_t ad1884_dac_nids[1] = {
3267         0x04,
3268 };
3269
3270 static hda_nid_t ad1884_adc_nids[2] = {
3271         0x08, 0x09,
3272 };
3273
3274 static hda_nid_t ad1884_capsrc_nids[2] = {
3275         0x0c, 0x0d,
3276 };
3277
3278 #define AD1884_SPDIF_OUT        0x02
3279
3280 static struct hda_input_mux ad1884_capture_source = {
3281         .num_items = 4,
3282         .items = {
3283                 { "Front Mic", 0x0 },
3284                 { "Mic", 0x1 },
3285                 { "CD", 0x2 },
3286                 { "Mix", 0x3 },
3287         },
3288 };
3289
3290 static struct snd_kcontrol_new ad1884_base_mixers[] = {
3291         HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
3292         /* HDA_CODEC_VOLUME_IDX("PCM Playback Volume", 1, 0x03, 0x0, HDA_OUTPUT), */
3293         HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
3294         HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT),
3295         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
3296         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
3297         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
3298         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3299         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
3300         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
3301         HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x02, HDA_INPUT),
3302         HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x02, HDA_INPUT),
3303         HDA_CODEC_VOLUME("Mic Boost", 0x15, 0x0, HDA_INPUT),
3304         HDA_CODEC_VOLUME("Front Mic Boost", 0x14, 0x0, HDA_INPUT),
3305         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3306         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3307         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
3308         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
3309         {
3310                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3311                 /* The multiple "Capture Source" controls confuse alsamixer
3312                  * So call somewhat different..
3313                  */
3314                 /* .name = "Capture Source", */
3315                 .name = "Input Source",
3316                 .count = 2,
3317                 .info = ad198x_mux_enum_info,
3318                 .get = ad198x_mux_enum_get,
3319                 .put = ad198x_mux_enum_put,
3320         },
3321         /* SPDIF controls */
3322         HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
3323         {
3324                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3325                 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
3326                 /* identical with ad1983 */
3327                 .info = ad1983_spdif_route_info,
3328                 .get = ad1983_spdif_route_get,
3329                 .put = ad1983_spdif_route_put,
3330         },
3331         { } /* end */
3332 };
3333
3334 static struct snd_kcontrol_new ad1984_dmic_mixers[] = {
3335         HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x05, 0x0, HDA_INPUT),
3336         HDA_CODEC_MUTE("Digital Mic Capture Switch", 0x05, 0x0, HDA_INPUT),
3337         HDA_CODEC_VOLUME_IDX("Digital Mic Capture Volume", 1, 0x06, 0x0,
3338                              HDA_INPUT),
3339         HDA_CODEC_MUTE_IDX("Digital Mic Capture Switch", 1, 0x06, 0x0,
3340                            HDA_INPUT),
3341         { } /* end */
3342 };
3343
3344 /*
3345  * initialization verbs
3346  */
3347 static struct hda_verb ad1884_init_verbs[] = {
3348         /* DACs; mute as default */
3349         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3350         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3351         /* Port-A (HP) mixer */
3352         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3353         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3354         /* Port-A pin */
3355         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3356         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3357         /* HP selector - select DAC2 */
3358         {0x22, AC_VERB_SET_CONNECT_SEL, 0x1},
3359         /* Port-D (Line-out) mixer */
3360         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3361         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3362         /* Port-D pin */
3363         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3364         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3365         /* Mono-out mixer */
3366         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3367         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3368         /* Mono-out pin */
3369         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3370         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3371         /* Mono selector */
3372         {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
3373         /* Port-B (front mic) pin */
3374         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3375         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3376         /* Port-C (rear mic) pin */
3377         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3378         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3379         /* Analog mixer; mute as default */
3380         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3381         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3382         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3383         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3384         /* Analog Mix output amp */
3385         {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
3386         /* SPDIF output selector */
3387         {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */
3388         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
3389         { } /* end */
3390 };
3391
3392 #ifdef CONFIG_SND_HDA_POWER_SAVE
3393 static struct hda_amp_list ad1884_loopbacks[] = {
3394         { 0x20, HDA_INPUT, 0 }, /* Front Mic */
3395         { 0x20, HDA_INPUT, 1 }, /* Mic */
3396         { 0x20, HDA_INPUT, 2 }, /* CD */
3397         { 0x20, HDA_INPUT, 4 }, /* Docking */
3398         { } /* end */
3399 };
3400 #endif
3401
3402 static const char *ad1884_slave_vols[] = {
3403         "PCM Playback Volume",
3404         "Mic Playback Volume",
3405         "Mono Playback Volume",
3406         "Front Mic Playback Volume",
3407         "Mic Playback Volume",
3408         "CD Playback Volume",
3409         "Internal Mic Playback Volume",
3410         "Docking Mic Playback Volume",
3411         /* "Beep Playback Volume", */
3412         "IEC958 Playback Volume",
3413         NULL
3414 };
3415
3416 static int patch_ad1884(struct hda_codec *codec)
3417 {
3418         struct ad198x_spec *spec;
3419         int err;
3420
3421         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3422         if (spec == NULL)
3423                 return -ENOMEM;
3424
3425         codec->spec = spec;
3426
3427         err = snd_hda_attach_beep_device(codec, 0x10);
3428         if (err < 0) {
3429                 ad198x_free(codec);
3430                 return err;
3431         }
3432         set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
3433
3434         spec->multiout.max_channels = 2;
3435         spec->multiout.num_dacs = ARRAY_SIZE(ad1884_dac_nids);
3436         spec->multiout.dac_nids = ad1884_dac_nids;
3437         spec->multiout.dig_out_nid = AD1884_SPDIF_OUT;
3438         spec->num_adc_nids = ARRAY_SIZE(ad1884_adc_nids);
3439         spec->adc_nids = ad1884_adc_nids;
3440         spec->capsrc_nids = ad1884_capsrc_nids;
3441         spec->input_mux = &ad1884_capture_source;
3442         spec->num_mixers = 1;
3443         spec->mixers[0] = ad1884_base_mixers;
3444         spec->num_init_verbs = 1;
3445         spec->init_verbs[0] = ad1884_init_verbs;
3446         spec->spdif_route = 0;
3447 #ifdef CONFIG_SND_HDA_POWER_SAVE
3448         spec->loopback.amplist = ad1884_loopbacks;
3449 #endif
3450         spec->vmaster_nid = 0x04;
3451         /* we need to cover all playback volumes */
3452         spec->slave_vols = ad1884_slave_vols;
3453
3454         codec->patch_ops = ad198x_patch_ops;
3455
3456         codec->no_trigger_sense = 1;
3457         codec->no_sticky_stream = 1;
3458
3459         return 0;
3460 }
3461
3462 /*
3463  * Lenovo Thinkpad T61/X61
3464  */
3465 static struct hda_input_mux ad1984_thinkpad_capture_source = {
3466         .num_items = 4,
3467         .items = {
3468                 { "Mic", 0x0 },
3469                 { "Internal Mic", 0x1 },
3470                 { "Mix", 0x3 },
3471                 { "Docking-Station", 0x4 },
3472         },
3473 };
3474
3475
3476 /*
3477  * Dell Precision T3400
3478  */
3479 static struct hda_input_mux ad1984_dell_desktop_capture_source = {
3480         .num_items = 3,
3481         .items = {
3482                 { "Front Mic", 0x0 },
3483                 { "Line-In", 0x1 },
3484                 { "Mix", 0x3 },
3485         },
3486 };
3487
3488
3489 static struct snd_kcontrol_new ad1984_thinkpad_mixers[] = {
3490         HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
3491         /* HDA_CODEC_VOLUME_IDX("PCM Playback Volume", 1, 0x03, 0x0, HDA_OUTPUT), */
3492         HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
3493         HDA_CODEC_MUTE("Speaker Playback Switch", 0x12, 0x0, HDA_OUTPUT),
3494         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
3495         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3496         HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
3497         HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
3498         HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x03, HDA_INPUT),
3499         HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x03, HDA_INPUT),
3500         HDA_CODEC_VOLUME("Docking Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
3501         HDA_CODEC_MUTE("Docking Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
3502         HDA_CODEC_VOLUME("Mic Boost", 0x14, 0x0, HDA_INPUT),
3503         HDA_CODEC_VOLUME("Internal Mic Boost", 0x15, 0x0, HDA_INPUT),
3504         HDA_CODEC_VOLUME("Docking Mic Boost", 0x25, 0x0, HDA_OUTPUT),
3505         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3506         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3507         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
3508         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
3509         {
3510                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3511                 /* The multiple "Capture Source" controls confuse alsamixer
3512                  * So call somewhat different..
3513                  */
3514                 /* .name = "Capture Source", */
3515                 .name = "Input Source",
3516                 .count = 2,
3517                 .info = ad198x_mux_enum_info,
3518                 .get = ad198x_mux_enum_get,
3519                 .put = ad198x_mux_enum_put,
3520         },
3521         /* SPDIF controls */
3522         HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
3523         {
3524                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3525                 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
3526                 /* identical with ad1983 */
3527                 .info = ad1983_spdif_route_info,
3528                 .get = ad1983_spdif_route_get,
3529                 .put = ad1983_spdif_route_put,
3530         },
3531         { } /* end */
3532 };
3533
3534 /* additional verbs */
3535 static struct hda_verb ad1984_thinkpad_init_verbs[] = {
3536         /* Port-E (docking station mic) pin */
3537         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3538         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3539         /* docking mic boost */
3540         {0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3541         /* Analog PC Beeper - allow firmware/ACPI beeps */
3542         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3) | 0x1a},
3543         /* Analog mixer - docking mic; mute as default */
3544         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3545         /* enable EAPD bit */
3546         {0x12, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
3547         { } /* end */
3548 };
3549
3550 /*
3551  * Dell Precision T3400
3552  */
3553 static struct snd_kcontrol_new ad1984_dell_desktop_mixers[] = {
3554         HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
3555         HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
3556         HDA_CODEC_MUTE("Speaker Playback Switch", 0x12, 0x0, HDA_OUTPUT),
3557         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
3558         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
3559         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
3560         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3561         HDA_CODEC_VOLUME("Line-In Playback Volume", 0x20, 0x01, HDA_INPUT),
3562         HDA_CODEC_MUTE("Line-In Playback Switch", 0x20, 0x01, HDA_INPUT),
3563         HDA_CODEC_VOLUME("Line-In Boost", 0x15, 0x0, HDA_INPUT),
3564         HDA_CODEC_VOLUME("Front Mic Boost", 0x14, 0x0, HDA_INPUT),
3565         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3566         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3567         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
3568         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
3569         {
3570                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3571                 /* The multiple "Capture Source" controls confuse alsamixer
3572                  * So call somewhat different..
3573                  */
3574                 /* .name = "Capture Source", */
3575                 .name = "Input Source",
3576                 .count = 2,
3577                 .info = ad198x_mux_enum_info,
3578                 .get = ad198x_mux_enum_get,
3579                 .put = ad198x_mux_enum_put,
3580         },
3581         { } /* end */
3582 };
3583
3584 /* Digial MIC ADC NID 0x05 + 0x06 */
3585 static int ad1984_pcm_dmic_prepare(struct hda_pcm_stream *hinfo,
3586                                    struct hda_codec *codec,
3587                                    unsigned int stream_tag,
3588                                    unsigned int format,
3589                                    struct snd_pcm_substream *substream)
3590 {
3591         snd_hda_codec_setup_stream(codec, 0x05 + substream->number,
3592                                    stream_tag, 0, format);
3593         return 0;
3594 }
3595
3596 static int ad1984_pcm_dmic_cleanup(struct hda_pcm_stream *hinfo,
3597                                    struct hda_codec *codec,
3598                                    struct snd_pcm_substream *substream)
3599 {
3600         snd_hda_codec_cleanup_stream(codec, 0x05 + substream->number);
3601         return 0;
3602 }
3603
3604 static struct hda_pcm_stream ad1984_pcm_dmic_capture = {
3605         .substreams = 2,
3606         .channels_min = 2,
3607         .channels_max = 2,
3608         .nid = 0x05,
3609         .ops = {
3610                 .prepare = ad1984_pcm_dmic_prepare,
3611                 .cleanup = ad1984_pcm_dmic_cleanup
3612         },
3613 };
3614
3615 static int ad1984_build_pcms(struct hda_codec *codec)
3616 {
3617         struct ad198x_spec *spec = codec->spec;
3618         struct hda_pcm *info;
3619         int err;
3620
3621         err = ad198x_build_pcms(codec);
3622         if (err < 0)
3623                 return err;
3624
3625         info = spec->pcm_rec + codec->num_pcms;
3626         codec->num_pcms++;
3627         info->name = "AD1984 Digital Mic";
3628         info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad1984_pcm_dmic_capture;
3629         return 0;
3630 }
3631
3632 /* models */
3633 enum {
3634         AD1984_BASIC,
3635         AD1984_THINKPAD,
3636         AD1984_DELL_DESKTOP,
3637         AD1984_MODELS
3638 };
3639
3640 static const char *ad1984_models[AD1984_MODELS] = {
3641         [AD1984_BASIC]          = "basic",
3642         [AD1984_THINKPAD]       = "thinkpad",
3643         [AD1984_DELL_DESKTOP]   = "dell_desktop",
3644 };
3645
3646 static struct snd_pci_quirk ad1984_cfg_tbl[] = {
3647         /* Lenovo Thinkpad T61/X61 */
3648         SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo Thinkpad", AD1984_THINKPAD),
3649         SND_PCI_QUIRK(0x1028, 0x0214, "Dell T3400", AD1984_DELL_DESKTOP),
3650         SND_PCI_QUIRK(0x1028, 0x0233, "Dell Latitude E6400", AD1984_DELL_DESKTOP),
3651         {}
3652 };
3653
3654 static int patch_ad1984(struct hda_codec *codec)
3655 {
3656         struct ad198x_spec *spec;
3657         int board_config, err;
3658
3659         err = patch_ad1884(codec);
3660         if (err < 0)
3661                 return err;
3662         spec = codec->spec;
3663         board_config = snd_hda_check_board_config(codec, AD1984_MODELS,
3664                                                   ad1984_models, ad1984_cfg_tbl);
3665         switch (board_config) {
3666         case AD1984_BASIC:
3667                 /* additional digital mics */
3668                 spec->mixers[spec->num_mixers++] = ad1984_dmic_mixers;
3669                 codec->patch_ops.build_pcms = ad1984_build_pcms;
3670                 break;
3671         case AD1984_THINKPAD:
3672                 if (codec->subsystem_id == 0x17aa20fb) {
3673                         /* Thinpad X300 does not have the ability to do SPDIF,
3674                            or attach to docking station to use SPDIF */
3675                         spec->multiout.dig_out_nid = 0;
3676                 } else
3677                         spec->multiout.dig_out_nid = AD1884_SPDIF_OUT;
3678                 spec->input_mux = &ad1984_thinkpad_capture_source;
3679                 spec->mixers[0] = ad1984_thinkpad_mixers;
3680                 spec->init_verbs[spec->num_init_verbs++] = ad1984_thinkpad_init_verbs;
3681                 spec->analog_beep = 1;
3682                 break;
3683         case AD1984_DELL_DESKTOP:
3684                 spec->multiout.dig_out_nid = 0;
3685                 spec->input_mux = &ad1984_dell_desktop_capture_source;
3686                 spec->mixers[0] = ad1984_dell_desktop_mixers;
3687                 break;
3688         }
3689         return 0;
3690 }
3691
3692
3693 /*
3694  * AD1883 / AD1884A / AD1984A / AD1984B
3695  *
3696  * port-B (0x14) - front mic-in
3697  * port-E (0x1c) - rear mic-in
3698  * port-F (0x16) - CD / ext out
3699  * port-C (0x15) - rear line-in
3700  * port-D (0x12) - rear line-out
3701  * port-A (0x11) - front hp-out
3702  *
3703  * AD1984A = AD1884A + digital-mic
3704  * AD1883 = equivalent with AD1984A
3705  * AD1984B = AD1984A + extra SPDIF-out
3706  *
3707  * FIXME:
3708  * We share the single DAC for both HP and line-outs (see AD1884/1984).
3709  */
3710
3711 static hda_nid_t ad1884a_dac_nids[1] = {
3712         0x03,
3713 };
3714
3715 #define ad1884a_adc_nids        ad1884_adc_nids
3716 #define ad1884a_capsrc_nids     ad1884_capsrc_nids
3717
3718 #define AD1884A_SPDIF_OUT       0x02
3719
3720 static struct hda_input_mux ad1884a_capture_source = {
3721         .num_items = 5,
3722         .items = {
3723                 { "Front Mic", 0x0 },
3724                 { "Mic", 0x4 },
3725                 { "Line", 0x1 },
3726                 { "CD", 0x2 },
3727                 { "Mix", 0x3 },
3728         },
3729 };
3730
3731 static struct snd_kcontrol_new ad1884a_base_mixers[] = {
3732         HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
3733         HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),
3734         HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
3735         HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT),
3736         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
3737         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
3738         HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
3739         HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
3740         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
3741         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3742         HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x01, HDA_INPUT),
3743         HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x01, HDA_INPUT),
3744         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
3745         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
3746         HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x02, HDA_INPUT),
3747         HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x02, HDA_INPUT),
3748         HDA_CODEC_VOLUME("Front Mic Boost", 0x14, 0x0, HDA_INPUT),
3749         HDA_CODEC_VOLUME("Line Boost", 0x15, 0x0, HDA_INPUT),
3750         HDA_CODEC_VOLUME("Mic Boost", 0x25, 0x0, HDA_OUTPUT),
3751         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3752         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3753         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
3754         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
3755         {
3756                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3757                 /* The multiple "Capture Source" controls confuse alsamixer
3758                  * So call somewhat different..
3759                  */
3760                 /* .name = "Capture Source", */
3761                 .name = "Input Source",
3762                 .count = 2,
3763                 .info = ad198x_mux_enum_info,
3764                 .get = ad198x_mux_enum_get,
3765                 .put = ad198x_mux_enum_put,
3766         },
3767         /* SPDIF controls */
3768         HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
3769         {
3770                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3771                 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
3772                 /* identical with ad1983 */
3773                 .info = ad1983_spdif_route_info,
3774                 .get = ad1983_spdif_route_get,
3775                 .put = ad1983_spdif_route_put,
3776         },
3777         { } /* end */
3778 };
3779
3780 /*
3781  * initialization verbs
3782  */
3783 static struct hda_verb ad1884a_init_verbs[] = {
3784         /* DACs; unmute as default */
3785         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
3786         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
3787         /* Port-A (HP) mixer - route only from analog mixer */
3788         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3789         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3790         /* Port-A pin */
3791         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3792         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3793         /* Port-D (Line-out) mixer - route only from analog mixer */
3794         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3795         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3796         /* Port-D pin */
3797         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3798         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3799         /* Mono-out mixer - route only from analog mixer */
3800         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3801         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3802         /* Mono-out pin */
3803         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3804         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3805         /* Port-B (front mic) pin */
3806         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3807         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3808         /* Port-C (rear line-in) pin */
3809         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3810         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3811         /* Port-E (rear mic) pin */
3812         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3813         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3814         {0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* no boost */
3815         /* Port-F (CD) pin */
3816         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3817         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3818         /* Analog mixer; mute as default */
3819         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3820         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3821         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3822         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3823         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, /* aux */
3824         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
3825         /* Analog Mix output amp */
3826         {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3827         /* capture sources */
3828         {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0},
3829         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3830         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
3831         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3832         /* SPDIF output amp */
3833         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
3834         { } /* end */
3835 };
3836
3837 #ifdef CONFIG_SND_HDA_POWER_SAVE
3838 static struct hda_amp_list ad1884a_loopbacks[] = {
3839         { 0x20, HDA_INPUT, 0 }, /* Front Mic */
3840         { 0x20, HDA_INPUT, 1 }, /* Mic */
3841         { 0x20, HDA_INPUT, 2 }, /* CD */
3842         { 0x20, HDA_INPUT, 4 }, /* Docking */
3843         { } /* end */
3844 };
3845 #endif
3846
3847 /*
3848  * Laptop model
3849  *
3850  * Port A: Headphone jack
3851  * Port B: MIC jack
3852  * Port C: Internal MIC
3853  * Port D: Dock Line Out (if enabled)
3854  * Port E: Dock Line In (if enabled)
3855  * Port F: Internal speakers
3856  */
3857
3858 static int ad1884a_mobile_master_sw_put(struct snd_kcontrol *kcontrol,
3859                                         struct snd_ctl_elem_value *ucontrol)
3860 {
3861         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3862         int ret = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
3863         int mute = (!ucontrol->value.integer.value[0] &&
3864                     !ucontrol->value.integer.value[1]);
3865         /* toggle GPIO1 according to the mute state */
3866         snd_hda_codec_write_cache(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
3867                             mute ? 0x02 : 0x0);
3868         return ret;
3869 }
3870
3871 static struct snd_kcontrol_new ad1884a_laptop_mixers[] = {
3872         HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
3873         {
3874                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3875                 .name = "Master Playback Switch",
3876                 .subdevice = HDA_SUBDEV_AMP_FLAG,
3877                 .info = snd_hda_mixer_amp_switch_info,
3878                 .get = snd_hda_mixer_amp_switch_get,
3879                 .put = ad1884a_mobile_master_sw_put,
3880                 .private_value = HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
3881         },
3882         HDA_CODEC_MUTE("Dock Playback Switch", 0x12, 0x0, HDA_OUTPUT),
3883         HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
3884         HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
3885         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
3886         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3887         HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
3888         HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
3889         HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
3890         HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
3891         HDA_CODEC_VOLUME("Mic Boost", 0x14, 0x0, HDA_INPUT),
3892         HDA_CODEC_VOLUME("Internal Mic Boost", 0x15, 0x0, HDA_INPUT),
3893         HDA_CODEC_VOLUME("Dock Mic Boost", 0x25, 0x0, HDA_OUTPUT),
3894         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3895         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3896         { } /* end */
3897 };
3898
3899 static struct snd_kcontrol_new ad1884a_mobile_mixers[] = {
3900         HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
3901         /*HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/
3902         {
3903                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3904                 .name = "Master Playback Switch",
3905                 .subdevice = HDA_SUBDEV_AMP_FLAG,
3906                 .info = snd_hda_mixer_amp_switch_info,
3907                 .get = snd_hda_mixer_amp_switch_get,
3908                 .put = ad1884a_mobile_master_sw_put,
3909                 .private_value = HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
3910         },
3911         HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
3912         HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
3913         HDA_CODEC_VOLUME("Mic Capture Volume", 0x14, 0x0, HDA_INPUT),
3914         HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x15, 0x0, HDA_INPUT),
3915         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3916         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3917         { } /* end */
3918 };
3919
3920 /* mute internal speaker if HP is plugged */
3921 static void ad1884a_hp_automute(struct hda_codec *codec)
3922 {
3923         unsigned int present;
3924
3925         present = snd_hda_jack_detect(codec, 0x11);
3926         snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
3927                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
3928         snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_EAPD_BTLENABLE,
3929                             present ? 0x00 : 0x02);
3930 }
3931
3932 /* switch to external mic if plugged */
3933 static void ad1884a_hp_automic(struct hda_codec *codec)
3934 {
3935         unsigned int present;
3936
3937         present = snd_hda_jack_detect(codec, 0x14);
3938         snd_hda_codec_write(codec, 0x0c, 0, AC_VERB_SET_CONNECT_SEL,
3939                             present ? 0 : 1);
3940 }
3941
3942 #define AD1884A_HP_EVENT                0x37
3943 #define AD1884A_MIC_EVENT               0x36
3944
3945 /* unsolicited event for HP jack sensing */
3946 static void ad1884a_hp_unsol_event(struct hda_codec *codec, unsigned int res)
3947 {
3948         switch (res >> 26) {
3949         case AD1884A_HP_EVENT:
3950                 ad1884a_hp_automute(codec);
3951                 break;
3952         case AD1884A_MIC_EVENT:
3953                 ad1884a_hp_automic(codec);
3954                 break;
3955         }
3956 }
3957
3958 /* initialize jack-sensing, too */
3959 static int ad1884a_hp_init(struct hda_codec *codec)
3960 {
3961         ad198x_init(codec);
3962         ad1884a_hp_automute(codec);
3963         ad1884a_hp_automic(codec);
3964         return 0;
3965 }
3966
3967 /* mute internal speaker if HP or docking HP is plugged */
3968 static void ad1884a_laptop_automute(struct hda_codec *codec)
3969 {
3970         unsigned int present;
3971
3972         present = snd_hda_jack_detect(codec, 0x11);
3973         if (!present)
3974                 present = snd_hda_jack_detect(codec, 0x12);
3975         snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
3976                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
3977         snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_EAPD_BTLENABLE,
3978                             present ? 0x00 : 0x02);
3979 }
3980
3981 /* switch to external mic if plugged */
3982 static void ad1884a_laptop_automic(struct hda_codec *codec)
3983 {
3984         unsigned int idx;
3985
3986         if (snd_hda_jack_detect(codec, 0x14))
3987                 idx = 0;
3988         else if (snd_hda_jack_detect(codec, 0x1c))
3989                 idx = 4;
3990         else
3991                 idx = 1;
3992         snd_hda_codec_write(codec, 0x0c, 0, AC_VERB_SET_CONNECT_SEL, idx);
3993 }
3994
3995 /* unsolicited event for HP jack sensing */
3996 static void ad1884a_laptop_unsol_event(struct hda_codec *codec,
3997                                        unsigned int res)
3998 {
3999         switch (res >> 26) {
4000         case AD1884A_HP_EVENT:
4001                 ad1884a_laptop_automute(codec);
4002                 break;
4003         case AD1884A_MIC_EVENT:
4004                 ad1884a_laptop_automic(codec);
4005                 break;
4006         }
4007 }
4008
4009 /* initialize jack-sensing, too */
4010 static int ad1884a_laptop_init(struct hda_codec *codec)
4011 {
4012         ad198x_init(codec);
4013         ad1884a_laptop_automute(codec);
4014         ad1884a_laptop_automic(codec);
4015         return 0;
4016 }
4017
4018 /* additional verbs for laptop model */
4019 static struct hda_verb ad1884a_laptop_verbs[] = {
4020         /* Port-A (HP) pin - always unmuted */
4021         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4022         /* Port-F (int speaker) mixer - route only from analog mixer */
4023         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4024         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4025         /* Port-F (int speaker) pin */
4026         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4027         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4028         /* required for compaq 6530s/6531s speaker output */
4029         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4030         /* Port-C pin - internal mic-in */
4031         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4032         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
4033         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
4034         /* Port-D (docking line-out) pin - default unmuted */
4035         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4036         /* analog mix */
4037         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4038         /* unsolicited event for pin-sense */
4039         {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
4040         {0x12, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
4041         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT},
4042         {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT},
4043         /* allow to touch GPIO1 (for mute control) */
4044         {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
4045         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
4046         {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, /* first muted */
4047         { } /* end */
4048 };
4049
4050 static struct hda_verb ad1884a_mobile_verbs[] = {
4051         /* DACs; unmute as default */
4052         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
4053         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
4054         /* Port-A (HP) mixer - route only from analog mixer */
4055         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4056         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4057         /* Port-A pin */
4058         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4059         /* Port-A (HP) pin - always unmuted */
4060         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4061         /* Port-B (mic jack) pin */
4062         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4063         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
4064         /* Port-C (int mic) pin */
4065         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4066         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
4067         /* Port-F (int speaker) mixer - route only from analog mixer */
4068         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4069         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4070         /* Port-F pin */
4071         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4072         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4073         /* Analog mixer; mute as default */
4074         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4075         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4076         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4077         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4078         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4079         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
4080         /* Analog Mix output amp */
4081         {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4082         /* capture sources */
4083         /* {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0}, */ /* set via unsol */
4084         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4085         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
4086         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4087         /* unsolicited event for pin-sense */
4088         {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
4089         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT},
4090         /* allow to touch GPIO1 (for mute control) */
4091         {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
4092         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
4093         {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, /* first muted */
4094         { } /* end */
4095 };
4096
4097 /*
4098  * Thinkpad X300
4099  * 0x11 - HP
4100  * 0x12 - speaker
4101  * 0x14 - mic-in
4102  * 0x17 - built-in mic
4103  */
4104
4105 static struct hda_verb ad1984a_thinkpad_verbs[] = {
4106         /* HP unmute */
4107         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4108         /* analog mix */
4109         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4110         /* turn on EAPD */
4111         {0x12, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4112         /* unsolicited event for pin-sense */
4113         {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
4114         /* internal mic - dmic */
4115         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4116         /* set magic COEFs for dmic */
4117         {0x01, AC_VERB_SET_COEF_INDEX, 0x13f7},
4118         {0x01, AC_VERB_SET_PROC_COEF, 0x08},
4119         { } /* end */
4120 };
4121
4122 static struct snd_kcontrol_new ad1984a_thinkpad_mixers[] = {
4123         HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
4124         HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),
4125         HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
4126         HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
4127         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
4128         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
4129         HDA_CODEC_VOLUME("Mic Boost", 0x14, 0x0, HDA_INPUT),
4130         HDA_CODEC_VOLUME("Internal Mic Boost", 0x17, 0x0, HDA_INPUT),
4131         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
4132         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
4133         {
4134                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4135                 .name = "Capture Source",
4136                 .info = ad198x_mux_enum_info,
4137                 .get = ad198x_mux_enum_get,
4138                 .put = ad198x_mux_enum_put,
4139         },
4140         { } /* end */
4141 };
4142
4143 static struct hda_input_mux ad1984a_thinkpad_capture_source = {
4144         .num_items = 3,
4145         .items = {
4146                 { "Mic", 0x0 },
4147                 { "Internal Mic", 0x5 },
4148                 { "Mix", 0x3 },
4149         },
4150 };
4151
4152 /* mute internal speaker if HP is plugged */
4153 static void ad1984a_thinkpad_automute(struct hda_codec *codec)
4154 {
4155         unsigned int present;
4156
4157         present = snd_hda_jack_detect(codec, 0x11);
4158         snd_hda_codec_amp_stereo(codec, 0x12, HDA_OUTPUT, 0,
4159                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
4160 }
4161
4162 /* unsolicited event for HP jack sensing */
4163 static void ad1984a_thinkpad_unsol_event(struct hda_codec *codec,
4164                                          unsigned int res)
4165 {
4166         if ((res >> 26) != AD1884A_HP_EVENT)
4167                 return;
4168         ad1984a_thinkpad_automute(codec);
4169 }
4170
4171 /* initialize jack-sensing, too */
4172 static int ad1984a_thinkpad_init(struct hda_codec *codec)
4173 {
4174         ad198x_init(codec);
4175         ad1984a_thinkpad_automute(codec);
4176         return 0;
4177 }
4178
4179 /*
4180  * HP Touchsmart
4181  * port-A (0x11)      - front hp-out
4182  * port-B (0x14)      - unused
4183  * port-C (0x15)      - unused
4184  * port-D (0x12)      - rear line out
4185  * port-E (0x1c)      - front mic-in
4186  * port-F (0x16)      - Internal speakers
4187  * digital-mic (0x17) - Internal mic
4188  */
4189
4190 static struct hda_verb ad1984a_touchsmart_verbs[] = {
4191         /* DACs; unmute as default */
4192         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
4193         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
4194         /* Port-A (HP) mixer - route only from analog mixer */
4195         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4196         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4197         /* Port-A pin */
4198         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4199         /* Port-A (HP) pin - always unmuted */
4200         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4201         /* Port-E (int speaker) mixer - route only from analog mixer */
4202         {0x25, AC_VERB_SET_AMP_GAIN_MUTE, 0x03},
4203         /* Port-E pin */
4204         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4205         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4206         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4207         /* Port-F (int speaker) mixer - route only from analog mixer */
4208         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4209         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4210         /* Port-F pin */
4211         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4212         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4213         /* Analog mixer; mute as default */
4214         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4215         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4216         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4217         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4218         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4219         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
4220         /* Analog Mix output amp */
4221         {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4222         /* capture sources */
4223         /* {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0}, */ /* set via unsol */
4224         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4225         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
4226         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4227         /* unsolicited event for pin-sense */
4228         {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
4229         {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT},
4230         /* allow to touch GPIO1 (for mute control) */
4231         {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
4232         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
4233         {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, /* first muted */
4234         /* internal mic - dmic */
4235         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4236         /* set magic COEFs for dmic */
4237         {0x01, AC_VERB_SET_COEF_INDEX, 0x13f7},
4238         {0x01, AC_VERB_SET_PROC_COEF, 0x08},
4239         { } /* end */
4240 };
4241
4242 static struct snd_kcontrol_new ad1984a_touchsmart_mixers[] = {
4243         HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
4244 /*      HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/
4245         {
4246                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4247                 .subdevice = HDA_SUBDEV_AMP_FLAG,
4248                 .name = "Master Playback Switch",
4249                 .info = snd_hda_mixer_amp_switch_info,
4250                 .get = snd_hda_mixer_amp_switch_get,
4251                 .put = ad1884a_mobile_master_sw_put,
4252                 .private_value = HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
4253         },
4254         HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
4255         HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
4256         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
4257         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
4258         HDA_CODEC_VOLUME("Mic Boost", 0x25, 0x0, HDA_OUTPUT),
4259         HDA_CODEC_VOLUME("Internal Mic Boost", 0x17, 0x0, HDA_INPUT),
4260         { } /* end */
4261 };
4262
4263 /* switch to external mic if plugged */
4264 static void ad1984a_touchsmart_automic(struct hda_codec *codec)
4265 {
4266         if (snd_hda_jack_detect(codec, 0x1c))
4267                 snd_hda_codec_write(codec, 0x0c, 0,
4268                                      AC_VERB_SET_CONNECT_SEL, 0x4);
4269         else
4270                 snd_hda_codec_write(codec, 0x0c, 0,
4271                                      AC_VERB_SET_CONNECT_SEL, 0x5);
4272 }
4273
4274
4275 /* unsolicited event for HP jack sensing */
4276 static void ad1984a_touchsmart_unsol_event(struct hda_codec *codec,
4277         unsigned int res)
4278 {
4279         switch (res >> 26) {
4280         case AD1884A_HP_EVENT:
4281                 ad1884a_hp_automute(codec);
4282                 break;
4283         case AD1884A_MIC_EVENT:
4284                 ad1984a_touchsmart_automic(codec);
4285                 break;
4286         }
4287 }
4288
4289 /* initialize jack-sensing, too */
4290 static int ad1984a_touchsmart_init(struct hda_codec *codec)
4291 {
4292         ad198x_init(codec);
4293         ad1884a_hp_automute(codec);
4294         ad1984a_touchsmart_automic(codec);
4295         return 0;
4296 }
4297
4298
4299 /*
4300  */
4301
4302 enum {
4303         AD1884A_DESKTOP,
4304         AD1884A_LAPTOP,
4305         AD1884A_MOBILE,
4306         AD1884A_THINKPAD,
4307         AD1984A_TOUCHSMART,
4308         AD1884A_MODELS
4309 };
4310
4311 static const char *ad1884a_models[AD1884A_MODELS] = {
4312         [AD1884A_DESKTOP]       = "desktop",
4313         [AD1884A_LAPTOP]        = "laptop",
4314         [AD1884A_MOBILE]        = "mobile",
4315         [AD1884A_THINKPAD]      = "thinkpad",
4316         [AD1984A_TOUCHSMART]    = "touchsmart",
4317 };
4318
4319 static struct snd_pci_quirk ad1884a_cfg_tbl[] = {
4320         SND_PCI_QUIRK(0x103c, 0x3030, "HP", AD1884A_MOBILE),
4321         SND_PCI_QUIRK(0x103c, 0x3037, "HP 2230s", AD1884A_LAPTOP),
4322         SND_PCI_QUIRK(0x103c, 0x3056, "HP", AD1884A_MOBILE),
4323         SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x3070, "HP", AD1884A_MOBILE),
4324         SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x30d0, "HP laptop", AD1884A_LAPTOP),
4325         SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x30e0, "HP laptop", AD1884A_LAPTOP),
4326         SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3600, "HP laptop", AD1884A_LAPTOP),
4327         SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x7010, "HP laptop", AD1884A_MOBILE),
4328         SND_PCI_QUIRK(0x17aa, 0x20ac, "Thinkpad X300", AD1884A_THINKPAD),
4329         SND_PCI_QUIRK(0x103c, 0x2a82, "Touchsmart", AD1984A_TOUCHSMART),
4330         {}
4331 };
4332
4333 static int patch_ad1884a(struct hda_codec *codec)
4334 {
4335         struct ad198x_spec *spec;
4336         int err, board_config;
4337
4338         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4339         if (spec == NULL)
4340                 return -ENOMEM;
4341
4342         codec->spec = spec;
4343
4344         err = snd_hda_attach_beep_device(codec, 0x10);
4345         if (err < 0) {
4346                 ad198x_free(codec);
4347                 return err;
4348         }
4349         set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
4350
4351         spec->multiout.max_channels = 2;
4352         spec->multiout.num_dacs = ARRAY_SIZE(ad1884a_dac_nids);
4353         spec->multiout.dac_nids = ad1884a_dac_nids;
4354         spec->multiout.dig_out_nid = AD1884A_SPDIF_OUT;
4355         spec->num_adc_nids = ARRAY_SIZE(ad1884a_adc_nids);
4356         spec->adc_nids = ad1884a_adc_nids;
4357         spec->capsrc_nids = ad1884a_capsrc_nids;
4358         spec->input_mux = &ad1884a_capture_source;
4359         spec->num_mixers = 1;
4360         spec->mixers[0] = ad1884a_base_mixers;
4361         spec->num_init_verbs = 1;
4362         spec->init_verbs[0] = ad1884a_init_verbs;
4363         spec->spdif_route = 0;
4364 #ifdef CONFIG_SND_HDA_POWER_SAVE
4365         spec->loopback.amplist = ad1884a_loopbacks;
4366 #endif
4367         codec->patch_ops = ad198x_patch_ops;
4368
4369         /* override some parameters */
4370         board_config = snd_hda_check_board_config(codec, AD1884A_MODELS,
4371                                                   ad1884a_models,
4372                                                   ad1884a_cfg_tbl);
4373         switch (board_config) {
4374         case AD1884A_LAPTOP:
4375                 spec->mixers[0] = ad1884a_laptop_mixers;
4376                 spec->init_verbs[spec->num_init_verbs++] = ad1884a_laptop_verbs;
4377                 spec->multiout.dig_out_nid = 0;
4378                 codec->patch_ops.unsol_event = ad1884a_laptop_unsol_event;
4379                 codec->patch_ops.init = ad1884a_laptop_init;
4380                 /* set the upper-limit for mixer amp to 0dB for avoiding the
4381                  * possible damage by overloading
4382                  */
4383                 snd_hda_override_amp_caps(codec, 0x20, HDA_INPUT,
4384                                           (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
4385                                           (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
4386                                           (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
4387                                           (1 << AC_AMPCAP_MUTE_SHIFT));
4388                 break;
4389         case AD1884A_MOBILE:
4390                 spec->mixers[0] = ad1884a_mobile_mixers;
4391                 spec->init_verbs[0] = ad1884a_mobile_verbs;
4392                 spec->multiout.dig_out_nid = 0;
4393                 codec->patch_ops.unsol_event = ad1884a_hp_unsol_event;
4394                 codec->patch_ops.init = ad1884a_hp_init;
4395                 /* set the upper-limit for mixer amp to 0dB for avoiding the
4396                  * possible damage by overloading
4397                  */
4398                 snd_hda_override_amp_caps(codec, 0x20, HDA_INPUT,
4399                                           (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
4400                                           (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
4401                                           (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
4402                                           (1 << AC_AMPCAP_MUTE_SHIFT));
4403                 break;
4404         case AD1884A_THINKPAD:
4405                 spec->mixers[0] = ad1984a_thinkpad_mixers;
4406                 spec->init_verbs[spec->num_init_verbs++] =
4407                         ad1984a_thinkpad_verbs;
4408                 spec->multiout.dig_out_nid = 0;
4409                 spec->input_mux = &ad1984a_thinkpad_capture_source;
4410                 codec->patch_ops.unsol_event = ad1984a_thinkpad_unsol_event;
4411                 codec->patch_ops.init = ad1984a_thinkpad_init;
4412                 break;
4413         case AD1984A_TOUCHSMART:
4414                 spec->mixers[0] = ad1984a_touchsmart_mixers;
4415                 spec->init_verbs[0] = ad1984a_touchsmart_verbs;
4416                 spec->multiout.dig_out_nid = 0;
4417                 codec->patch_ops.unsol_event = ad1984a_touchsmart_unsol_event;
4418                 codec->patch_ops.init = ad1984a_touchsmart_init;
4419                 /* set the upper-limit for mixer amp to 0dB for avoiding the
4420                  * possible damage by overloading
4421                  */
4422                 snd_hda_override_amp_caps(codec, 0x20, HDA_INPUT,
4423                                           (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
4424                                           (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
4425                                           (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
4426                                           (1 << AC_AMPCAP_MUTE_SHIFT));
4427                 break;
4428         }
4429
4430         codec->no_trigger_sense = 1;
4431         codec->no_sticky_stream = 1;
4432
4433         return 0;
4434 }
4435
4436
4437 /*
4438  * AD1882 / AD1882A
4439  *
4440  * port-A - front hp-out
4441  * port-B - front mic-in
4442  * port-C - rear line-in, shared surr-out (3stack)
4443  * port-D - rear line-out
4444  * port-E - rear mic-in, shared clfe-out (3stack)
4445  * port-F - rear surr-out (6stack)
4446  * port-G - rear clfe-out (6stack)
4447  */
4448
4449 static hda_nid_t ad1882_dac_nids[3] = {
4450         0x04, 0x03, 0x05
4451 };
4452
4453 static hda_nid_t ad1882_adc_nids[2] = {
4454         0x08, 0x09,
4455 };
4456
4457 static hda_nid_t ad1882_capsrc_nids[2] = {
4458         0x0c, 0x0d,
4459 };
4460
4461 #define AD1882_SPDIF_OUT        0x02
4462
4463 /* list: 0x11, 0x39, 0x3a, 0x18, 0x3c, 0x3b, 0x12, 0x20 */
4464 static struct hda_input_mux ad1882_capture_source = {
4465         .num_items = 5,
4466         .items = {
4467                 { "Front Mic", 0x1 },
4468                 { "Mic", 0x4 },
4469                 { "Line", 0x2 },
4470                 { "CD", 0x3 },
4471                 { "Mix", 0x7 },
4472         },
4473 };
4474
4475 /* list: 0x11, 0x39, 0x3a, 0x3c, 0x18, 0x1f, 0x12, 0x20 */
4476 static struct hda_input_mux ad1882a_capture_source = {
4477         .num_items = 5,
4478         .items = {
4479                 { "Front Mic", 0x1 },
4480                 { "Mic", 0x4},
4481                 { "Line", 0x2 },
4482                 { "Digital Mic", 0x06 },
4483                 { "Mix", 0x7 },
4484         },
4485 };
4486
4487 static struct snd_kcontrol_new ad1882_base_mixers[] = {
4488         HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
4489         HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
4490         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT),
4491         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT),
4492         HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
4493         HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT),
4494         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
4495         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
4496
4497         HDA_CODEC_VOLUME("Mic Boost", 0x3c, 0x0, HDA_OUTPUT),
4498         HDA_CODEC_VOLUME("Front Mic Boost", 0x39, 0x0, HDA_OUTPUT),
4499         HDA_CODEC_VOLUME("Line-In Boost", 0x3a, 0x0, HDA_OUTPUT),
4500         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
4501         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
4502         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
4503         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
4504         {
4505                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4506                 /* The multiple "Capture Source" controls confuse alsamixer
4507                  * So call somewhat different..
4508                  */
4509                 /* .name = "Capture Source", */
4510                 .name = "Input Source",
4511                 .count = 2,
4512                 .info = ad198x_mux_enum_info,
4513                 .get = ad198x_mux_enum_get,
4514                 .put = ad198x_mux_enum_put,
4515         },
4516         /* SPDIF controls */
4517         HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
4518         {
4519                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4520                 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
4521                 /* identical with ad1983 */
4522                 .info = ad1983_spdif_route_info,
4523                 .get = ad1983_spdif_route_get,
4524                 .put = ad1983_spdif_route_put,
4525         },
4526         { } /* end */
4527 };
4528
4529 static struct snd_kcontrol_new ad1882_loopback_mixers[] = {
4530         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
4531         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
4532         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
4533         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
4534         HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x04, HDA_INPUT),
4535         HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x04, HDA_INPUT),
4536         HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x06, HDA_INPUT),
4537         HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x06, HDA_INPUT),
4538         { } /* end */
4539 };
4540
4541 static struct snd_kcontrol_new ad1882a_loopback_mixers[] = {
4542         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
4543         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
4544         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
4545         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
4546         HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x01, HDA_INPUT),
4547         HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x01, HDA_INPUT),
4548         HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x06, HDA_INPUT),
4549         HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x06, HDA_INPUT),
4550         HDA_CODEC_VOLUME("Digital Mic Boost", 0x1f, 0x0, HDA_INPUT),
4551         { } /* end */
4552 };
4553
4554 static struct snd_kcontrol_new ad1882_3stack_mixers[] = {
4555         HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
4556         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x17, 1, 0x0, HDA_OUTPUT),
4557         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x17, 2, 0x0, HDA_OUTPUT),
4558         {
4559                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4560                 .name = "Channel Mode",
4561                 .info = ad198x_ch_mode_info,
4562                 .get = ad198x_ch_mode_get,
4563                 .put = ad198x_ch_mode_put,
4564         },
4565         { } /* end */
4566 };
4567
4568 static struct snd_kcontrol_new ad1882_6stack_mixers[] = {
4569         HDA_CODEC_MUTE("Surround Playback Switch", 0x16, 0x0, HDA_OUTPUT),
4570         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x24, 1, 0x0, HDA_OUTPUT),
4571         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x24, 2, 0x0, HDA_OUTPUT),
4572         { } /* end */
4573 };
4574
4575 static struct hda_verb ad1882_ch2_init[] = {
4576         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4577         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4578         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4579         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4580         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4581         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4582         { } /* end */
4583 };
4584
4585 static struct hda_verb ad1882_ch4_init[] = {
4586         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4587         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4588         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4589         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4590         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4591         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4592         { } /* end */
4593 };
4594
4595 static struct hda_verb ad1882_ch6_init[] = {
4596         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4597         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4598         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4599         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4600         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4601         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4602         { } /* end */
4603 };
4604
4605 static struct hda_channel_mode ad1882_modes[3] = {
4606         { 2, ad1882_ch2_init },
4607         { 4, ad1882_ch4_init },
4608         { 6, ad1882_ch6_init },
4609 };
4610
4611 /*
4612  * initialization verbs
4613  */
4614 static struct hda_verb ad1882_init_verbs[] = {
4615         /* DACs; mute as default */
4616         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4617         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4618         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4619         /* Port-A (HP) mixer */
4620         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4621         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4622         /* Port-A pin */
4623         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4624         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4625         /* HP selector - select DAC2 */
4626         {0x37, AC_VERB_SET_CONNECT_SEL, 0x1},
4627         /* Port-D (Line-out) mixer */
4628         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4629         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4630         /* Port-D pin */
4631         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4632         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4633         /* Mono-out mixer */
4634         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4635         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4636         /* Mono-out pin */
4637         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4638         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4639         /* Port-B (front mic) pin */
4640         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4641         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4642         {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */
4643         /* Port-C (line-in) pin */
4644         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4645         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4646         {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */
4647         /* Port-C mixer - mute as input */
4648         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4649         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4650         /* Port-E (mic-in) pin */
4651         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4652         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4653         {0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */
4654         /* Port-E mixer - mute as input */
4655         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4656         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4657         /* Port-F (surround) */
4658         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4659         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4660         /* Port-G (CLFE) */
4661         {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4662         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4663         /* Analog mixer; mute as default */
4664         /* list: 0x39, 0x3a, 0x11, 0x12, 0x3c, 0x3b, 0x18, 0x1a */
4665         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4666         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4667         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4668         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4669         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4670         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
4671         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
4672         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
4673         /* Analog Mix output amp */
4674         {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
4675         /* SPDIF output selector */
4676         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
4677         {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */
4678         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
4679         { } /* end */
4680 };
4681
4682 #ifdef CONFIG_SND_HDA_POWER_SAVE
4683 static struct hda_amp_list ad1882_loopbacks[] = {
4684         { 0x20, HDA_INPUT, 0 }, /* Front Mic */
4685         { 0x20, HDA_INPUT, 1 }, /* Mic */
4686         { 0x20, HDA_INPUT, 4 }, /* Line */
4687         { 0x20, HDA_INPUT, 6 }, /* CD */
4688         { } /* end */
4689 };
4690 #endif
4691
4692 /* models */
4693 enum {
4694         AD1882_3STACK,
4695         AD1882_6STACK,
4696         AD1882_MODELS
4697 };
4698
4699 static const char *ad1882_models[AD1986A_MODELS] = {
4700         [AD1882_3STACK]         = "3stack",
4701         [AD1882_6STACK]         = "6stack",
4702 };
4703
4704
4705 static int patch_ad1882(struct hda_codec *codec)
4706 {
4707         struct ad198x_spec *spec;
4708         int err, board_config;
4709
4710         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4711         if (spec == NULL)
4712                 return -ENOMEM;
4713
4714         codec->spec = spec;
4715
4716         err = snd_hda_attach_beep_device(codec, 0x10);
4717         if (err < 0) {
4718                 ad198x_free(codec);
4719                 return err;
4720         }
4721         set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
4722
4723         spec->multiout.max_channels = 6;
4724         spec->multiout.num_dacs = 3;
4725         spec->multiout.dac_nids = ad1882_dac_nids;
4726         spec->multiout.dig_out_nid = AD1882_SPDIF_OUT;
4727         spec->num_adc_nids = ARRAY_SIZE(ad1882_adc_nids);
4728         spec->adc_nids = ad1882_adc_nids;
4729         spec->capsrc_nids = ad1882_capsrc_nids;
4730         if (codec->vendor_id == 0x11d41882)
4731                 spec->input_mux = &ad1882_capture_source;
4732         else
4733                 spec->input_mux = &ad1882a_capture_source;
4734         spec->num_mixers = 2;
4735         spec->mixers[0] = ad1882_base_mixers;
4736         if (codec->vendor_id == 0x11d41882)
4737                 spec->mixers[1] = ad1882_loopback_mixers;
4738         else
4739                 spec->mixers[1] = ad1882a_loopback_mixers;
4740         spec->num_init_verbs = 1;
4741         spec->init_verbs[0] = ad1882_init_verbs;
4742         spec->spdif_route = 0;
4743 #ifdef CONFIG_SND_HDA_POWER_SAVE
4744         spec->loopback.amplist = ad1882_loopbacks;
4745 #endif
4746         spec->vmaster_nid = 0x04;
4747
4748         codec->patch_ops = ad198x_patch_ops;
4749
4750         /* override some parameters */
4751         board_config = snd_hda_check_board_config(codec, AD1882_MODELS,
4752                                                   ad1882_models, NULL);
4753         switch (board_config) {
4754         default:
4755         case AD1882_3STACK:
4756                 spec->num_mixers = 3;
4757                 spec->mixers[2] = ad1882_3stack_mixers;
4758                 spec->channel_mode = ad1882_modes;
4759                 spec->num_channel_mode = ARRAY_SIZE(ad1882_modes);
4760                 spec->need_dac_fix = 1;
4761                 spec->multiout.max_channels = 2;
4762                 spec->multiout.num_dacs = 1;
4763                 break;
4764         case AD1882_6STACK:
4765                 spec->num_mixers = 3;
4766                 spec->mixers[2] = ad1882_6stack_mixers;
4767                 break;
4768         }
4769
4770         codec->no_trigger_sense = 1;
4771         codec->no_sticky_stream = 1;
4772
4773         return 0;
4774 }
4775
4776
4777 /*
4778  * patch entries
4779  */
4780 static struct hda_codec_preset snd_hda_preset_analog[] = {
4781         { .id = 0x11d4184a, .name = "AD1884A", .patch = patch_ad1884a },
4782         { .id = 0x11d41882, .name = "AD1882", .patch = patch_ad1882 },
4783         { .id = 0x11d41883, .name = "AD1883", .patch = patch_ad1884a },
4784         { .id = 0x11d41884, .name = "AD1884", .patch = patch_ad1884 },
4785         { .id = 0x11d4194a, .name = "AD1984A", .patch = patch_ad1884a },
4786         { .id = 0x11d4194b, .name = "AD1984B", .patch = patch_ad1884a },
4787         { .id = 0x11d41981, .name = "AD1981", .patch = patch_ad1981 },
4788         { .id = 0x11d41983, .name = "AD1983", .patch = patch_ad1983 },
4789         { .id = 0x11d41984, .name = "AD1984", .patch = patch_ad1984 },
4790         { .id = 0x11d41986, .name = "AD1986A", .patch = patch_ad1986a },
4791         { .id = 0x11d41988, .name = "AD1988", .patch = patch_ad1988 },
4792         { .id = 0x11d4198b, .name = "AD1988B", .patch = patch_ad1988 },
4793         { .id = 0x11d4882a, .name = "AD1882A", .patch = patch_ad1882 },
4794         { .id = 0x11d4989a, .name = "AD1989A", .patch = patch_ad1988 },
4795         { .id = 0x11d4989b, .name = "AD1989B", .patch = patch_ad1988 },
4796         {} /* terminator */
4797 };
4798
4799 MODULE_ALIAS("snd-hda-codec-id:11d4*");
4800
4801 MODULE_LICENSE("GPL");
4802 MODULE_DESCRIPTION("Analog Devices HD-audio codec");
4803
4804 static struct hda_codec_preset_list analog_list = {
4805         .preset = snd_hda_preset_analog,
4806         .owner = THIS_MODULE,
4807 };
4808
4809 static int __init patch_analog_init(void)
4810 {
4811         return snd_hda_add_codec_preset(&analog_list);
4812 }
4813
4814 static void __exit patch_analog_exit(void)
4815 {
4816         snd_hda_delete_codec_preset(&analog_list);
4817 }
4818
4819 module_init(patch_analog_init)
4820 module_exit(patch_analog_exit)