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