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