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