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