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