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