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