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