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