ALSA: hda - Use digital beep for AD codecs
[safe/jmp/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, 0xc023, "Samsung X60", AD1986A_SAMSUNG),
1019         SND_PCI_QUIRK(0x144d, 0xc024, "Samsung R65", AD1986A_SAMSUNG),
1020         SND_PCI_QUIRK(0x144d, 0xc026, "Samsung X11", AD1986A_SAMSUNG),
1021         SND_PCI_QUIRK(0x144d, 0xc027, "Samsung Q1", AD1986A_ULTRA),
1022         SND_PCI_QUIRK(0x144d, 0xc504, "Samsung Q35", AD1986A_3STACK),
1023         SND_PCI_QUIRK(0x17aa, 0x1011, "Lenovo M55", AD1986A_LAPTOP),
1024         SND_PCI_QUIRK(0x17aa, 0x1017, "Lenovo A60", AD1986A_3STACK),
1025         SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo N100", AD1986A_LAPTOP_AUTOMUTE),
1026         SND_PCI_QUIRK(0x17c0, 0x2017, "Samsung M50", AD1986A_LAPTOP),
1027         {}
1028 };
1029
1030 #ifdef CONFIG_SND_HDA_POWER_SAVE
1031 static struct hda_amp_list ad1986a_loopbacks[] = {
1032         { 0x13, HDA_OUTPUT, 0 }, /* Mic */
1033         { 0x14, HDA_OUTPUT, 0 }, /* Phone */
1034         { 0x15, HDA_OUTPUT, 0 }, /* CD */
1035         { 0x16, HDA_OUTPUT, 0 }, /* Aux */
1036         { 0x17, HDA_OUTPUT, 0 }, /* Line */
1037         { } /* end */
1038 };
1039 #endif
1040
1041 static int is_jack_available(struct hda_codec *codec, hda_nid_t nid)
1042 {
1043         unsigned int conf = snd_hda_codec_read(codec, nid, 0,
1044                                                AC_VERB_GET_CONFIG_DEFAULT, 0);
1045         return get_defcfg_connect(conf) != AC_JACK_PORT_NONE;
1046 }
1047
1048 static int patch_ad1986a(struct hda_codec *codec)
1049 {
1050         struct ad198x_spec *spec;
1051         int err, board_config;
1052
1053         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1054         if (spec == NULL)
1055                 return -ENOMEM;
1056
1057         codec->spec = spec;
1058
1059         err = snd_hda_attach_beep_device(codec, 0x19);
1060         if (err < 0) {
1061                 ad198x_free(codec);
1062                 return err;
1063         }
1064         set_beep_amp(spec, 0x18, 0, HDA_OUTPUT);
1065
1066         spec->multiout.max_channels = 6;
1067         spec->multiout.num_dacs = ARRAY_SIZE(ad1986a_dac_nids);
1068         spec->multiout.dac_nids = ad1986a_dac_nids;
1069         spec->multiout.dig_out_nid = AD1986A_SPDIF_OUT;
1070         spec->num_adc_nids = 1;
1071         spec->adc_nids = ad1986a_adc_nids;
1072         spec->capsrc_nids = ad1986a_capsrc_nids;
1073         spec->input_mux = &ad1986a_capture_source;
1074         spec->num_mixers = 1;
1075         spec->mixers[0] = ad1986a_mixers;
1076         spec->num_init_verbs = 1;
1077         spec->init_verbs[0] = ad1986a_init_verbs;
1078 #ifdef CONFIG_SND_HDA_POWER_SAVE
1079         spec->loopback.amplist = ad1986a_loopbacks;
1080 #endif
1081         spec->vmaster_nid = 0x1b;
1082
1083         codec->patch_ops = ad198x_patch_ops;
1084
1085         /* override some parameters */
1086         board_config = snd_hda_check_board_config(codec, AD1986A_MODELS,
1087                                                   ad1986a_models,
1088                                                   ad1986a_cfg_tbl);
1089         switch (board_config) {
1090         case AD1986A_3STACK:
1091                 spec->num_mixers = 2;
1092                 spec->mixers[1] = ad1986a_3st_mixers;
1093                 spec->num_init_verbs = 2;
1094                 spec->init_verbs[1] = ad1986a_ch2_init;
1095                 spec->channel_mode = ad1986a_modes;
1096                 spec->num_channel_mode = ARRAY_SIZE(ad1986a_modes);
1097                 spec->need_dac_fix = 1;
1098                 spec->multiout.max_channels = 2;
1099                 spec->multiout.num_dacs = 1;
1100                 break;
1101         case AD1986A_LAPTOP:
1102                 spec->mixers[0] = ad1986a_laptop_mixers;
1103                 spec->multiout.max_channels = 2;
1104                 spec->multiout.num_dacs = 1;
1105                 spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
1106                 break;
1107         case AD1986A_LAPTOP_EAPD:
1108                 spec->mixers[0] = ad1986a_laptop_eapd_mixers;
1109                 spec->num_init_verbs = 2;
1110                 spec->init_verbs[1] = ad1986a_eapd_init_verbs;
1111                 spec->multiout.max_channels = 2;
1112                 spec->multiout.num_dacs = 1;
1113                 spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
1114                 if (!is_jack_available(codec, 0x25))
1115                         spec->multiout.dig_out_nid = 0;
1116                 spec->input_mux = &ad1986a_laptop_eapd_capture_source;
1117                 break;
1118         case AD1986A_SAMSUNG:
1119                 spec->mixers[0] = ad1986a_samsung_mixers;
1120                 spec->num_init_verbs = 3;
1121                 spec->init_verbs[1] = ad1986a_eapd_init_verbs;
1122                 spec->init_verbs[2] = ad1986a_automic_verbs;
1123                 spec->multiout.max_channels = 2;
1124                 spec->multiout.num_dacs = 1;
1125                 spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
1126                 if (!is_jack_available(codec, 0x25))
1127                         spec->multiout.dig_out_nid = 0;
1128                 spec->input_mux = &ad1986a_automic_capture_source;
1129                 codec->patch_ops.unsol_event = ad1986a_automic_unsol_event;
1130                 codec->patch_ops.init = ad1986a_automic_init;
1131                 break;
1132         case AD1986A_LAPTOP_AUTOMUTE:
1133                 spec->mixers[0] = ad1986a_laptop_automute_mixers;
1134                 spec->num_init_verbs = 3;
1135                 spec->init_verbs[1] = ad1986a_eapd_init_verbs;
1136                 spec->init_verbs[2] = ad1986a_hp_init_verbs;
1137                 spec->multiout.max_channels = 2;
1138                 spec->multiout.num_dacs = 1;
1139                 spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
1140                 if (!is_jack_available(codec, 0x25))
1141                         spec->multiout.dig_out_nid = 0;
1142                 spec->input_mux = &ad1986a_laptop_eapd_capture_source;
1143                 codec->patch_ops.unsol_event = ad1986a_hp_unsol_event;
1144                 codec->patch_ops.init = ad1986a_hp_init;
1145                 break;
1146         case AD1986A_ULTRA:
1147                 spec->mixers[0] = ad1986a_laptop_eapd_mixers;
1148                 spec->num_init_verbs = 2;
1149                 spec->init_verbs[1] = ad1986a_ultra_init;
1150                 spec->multiout.max_channels = 2;
1151                 spec->multiout.num_dacs = 1;
1152                 spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
1153                 spec->multiout.dig_out_nid = 0;
1154                 break;
1155         }
1156
1157         /* AD1986A has a hardware problem that it can't share a stream
1158          * with multiple output pins.  The copy of front to surrounds
1159          * causes noisy or silent outputs at a certain timing, e.g.
1160          * changing the volume.
1161          * So, let's disable the shared stream.
1162          */
1163         spec->multiout.no_share_stream = 1;
1164
1165         return 0;
1166 }
1167
1168 /*
1169  * AD1983 specific
1170  */
1171
1172 #define AD1983_SPDIF_OUT        0x02
1173 #define AD1983_DAC              0x03
1174 #define AD1983_ADC              0x04
1175
1176 static hda_nid_t ad1983_dac_nids[1] = { AD1983_DAC };
1177 static hda_nid_t ad1983_adc_nids[1] = { AD1983_ADC };
1178 static hda_nid_t ad1983_capsrc_nids[1] = { 0x15 };
1179
1180 static struct hda_input_mux ad1983_capture_source = {
1181         .num_items = 4,
1182         .items = {
1183                 { "Mic", 0x0 },
1184                 { "Line", 0x1 },
1185                 { "Mix", 0x2 },
1186                 { "Mix Mono", 0x3 },
1187         },
1188 };
1189
1190 /*
1191  * SPDIF playback route
1192  */
1193 static int ad1983_spdif_route_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1194 {
1195         static char *texts[] = { "PCM", "ADC" };
1196
1197         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1198         uinfo->count = 1;
1199         uinfo->value.enumerated.items = 2;
1200         if (uinfo->value.enumerated.item > 1)
1201                 uinfo->value.enumerated.item = 1;
1202         strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1203         return 0;
1204 }
1205
1206 static int ad1983_spdif_route_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1207 {
1208         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1209         struct ad198x_spec *spec = codec->spec;
1210
1211         ucontrol->value.enumerated.item[0] = spec->spdif_route;
1212         return 0;
1213 }
1214
1215 static int ad1983_spdif_route_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1216 {
1217         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1218         struct ad198x_spec *spec = codec->spec;
1219
1220         if (ucontrol->value.enumerated.item[0] > 1)
1221                 return -EINVAL;
1222         if (spec->spdif_route != ucontrol->value.enumerated.item[0]) {
1223                 spec->spdif_route = ucontrol->value.enumerated.item[0];
1224                 snd_hda_codec_write_cache(codec, spec->multiout.dig_out_nid, 0,
1225                                           AC_VERB_SET_CONNECT_SEL,
1226                                           spec->spdif_route);
1227                 return 1;
1228         }
1229         return 0;
1230 }
1231
1232 static struct snd_kcontrol_new ad1983_mixers[] = {
1233         HDA_CODEC_VOLUME("Front Playback Volume", 0x05, 0x0, HDA_OUTPUT),
1234         HDA_CODEC_MUTE("Front Playback Switch", 0x05, 0x0, HDA_OUTPUT),
1235         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x06, 0x0, HDA_OUTPUT),
1236         HDA_CODEC_MUTE("Headphone Playback Switch", 0x06, 0x0, HDA_OUTPUT),
1237         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x07, 1, 0x0, HDA_OUTPUT),
1238         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x07, 1, 0x0, HDA_OUTPUT),
1239         HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
1240         HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT),
1241         HDA_CODEC_VOLUME("Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
1242         HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
1243         HDA_CODEC_VOLUME("Line Playback Volume", 0x13, 0x0, HDA_OUTPUT),
1244         HDA_CODEC_MUTE("Line Playback Switch", 0x13, 0x0, HDA_OUTPUT),
1245         HDA_CODEC_VOLUME("Mic Boost", 0x0c, 0x0, HDA_OUTPUT),
1246         HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
1247         HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
1248         {
1249                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1250                 .name = "Capture Source",
1251                 .info = ad198x_mux_enum_info,
1252                 .get = ad198x_mux_enum_get,
1253                 .put = ad198x_mux_enum_put,
1254         },
1255         {
1256                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1257                 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
1258                 .info = ad1983_spdif_route_info,
1259                 .get = ad1983_spdif_route_get,
1260                 .put = ad1983_spdif_route_put,
1261         },
1262         { } /* end */
1263 };
1264
1265 static struct hda_verb ad1983_init_verbs[] = {
1266         /* Front, HP, Mono; mute as default */
1267         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1268         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1269         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1270         /* Beep, PCM, Mic, Line-In: mute */
1271         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1272         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1273         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1274         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1275         /* Front, HP selectors; from Mix */
1276         {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
1277         {0x06, AC_VERB_SET_CONNECT_SEL, 0x01},
1278         /* Mono selector; from Mix */
1279         {0x0b, AC_VERB_SET_CONNECT_SEL, 0x03},
1280         /* Mic selector; Mic */
1281         {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0},
1282         /* Line-in selector: Line-in */
1283         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
1284         /* Mic boost: 0dB */
1285         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1286         /* Record selector: mic */
1287         {0x15, AC_VERB_SET_CONNECT_SEL, 0x0},
1288         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1289         /* SPDIF route: PCM */
1290         {0x02, AC_VERB_SET_CONNECT_SEL, 0x0},
1291         /* Front Pin */
1292         {0x05, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
1293         /* HP Pin */
1294         {0x06, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
1295         /* Mono Pin */
1296         {0x07, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
1297         /* Mic Pin */
1298         {0x08, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
1299         /* Line Pin */
1300         {0x09, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
1301         { } /* end */
1302 };
1303
1304 #ifdef CONFIG_SND_HDA_POWER_SAVE
1305 static struct hda_amp_list ad1983_loopbacks[] = {
1306         { 0x12, HDA_OUTPUT, 0 }, /* Mic */
1307         { 0x13, HDA_OUTPUT, 0 }, /* Line */
1308         { } /* end */
1309 };
1310 #endif
1311
1312 static int patch_ad1983(struct hda_codec *codec)
1313 {
1314         struct ad198x_spec *spec;
1315         int err;
1316
1317         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1318         if (spec == NULL)
1319                 return -ENOMEM;
1320
1321         codec->spec = spec;
1322
1323         err = snd_hda_attach_beep_device(codec, 0x10);
1324         if (err < 0) {
1325                 ad198x_free(codec);
1326                 return err;
1327         }
1328         set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
1329
1330         spec->multiout.max_channels = 2;
1331         spec->multiout.num_dacs = ARRAY_SIZE(ad1983_dac_nids);
1332         spec->multiout.dac_nids = ad1983_dac_nids;
1333         spec->multiout.dig_out_nid = AD1983_SPDIF_OUT;
1334         spec->num_adc_nids = 1;
1335         spec->adc_nids = ad1983_adc_nids;
1336         spec->capsrc_nids = ad1983_capsrc_nids;
1337         spec->input_mux = &ad1983_capture_source;
1338         spec->num_mixers = 1;
1339         spec->mixers[0] = ad1983_mixers;
1340         spec->num_init_verbs = 1;
1341         spec->init_verbs[0] = ad1983_init_verbs;
1342         spec->spdif_route = 0;
1343 #ifdef CONFIG_SND_HDA_POWER_SAVE
1344         spec->loopback.amplist = ad1983_loopbacks;
1345 #endif
1346         spec->vmaster_nid = 0x05;
1347
1348         codec->patch_ops = ad198x_patch_ops;
1349
1350         return 0;
1351 }
1352
1353
1354 /*
1355  * AD1981 HD specific
1356  */
1357
1358 #define AD1981_SPDIF_OUT        0x02
1359 #define AD1981_DAC              0x03
1360 #define AD1981_ADC              0x04
1361
1362 static hda_nid_t ad1981_dac_nids[1] = { AD1981_DAC };
1363 static hda_nid_t ad1981_adc_nids[1] = { AD1981_ADC };
1364 static hda_nid_t ad1981_capsrc_nids[1] = { 0x15 };
1365
1366 /* 0x0c, 0x09, 0x0e, 0x0f, 0x19, 0x05, 0x18, 0x17 */
1367 static struct hda_input_mux ad1981_capture_source = {
1368         .num_items = 7,
1369         .items = {
1370                 { "Front Mic", 0x0 },
1371                 { "Line", 0x1 },
1372                 { "Mix", 0x2 },
1373                 { "Mix Mono", 0x3 },
1374                 { "CD", 0x4 },
1375                 { "Mic", 0x6 },
1376                 { "Aux", 0x7 },
1377         },
1378 };
1379
1380 static struct snd_kcontrol_new ad1981_mixers[] = {
1381         HDA_CODEC_VOLUME("Front Playback Volume", 0x05, 0x0, HDA_OUTPUT),
1382         HDA_CODEC_MUTE("Front Playback Switch", 0x05, 0x0, HDA_OUTPUT),
1383         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x06, 0x0, HDA_OUTPUT),
1384         HDA_CODEC_MUTE("Headphone Playback Switch", 0x06, 0x0, HDA_OUTPUT),
1385         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x07, 1, 0x0, HDA_OUTPUT),
1386         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x07, 1, 0x0, HDA_OUTPUT),
1387         HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
1388         HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT),
1389         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
1390         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
1391         HDA_CODEC_VOLUME("Line Playback Volume", 0x13, 0x0, HDA_OUTPUT),
1392         HDA_CODEC_MUTE("Line Playback Switch", 0x13, 0x0, HDA_OUTPUT),
1393         HDA_CODEC_VOLUME("Aux Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
1394         HDA_CODEC_MUTE("Aux Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1395         HDA_CODEC_VOLUME("Mic Playback Volume", 0x1c, 0x0, HDA_OUTPUT),
1396         HDA_CODEC_MUTE("Mic Playback Switch", 0x1c, 0x0, HDA_OUTPUT),
1397         HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
1398         HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
1399         HDA_CODEC_VOLUME("Front Mic Boost", 0x08, 0x0, HDA_INPUT),
1400         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x0, HDA_INPUT),
1401         HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
1402         HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
1403         {
1404                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1405                 .name = "Capture Source",
1406                 .info = ad198x_mux_enum_info,
1407                 .get = ad198x_mux_enum_get,
1408                 .put = ad198x_mux_enum_put,
1409         },
1410         /* identical with AD1983 */
1411         {
1412                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1413                 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
1414                 .info = ad1983_spdif_route_info,
1415                 .get = ad1983_spdif_route_get,
1416                 .put = ad1983_spdif_route_put,
1417         },
1418         { } /* end */
1419 };
1420
1421 static struct hda_verb ad1981_init_verbs[] = {
1422         /* Front, HP, Mono; mute as default */
1423         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1424         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1425         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1426         /* Beep, PCM, Front Mic, Line, Rear Mic, Aux, CD-In: mute */
1427         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1428         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1429         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1430         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1431         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1432         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1433         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1434         /* Front, HP selectors; from Mix */
1435         {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
1436         {0x06, AC_VERB_SET_CONNECT_SEL, 0x01},
1437         /* Mono selector; from Mix */
1438         {0x0b, AC_VERB_SET_CONNECT_SEL, 0x03},
1439         /* Mic Mixer; select Front Mic */
1440         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1441         {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1442         /* Mic boost: 0dB */
1443         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1444         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1445         /* Record selector: Front mic */
1446         {0x15, AC_VERB_SET_CONNECT_SEL, 0x0},
1447         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1448         /* SPDIF route: PCM */
1449         {0x02, AC_VERB_SET_CONNECT_SEL, 0x0},
1450         /* Front Pin */
1451         {0x05, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
1452         /* HP Pin */
1453         {0x06, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
1454         /* Mono Pin */
1455         {0x07, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
1456         /* Front & Rear Mic Pins */
1457         {0x08, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
1458         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
1459         /* Line Pin */
1460         {0x09, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
1461         /* Digital Beep */
1462         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
1463         /* Line-Out as Input: disabled */
1464         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1465         { } /* end */
1466 };
1467
1468 #ifdef CONFIG_SND_HDA_POWER_SAVE
1469 static struct hda_amp_list ad1981_loopbacks[] = {
1470         { 0x12, HDA_OUTPUT, 0 }, /* Front Mic */
1471         { 0x13, HDA_OUTPUT, 0 }, /* Line */
1472         { 0x1b, HDA_OUTPUT, 0 }, /* Aux */
1473         { 0x1c, HDA_OUTPUT, 0 }, /* Mic */
1474         { 0x1d, HDA_OUTPUT, 0 }, /* CD */
1475         { } /* end */
1476 };
1477 #endif
1478
1479 /*
1480  * Patch for HP nx6320
1481  *
1482  * nx6320 uses EAPD in the reverse way - EAPD-on means the internal
1483  * speaker output enabled _and_ mute-LED off.
1484  */
1485
1486 #define AD1981_HP_EVENT         0x37
1487 #define AD1981_MIC_EVENT        0x38
1488
1489 static struct hda_verb ad1981_hp_init_verbs[] = {
1490         {0x05, AC_VERB_SET_EAPD_BTLENABLE, 0x00 }, /* default off */
1491         /* pin sensing on HP and Mic jacks */
1492         {0x06, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_HP_EVENT},
1493         {0x08, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_MIC_EVENT},
1494         {}
1495 };
1496
1497 /* turn on/off EAPD (+ mute HP) as a master switch */
1498 static int ad1981_hp_master_sw_put(struct snd_kcontrol *kcontrol,
1499                                    struct snd_ctl_elem_value *ucontrol)
1500 {
1501         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1502         struct ad198x_spec *spec = codec->spec;
1503
1504         if (! ad198x_eapd_put(kcontrol, ucontrol))
1505                 return 0;
1506         /* change speaker pin appropriately */
1507         snd_hda_codec_write(codec, 0x05, 0,
1508                             AC_VERB_SET_PIN_WIDGET_CONTROL,
1509                             spec->cur_eapd ? PIN_OUT : 0);
1510         /* toggle HP mute appropriately */
1511         snd_hda_codec_amp_stereo(codec, 0x06, HDA_OUTPUT, 0,
1512                                  HDA_AMP_MUTE,
1513                                  spec->cur_eapd ? 0 : HDA_AMP_MUTE);
1514         return 1;
1515 }
1516
1517 /* bind volumes of both NID 0x05 and 0x06 */
1518 static struct hda_bind_ctls ad1981_hp_bind_master_vol = {
1519         .ops = &snd_hda_bind_vol,
1520         .values = {
1521                 HDA_COMPOSE_AMP_VAL(0x05, 3, 0, HDA_OUTPUT),
1522                 HDA_COMPOSE_AMP_VAL(0x06, 3, 0, HDA_OUTPUT),
1523                 0
1524         },
1525 };
1526
1527 /* mute internal speaker if HP is plugged */
1528 static void ad1981_hp_automute(struct hda_codec *codec)
1529 {
1530         unsigned int present;
1531
1532         present = snd_hda_codec_read(codec, 0x06, 0,
1533                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1534         snd_hda_codec_amp_stereo(codec, 0x05, HDA_OUTPUT, 0,
1535                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
1536 }
1537
1538 /* toggle input of built-in and mic jack appropriately */
1539 static void ad1981_hp_automic(struct hda_codec *codec)
1540 {
1541         static struct hda_verb mic_jack_on[] = {
1542                 {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1543                 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1544                 {}
1545         };
1546         static struct hda_verb mic_jack_off[] = {
1547                 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1548                 {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1549                 {}
1550         };
1551         unsigned int present;
1552
1553         present = snd_hda_codec_read(codec, 0x08, 0,
1554                                  AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1555         if (present)
1556                 snd_hda_sequence_write(codec, mic_jack_on);
1557         else
1558                 snd_hda_sequence_write(codec, mic_jack_off);
1559 }
1560
1561 /* unsolicited event for HP jack sensing */
1562 static void ad1981_hp_unsol_event(struct hda_codec *codec,
1563                                   unsigned int res)
1564 {
1565         res >>= 26;
1566         switch (res) {
1567         case AD1981_HP_EVENT:
1568                 ad1981_hp_automute(codec);
1569                 break;
1570         case AD1981_MIC_EVENT:
1571                 ad1981_hp_automic(codec);
1572                 break;
1573         }
1574 }
1575
1576 static struct hda_input_mux ad1981_hp_capture_source = {
1577         .num_items = 3,
1578         .items = {
1579                 { "Mic", 0x0 },
1580                 { "Docking-Station", 0x1 },
1581                 { "Mix", 0x2 },
1582         },
1583 };
1584
1585 static struct snd_kcontrol_new ad1981_hp_mixers[] = {
1586         HDA_BIND_VOL("Master Playback Volume", &ad1981_hp_bind_master_vol),
1587         {
1588                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1589                 .name = "Master Playback Switch",
1590                 .info = ad198x_eapd_info,
1591                 .get = ad198x_eapd_get,
1592                 .put = ad1981_hp_master_sw_put,
1593                 .private_value = 0x05,
1594         },
1595         HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
1596         HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT),
1597 #if 0
1598         /* FIXME: analog mic/line loopback doesn't work with my tests...
1599          *        (although recording is OK)
1600          */
1601         HDA_CODEC_VOLUME("Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
1602         HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
1603         HDA_CODEC_VOLUME("Docking-Station Playback Volume", 0x13, 0x0, HDA_OUTPUT),
1604         HDA_CODEC_MUTE("Docking-Station Playback Switch", 0x13, 0x0, HDA_OUTPUT),
1605         HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x1c, 0x0, HDA_OUTPUT),
1606         HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x1c, 0x0, HDA_OUTPUT),
1607         /* FIXME: does this laptop have analog CD connection? */
1608         HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
1609         HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
1610 #endif
1611         HDA_CODEC_VOLUME("Mic Boost", 0x08, 0x0, HDA_INPUT),
1612         HDA_CODEC_VOLUME("Internal Mic Boost", 0x18, 0x0, HDA_INPUT),
1613         HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
1614         HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
1615         {
1616                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1617                 .name = "Capture Source",
1618                 .info = ad198x_mux_enum_info,
1619                 .get = ad198x_mux_enum_get,
1620                 .put = ad198x_mux_enum_put,
1621         },
1622         { } /* end */
1623 };
1624
1625 /* initialize jack-sensing, too */
1626 static int ad1981_hp_init(struct hda_codec *codec)
1627 {
1628         ad198x_init(codec);
1629         ad1981_hp_automute(codec);
1630         ad1981_hp_automic(codec);
1631         return 0;
1632 }
1633
1634 /* configuration for Toshiba Laptops */
1635 static struct hda_verb ad1981_toshiba_init_verbs[] = {
1636         {0x05, AC_VERB_SET_EAPD_BTLENABLE, 0x01 }, /* default on */
1637         /* pin sensing on HP and Mic jacks */
1638         {0x06, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_HP_EVENT},
1639         {0x08, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_MIC_EVENT},
1640         {}
1641 };
1642
1643 static struct snd_kcontrol_new ad1981_toshiba_mixers[] = {
1644         HDA_CODEC_VOLUME("Amp Volume", 0x1a, 0x0, HDA_OUTPUT),
1645         HDA_CODEC_MUTE("Amp Switch", 0x1a, 0x0, HDA_OUTPUT),
1646         { }
1647 };
1648
1649 /* configuration for Lenovo Thinkpad T60 */
1650 static struct snd_kcontrol_new ad1981_thinkpad_mixers[] = {
1651         HDA_CODEC_VOLUME("Master Playback Volume", 0x05, 0x0, HDA_OUTPUT),
1652         HDA_CODEC_MUTE("Master Playback Switch", 0x05, 0x0, HDA_OUTPUT),
1653         HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
1654         HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT),
1655         HDA_CODEC_VOLUME("Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
1656         HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
1657         HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
1658         HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
1659         HDA_CODEC_VOLUME("Mic Boost", 0x08, 0x0, HDA_INPUT),
1660         HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
1661         HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
1662         {
1663                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1664                 .name = "Capture Source",
1665                 .info = ad198x_mux_enum_info,
1666                 .get = ad198x_mux_enum_get,
1667                 .put = ad198x_mux_enum_put,
1668         },
1669         /* identical with AD1983 */
1670         {
1671                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1672                 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
1673                 .info = ad1983_spdif_route_info,
1674                 .get = ad1983_spdif_route_get,
1675                 .put = ad1983_spdif_route_put,
1676         },
1677         { } /* end */
1678 };
1679
1680 static struct hda_input_mux ad1981_thinkpad_capture_source = {
1681         .num_items = 3,
1682         .items = {
1683                 { "Mic", 0x0 },
1684                 { "Mix", 0x2 },
1685                 { "CD", 0x4 },
1686         },
1687 };
1688
1689 /* models */
1690 enum {
1691         AD1981_BASIC,
1692         AD1981_HP,
1693         AD1981_THINKPAD,
1694         AD1981_TOSHIBA,
1695         AD1981_MODELS
1696 };
1697
1698 static const char *ad1981_models[AD1981_MODELS] = {
1699         [AD1981_HP]             = "hp",
1700         [AD1981_THINKPAD]       = "thinkpad",
1701         [AD1981_BASIC]          = "basic",
1702         [AD1981_TOSHIBA]        = "toshiba"
1703 };
1704
1705 static struct snd_pci_quirk ad1981_cfg_tbl[] = {
1706         SND_PCI_QUIRK(0x1014, 0x0597, "Lenovo Z60", AD1981_THINKPAD),
1707         SND_PCI_QUIRK(0x1014, 0x05b7, "Lenovo Z60m", AD1981_THINKPAD),
1708         /* All HP models */
1709         SND_PCI_QUIRK(0x103c, 0, "HP nx", AD1981_HP),
1710         SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba U205", AD1981_TOSHIBA),
1711         /* Lenovo Thinkpad T60/X60/Z6xx */
1712         SND_PCI_QUIRK(0x17aa, 0, "Lenovo Thinkpad", AD1981_THINKPAD),
1713         /* HP nx6320 (reversed SSID, H/W bug) */
1714         SND_PCI_QUIRK(0x30b0, 0x103c, "HP nx6320", AD1981_HP),
1715         {}
1716 };
1717
1718 static int patch_ad1981(struct hda_codec *codec)
1719 {
1720         struct ad198x_spec *spec;
1721         int err, board_config;
1722
1723         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1724         if (spec == NULL)
1725                 return -ENOMEM;
1726
1727         codec->spec = spec;
1728
1729         err = snd_hda_attach_beep_device(codec, 0x10);
1730         if (err < 0) {
1731                 ad198x_free(codec);
1732                 return err;
1733         }
1734         set_beep_amp(spec, 0x0d, 0, HDA_OUTPUT);
1735
1736         spec->multiout.max_channels = 2;
1737         spec->multiout.num_dacs = ARRAY_SIZE(ad1981_dac_nids);
1738         spec->multiout.dac_nids = ad1981_dac_nids;
1739         spec->multiout.dig_out_nid = AD1981_SPDIF_OUT;
1740         spec->num_adc_nids = 1;
1741         spec->adc_nids = ad1981_adc_nids;
1742         spec->capsrc_nids = ad1981_capsrc_nids;
1743         spec->input_mux = &ad1981_capture_source;
1744         spec->num_mixers = 1;
1745         spec->mixers[0] = ad1981_mixers;
1746         spec->num_init_verbs = 1;
1747         spec->init_verbs[0] = ad1981_init_verbs;
1748         spec->spdif_route = 0;
1749 #ifdef CONFIG_SND_HDA_POWER_SAVE
1750         spec->loopback.amplist = ad1981_loopbacks;
1751 #endif
1752         spec->vmaster_nid = 0x05;
1753
1754         codec->patch_ops = ad198x_patch_ops;
1755
1756         /* override some parameters */
1757         board_config = snd_hda_check_board_config(codec, AD1981_MODELS,
1758                                                   ad1981_models,
1759                                                   ad1981_cfg_tbl);
1760         switch (board_config) {
1761         case AD1981_HP:
1762                 spec->mixers[0] = ad1981_hp_mixers;
1763                 spec->num_init_verbs = 2;
1764                 spec->init_verbs[1] = ad1981_hp_init_verbs;
1765                 spec->multiout.dig_out_nid = 0;
1766                 spec->input_mux = &ad1981_hp_capture_source;
1767
1768                 codec->patch_ops.init = ad1981_hp_init;
1769                 codec->patch_ops.unsol_event = ad1981_hp_unsol_event;
1770                 break;
1771         case AD1981_THINKPAD:
1772                 spec->mixers[0] = ad1981_thinkpad_mixers;
1773                 spec->input_mux = &ad1981_thinkpad_capture_source;
1774                 break;
1775         case AD1981_TOSHIBA:
1776                 spec->mixers[0] = ad1981_hp_mixers;
1777                 spec->mixers[1] = ad1981_toshiba_mixers;
1778                 spec->num_init_verbs = 2;
1779                 spec->init_verbs[1] = ad1981_toshiba_init_verbs;
1780                 spec->multiout.dig_out_nid = 0;
1781                 spec->input_mux = &ad1981_hp_capture_source;
1782                 codec->patch_ops.init = ad1981_hp_init;
1783                 codec->patch_ops.unsol_event = ad1981_hp_unsol_event;
1784                 break;
1785         }
1786         return 0;
1787 }
1788
1789
1790 /*
1791  * AD1988
1792  *
1793  * Output pins and routes
1794  *
1795  *        Pin               Mix     Sel     DAC (*)
1796  * port-A 0x11 (mute/hp) <- 0x22 <- 0x37 <- 03/04/06
1797  * port-B 0x14 (mute/hp) <- 0x2b <- 0x30 <- 03/04/06
1798  * port-C 0x15 (mute)    <- 0x2c <- 0x31 <- 05/0a
1799  * port-D 0x12 (mute/hp) <- 0x29         <- 04
1800  * port-E 0x17 (mute/hp) <- 0x26 <- 0x32 <- 05/0a
1801  * port-F 0x16 (mute)    <- 0x2a         <- 06
1802  * port-G 0x24 (mute)    <- 0x27         <- 05
1803  * port-H 0x25 (mute)    <- 0x28         <- 0a
1804  * mono   0x13 (mute/amp)<- 0x1e <- 0x36 <- 03/04/06
1805  *
1806  * DAC0 = 03h, DAC1 = 04h, DAC2 = 05h, DAC3 = 06h, DAC4 = 0ah
1807  * (*) DAC2/3/4 are swapped to DAC3/4/2 on AD198A rev.2 due to a h/w bug.
1808  *
1809  * Input pins and routes
1810  *
1811  *        pin     boost   mix input # / adc input #
1812  * port-A 0x11 -> 0x38 -> mix 2, ADC 0
1813  * port-B 0x14 -> 0x39 -> mix 0, ADC 1
1814  * port-C 0x15 -> 0x3a -> 33:0 - mix 1, ADC 2
1815  * port-D 0x12 -> 0x3d -> mix 3, ADC 8
1816  * port-E 0x17 -> 0x3c -> 34:0 - mix 4, ADC 4
1817  * port-F 0x16 -> 0x3b -> mix 5, ADC 3
1818  * port-G 0x24 -> N/A  -> 33:1 - mix 1, 34:1 - mix 4, ADC 6
1819  * port-H 0x25 -> N/A  -> 33:2 - mix 1, 34:2 - mix 4, ADC 7
1820  *
1821  *
1822  * DAC assignment
1823  *   6stack - front/surr/CLFE/side/opt DACs - 04/06/05/0a/03
1824  *   3stack - front/surr/CLFE/opt DACs - 04/05/0a/03
1825  *
1826  * Inputs of Analog Mix (0x20)
1827  *   0:Port-B (front mic)
1828  *   1:Port-C/G/H (line-in)
1829  *   2:Port-A
1830  *   3:Port-D (line-in/2)
1831  *   4:Port-E/G/H (mic-in)
1832  *   5:Port-F (mic2-in)
1833  *   6:CD
1834  *   7:Beep
1835  *
1836  * ADC selection
1837  *   0:Port-A
1838  *   1:Port-B (front mic-in)
1839  *   2:Port-C (line-in)
1840  *   3:Port-F (mic2-in)
1841  *   4:Port-E (mic-in)
1842  *   5:CD
1843  *   6:Port-G
1844  *   7:Port-H
1845  *   8:Port-D (line-in/2)
1846  *   9:Mix
1847  *
1848  * Proposed pin assignments by the datasheet
1849  *
1850  * 6-stack
1851  * Port-A front headphone
1852  *      B front mic-in
1853  *      C rear line-in
1854  *      D rear front-out
1855  *      E rear mic-in
1856  *      F rear surround
1857  *      G rear CLFE
1858  *      H rear side
1859  *
1860  * 3-stack
1861  * Port-A front headphone
1862  *      B front mic
1863  *      C rear line-in/surround
1864  *      D rear front-out
1865  *      E rear mic-in/CLFE
1866  *
1867  * laptop
1868  * Port-A headphone
1869  *      B mic-in
1870  *      C docking station
1871  *      D internal speaker (with EAPD)
1872  *      E/F quad mic array
1873  */
1874
1875
1876 /* models */
1877 enum {
1878         AD1988_6STACK,
1879         AD1988_6STACK_DIG,
1880         AD1988_3STACK,
1881         AD1988_3STACK_DIG,
1882         AD1988_LAPTOP,
1883         AD1988_LAPTOP_DIG,
1884         AD1988_AUTO,
1885         AD1988_MODEL_LAST,
1886 };
1887
1888 /* reivision id to check workarounds */
1889 #define AD1988A_REV2            0x100200
1890
1891 #define is_rev2(codec) \
1892         ((codec)->vendor_id == 0x11d41988 && \
1893          (codec)->revision_id == AD1988A_REV2)
1894
1895 /*
1896  * mixers
1897  */
1898
1899 static hda_nid_t ad1988_6stack_dac_nids[4] = {
1900         0x04, 0x06, 0x05, 0x0a
1901 };
1902
1903 static hda_nid_t ad1988_3stack_dac_nids[3] = {
1904         0x04, 0x05, 0x0a
1905 };
1906
1907 /* for AD1988A revision-2, DAC2-4 are swapped */
1908 static hda_nid_t ad1988_6stack_dac_nids_rev2[4] = {
1909         0x04, 0x05, 0x0a, 0x06
1910 };
1911
1912 static hda_nid_t ad1988_3stack_dac_nids_rev2[3] = {
1913         0x04, 0x0a, 0x06
1914 };
1915
1916 static hda_nid_t ad1988_adc_nids[3] = {
1917         0x08, 0x09, 0x0f
1918 };
1919
1920 static hda_nid_t ad1988_capsrc_nids[3] = {
1921         0x0c, 0x0d, 0x0e
1922 };
1923
1924 #define AD1988_SPDIF_OUT                0x02
1925 #define AD1988_SPDIF_OUT_HDMI   0x0b
1926 #define AD1988_SPDIF_IN         0x07
1927
1928 static hda_nid_t ad1989b_slave_dig_outs[2] = {
1929         AD1988_SPDIF_OUT, AD1988_SPDIF_OUT_HDMI
1930 };
1931
1932 static struct hda_input_mux ad1988_6stack_capture_source = {
1933         .num_items = 5,
1934         .items = {
1935                 { "Front Mic", 0x1 },   /* port-B */
1936                 { "Line", 0x2 },        /* port-C */
1937                 { "Mic", 0x4 },         /* port-E */
1938                 { "CD", 0x5 },
1939                 { "Mix", 0x9 },
1940         },
1941 };
1942
1943 static struct hda_input_mux ad1988_laptop_capture_source = {
1944         .num_items = 3,
1945         .items = {
1946                 { "Mic/Line", 0x1 },    /* port-B */
1947                 { "CD", 0x5 },
1948                 { "Mix", 0x9 },
1949         },
1950 };
1951
1952 /*
1953  */
1954 static int ad198x_ch_mode_info(struct snd_kcontrol *kcontrol,
1955                                struct snd_ctl_elem_info *uinfo)
1956 {
1957         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1958         struct ad198x_spec *spec = codec->spec;
1959         return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
1960                                     spec->num_channel_mode);
1961 }
1962
1963 static int ad198x_ch_mode_get(struct snd_kcontrol *kcontrol,
1964                               struct snd_ctl_elem_value *ucontrol)
1965 {
1966         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1967         struct ad198x_spec *spec = codec->spec;
1968         return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
1969                                    spec->num_channel_mode, spec->multiout.max_channels);
1970 }
1971
1972 static int ad198x_ch_mode_put(struct snd_kcontrol *kcontrol,
1973                               struct snd_ctl_elem_value *ucontrol)
1974 {
1975         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1976         struct ad198x_spec *spec = codec->spec;
1977         int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
1978                                       spec->num_channel_mode,
1979                                       &spec->multiout.max_channels);
1980         if (err >= 0 && spec->need_dac_fix)
1981                 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
1982         return err;
1983 }
1984
1985 /* 6-stack mode */
1986 static struct snd_kcontrol_new ad1988_6stack_mixers1[] = {
1987         HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
1988         HDA_CODEC_VOLUME("Surround Playback Volume", 0x06, 0x0, HDA_OUTPUT),
1989         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT),
1990         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT),
1991         HDA_CODEC_VOLUME("Side Playback Volume", 0x0a, 0x0, HDA_OUTPUT),
1992         { } /* end */
1993 };
1994
1995 static struct snd_kcontrol_new ad1988_6stack_mixers1_rev2[] = {
1996         HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
1997         HDA_CODEC_VOLUME("Surround Playback Volume", 0x05, 0x0, HDA_OUTPUT),
1998         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
1999         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0a, 2, 0x0, HDA_OUTPUT),
2000         HDA_CODEC_VOLUME("Side Playback Volume", 0x06, 0x0, HDA_OUTPUT),
2001         { } /* end */
2002 };
2003
2004 static struct snd_kcontrol_new ad1988_6stack_mixers2[] = {
2005         HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT),
2006         HDA_BIND_MUTE("Surround Playback Switch", 0x2a, 2, HDA_INPUT),
2007         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x27, 1, 2, HDA_INPUT),
2008         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x27, 2, 2, HDA_INPUT),
2009         HDA_BIND_MUTE("Side Playback Switch", 0x28, 2, HDA_INPUT),
2010         HDA_BIND_MUTE("Headphone Playback Switch", 0x22, 2, HDA_INPUT),
2011         HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT),
2012
2013         HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x6, HDA_INPUT),
2014         HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x6, HDA_INPUT),
2015         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x0, HDA_INPUT),
2016         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x0, HDA_INPUT),
2017         HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT),
2018         HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT),
2019         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x4, HDA_INPUT),
2020         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x4, HDA_INPUT),
2021
2022         HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT),
2023         HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT),
2024
2025         HDA_CODEC_VOLUME("Front Mic Boost", 0x39, 0x0, HDA_OUTPUT),
2026         HDA_CODEC_VOLUME("Mic Boost", 0x3c, 0x0, HDA_OUTPUT),
2027
2028         { } /* end */
2029 };
2030
2031 /* 3-stack mode */
2032 static struct snd_kcontrol_new ad1988_3stack_mixers1[] = {
2033         HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
2034         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0a, 0x0, HDA_OUTPUT),
2035         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT),
2036         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT),
2037         { } /* end */
2038 };
2039
2040 static struct snd_kcontrol_new ad1988_3stack_mixers1_rev2[] = {
2041         HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
2042         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0a, 0x0, HDA_OUTPUT),
2043         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x06, 1, 0x0, HDA_OUTPUT),
2044         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x06, 2, 0x0, HDA_OUTPUT),
2045         { } /* end */
2046 };
2047
2048 static struct snd_kcontrol_new ad1988_3stack_mixers2[] = {
2049         HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT),
2050         HDA_BIND_MUTE("Surround Playback Switch", 0x2c, 2, HDA_INPUT),
2051         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x26, 1, 2, HDA_INPUT),
2052         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x26, 2, 2, HDA_INPUT),
2053         HDA_BIND_MUTE("Headphone Playback Switch", 0x22, 2, HDA_INPUT),
2054         HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT),
2055
2056         HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x6, HDA_INPUT),
2057         HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x6, HDA_INPUT),
2058         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x0, HDA_INPUT),
2059         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x0, HDA_INPUT),
2060         HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT),
2061         HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT),
2062         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x4, HDA_INPUT),
2063         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x4, HDA_INPUT),
2064
2065         HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT),
2066         HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT),
2067
2068         HDA_CODEC_VOLUME("Front Mic Boost", 0x39, 0x0, HDA_OUTPUT),
2069         HDA_CODEC_VOLUME("Mic Boost", 0x3c, 0x0, HDA_OUTPUT),
2070         {
2071                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2072                 .name = "Channel Mode",
2073                 .info = ad198x_ch_mode_info,
2074                 .get = ad198x_ch_mode_get,
2075                 .put = ad198x_ch_mode_put,
2076         },
2077
2078         { } /* end */
2079 };
2080
2081 /* laptop mode */
2082 static struct snd_kcontrol_new ad1988_laptop_mixers[] = {
2083         HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
2084         HDA_CODEC_MUTE("PCM Playback Switch", 0x29, 0x0, HDA_INPUT),
2085         HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT),
2086
2087         HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x6, HDA_INPUT),
2088         HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x6, HDA_INPUT),
2089         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x0, HDA_INPUT),
2090         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x0, HDA_INPUT),
2091         HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT),
2092         HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT),
2093
2094         HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT),
2095         HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT),
2096
2097         HDA_CODEC_VOLUME("Mic Boost", 0x39, 0x0, HDA_OUTPUT),
2098
2099         {
2100                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2101                 .name = "External Amplifier",
2102                 .info = ad198x_eapd_info,
2103                 .get = ad198x_eapd_get,
2104                 .put = ad198x_eapd_put,
2105                 .private_value = 0x12 | (1 << 8), /* port-D, inversed */
2106         },
2107
2108         { } /* end */
2109 };
2110
2111 /* capture */
2112 static struct snd_kcontrol_new ad1988_capture_mixers[] = {
2113         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
2114         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
2115         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
2116         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
2117         HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x0e, 0x0, HDA_OUTPUT),
2118         HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x0e, 0x0, HDA_OUTPUT),
2119         {
2120                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2121                 /* The multiple "Capture Source" controls confuse alsamixer
2122                  * So call somewhat different..
2123                  */
2124                 /* .name = "Capture Source", */
2125                 .name = "Input Source",
2126                 .count = 3,
2127                 .info = ad198x_mux_enum_info,
2128                 .get = ad198x_mux_enum_get,
2129                 .put = ad198x_mux_enum_put,
2130         },
2131         { } /* end */
2132 };
2133
2134 static int ad1988_spdif_playback_source_info(struct snd_kcontrol *kcontrol,
2135                                              struct snd_ctl_elem_info *uinfo)
2136 {
2137         static char *texts[] = {
2138                 "PCM", "ADC1", "ADC2", "ADC3"
2139         };
2140         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2141         uinfo->count = 1;
2142         uinfo->value.enumerated.items = 4;
2143         if (uinfo->value.enumerated.item >= 4)
2144                 uinfo->value.enumerated.item = 3;
2145         strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2146         return 0;
2147 }
2148
2149 static int ad1988_spdif_playback_source_get(struct snd_kcontrol *kcontrol,
2150                                             struct snd_ctl_elem_value *ucontrol)
2151 {
2152         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2153         unsigned int sel;
2154
2155         sel = snd_hda_codec_read(codec, 0x1d, 0, AC_VERB_GET_AMP_GAIN_MUTE,
2156                                  AC_AMP_GET_INPUT);
2157         if (!(sel & 0x80))
2158                 ucontrol->value.enumerated.item[0] = 0;
2159         else {
2160                 sel = snd_hda_codec_read(codec, 0x0b, 0,
2161                                          AC_VERB_GET_CONNECT_SEL, 0);
2162                 if (sel < 3)
2163                         sel++;
2164                 else
2165                         sel = 0;
2166                 ucontrol->value.enumerated.item[0] = sel;
2167         }
2168         return 0;
2169 }
2170
2171 static int ad1988_spdif_playback_source_put(struct snd_kcontrol *kcontrol,
2172                                             struct snd_ctl_elem_value *ucontrol)
2173 {
2174         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2175         unsigned int val, sel;
2176         int change;
2177
2178         val = ucontrol->value.enumerated.item[0];
2179         if (val > 3)
2180                 return -EINVAL;
2181         if (!val) {
2182                 sel = snd_hda_codec_read(codec, 0x1d, 0,
2183                                          AC_VERB_GET_AMP_GAIN_MUTE,
2184                                          AC_AMP_GET_INPUT);
2185                 change = sel & 0x80;
2186                 if (change) {
2187                         snd_hda_codec_write_cache(codec, 0x1d, 0,
2188                                                   AC_VERB_SET_AMP_GAIN_MUTE,
2189                                                   AMP_IN_UNMUTE(0));
2190                         snd_hda_codec_write_cache(codec, 0x1d, 0,
2191                                                   AC_VERB_SET_AMP_GAIN_MUTE,
2192                                                   AMP_IN_MUTE(1));
2193                 }
2194         } else {
2195                 sel = snd_hda_codec_read(codec, 0x1d, 0,
2196                                          AC_VERB_GET_AMP_GAIN_MUTE,
2197                                          AC_AMP_GET_INPUT | 0x01);
2198                 change = sel & 0x80;
2199                 if (change) {
2200                         snd_hda_codec_write_cache(codec, 0x1d, 0,
2201                                                   AC_VERB_SET_AMP_GAIN_MUTE,
2202                                                   AMP_IN_MUTE(0));
2203                         snd_hda_codec_write_cache(codec, 0x1d, 0,
2204                                                   AC_VERB_SET_AMP_GAIN_MUTE,
2205                                                   AMP_IN_UNMUTE(1));
2206                 }
2207                 sel = snd_hda_codec_read(codec, 0x0b, 0,
2208                                          AC_VERB_GET_CONNECT_SEL, 0) + 1;
2209                 change |= sel != val;
2210                 if (change)
2211                         snd_hda_codec_write_cache(codec, 0x0b, 0,
2212                                                   AC_VERB_SET_CONNECT_SEL,
2213                                                   val - 1);
2214         }
2215         return change;
2216 }
2217
2218 static struct snd_kcontrol_new ad1988_spdif_out_mixers[] = {
2219         HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
2220         {
2221                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2222                 .name = "IEC958 Playback Source",
2223                 .info = ad1988_spdif_playback_source_info,
2224                 .get = ad1988_spdif_playback_source_get,
2225                 .put = ad1988_spdif_playback_source_put,
2226         },
2227         { } /* end */
2228 };
2229
2230 static struct snd_kcontrol_new ad1988_spdif_in_mixers[] = {
2231         HDA_CODEC_VOLUME("IEC958 Capture Volume", 0x1c, 0x0, HDA_INPUT),
2232         { } /* end */
2233 };
2234
2235 static struct snd_kcontrol_new ad1989_spdif_out_mixers[] = {
2236         HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
2237         HDA_CODEC_VOLUME("HDMI Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
2238         { } /* end */
2239 };
2240
2241 /*
2242  * initialization verbs
2243  */
2244
2245 /*
2246  * for 6-stack (+dig)
2247  */
2248 static struct hda_verb ad1988_6stack_init_verbs[] = {
2249         /* Front, Surround, CLFE, side DAC; unmute as default */
2250         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2251         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2252         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2253         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2254         /* Port-A front headphon path */
2255         {0x37, AC_VERB_SET_CONNECT_SEL, 0x01}, /* DAC1:04h */
2256         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2257         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2258         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2259         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2260         /* Port-D line-out path */
2261         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2262         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2263         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2264         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2265         /* Port-F surround path */
2266         {0x2a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2267         {0x2a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2268         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2269         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2270         /* Port-G CLFE path */
2271         {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2272         {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2273         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2274         {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2275         /* Port-H side path */
2276         {0x28, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2277         {0x28, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2278         {0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2279         {0x25, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2280         /* Mono out path */
2281         {0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */
2282         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2283         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2284         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2285         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */
2286         /* Port-B front mic-in path */
2287         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2288         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2289         {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2290         /* Port-C line-in path */
2291         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2292         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2293         {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2294         {0x33, AC_VERB_SET_CONNECT_SEL, 0x0},
2295         /* Port-E mic-in path */
2296         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2297         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2298         {0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2299         {0x34, AC_VERB_SET_CONNECT_SEL, 0x0},
2300         /* Analog CD Input */
2301         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2302         /* Analog Mix output amp */
2303         {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
2304
2305         { }
2306 };
2307
2308 static struct hda_verb ad1988_capture_init_verbs[] = {
2309         /* mute analog mix */
2310         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2311         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2312         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2313         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2314         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2315         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
2316         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2317         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2318         /* select ADCs - front-mic */
2319         {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1},
2320         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x1},
2321         {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
2322
2323         { }
2324 };
2325
2326 static struct hda_verb ad1988_spdif_init_verbs[] = {
2327         /* SPDIF out sel */
2328         {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */
2329         {0x0b, AC_VERB_SET_CONNECT_SEL, 0x0}, /* ADC1 */
2330         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2331         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2332         /* SPDIF out pin */
2333         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
2334
2335         { }
2336 };
2337
2338 /* AD1989 has no ADC -> SPDIF route */
2339 static struct hda_verb ad1989_spdif_init_verbs[] = {
2340         /* SPDIF-1 out pin */
2341         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2342         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
2343         /* SPDIF-2/HDMI out pin */
2344         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2345         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
2346         { }
2347 };
2348
2349 /*
2350  * verbs for 3stack (+dig)
2351  */
2352 static struct hda_verb ad1988_3stack_ch2_init[] = {
2353         /* set port-C to line-in */
2354         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2355         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2356         /* set port-E to mic-in */
2357         { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2358         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2359         { } /* end */
2360 };
2361
2362 static struct hda_verb ad1988_3stack_ch6_init[] = {
2363         /* set port-C to surround out */
2364         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2365         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2366         /* set port-E to CLFE out */
2367         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2368         { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2369         { } /* end */
2370 };
2371
2372 static struct hda_channel_mode ad1988_3stack_modes[2] = {
2373         { 2, ad1988_3stack_ch2_init },
2374         { 6, ad1988_3stack_ch6_init },
2375 };
2376
2377 static struct hda_verb ad1988_3stack_init_verbs[] = {
2378         /* Front, Surround, CLFE, side DAC; unmute as default */
2379         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2380         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2381         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2382         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2383         /* Port-A front headphon path */
2384         {0x37, AC_VERB_SET_CONNECT_SEL, 0x01}, /* DAC1:04h */
2385         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2386         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2387         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2388         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2389         /* Port-D line-out path */
2390         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2391         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2392         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2393         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2394         /* Mono out path */
2395         {0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */
2396         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2397         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2398         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2399         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */
2400         /* Port-B front mic-in path */
2401         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2402         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2403         {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2404         /* Port-C line-in/surround path - 6ch mode as default */
2405         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2406         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2407         {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2408         {0x31, AC_VERB_SET_CONNECT_SEL, 0x0}, /* output sel: DAC 0x05 */
2409         {0x33, AC_VERB_SET_CONNECT_SEL, 0x0},
2410         /* Port-E mic-in/CLFE path - 6ch mode as default */
2411         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2412         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2413         {0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2414         {0x32, AC_VERB_SET_CONNECT_SEL, 0x1}, /* output sel: DAC 0x0a */
2415         {0x34, AC_VERB_SET_CONNECT_SEL, 0x0},
2416         /* mute analog mix */
2417         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2418         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2419         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2420         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2421         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2422         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
2423         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2424         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2425         /* select ADCs - front-mic */
2426         {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1},
2427         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x1},
2428         {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
2429         /* Analog Mix output amp */
2430         {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
2431         { }
2432 };
2433
2434 /*
2435  * verbs for laptop mode (+dig)
2436  */
2437 static struct hda_verb ad1988_laptop_hp_on[] = {
2438         /* unmute port-A and mute port-D */
2439         { 0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2440         { 0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2441         { } /* end */
2442 };
2443 static struct hda_verb ad1988_laptop_hp_off[] = {
2444         /* mute port-A and unmute port-D */
2445         { 0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2446         { 0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2447         { } /* end */
2448 };
2449
2450 #define AD1988_HP_EVENT 0x01
2451
2452 static struct hda_verb ad1988_laptop_init_verbs[] = {
2453         /* Front, Surround, CLFE, side DAC; unmute as default */
2454         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2455         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2456         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2457         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2458         /* Port-A front headphon path */
2459         {0x37, AC_VERB_SET_CONNECT_SEL, 0x01}, /* DAC1:04h */
2460         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2461         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2462         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2463         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2464         /* unsolicited event for pin-sense */
2465         {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1988_HP_EVENT },
2466         /* Port-D line-out path + EAPD */
2467         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2468         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2469         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2470         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2471         {0x12, AC_VERB_SET_EAPD_BTLENABLE, 0x00}, /* EAPD-off */
2472         /* Mono out path */
2473         {0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */
2474         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2475         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2476         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2477         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */
2478         /* Port-B mic-in path */
2479         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2480         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2481         {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2482         /* Port-C docking station - try to output */
2483         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2484         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2485         {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2486         {0x33, AC_VERB_SET_CONNECT_SEL, 0x0},
2487         /* mute analog mix */
2488         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2489         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2490         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2491         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2492         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2493         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
2494         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2495         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2496         /* select ADCs - mic */
2497         {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1},
2498         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x1},
2499         {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
2500         /* Analog Mix output amp */
2501         {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
2502         { }
2503 };
2504
2505 static void ad1988_laptop_unsol_event(struct hda_codec *codec, unsigned int res)
2506 {
2507         if ((res >> 26) != AD1988_HP_EVENT)
2508                 return;
2509         if (snd_hda_codec_read(codec, 0x11, 0, AC_VERB_GET_PIN_SENSE, 0) & (1 << 31))
2510                 snd_hda_sequence_write(codec, ad1988_laptop_hp_on);
2511         else
2512                 snd_hda_sequence_write(codec, ad1988_laptop_hp_off);
2513
2514
2515 #ifdef CONFIG_SND_HDA_POWER_SAVE
2516 static struct hda_amp_list ad1988_loopbacks[] = {
2517         { 0x20, HDA_INPUT, 0 }, /* Front Mic */
2518         { 0x20, HDA_INPUT, 1 }, /* Line */
2519         { 0x20, HDA_INPUT, 4 }, /* Mic */
2520         { 0x20, HDA_INPUT, 6 }, /* CD */
2521         { } /* end */
2522 };
2523 #endif
2524
2525 /*
2526  * Automatic parse of I/O pins from the BIOS configuration
2527  */
2528
2529 enum {
2530         AD_CTL_WIDGET_VOL,
2531         AD_CTL_WIDGET_MUTE,
2532         AD_CTL_BIND_MUTE,
2533 };
2534 static struct snd_kcontrol_new ad1988_control_templates[] = {
2535         HDA_CODEC_VOLUME(NULL, 0, 0, 0),
2536         HDA_CODEC_MUTE(NULL, 0, 0, 0),
2537         HDA_BIND_MUTE(NULL, 0, 0, 0),
2538 };
2539
2540 /* add dynamic controls */
2541 static int add_control(struct ad198x_spec *spec, int type, const char *name,
2542                        unsigned long val)
2543 {
2544         struct snd_kcontrol_new *knew;
2545
2546         snd_array_init(&spec->kctls, sizeof(*knew), 32);
2547         knew = snd_array_new(&spec->kctls);
2548         if (!knew)
2549                 return -ENOMEM;
2550         *knew = ad1988_control_templates[type];
2551         knew->name = kstrdup(name, GFP_KERNEL);
2552         if (! knew->name)
2553                 return -ENOMEM;
2554         knew->private_value = val;
2555         return 0;
2556 }
2557
2558 #define AD1988_PIN_CD_NID               0x18
2559 #define AD1988_PIN_BEEP_NID             0x10
2560
2561 static hda_nid_t ad1988_mixer_nids[8] = {
2562         /* A     B     C     D     E     F     G     H */
2563         0x22, 0x2b, 0x2c, 0x29, 0x26, 0x2a, 0x27, 0x28
2564 };
2565
2566 static inline hda_nid_t ad1988_idx_to_dac(struct hda_codec *codec, int idx)
2567 {
2568         static hda_nid_t idx_to_dac[8] = {
2569                 /* A     B     C     D     E     F     G     H */
2570                 0x04, 0x06, 0x05, 0x04, 0x0a, 0x06, 0x05, 0x0a
2571         };
2572         static hda_nid_t idx_to_dac_rev2[8] = {
2573                 /* A     B     C     D     E     F     G     H */
2574                 0x04, 0x05, 0x0a, 0x04, 0x06, 0x05, 0x0a, 0x06
2575         };
2576         if (is_rev2(codec))
2577                 return idx_to_dac_rev2[idx];
2578         else
2579                 return idx_to_dac[idx];
2580 }
2581
2582 static hda_nid_t ad1988_boost_nids[8] = {
2583         0x38, 0x39, 0x3a, 0x3d, 0x3c, 0x3b, 0, 0
2584 };
2585
2586 static int ad1988_pin_idx(hda_nid_t nid)
2587 {
2588         static hda_nid_t ad1988_io_pins[8] = {
2589                 0x11, 0x14, 0x15, 0x12, 0x17, 0x16, 0x24, 0x25
2590         };
2591         int i;
2592         for (i = 0; i < ARRAY_SIZE(ad1988_io_pins); i++)
2593                 if (ad1988_io_pins[i] == nid)
2594                         return i;
2595         return 0; /* should be -1 */
2596 }
2597
2598 static int ad1988_pin_to_loopback_idx(hda_nid_t nid)
2599 {
2600         static int loopback_idx[8] = {
2601                 2, 0, 1, 3, 4, 5, 1, 4
2602         };
2603         switch (nid) {
2604         case AD1988_PIN_CD_NID:
2605                 return 6;
2606         default:
2607                 return loopback_idx[ad1988_pin_idx(nid)];
2608         }
2609 }
2610
2611 static int ad1988_pin_to_adc_idx(hda_nid_t nid)
2612 {
2613         static int adc_idx[8] = {
2614                 0, 1, 2, 8, 4, 3, 6, 7
2615         };
2616         switch (nid) {
2617         case AD1988_PIN_CD_NID:
2618                 return 5;
2619         default:
2620                 return adc_idx[ad1988_pin_idx(nid)];
2621         }
2622 }
2623
2624 /* fill in the dac_nids table from the parsed pin configuration */
2625 static int ad1988_auto_fill_dac_nids(struct hda_codec *codec,
2626                                      const struct auto_pin_cfg *cfg)
2627 {
2628         struct ad198x_spec *spec = codec->spec;
2629         int i, idx;
2630
2631         spec->multiout.dac_nids = spec->private_dac_nids;
2632
2633         /* check the pins hardwired to audio widget */
2634         for (i = 0; i < cfg->line_outs; i++) {
2635                 idx = ad1988_pin_idx(cfg->line_out_pins[i]);
2636                 spec->multiout.dac_nids[i] = ad1988_idx_to_dac(codec, idx);
2637         }
2638         spec->multiout.num_dacs = cfg->line_outs;
2639         return 0;
2640 }
2641
2642 /* add playback controls from the parsed DAC table */
2643 static int ad1988_auto_create_multi_out_ctls(struct ad198x_spec *spec,
2644                                              const struct auto_pin_cfg *cfg)
2645 {
2646         char name[32];
2647         static const char *chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" };
2648         hda_nid_t nid;
2649         int i, err;
2650
2651         for (i = 0; i < cfg->line_outs; i++) {
2652                 hda_nid_t dac = spec->multiout.dac_nids[i];
2653                 if (! dac)
2654                         continue;
2655                 nid = ad1988_mixer_nids[ad1988_pin_idx(cfg->line_out_pins[i])];
2656                 if (i == 2) {
2657                         /* Center/LFE */
2658                         err = add_control(spec, AD_CTL_WIDGET_VOL,
2659                                           "Center Playback Volume",
2660                                           HDA_COMPOSE_AMP_VAL(dac, 1, 0, HDA_OUTPUT));
2661                         if (err < 0)
2662                                 return err;
2663                         err = add_control(spec, AD_CTL_WIDGET_VOL,
2664                                           "LFE Playback Volume",
2665                                           HDA_COMPOSE_AMP_VAL(dac, 2, 0, HDA_OUTPUT));
2666                         if (err < 0)
2667                                 return err;
2668                         err = add_control(spec, AD_CTL_BIND_MUTE,
2669                                           "Center Playback Switch",
2670                                           HDA_COMPOSE_AMP_VAL(nid, 1, 2, HDA_INPUT));
2671                         if (err < 0)
2672                                 return err;
2673                         err = add_control(spec, AD_CTL_BIND_MUTE,
2674                                           "LFE Playback Switch",
2675                                           HDA_COMPOSE_AMP_VAL(nid, 2, 2, HDA_INPUT));
2676                         if (err < 0)
2677                                 return err;
2678                 } else {
2679                         sprintf(name, "%s Playback Volume", chname[i]);
2680                         err = add_control(spec, AD_CTL_WIDGET_VOL, name,
2681                                           HDA_COMPOSE_AMP_VAL(dac, 3, 0, HDA_OUTPUT));
2682                         if (err < 0)
2683                                 return err;
2684                         sprintf(name, "%s Playback Switch", chname[i]);
2685                         err = add_control(spec, AD_CTL_BIND_MUTE, name,
2686                                           HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
2687                         if (err < 0)
2688                                 return err;
2689                 }
2690         }
2691         return 0;
2692 }
2693
2694 /* add playback controls for speaker and HP outputs */
2695 static int ad1988_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
2696                                         const char *pfx)
2697 {
2698         struct ad198x_spec *spec = codec->spec;
2699         hda_nid_t nid;
2700         int i, idx, err;
2701         char name[32];
2702
2703         if (! pin)
2704                 return 0;
2705
2706         idx = ad1988_pin_idx(pin);
2707         nid = ad1988_idx_to_dac(codec, idx);
2708         /* check whether the corresponding DAC was already taken */
2709         for (i = 0; i < spec->autocfg.line_outs; i++) {
2710                 hda_nid_t pin = spec->autocfg.line_out_pins[i];
2711                 hda_nid_t dac = ad1988_idx_to_dac(codec, ad1988_pin_idx(pin));
2712                 if (dac == nid)
2713                         break;
2714         }
2715         if (i >= spec->autocfg.line_outs) {
2716                 /* specify the DAC as the extra output */
2717                 if (!spec->multiout.hp_nid)
2718                         spec->multiout.hp_nid = nid;
2719                 else
2720                         spec->multiout.extra_out_nid[0] = nid;
2721                 /* control HP volume/switch on the output mixer amp */
2722                 sprintf(name, "%s Playback Volume", pfx);
2723                 err = add_control(spec, AD_CTL_WIDGET_VOL, name,
2724                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
2725                 if (err < 0)
2726                         return err;
2727         }
2728         nid = ad1988_mixer_nids[idx];
2729         sprintf(name, "%s Playback Switch", pfx);
2730         if ((err = add_control(spec, AD_CTL_BIND_MUTE, name,
2731                                HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT))) < 0)
2732                 return err;
2733         return 0;
2734 }
2735
2736 /* create input playback/capture controls for the given pin */
2737 static int new_analog_input(struct ad198x_spec *spec, hda_nid_t pin,
2738                             const char *ctlname, int boost)
2739 {
2740         char name[32];
2741         int err, idx;
2742
2743         sprintf(name, "%s Playback Volume", ctlname);
2744         idx = ad1988_pin_to_loopback_idx(pin);
2745         if ((err = add_control(spec, AD_CTL_WIDGET_VOL, name,
2746                                HDA_COMPOSE_AMP_VAL(0x20, 3, idx, HDA_INPUT))) < 0)
2747                 return err;
2748         sprintf(name, "%s Playback Switch", ctlname);
2749         if ((err = add_control(spec, AD_CTL_WIDGET_MUTE, name,
2750                                HDA_COMPOSE_AMP_VAL(0x20, 3, idx, HDA_INPUT))) < 0)
2751                 return err;
2752         if (boost) {
2753                 hda_nid_t bnid;
2754                 idx = ad1988_pin_idx(pin);
2755                 bnid = ad1988_boost_nids[idx];
2756                 if (bnid) {
2757                         sprintf(name, "%s Boost", ctlname);
2758                         return add_control(spec, AD_CTL_WIDGET_VOL, name,
2759                                            HDA_COMPOSE_AMP_VAL(bnid, 3, idx, HDA_OUTPUT));
2760
2761                 }
2762         }
2763         return 0;
2764 }
2765
2766 /* create playback/capture controls for input pins */
2767 static int ad1988_auto_create_analog_input_ctls(struct ad198x_spec *spec,
2768                                                 const struct auto_pin_cfg *cfg)
2769 {
2770         struct hda_input_mux *imux = &spec->private_imux;
2771         int i, err;
2772
2773         for (i = 0; i < AUTO_PIN_LAST; i++) {
2774                 err = new_analog_input(spec, cfg->input_pins[i],
2775                                        auto_pin_cfg_labels[i],
2776                                        i <= AUTO_PIN_FRONT_MIC);
2777                 if (err < 0)
2778                         return err;
2779                 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
2780                 imux->items[imux->num_items].index = ad1988_pin_to_adc_idx(cfg->input_pins[i]);
2781                 imux->num_items++;
2782         }
2783         imux->items[imux->num_items].label = "Mix";
2784         imux->items[imux->num_items].index = 9;
2785         imux->num_items++;
2786
2787         if ((err = add_control(spec, AD_CTL_WIDGET_VOL,
2788                                "Analog Mix Playback Volume",
2789                                HDA_COMPOSE_AMP_VAL(0x21, 3, 0x0, HDA_OUTPUT))) < 0)
2790                 return err;
2791         if ((err = add_control(spec, AD_CTL_WIDGET_MUTE,
2792                                "Analog Mix Playback Switch",
2793                                HDA_COMPOSE_AMP_VAL(0x21, 3, 0x0, HDA_OUTPUT))) < 0)
2794                 return err;
2795
2796         return 0;
2797 }
2798
2799 static void ad1988_auto_set_output_and_unmute(struct hda_codec *codec,
2800                                               hda_nid_t nid, int pin_type,
2801                                               int dac_idx)
2802 {
2803         /* set as output */
2804         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
2805         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
2806         switch (nid) {
2807         case 0x11: /* port-A - DAC 04 */
2808                 snd_hda_codec_write(codec, 0x37, 0, AC_VERB_SET_CONNECT_SEL, 0x01);
2809                 break;
2810         case 0x14: /* port-B - DAC 06 */
2811                 snd_hda_codec_write(codec, 0x30, 0, AC_VERB_SET_CONNECT_SEL, 0x02);
2812                 break;
2813         case 0x15: /* port-C - DAC 05 */
2814                 snd_hda_codec_write(codec, 0x31, 0, AC_VERB_SET_CONNECT_SEL, 0x00);
2815                 break;
2816         case 0x17: /* port-E - DAC 0a */
2817                 snd_hda_codec_write(codec, 0x32, 0, AC_VERB_SET_CONNECT_SEL, 0x01);
2818                 break;
2819         case 0x13: /* mono - DAC 04 */
2820                 snd_hda_codec_write(codec, 0x36, 0, AC_VERB_SET_CONNECT_SEL, 0x01);
2821                 break;
2822         }
2823 }
2824
2825 static void ad1988_auto_init_multi_out(struct hda_codec *codec)
2826 {
2827         struct ad198x_spec *spec = codec->spec;
2828         int i;
2829
2830         for (i = 0; i < spec->autocfg.line_outs; i++) {
2831                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
2832                 ad1988_auto_set_output_and_unmute(codec, nid, PIN_OUT, i);
2833         }
2834 }
2835
2836 static void ad1988_auto_init_extra_out(struct hda_codec *codec)
2837 {
2838         struct ad198x_spec *spec = codec->spec;
2839         hda_nid_t pin;
2840
2841         pin = spec->autocfg.speaker_pins[0];
2842         if (pin) /* connect to front */
2843                 ad1988_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
2844         pin = spec->autocfg.hp_pins[0];
2845         if (pin) /* connect to front */
2846                 ad1988_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
2847 }
2848
2849 static void ad1988_auto_init_analog_input(struct hda_codec *codec)
2850 {
2851         struct ad198x_spec *spec = codec->spec;
2852         int i, idx;
2853
2854         for (i = 0; i < AUTO_PIN_LAST; i++) {
2855                 hda_nid_t nid = spec->autocfg.input_pins[i];
2856                 if (! nid)
2857                         continue;
2858                 switch (nid) {
2859                 case 0x15: /* port-C */
2860                         snd_hda_codec_write(codec, 0x33, 0, AC_VERB_SET_CONNECT_SEL, 0x0);
2861                         break;
2862                 case 0x17: /* port-E */
2863                         snd_hda_codec_write(codec, 0x34, 0, AC_VERB_SET_CONNECT_SEL, 0x0);
2864                         break;
2865                 }
2866                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
2867                                     i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN);
2868                 if (nid != AD1988_PIN_CD_NID)
2869                         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
2870                                             AMP_OUT_MUTE);
2871                 idx = ad1988_pin_idx(nid);
2872                 if (ad1988_boost_nids[idx])
2873                         snd_hda_codec_write(codec, ad1988_boost_nids[idx], 0,
2874                                             AC_VERB_SET_AMP_GAIN_MUTE,
2875                                             AMP_OUT_ZERO);
2876         }
2877 }
2878
2879 /* parse the BIOS configuration and set up the alc_spec */
2880 /* return 1 if successful, 0 if the proper config is not found, or a negative error code */
2881 static int ad1988_parse_auto_config(struct hda_codec *codec)
2882 {
2883         struct ad198x_spec *spec = codec->spec;
2884         int err;
2885
2886         if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL)) < 0)
2887                 return err;
2888         if ((err = ad1988_auto_fill_dac_nids(codec, &spec->autocfg)) < 0)
2889                 return err;
2890         if (! spec->autocfg.line_outs)
2891                 return 0; /* can't find valid BIOS pin config */
2892         if ((err = ad1988_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 ||
2893             (err = ad1988_auto_create_extra_out(codec,
2894                                                 spec->autocfg.speaker_pins[0],
2895                                                 "Speaker")) < 0 ||
2896             (err = ad1988_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
2897                                                 "Headphone")) < 0 ||
2898             (err = ad1988_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0)
2899                 return err;
2900
2901         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
2902
2903         if (spec->autocfg.dig_out_pin)
2904                 spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
2905         if (spec->autocfg.dig_in_pin)
2906                 spec->dig_in_nid = AD1988_SPDIF_IN;
2907
2908         if (spec->kctls.list)
2909                 spec->mixers[spec->num_mixers++] = spec->kctls.list;
2910
2911         spec->init_verbs[spec->num_init_verbs++] = ad1988_6stack_init_verbs;
2912
2913         spec->input_mux = &spec->private_imux;
2914
2915         return 1;
2916 }
2917
2918 /* init callback for auto-configuration model -- overriding the default init */
2919 static int ad1988_auto_init(struct hda_codec *codec)
2920 {
2921         ad198x_init(codec);
2922         ad1988_auto_init_multi_out(codec);
2923         ad1988_auto_init_extra_out(codec);
2924         ad1988_auto_init_analog_input(codec);
2925         return 0;
2926 }
2927
2928
2929 /*
2930  */
2931
2932 static const char *ad1988_models[AD1988_MODEL_LAST] = {
2933         [AD1988_6STACK]         = "6stack",
2934         [AD1988_6STACK_DIG]     = "6stack-dig",
2935         [AD1988_3STACK]         = "3stack",
2936         [AD1988_3STACK_DIG]     = "3stack-dig",
2937         [AD1988_LAPTOP]         = "laptop",
2938         [AD1988_LAPTOP_DIG]     = "laptop-dig",
2939         [AD1988_AUTO]           = "auto",
2940 };
2941
2942 static struct snd_pci_quirk ad1988_cfg_tbl[] = {
2943         SND_PCI_QUIRK(0x1043, 0x81ec, "Asus P5B-DLX", AD1988_6STACK_DIG),
2944         SND_PCI_QUIRK(0x1043, 0x81f6, "Asus M2N-SLI", AD1988_6STACK_DIG),
2945         SND_PCI_QUIRK(0x1043, 0x8277, "Asus P5K-E/WIFI-AP", AD1988_6STACK_DIG),
2946         SND_PCI_QUIRK(0x1043, 0x8311, "Asus P5Q-Premium/Pro", AD1988_6STACK_DIG),
2947         {}
2948 };
2949
2950 static int patch_ad1988(struct hda_codec *codec)
2951 {
2952         struct ad198x_spec *spec;
2953         int err, board_config;
2954
2955         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2956         if (spec == NULL)
2957                 return -ENOMEM;
2958
2959         codec->spec = spec;
2960
2961         if (is_rev2(codec))
2962                 snd_printk(KERN_INFO "patch_analog: AD1988A rev.2 is detected, enable workarounds\n");
2963
2964         board_config = snd_hda_check_board_config(codec, AD1988_MODEL_LAST,
2965                                                   ad1988_models, ad1988_cfg_tbl);
2966         if (board_config < 0) {
2967                 printk(KERN_INFO "hda_codec: Unknown model for AD1988, trying auto-probe from BIOS...\n");
2968                 board_config = AD1988_AUTO;
2969         }
2970
2971         if (board_config == AD1988_AUTO) {
2972                 /* automatic parse from the BIOS config */
2973                 err = ad1988_parse_auto_config(codec);
2974                 if (err < 0) {
2975                         ad198x_free(codec);
2976                         return err;
2977                 } else if (! err) {
2978                         printk(KERN_INFO "hda_codec: Cannot set up configuration from BIOS.  Using 6-stack mode...\n");
2979                         board_config = AD1988_6STACK;
2980                 }
2981         }
2982
2983         err = snd_hda_attach_beep_device(codec, 0x10);
2984         if (err < 0) {
2985                 ad198x_free(codec);
2986                 return err;
2987         }
2988         set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
2989
2990         switch (board_config) {
2991         case AD1988_6STACK:
2992         case AD1988_6STACK_DIG:
2993                 spec->multiout.max_channels = 8;
2994                 spec->multiout.num_dacs = 4;
2995                 if (is_rev2(codec))
2996                         spec->multiout.dac_nids = ad1988_6stack_dac_nids_rev2;
2997                 else
2998                         spec->multiout.dac_nids = ad1988_6stack_dac_nids;
2999                 spec->input_mux = &ad1988_6stack_capture_source;
3000                 spec->num_mixers = 2;
3001                 if (is_rev2(codec))
3002                         spec->mixers[0] = ad1988_6stack_mixers1_rev2;
3003                 else
3004                         spec->mixers[0] = ad1988_6stack_mixers1;
3005                 spec->mixers[1] = ad1988_6stack_mixers2;
3006                 spec->num_init_verbs = 1;
3007                 spec->init_verbs[0] = ad1988_6stack_init_verbs;
3008                 if (board_config == AD1988_6STACK_DIG) {
3009                         spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
3010                         spec->dig_in_nid = AD1988_SPDIF_IN;
3011                 }
3012                 break;
3013         case AD1988_3STACK:
3014         case AD1988_3STACK_DIG:
3015                 spec->multiout.max_channels = 6;
3016                 spec->multiout.num_dacs = 3;
3017                 if (is_rev2(codec))
3018                         spec->multiout.dac_nids = ad1988_3stack_dac_nids_rev2;
3019                 else
3020                         spec->multiout.dac_nids = ad1988_3stack_dac_nids;
3021                 spec->input_mux = &ad1988_6stack_capture_source;
3022                 spec->channel_mode = ad1988_3stack_modes;
3023                 spec->num_channel_mode = ARRAY_SIZE(ad1988_3stack_modes);
3024                 spec->num_mixers = 2;
3025                 if (is_rev2(codec))
3026                         spec->mixers[0] = ad1988_3stack_mixers1_rev2;
3027                 else
3028                         spec->mixers[0] = ad1988_3stack_mixers1;
3029                 spec->mixers[1] = ad1988_3stack_mixers2;
3030                 spec->num_init_verbs = 1;
3031                 spec->init_verbs[0] = ad1988_3stack_init_verbs;
3032                 if (board_config == AD1988_3STACK_DIG)
3033                         spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
3034                 break;
3035         case AD1988_LAPTOP:
3036         case AD1988_LAPTOP_DIG:
3037                 spec->multiout.max_channels = 2;
3038                 spec->multiout.num_dacs = 1;
3039                 spec->multiout.dac_nids = ad1988_3stack_dac_nids;
3040                 spec->input_mux = &ad1988_laptop_capture_source;
3041                 spec->num_mixers = 1;
3042                 spec->mixers[0] = ad1988_laptop_mixers;
3043                 spec->num_init_verbs = 1;
3044                 spec->init_verbs[0] = ad1988_laptop_init_verbs;
3045                 if (board_config == AD1988_LAPTOP_DIG)
3046                         spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
3047                 break;
3048         }
3049
3050         spec->num_adc_nids = ARRAY_SIZE(ad1988_adc_nids);
3051         spec->adc_nids = ad1988_adc_nids;
3052         spec->capsrc_nids = ad1988_capsrc_nids;
3053         spec->mixers[spec->num_mixers++] = ad1988_capture_mixers;
3054         spec->init_verbs[spec->num_init_verbs++] = ad1988_capture_init_verbs;
3055         if (spec->multiout.dig_out_nid) {
3056                 if (codec->vendor_id >= 0x11d4989a) {
3057                         spec->mixers[spec->num_mixers++] =
3058                                 ad1989_spdif_out_mixers;
3059                         spec->init_verbs[spec->num_init_verbs++] =
3060                                 ad1989_spdif_init_verbs;
3061                         codec->slave_dig_outs = ad1989b_slave_dig_outs;
3062                 } else {
3063                         spec->mixers[spec->num_mixers++] =
3064                                 ad1988_spdif_out_mixers;
3065                         spec->init_verbs[spec->num_init_verbs++] =
3066                                 ad1988_spdif_init_verbs;
3067                 }
3068         }
3069         if (spec->dig_in_nid && codec->vendor_id < 0x11d4989a)
3070                 spec->mixers[spec->num_mixers++] = ad1988_spdif_in_mixers;
3071
3072         codec->patch_ops = ad198x_patch_ops;
3073         switch (board_config) {
3074         case AD1988_AUTO:
3075                 codec->patch_ops.init = ad1988_auto_init;
3076                 break;
3077         case AD1988_LAPTOP:
3078         case AD1988_LAPTOP_DIG:
3079                 codec->patch_ops.unsol_event = ad1988_laptop_unsol_event;
3080                 break;
3081         }
3082 #ifdef CONFIG_SND_HDA_POWER_SAVE
3083         spec->loopback.amplist = ad1988_loopbacks;
3084 #endif
3085         spec->vmaster_nid = 0x04;
3086
3087         return 0;
3088 }
3089
3090
3091 /*
3092  * AD1884 / AD1984
3093  *
3094  * port-B - front line/mic-in
3095  * port-E - aux in/out
3096  * port-F - aux in/out
3097  * port-C - rear line/mic-in
3098  * port-D - rear line/hp-out
3099  * port-A - front line/hp-out
3100  *
3101  * AD1984 = AD1884 + two digital mic-ins
3102  *
3103  * FIXME:
3104  * For simplicity, we share the single DAC for both HP and line-outs
3105  * right now.  The inidividual playbacks could be easily implemented,
3106  * but no build-up framework is given, so far.
3107  */
3108
3109 static hda_nid_t ad1884_dac_nids[1] = {
3110         0x04,
3111 };
3112
3113 static hda_nid_t ad1884_adc_nids[2] = {
3114         0x08, 0x09,
3115 };
3116
3117 static hda_nid_t ad1884_capsrc_nids[2] = {
3118         0x0c, 0x0d,
3119 };
3120
3121 #define AD1884_SPDIF_OUT        0x02
3122
3123 static struct hda_input_mux ad1884_capture_source = {
3124         .num_items = 4,
3125         .items = {
3126                 { "Front Mic", 0x0 },
3127                 { "Mic", 0x1 },
3128                 { "CD", 0x2 },
3129                 { "Mix", 0x3 },
3130         },
3131 };
3132
3133 static struct snd_kcontrol_new ad1884_base_mixers[] = {
3134         HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
3135         /* HDA_CODEC_VOLUME_IDX("PCM Playback Volume", 1, 0x03, 0x0, HDA_OUTPUT), */
3136         HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
3137         HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT),
3138         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
3139         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
3140         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
3141         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3142         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
3143         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
3144         HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x02, HDA_INPUT),
3145         HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x02, HDA_INPUT),
3146         HDA_CODEC_VOLUME("Mic Boost", 0x15, 0x0, HDA_INPUT),
3147         HDA_CODEC_VOLUME("Front Mic Boost", 0x14, 0x0, HDA_INPUT),
3148         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3149         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3150         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
3151         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
3152         {
3153                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3154                 /* The multiple "Capture Source" controls confuse alsamixer
3155                  * So call somewhat different..
3156                  */
3157                 /* .name = "Capture Source", */
3158                 .name = "Input Source",
3159                 .count = 2,
3160                 .info = ad198x_mux_enum_info,
3161                 .get = ad198x_mux_enum_get,
3162                 .put = ad198x_mux_enum_put,
3163         },
3164         /* SPDIF controls */
3165         HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
3166         {
3167                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3168                 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
3169                 /* identical with ad1983 */
3170                 .info = ad1983_spdif_route_info,
3171                 .get = ad1983_spdif_route_get,
3172                 .put = ad1983_spdif_route_put,
3173         },
3174         { } /* end */
3175 };
3176
3177 static struct snd_kcontrol_new ad1984_dmic_mixers[] = {
3178         HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x05, 0x0, HDA_INPUT),
3179         HDA_CODEC_MUTE("Digital Mic Capture Switch", 0x05, 0x0, HDA_INPUT),
3180         HDA_CODEC_VOLUME_IDX("Digital Mic Capture Volume", 1, 0x06, 0x0,
3181                              HDA_INPUT),
3182         HDA_CODEC_MUTE_IDX("Digital Mic Capture Switch", 1, 0x06, 0x0,
3183                            HDA_INPUT),
3184         { } /* end */
3185 };
3186
3187 /*
3188  * initialization verbs
3189  */
3190 static struct hda_verb ad1884_init_verbs[] = {
3191         /* DACs; mute as default */
3192         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3193         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3194         /* Port-A (HP) mixer */
3195         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3196         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3197         /* Port-A pin */
3198         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3199         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3200         /* HP selector - select DAC2 */
3201         {0x22, AC_VERB_SET_CONNECT_SEL, 0x1},
3202         /* Port-D (Line-out) mixer */
3203         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3204         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3205         /* Port-D pin */
3206         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3207         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3208         /* Mono-out mixer */
3209         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3210         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3211         /* Mono-out pin */
3212         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3213         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3214         /* Mono selector */
3215         {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
3216         /* Port-B (front mic) pin */
3217         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3218         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3219         /* Port-C (rear mic) pin */
3220         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3221         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3222         /* Analog mixer; mute as default */
3223         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3224         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3225         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3226         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3227         /* Analog Mix output amp */
3228         {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
3229         /* SPDIF output selector */
3230         {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */
3231         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
3232         { } /* end */
3233 };
3234
3235 #ifdef CONFIG_SND_HDA_POWER_SAVE
3236 static struct hda_amp_list ad1884_loopbacks[] = {
3237         { 0x20, HDA_INPUT, 0 }, /* Front Mic */
3238         { 0x20, HDA_INPUT, 1 }, /* Mic */
3239         { 0x20, HDA_INPUT, 2 }, /* CD */
3240         { 0x20, HDA_INPUT, 4 }, /* Docking */
3241         { } /* end */
3242 };
3243 #endif
3244
3245 static const char *ad1884_slave_vols[] = {
3246         "PCM Playback Volume",
3247         "Mic Playback Volume",
3248         "Mono Playback Volume",
3249         "Front Mic Playback Volume",
3250         "Mic Playback Volume",
3251         "CD Playback Volume",
3252         "Internal Mic Playback Volume",
3253         "Docking Mic Playback Volume"
3254         /* "Beep Playback Volume", */
3255         "IEC958 Playback Volume",
3256         NULL
3257 };
3258
3259 static int patch_ad1884(struct hda_codec *codec)
3260 {
3261         struct ad198x_spec *spec;
3262         int err;
3263
3264         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3265         if (spec == NULL)
3266                 return -ENOMEM;
3267
3268         codec->spec = spec;
3269
3270         err = snd_hda_attach_beep_device(codec, 0x10);
3271         if (err < 0) {
3272                 ad198x_free(codec);
3273                 return err;
3274         }
3275         set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
3276
3277         spec->multiout.max_channels = 2;
3278         spec->multiout.num_dacs = ARRAY_SIZE(ad1884_dac_nids);
3279         spec->multiout.dac_nids = ad1884_dac_nids;
3280         spec->multiout.dig_out_nid = AD1884_SPDIF_OUT;
3281         spec->num_adc_nids = ARRAY_SIZE(ad1884_adc_nids);
3282         spec->adc_nids = ad1884_adc_nids;
3283         spec->capsrc_nids = ad1884_capsrc_nids;
3284         spec->input_mux = &ad1884_capture_source;
3285         spec->num_mixers = 1;
3286         spec->mixers[0] = ad1884_base_mixers;
3287         spec->num_init_verbs = 1;
3288         spec->init_verbs[0] = ad1884_init_verbs;
3289         spec->spdif_route = 0;
3290 #ifdef CONFIG_SND_HDA_POWER_SAVE
3291         spec->loopback.amplist = ad1884_loopbacks;
3292 #endif
3293         spec->vmaster_nid = 0x04;
3294         /* we need to cover all playback volumes */
3295         spec->slave_vols = ad1884_slave_vols;
3296
3297         codec->patch_ops = ad198x_patch_ops;
3298
3299         return 0;
3300 }
3301
3302 /*
3303  * Lenovo Thinkpad T61/X61
3304  */
3305 static struct hda_input_mux ad1984_thinkpad_capture_source = {
3306         .num_items = 4,
3307         .items = {
3308                 { "Mic", 0x0 },
3309                 { "Internal Mic", 0x1 },
3310                 { "Mix", 0x3 },
3311                 { "Docking-Station", 0x4 },
3312         },
3313 };
3314
3315
3316 /*
3317  * Dell Precision T3400
3318  */
3319 static struct hda_input_mux ad1984_dell_desktop_capture_source = {
3320         .num_items = 3,
3321         .items = {
3322                 { "Front Mic", 0x0 },
3323                 { "Line-In", 0x1 },
3324                 { "Mix", 0x3 },
3325         },
3326 };
3327
3328
3329 static struct snd_kcontrol_new ad1984_thinkpad_mixers[] = {
3330         HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
3331         /* HDA_CODEC_VOLUME_IDX("PCM Playback Volume", 1, 0x03, 0x0, HDA_OUTPUT), */
3332         HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
3333         HDA_CODEC_MUTE("Speaker Playback Switch", 0x12, 0x0, HDA_OUTPUT),
3334         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
3335         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3336         HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
3337         HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
3338         HDA_CODEC_VOLUME("Docking Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
3339         HDA_CODEC_MUTE("Docking Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
3340         HDA_CODEC_VOLUME("Mic Boost", 0x14, 0x0, HDA_INPUT),
3341         HDA_CODEC_VOLUME("Internal Mic Boost", 0x15, 0x0, HDA_INPUT),
3342         HDA_CODEC_VOLUME("Docking Mic Boost", 0x25, 0x0, HDA_OUTPUT),
3343         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3344         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3345         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
3346         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
3347         {
3348                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3349                 /* The multiple "Capture Source" controls confuse alsamixer
3350                  * So call somewhat different..
3351                  */
3352                 /* .name = "Capture Source", */
3353                 .name = "Input Source",
3354                 .count = 2,
3355                 .info = ad198x_mux_enum_info,
3356                 .get = ad198x_mux_enum_get,
3357                 .put = ad198x_mux_enum_put,
3358         },
3359         /* SPDIF controls */
3360         HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
3361         {
3362                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3363                 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
3364                 /* identical with ad1983 */
3365                 .info = ad1983_spdif_route_info,
3366                 .get = ad1983_spdif_route_get,
3367                 .put = ad1983_spdif_route_put,
3368         },
3369         { } /* end */
3370 };
3371
3372 /* additional verbs */
3373 static struct hda_verb ad1984_thinkpad_init_verbs[] = {
3374         /* Port-E (docking station mic) pin */
3375         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3376         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3377         /* docking mic boost */
3378         {0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3379         /* Analog mixer - docking mic; mute as default */
3380         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3381         /* enable EAPD bit */
3382         {0x12, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
3383         { } /* end */
3384 };
3385
3386 /*
3387  * Dell Precision T3400
3388  */
3389 static struct snd_kcontrol_new ad1984_dell_desktop_mixers[] = {
3390         HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
3391         HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
3392         HDA_CODEC_MUTE("Speaker Playback Switch", 0x12, 0x0, HDA_OUTPUT),
3393         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
3394         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
3395         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
3396         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3397         HDA_CODEC_VOLUME("Line-In Playback Volume", 0x20, 0x01, HDA_INPUT),
3398         HDA_CODEC_MUTE("Line-In Playback Switch", 0x20, 0x01, HDA_INPUT),
3399         HDA_CODEC_VOLUME("Line-In Boost", 0x15, 0x0, HDA_INPUT),
3400         HDA_CODEC_VOLUME("Front Mic Boost", 0x14, 0x0, HDA_INPUT),
3401         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3402         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3403         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
3404         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
3405         {
3406                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3407                 /* The multiple "Capture Source" controls confuse alsamixer
3408                  * So call somewhat different..
3409                  */
3410                 /* .name = "Capture Source", */
3411                 .name = "Input Source",
3412                 .count = 2,
3413                 .info = ad198x_mux_enum_info,
3414                 .get = ad198x_mux_enum_get,
3415                 .put = ad198x_mux_enum_put,
3416         },
3417         { } /* end */
3418 };
3419
3420 /* Digial MIC ADC NID 0x05 + 0x06 */
3421 static int ad1984_pcm_dmic_prepare(struct hda_pcm_stream *hinfo,
3422                                    struct hda_codec *codec,
3423                                    unsigned int stream_tag,
3424                                    unsigned int format,
3425                                    struct snd_pcm_substream *substream)
3426 {
3427         snd_hda_codec_setup_stream(codec, 0x05 + substream->number,
3428                                    stream_tag, 0, format);
3429         return 0;
3430 }
3431
3432 static int ad1984_pcm_dmic_cleanup(struct hda_pcm_stream *hinfo,
3433                                    struct hda_codec *codec,
3434                                    struct snd_pcm_substream *substream)
3435 {
3436         snd_hda_codec_cleanup_stream(codec, 0x05 + substream->number);
3437         return 0;
3438 }
3439
3440 static struct hda_pcm_stream ad1984_pcm_dmic_capture = {
3441         .substreams = 2,
3442         .channels_min = 2,
3443         .channels_max = 2,
3444         .nid = 0x05,
3445         .ops = {
3446                 .prepare = ad1984_pcm_dmic_prepare,
3447                 .cleanup = ad1984_pcm_dmic_cleanup
3448         },
3449 };
3450
3451 static int ad1984_build_pcms(struct hda_codec *codec)
3452 {
3453         struct ad198x_spec *spec = codec->spec;
3454         struct hda_pcm *info;
3455         int err;
3456
3457         err = ad198x_build_pcms(codec);
3458         if (err < 0)
3459                 return err;
3460
3461         info = spec->pcm_rec + codec->num_pcms;
3462         codec->num_pcms++;
3463         info->name = "AD1984 Digital Mic";
3464         info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad1984_pcm_dmic_capture;
3465         return 0;
3466 }
3467
3468 /* models */
3469 enum {
3470         AD1984_BASIC,
3471         AD1984_THINKPAD,
3472         AD1984_DELL_DESKTOP,
3473         AD1984_MODELS
3474 };
3475
3476 static const char *ad1984_models[AD1984_MODELS] = {
3477         [AD1984_BASIC]          = "basic",
3478         [AD1984_THINKPAD]       = "thinkpad",
3479         [AD1984_DELL_DESKTOP]   = "dell_desktop",
3480 };
3481
3482 static struct snd_pci_quirk ad1984_cfg_tbl[] = {
3483         /* Lenovo Thinkpad T61/X61 */
3484         SND_PCI_QUIRK(0x17aa, 0, "Lenovo Thinkpad", AD1984_THINKPAD),
3485         SND_PCI_QUIRK(0x1028, 0x0214, "Dell T3400", AD1984_DELL_DESKTOP),
3486         {}
3487 };
3488
3489 static int patch_ad1984(struct hda_codec *codec)
3490 {
3491         struct ad198x_spec *spec;
3492         int board_config, err;
3493
3494         err = patch_ad1884(codec);
3495         if (err < 0)
3496                 return err;
3497         spec = codec->spec;
3498         board_config = snd_hda_check_board_config(codec, AD1984_MODELS,
3499                                                   ad1984_models, ad1984_cfg_tbl);
3500         switch (board_config) {
3501         case AD1984_BASIC:
3502                 /* additional digital mics */
3503                 spec->mixers[spec->num_mixers++] = ad1984_dmic_mixers;
3504                 codec->patch_ops.build_pcms = ad1984_build_pcms;
3505                 break;
3506         case AD1984_THINKPAD:
3507                 spec->multiout.dig_out_nid = AD1884_SPDIF_OUT;
3508                 spec->input_mux = &ad1984_thinkpad_capture_source;
3509                 spec->mixers[0] = ad1984_thinkpad_mixers;
3510                 spec->init_verbs[spec->num_init_verbs++] = ad1984_thinkpad_init_verbs;
3511                 break;
3512         case AD1984_DELL_DESKTOP:
3513                 spec->multiout.dig_out_nid = 0;
3514                 spec->input_mux = &ad1984_dell_desktop_capture_source;
3515                 spec->mixers[0] = ad1984_dell_desktop_mixers;
3516                 break;
3517         }
3518         return 0;
3519 }
3520
3521
3522 /*
3523  * AD1883 / AD1884A / AD1984A / AD1984B
3524  *
3525  * port-B (0x14) - front mic-in
3526  * port-E (0x1c) - rear mic-in
3527  * port-F (0x16) - CD / ext out
3528  * port-C (0x15) - rear line-in
3529  * port-D (0x12) - rear line-out
3530  * port-A (0x11) - front hp-out
3531  *
3532  * AD1984A = AD1884A + digital-mic
3533  * AD1883 = equivalent with AD1984A
3534  * AD1984B = AD1984A + extra SPDIF-out
3535  *
3536  * FIXME:
3537  * We share the single DAC for both HP and line-outs (see AD1884/1984).
3538  */
3539
3540 static hda_nid_t ad1884a_dac_nids[1] = {
3541         0x03,
3542 };
3543
3544 #define ad1884a_adc_nids        ad1884_adc_nids
3545 #define ad1884a_capsrc_nids     ad1884_capsrc_nids
3546
3547 #define AD1884A_SPDIF_OUT       0x02
3548
3549 static struct hda_input_mux ad1884a_capture_source = {
3550         .num_items = 5,
3551         .items = {
3552                 { "Front Mic", 0x0 },
3553                 { "Mic", 0x4 },
3554                 { "Line", 0x1 },
3555                 { "CD", 0x2 },
3556                 { "Mix", 0x3 },
3557         },
3558 };
3559
3560 static struct snd_kcontrol_new ad1884a_base_mixers[] = {
3561         HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
3562         HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),
3563         HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
3564         HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT),
3565         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
3566         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
3567         HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
3568         HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
3569         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
3570         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3571         HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x01, HDA_INPUT),
3572         HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x01, HDA_INPUT),
3573         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
3574         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
3575         HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x02, HDA_INPUT),
3576         HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x02, HDA_INPUT),
3577         HDA_CODEC_VOLUME("Front Mic Boost", 0x14, 0x0, HDA_INPUT),
3578         HDA_CODEC_VOLUME("Line Boost", 0x15, 0x0, HDA_INPUT),
3579         HDA_CODEC_VOLUME("Mic Boost", 0x25, 0x0, HDA_OUTPUT),
3580         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3581         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3582         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
3583         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
3584         {
3585                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3586                 /* The multiple "Capture Source" controls confuse alsamixer
3587                  * So call somewhat different..
3588                  */
3589                 /* .name = "Capture Source", */
3590                 .name = "Input Source",
3591                 .count = 2,
3592                 .info = ad198x_mux_enum_info,
3593                 .get = ad198x_mux_enum_get,
3594                 .put = ad198x_mux_enum_put,
3595         },
3596         /* SPDIF controls */
3597         HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
3598         {
3599                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3600                 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
3601                 /* identical with ad1983 */
3602                 .info = ad1983_spdif_route_info,
3603                 .get = ad1983_spdif_route_get,
3604                 .put = ad1983_spdif_route_put,
3605         },
3606         { } /* end */
3607 };
3608
3609 /*
3610  * initialization verbs
3611  */
3612 static struct hda_verb ad1884a_init_verbs[] = {
3613         /* DACs; unmute as default */
3614         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
3615         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
3616         /* Port-A (HP) mixer - route only from analog mixer */
3617         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3618         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3619         /* Port-A pin */
3620         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3621         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3622         /* Port-D (Line-out) mixer - route only from analog mixer */
3623         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3624         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3625         /* Port-D pin */
3626         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3627         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3628         /* Mono-out mixer - route only from analog mixer */
3629         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3630         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3631         /* Mono-out pin */
3632         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3633         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3634         /* Port-B (front mic) pin */
3635         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3636         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3637         /* Port-C (rear line-in) pin */
3638         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3639         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3640         /* Port-E (rear mic) pin */
3641         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3642         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3643         {0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* no boost */
3644         /* Port-F (CD) pin */
3645         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3646         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3647         /* Analog mixer; mute as default */
3648         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3649         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3650         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3651         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3652         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, /* aux */
3653         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
3654         /* Analog Mix output amp */
3655         {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3656         /* capture sources */
3657         {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0},
3658         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3659         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
3660         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3661         /* SPDIF output amp */
3662         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
3663         { } /* end */
3664 };
3665
3666 #ifdef CONFIG_SND_HDA_POWER_SAVE
3667 static struct hda_amp_list ad1884a_loopbacks[] = {
3668         { 0x20, HDA_INPUT, 0 }, /* Front Mic */
3669         { 0x20, HDA_INPUT, 1 }, /* Mic */
3670         { 0x20, HDA_INPUT, 2 }, /* CD */
3671         { 0x20, HDA_INPUT, 4 }, /* Docking */
3672         { } /* end */
3673 };
3674 #endif
3675
3676 /*
3677  * Laptop model
3678  *
3679  * Port A: Headphone jack
3680  * Port B: MIC jack
3681  * Port C: Internal MIC
3682  * Port D: Dock Line Out (if enabled)
3683  * Port E: Dock Line In (if enabled)
3684  * Port F: Internal speakers
3685  */
3686
3687 static struct hda_input_mux ad1884a_laptop_capture_source = {
3688         .num_items = 4,
3689         .items = {
3690                 { "Mic", 0x0 },         /* port-B */
3691                 { "Internal Mic", 0x1 }, /* port-C */
3692                 { "Dock Mic", 0x4 },    /* port-E */
3693                 { "Mix", 0x3 },
3694         },
3695 };
3696
3697 static struct snd_kcontrol_new ad1884a_laptop_mixers[] = {
3698         HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
3699         HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),
3700         HDA_CODEC_MUTE("Dock Playback Switch", 0x12, 0x0, HDA_OUTPUT),
3701         HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
3702         HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
3703         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
3704         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3705         HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
3706         HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
3707         HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
3708         HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
3709         HDA_CODEC_VOLUME("Mic Boost", 0x14, 0x0, HDA_INPUT),
3710         HDA_CODEC_VOLUME("Internal Mic Boost", 0x15, 0x0, HDA_INPUT),
3711         HDA_CODEC_VOLUME("Dock Mic Boost", 0x25, 0x0, HDA_OUTPUT),
3712         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3713         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3714         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
3715         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
3716         {
3717                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3718                 /* The multiple "Capture Source" controls confuse alsamixer
3719                  * So call somewhat different..
3720                  */
3721                 /* .name = "Capture Source", */
3722                 .name = "Input Source",
3723                 .count = 2,
3724                 .info = ad198x_mux_enum_info,
3725                 .get = ad198x_mux_enum_get,
3726                 .put = ad198x_mux_enum_put,
3727         },
3728         { } /* end */
3729 };
3730
3731 static struct snd_kcontrol_new ad1884a_mobile_mixers[] = {
3732         HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
3733         HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),
3734         HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
3735         HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
3736         HDA_CODEC_VOLUME("Mic Capture Volume", 0x14, 0x0, HDA_INPUT),
3737         HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x15, 0x0, HDA_INPUT),
3738         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3739         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3740         { } /* end */
3741 };
3742
3743 /* mute internal speaker if HP is plugged */
3744 static void ad1884a_hp_automute(struct hda_codec *codec)
3745 {
3746         unsigned int present;
3747
3748         present = snd_hda_codec_read(codec, 0x11, 0,
3749                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
3750         snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
3751                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
3752         snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_EAPD_BTLENABLE,
3753                             present ? 0x00 : 0x02);
3754 }
3755
3756 /* switch to external mic if plugged */
3757 static void ad1884a_hp_automic(struct hda_codec *codec)
3758 {
3759         unsigned int present;
3760
3761         present = snd_hda_codec_read(codec, 0x14, 0,
3762                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
3763         snd_hda_codec_write(codec, 0x0c, 0, AC_VERB_SET_CONNECT_SEL,
3764                             present ? 0 : 1);
3765 }
3766
3767 #define AD1884A_HP_EVENT                0x37
3768 #define AD1884A_MIC_EVENT               0x36
3769
3770 /* unsolicited event for HP jack sensing */
3771 static void ad1884a_hp_unsol_event(struct hda_codec *codec, unsigned int res)
3772 {
3773         switch (res >> 26) {
3774         case AD1884A_HP_EVENT:
3775                 ad1884a_hp_automute(codec);
3776                 break;
3777         case AD1884A_MIC_EVENT:
3778                 ad1884a_hp_automic(codec);
3779                 break;
3780         }
3781 }
3782
3783 /* initialize jack-sensing, too */
3784 static int ad1884a_hp_init(struct hda_codec *codec)
3785 {
3786         ad198x_init(codec);
3787         ad1884a_hp_automute(codec);
3788         ad1884a_hp_automic(codec);
3789         return 0;
3790 }
3791
3792 /* additional verbs for laptop model */
3793 static struct hda_verb ad1884a_laptop_verbs[] = {
3794         /* Port-A (HP) pin - always unmuted */
3795         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3796         /* Port-F (int speaker) mixer - route only from analog mixer */
3797         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3798         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3799         /* Port-F pin */
3800         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3801         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3802         /* Port-C pin - internal mic-in */
3803         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3804         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
3805         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
3806         /* analog mix */
3807         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3808         /* unsolicited event for pin-sense */
3809         {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
3810         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT},
3811         { } /* end */
3812 };
3813
3814 /*
3815  * Thinkpad X300
3816  * 0x11 - HP
3817  * 0x12 - speaker
3818  * 0x14 - mic-in
3819  * 0x17 - built-in mic
3820  */
3821
3822 static struct hda_verb ad1984a_thinkpad_verbs[] = {
3823         /* HP unmute */
3824         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3825         /* analog mix */
3826         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3827         /* turn on EAPD */
3828         {0x12, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
3829         /* unsolicited event for pin-sense */
3830         {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
3831         /* internal mic - dmic */
3832         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3833         /* set magic COEFs for dmic */
3834         {0x01, AC_VERB_SET_COEF_INDEX, 0x13f7},
3835         {0x01, AC_VERB_SET_PROC_COEF, 0x08},
3836         { } /* end */
3837 };
3838
3839 static struct snd_kcontrol_new ad1984a_thinkpad_mixers[] = {
3840         HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
3841         HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),
3842         HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
3843         HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
3844         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
3845         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3846         HDA_CODEC_VOLUME("Mic Boost", 0x14, 0x0, HDA_INPUT),
3847         HDA_CODEC_VOLUME("Internal Mic Boost", 0x17, 0x0, HDA_INPUT),
3848         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3849         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3850         {
3851                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3852                 .name = "Capture Source",
3853                 .info = ad198x_mux_enum_info,
3854                 .get = ad198x_mux_enum_get,
3855                 .put = ad198x_mux_enum_put,
3856         },
3857         { } /* end */
3858 };
3859
3860 static struct hda_input_mux ad1984a_thinkpad_capture_source = {
3861         .num_items = 3,
3862         .items = {
3863                 { "Mic", 0x0 },
3864                 { "Internal Mic", 0x5 },
3865                 { "Mix", 0x3 },
3866         },
3867 };
3868
3869 /* mute internal speaker if HP is plugged */
3870 static void ad1984a_thinkpad_automute(struct hda_codec *codec)
3871 {
3872         unsigned int present;
3873
3874         present = snd_hda_codec_read(codec, 0x11, 0, AC_VERB_GET_PIN_SENSE, 0)
3875                 & AC_PINSENSE_PRESENCE;
3876         snd_hda_codec_amp_stereo(codec, 0x12, HDA_OUTPUT, 0,
3877                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
3878 }
3879
3880 /* unsolicited event for HP jack sensing */
3881 static void ad1984a_thinkpad_unsol_event(struct hda_codec *codec,
3882                                          unsigned int res)
3883 {
3884         if ((res >> 26) != AD1884A_HP_EVENT)
3885                 return;
3886         ad1984a_thinkpad_automute(codec);
3887 }
3888
3889 /* initialize jack-sensing, too */
3890 static int ad1984a_thinkpad_init(struct hda_codec *codec)
3891 {
3892         ad198x_init(codec);
3893         ad1984a_thinkpad_automute(codec);
3894         return 0;
3895 }
3896
3897 /*
3898  */
3899
3900 enum {
3901         AD1884A_DESKTOP,
3902         AD1884A_LAPTOP,
3903         AD1884A_MOBILE,
3904         AD1884A_THINKPAD,
3905         AD1884A_MODELS
3906 };
3907
3908 static const char *ad1884a_models[AD1884A_MODELS] = {
3909         [AD1884A_DESKTOP]       = "desktop",
3910         [AD1884A_LAPTOP]        = "laptop",
3911         [AD1884A_MOBILE]        = "mobile",
3912         [AD1884A_THINKPAD]      = "thinkpad",
3913 };
3914
3915 static struct snd_pci_quirk ad1884a_cfg_tbl[] = {
3916         SND_PCI_QUIRK(0x103c, 0x3030, "HP", AD1884A_MOBILE),
3917         SND_PCI_QUIRK(0x103c, 0x3037, "HP 2230s", AD1884A_LAPTOP),
3918         SND_PCI_QUIRK(0x103c, 0x3056, "HP", AD1884A_MOBILE),
3919         SND_PCI_QUIRK(0x103c, 0x3072, "HP", AD1884A_LAPTOP),
3920         SND_PCI_QUIRK(0x103c, 0x3077, "HP", AD1884A_LAPTOP),
3921         SND_PCI_QUIRK(0x103c, 0x30e6, "HP 6730b", AD1884A_LAPTOP),
3922         SND_PCI_QUIRK(0x103c, 0x30e7, "HP EliteBook 8530p", AD1884A_LAPTOP),
3923         SND_PCI_QUIRK(0x103c, 0x3614, "HP 6730s", AD1884A_LAPTOP),
3924         SND_PCI_QUIRK(0x17aa, 0x20ac, "Thinkpad X300", AD1884A_THINKPAD),
3925         {}
3926 };
3927
3928 static int patch_ad1884a(struct hda_codec *codec)
3929 {
3930         struct ad198x_spec *spec;
3931         int err, board_config;
3932
3933         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3934         if (spec == NULL)
3935                 return -ENOMEM;
3936
3937         codec->spec = spec;
3938
3939         err = snd_hda_attach_beep_device(codec, 0x10);
3940         if (err < 0) {
3941                 ad198x_free(codec);
3942                 return err;
3943         }
3944         set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
3945
3946         spec->multiout.max_channels = 2;
3947         spec->multiout.num_dacs = ARRAY_SIZE(ad1884a_dac_nids);
3948         spec->multiout.dac_nids = ad1884a_dac_nids;
3949         spec->multiout.dig_out_nid = AD1884A_SPDIF_OUT;
3950         spec->num_adc_nids = ARRAY_SIZE(ad1884a_adc_nids);
3951         spec->adc_nids = ad1884a_adc_nids;
3952         spec->capsrc_nids = ad1884a_capsrc_nids;
3953         spec->input_mux = &ad1884a_capture_source;
3954         spec->num_mixers = 1;
3955         spec->mixers[0] = ad1884a_base_mixers;
3956         spec->num_init_verbs = 1;
3957         spec->init_verbs[0] = ad1884a_init_verbs;
3958         spec->spdif_route = 0;
3959 #ifdef CONFIG_SND_HDA_POWER_SAVE
3960         spec->loopback.amplist = ad1884a_loopbacks;
3961 #endif
3962         codec->patch_ops = ad198x_patch_ops;
3963
3964         /* override some parameters */
3965         board_config = snd_hda_check_board_config(codec, AD1884A_MODELS,
3966                                                   ad1884a_models,
3967                                                   ad1884a_cfg_tbl);
3968         switch (board_config) {
3969         case AD1884A_LAPTOP:
3970                 spec->mixers[0] = ad1884a_laptop_mixers;
3971                 spec->init_verbs[spec->num_init_verbs++] = ad1884a_laptop_verbs;
3972                 spec->multiout.dig_out_nid = 0;
3973                 spec->input_mux = &ad1884a_laptop_capture_source;
3974                 codec->patch_ops.unsol_event = ad1884a_hp_unsol_event;
3975                 codec->patch_ops.init = ad1884a_hp_init;
3976                 break;
3977         case AD1884A_MOBILE:
3978                 spec->mixers[0] = ad1884a_mobile_mixers;
3979                 spec->init_verbs[spec->num_init_verbs++] = ad1884a_laptop_verbs;
3980                 spec->multiout.dig_out_nid = 0;
3981                 codec->patch_ops.unsol_event = ad1884a_hp_unsol_event;
3982                 codec->patch_ops.init = ad1884a_hp_init;
3983                 break;
3984         case AD1884A_THINKPAD:
3985                 spec->mixers[0] = ad1984a_thinkpad_mixers;
3986                 spec->init_verbs[spec->num_init_verbs++] =
3987                         ad1984a_thinkpad_verbs;
3988                 spec->multiout.dig_out_nid = 0;
3989                 spec->input_mux = &ad1984a_thinkpad_capture_source;
3990                 codec->patch_ops.unsol_event = ad1984a_thinkpad_unsol_event;
3991                 codec->patch_ops.init = ad1984a_thinkpad_init;
3992                 break;
3993         }
3994
3995         return 0;
3996 }
3997
3998
3999 /*
4000  * AD1882 / AD1882A
4001  *
4002  * port-A - front hp-out
4003  * port-B - front mic-in
4004  * port-C - rear line-in, shared surr-out (3stack)
4005  * port-D - rear line-out
4006  * port-E - rear mic-in, shared clfe-out (3stack)
4007  * port-F - rear surr-out (6stack)
4008  * port-G - rear clfe-out (6stack)
4009  */
4010
4011 static hda_nid_t ad1882_dac_nids[3] = {
4012         0x04, 0x03, 0x05
4013 };
4014
4015 static hda_nid_t ad1882_adc_nids[2] = {
4016         0x08, 0x09,
4017 };
4018
4019 static hda_nid_t ad1882_capsrc_nids[2] = {
4020         0x0c, 0x0d,
4021 };
4022
4023 #define AD1882_SPDIF_OUT        0x02
4024
4025 /* list: 0x11, 0x39, 0x3a, 0x18, 0x3c, 0x3b, 0x12, 0x20 */
4026 static struct hda_input_mux ad1882_capture_source = {
4027         .num_items = 5,
4028         .items = {
4029                 { "Front Mic", 0x1 },
4030                 { "Mic", 0x4 },
4031                 { "Line", 0x2 },
4032                 { "CD", 0x3 },
4033                 { "Mix", 0x7 },
4034         },
4035 };
4036
4037 /* list: 0x11, 0x39, 0x3a, 0x3c, 0x18, 0x1f, 0x12, 0x20 */
4038 static struct hda_input_mux ad1882a_capture_source = {
4039         .num_items = 5,
4040         .items = {
4041                 { "Front Mic", 0x1 },
4042                 { "Mic", 0x4},
4043                 { "Line", 0x2 },
4044                 { "Digital Mic", 0x06 },
4045                 { "Mix", 0x7 },
4046         },
4047 };
4048
4049 static struct snd_kcontrol_new ad1882_base_mixers[] = {
4050         HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
4051         HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
4052         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT),
4053         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT),
4054         HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
4055         HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT),
4056         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
4057         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
4058
4059         HDA_CODEC_VOLUME("Mic Boost", 0x3c, 0x0, HDA_OUTPUT),
4060         HDA_CODEC_VOLUME("Front Mic Boost", 0x39, 0x0, HDA_OUTPUT),
4061         HDA_CODEC_VOLUME("Line-In Boost", 0x3a, 0x0, HDA_OUTPUT),
4062         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
4063         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
4064         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
4065         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
4066         {
4067                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4068                 /* The multiple "Capture Source" controls confuse alsamixer
4069                  * So call somewhat different..
4070                  */
4071                 /* .name = "Capture Source", */
4072                 .name = "Input Source",
4073                 .count = 2,
4074                 .info = ad198x_mux_enum_info,
4075                 .get = ad198x_mux_enum_get,
4076                 .put = ad198x_mux_enum_put,
4077         },
4078         /* SPDIF controls */
4079         HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
4080         {
4081                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4082                 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
4083                 /* identical with ad1983 */
4084                 .info = ad1983_spdif_route_info,
4085                 .get = ad1983_spdif_route_get,
4086                 .put = ad1983_spdif_route_put,
4087         },
4088         { } /* end */
4089 };
4090
4091 static struct snd_kcontrol_new ad1882_loopback_mixers[] = {
4092         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
4093         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
4094         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
4095         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
4096         HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x04, HDA_INPUT),
4097         HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x04, HDA_INPUT),
4098         HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x06, HDA_INPUT),
4099         HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x06, HDA_INPUT),
4100         { } /* end */
4101 };
4102
4103 static struct snd_kcontrol_new ad1882a_loopback_mixers[] = {
4104         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
4105         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
4106         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
4107         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
4108         HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x01, HDA_INPUT),
4109         HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x01, HDA_INPUT),
4110         HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x06, HDA_INPUT),
4111         HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x06, HDA_INPUT),
4112         HDA_CODEC_VOLUME("Digital Mic Boost", 0x1f, 0x0, HDA_INPUT),
4113         { } /* end */
4114 };
4115
4116 static struct snd_kcontrol_new ad1882_3stack_mixers[] = {
4117         HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
4118         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x17, 1, 0x0, HDA_OUTPUT),
4119         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x17, 2, 0x0, HDA_OUTPUT),
4120         {
4121                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4122                 .name = "Channel Mode",
4123                 .info = ad198x_ch_mode_info,
4124                 .get = ad198x_ch_mode_get,
4125                 .put = ad198x_ch_mode_put,
4126         },
4127         { } /* end */
4128 };
4129
4130 static struct snd_kcontrol_new ad1882_6stack_mixers[] = {
4131         HDA_CODEC_MUTE("Surround Playback Switch", 0x16, 0x0, HDA_OUTPUT),
4132         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x24, 1, 0x0, HDA_OUTPUT),
4133         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x24, 2, 0x0, HDA_OUTPUT),
4134         { } /* end */
4135 };
4136
4137 static struct hda_verb ad1882_ch2_init[] = {
4138         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4139         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4140         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4141         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4142         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4143         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4144         { } /* end */
4145 };
4146
4147 static struct hda_verb ad1882_ch4_init[] = {
4148         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4149         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4150         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4151         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4152         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4153         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4154         { } /* end */
4155 };
4156
4157 static struct hda_verb ad1882_ch6_init[] = {
4158         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4159         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4160         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4161         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4162         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4163         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4164         { } /* end */
4165 };
4166
4167 static struct hda_channel_mode ad1882_modes[3] = {
4168         { 2, ad1882_ch2_init },
4169         { 4, ad1882_ch4_init },
4170         { 6, ad1882_ch6_init },
4171 };
4172
4173 /*
4174  * initialization verbs
4175  */
4176 static struct hda_verb ad1882_init_verbs[] = {
4177         /* DACs; mute as default */
4178         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4179         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4180         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4181         /* Port-A (HP) mixer */
4182         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4183         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4184         /* Port-A pin */
4185         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4186         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4187         /* HP selector - select DAC2 */
4188         {0x37, AC_VERB_SET_CONNECT_SEL, 0x1},
4189         /* Port-D (Line-out) mixer */
4190         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4191         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4192         /* Port-D pin */
4193         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4194         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4195         /* Mono-out mixer */
4196         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4197         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4198         /* Mono-out pin */
4199         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4200         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4201         /* Port-B (front mic) pin */
4202         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4203         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4204         {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */
4205         /* Port-C (line-in) pin */
4206         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4207         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4208         {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */
4209         /* Port-C mixer - mute as input */
4210         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4211         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4212         /* Port-E (mic-in) pin */
4213         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4214         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4215         {0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */
4216         /* Port-E mixer - mute as input */
4217         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4218         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4219         /* Port-F (surround) */
4220         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4221         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4222         /* Port-G (CLFE) */
4223         {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4224         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4225         /* Analog mixer; mute as default */
4226         /* list: 0x39, 0x3a, 0x11, 0x12, 0x3c, 0x3b, 0x18, 0x1a */
4227         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4228         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4229         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4230         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4231         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4232         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
4233         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
4234         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
4235         /* Analog Mix output amp */
4236         {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
4237         /* SPDIF output selector */
4238         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
4239         {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */
4240         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
4241         { } /* end */
4242 };
4243
4244 #ifdef CONFIG_SND_HDA_POWER_SAVE
4245 static struct hda_amp_list ad1882_loopbacks[] = {
4246         { 0x20, HDA_INPUT, 0 }, /* Front Mic */
4247         { 0x20, HDA_INPUT, 1 }, /* Mic */
4248         { 0x20, HDA_INPUT, 4 }, /* Line */
4249         { 0x20, HDA_INPUT, 6 }, /* CD */
4250         { } /* end */
4251 };
4252 #endif
4253
4254 /* models */
4255 enum {
4256         AD1882_3STACK,
4257         AD1882_6STACK,
4258         AD1882_MODELS
4259 };
4260
4261 static const char *ad1882_models[AD1986A_MODELS] = {
4262         [AD1882_3STACK]         = "3stack",
4263         [AD1882_6STACK]         = "6stack",
4264 };
4265
4266
4267 static int patch_ad1882(struct hda_codec *codec)
4268 {
4269         struct ad198x_spec *spec;
4270         int err, board_config;
4271
4272         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4273         if (spec == NULL)
4274                 return -ENOMEM;
4275
4276         codec->spec = spec;
4277
4278         err = snd_hda_attach_beep_device(codec, 0x10);
4279         if (err < 0) {
4280                 ad198x_free(codec);
4281                 return err;
4282         }
4283         set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
4284
4285         spec->multiout.max_channels = 6;
4286         spec->multiout.num_dacs = 3;
4287         spec->multiout.dac_nids = ad1882_dac_nids;
4288         spec->multiout.dig_out_nid = AD1882_SPDIF_OUT;
4289         spec->num_adc_nids = ARRAY_SIZE(ad1882_adc_nids);
4290         spec->adc_nids = ad1882_adc_nids;
4291         spec->capsrc_nids = ad1882_capsrc_nids;
4292         if (codec->vendor_id == 0x11d41882)
4293                 spec->input_mux = &ad1882_capture_source;
4294         else
4295                 spec->input_mux = &ad1882a_capture_source;
4296         spec->num_mixers = 2;
4297         spec->mixers[0] = ad1882_base_mixers;
4298         if (codec->vendor_id == 0x11d41882)
4299                 spec->mixers[1] = ad1882_loopback_mixers;
4300         else
4301                 spec->mixers[1] = ad1882a_loopback_mixers;
4302         spec->num_init_verbs = 1;
4303         spec->init_verbs[0] = ad1882_init_verbs;
4304         spec->spdif_route = 0;
4305 #ifdef CONFIG_SND_HDA_POWER_SAVE
4306         spec->loopback.amplist = ad1882_loopbacks;
4307 #endif
4308         spec->vmaster_nid = 0x04;
4309
4310         codec->patch_ops = ad198x_patch_ops;
4311
4312         /* override some parameters */
4313         board_config = snd_hda_check_board_config(codec, AD1882_MODELS,
4314                                                   ad1882_models, NULL);
4315         switch (board_config) {
4316         default:
4317         case AD1882_3STACK:
4318                 spec->num_mixers = 3;
4319                 spec->mixers[2] = ad1882_3stack_mixers;
4320                 spec->channel_mode = ad1882_modes;
4321                 spec->num_channel_mode = ARRAY_SIZE(ad1882_modes);
4322                 spec->need_dac_fix = 1;
4323                 spec->multiout.max_channels = 2;
4324                 spec->multiout.num_dacs = 1;
4325                 break;
4326         case AD1882_6STACK:
4327                 spec->num_mixers = 3;
4328                 spec->mixers[2] = ad1882_6stack_mixers;
4329                 break;
4330         }
4331         return 0;
4332 }
4333
4334
4335 /*
4336  * patch entries
4337  */
4338 static struct hda_codec_preset snd_hda_preset_analog[] = {
4339         { .id = 0x11d4184a, .name = "AD1884A", .patch = patch_ad1884a },
4340         { .id = 0x11d41882, .name = "AD1882", .patch = patch_ad1882 },
4341         { .id = 0x11d41883, .name = "AD1883", .patch = patch_ad1884a },
4342         { .id = 0x11d41884, .name = "AD1884", .patch = patch_ad1884 },
4343         { .id = 0x11d4194a, .name = "AD1984A", .patch = patch_ad1884a },
4344         { .id = 0x11d4194b, .name = "AD1984B", .patch = patch_ad1884a },
4345         { .id = 0x11d41981, .name = "AD1981", .patch = patch_ad1981 },
4346         { .id = 0x11d41983, .name = "AD1983", .patch = patch_ad1983 },
4347         { .id = 0x11d41984, .name = "AD1984", .patch = patch_ad1984 },
4348         { .id = 0x11d41986, .name = "AD1986A", .patch = patch_ad1986a },
4349         { .id = 0x11d41988, .name = "AD1988", .patch = patch_ad1988 },
4350         { .id = 0x11d4198b, .name = "AD1988B", .patch = patch_ad1988 },
4351         { .id = 0x11d4882a, .name = "AD1882A", .patch = patch_ad1882 },
4352         { .id = 0x11d4989a, .name = "AD1989A", .patch = patch_ad1988 },
4353         { .id = 0x11d4989b, .name = "AD1989B", .patch = patch_ad1988 },
4354         {} /* terminator */
4355 };
4356
4357 MODULE_ALIAS("snd-hda-codec-id:11d4*");
4358
4359 MODULE_LICENSE("GPL");
4360 MODULE_DESCRIPTION("Analog Devices HD-audio codec");
4361
4362 static struct hda_codec_preset_list analog_list = {
4363         .preset = snd_hda_preset_analog,
4364         .owner = THIS_MODULE,
4365 };
4366
4367 static int __init patch_analog_init(void)
4368 {
4369         return snd_hda_add_codec_preset(&analog_list);
4370 }
4371
4372 static void __exit patch_analog_exit(void)
4373 {
4374         snd_hda_delete_codec_preset(&analog_list);
4375 }
4376
4377 module_init(patch_analog_init)
4378 module_exit(patch_analog_exit)