[ALSA] hda-codec - Fix automute of AD1981HD hp model
[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         /* change speaker pin appropriately */
1370         snd_hda_codec_write(codec, 0x05, 0,
1371                             AC_VERB_SET_PIN_WIDGET_CONTROL,
1372                             spec->cur_eapd ? PIN_OUT : 0);
1373         /* toggle HP mute appropriately */
1374         snd_hda_codec_amp_stereo(codec, 0x06, HDA_OUTPUT, 0,
1375                                  HDA_AMP_MUTE,
1376                                  spec->cur_eapd ? 0 : HDA_AMP_MUTE);
1377         return 1;
1378 }
1379
1380 /* bind volumes of both NID 0x05 and 0x06 */
1381 static struct hda_bind_ctls ad1981_hp_bind_master_vol = {
1382         .ops = &snd_hda_bind_vol,
1383         .values = {
1384                 HDA_COMPOSE_AMP_VAL(0x05, 3, 0, HDA_OUTPUT),
1385                 HDA_COMPOSE_AMP_VAL(0x06, 3, 0, HDA_OUTPUT),
1386                 0
1387         },
1388 };
1389
1390 /* mute internal speaker if HP is plugged */
1391 static void ad1981_hp_automute(struct hda_codec *codec)
1392 {
1393         unsigned int present;
1394
1395         present = snd_hda_codec_read(codec, 0x06, 0,
1396                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1397         snd_hda_codec_amp_stereo(codec, 0x05, HDA_OUTPUT, 0,
1398                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
1399 }
1400
1401 /* toggle input of built-in and mic jack appropriately */
1402 static void ad1981_hp_automic(struct hda_codec *codec)
1403 {
1404         static struct hda_verb mic_jack_on[] = {
1405                 {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1406                 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1407                 {}
1408         };
1409         static struct hda_verb mic_jack_off[] = {
1410                 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1411                 {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1412                 {}
1413         };
1414         unsigned int present;
1415
1416         present = snd_hda_codec_read(codec, 0x08, 0,
1417                                  AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1418         if (present)
1419                 snd_hda_sequence_write(codec, mic_jack_on);
1420         else
1421                 snd_hda_sequence_write(codec, mic_jack_off);
1422 }
1423
1424 /* unsolicited event for HP jack sensing */
1425 static void ad1981_hp_unsol_event(struct hda_codec *codec,
1426                                   unsigned int res)
1427 {
1428         res >>= 26;
1429         switch (res) {
1430         case AD1981_HP_EVENT:
1431                 ad1981_hp_automute(codec);
1432                 break;
1433         case AD1981_MIC_EVENT:
1434                 ad1981_hp_automic(codec);
1435                 break;
1436         }
1437 }
1438
1439 static struct hda_input_mux ad1981_hp_capture_source = {
1440         .num_items = 3,
1441         .items = {
1442                 { "Mic", 0x0 },
1443                 { "Docking-Station", 0x1 },
1444                 { "Mix", 0x2 },
1445         },
1446 };
1447
1448 static struct snd_kcontrol_new ad1981_hp_mixers[] = {
1449         HDA_BIND_VOL("Master Playback Volume", &ad1981_hp_bind_master_vol),
1450         {
1451                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1452                 .name = "Master Playback Switch",
1453                 .info = ad198x_eapd_info,
1454                 .get = ad198x_eapd_get,
1455                 .put = ad1981_hp_master_sw_put,
1456                 .private_value = 0x05,
1457         },
1458         HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
1459         HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT),
1460 #if 0
1461         /* FIXME: analog mic/line loopback doesn't work with my tests...
1462          *        (although recording is OK)
1463          */
1464         HDA_CODEC_VOLUME("Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
1465         HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
1466         HDA_CODEC_VOLUME("Docking-Station Playback Volume", 0x13, 0x0, HDA_OUTPUT),
1467         HDA_CODEC_MUTE("Docking-Station Playback Switch", 0x13, 0x0, HDA_OUTPUT),
1468         HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x1c, 0x0, HDA_OUTPUT),
1469         HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x1c, 0x0, HDA_OUTPUT),
1470         /* FIXME: does this laptop have analog CD connection? */
1471         HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
1472         HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
1473 #endif
1474         HDA_CODEC_VOLUME("Mic Boost", 0x08, 0x0, HDA_INPUT),
1475         HDA_CODEC_VOLUME("Internal Mic Boost", 0x18, 0x0, HDA_INPUT),
1476         HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
1477         HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
1478         {
1479                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1480                 .name = "Capture Source",
1481                 .info = ad198x_mux_enum_info,
1482                 .get = ad198x_mux_enum_get,
1483                 .put = ad198x_mux_enum_put,
1484         },
1485         { } /* end */
1486 };
1487
1488 /* initialize jack-sensing, too */
1489 static int ad1981_hp_init(struct hda_codec *codec)
1490 {
1491         ad198x_init(codec);
1492         ad1981_hp_automute(codec);
1493         ad1981_hp_automic(codec);
1494         return 0;
1495 }
1496
1497 /* configuration for Toshiba Laptops */
1498 static struct hda_verb ad1981_toshiba_init_verbs[] = {
1499         {0x05, AC_VERB_SET_EAPD_BTLENABLE, 0x01 }, /* default on */
1500         /* pin sensing on HP and Mic jacks */
1501         {0x06, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_HP_EVENT},
1502         {0x08, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_MIC_EVENT},
1503         {}
1504 };
1505
1506 static struct snd_kcontrol_new ad1981_toshiba_mixers[] = {
1507         HDA_CODEC_VOLUME("Amp Volume", 0x1a, 0x0, HDA_OUTPUT),
1508         HDA_CODEC_MUTE("Amp Switch", 0x1a, 0x0, HDA_OUTPUT),
1509         { }
1510 };
1511
1512 /* configuration for Lenovo Thinkpad T60 */
1513 static struct snd_kcontrol_new ad1981_thinkpad_mixers[] = {
1514         HDA_CODEC_VOLUME("Master Playback Volume", 0x05, 0x0, HDA_OUTPUT),
1515         HDA_CODEC_MUTE("Master Playback Switch", 0x05, 0x0, HDA_OUTPUT),
1516         HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
1517         HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT),
1518         HDA_CODEC_VOLUME("Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
1519         HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
1520         HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
1521         HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
1522         HDA_CODEC_VOLUME("Mic Boost", 0x08, 0x0, HDA_INPUT),
1523         HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
1524         HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
1525         {
1526                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1527                 .name = "Capture Source",
1528                 .info = ad198x_mux_enum_info,
1529                 .get = ad198x_mux_enum_get,
1530                 .put = ad198x_mux_enum_put,
1531         },
1532         /* identical with AD1983 */
1533         {
1534                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1535                 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
1536                 .info = ad1983_spdif_route_info,
1537                 .get = ad1983_spdif_route_get,
1538                 .put = ad1983_spdif_route_put,
1539         },
1540         { } /* end */
1541 };
1542
1543 static struct hda_input_mux ad1981_thinkpad_capture_source = {
1544         .num_items = 3,
1545         .items = {
1546                 { "Mic", 0x0 },
1547                 { "Mix", 0x2 },
1548                 { "CD", 0x4 },
1549         },
1550 };
1551
1552 /* models */
1553 enum {
1554         AD1981_BASIC,
1555         AD1981_HP,
1556         AD1981_THINKPAD,
1557         AD1981_TOSHIBA,
1558         AD1981_MODELS
1559 };
1560
1561 static const char *ad1981_models[AD1981_MODELS] = {
1562         [AD1981_HP]             = "hp",
1563         [AD1981_THINKPAD]       = "thinkpad",
1564         [AD1981_BASIC]          = "basic",
1565         [AD1981_TOSHIBA]        = "toshiba"
1566 };
1567
1568 static struct snd_pci_quirk ad1981_cfg_tbl[] = {
1569         SND_PCI_QUIRK(0x1014, 0x0597, "Lenovo Z60", AD1981_THINKPAD),
1570         /* All HP models */
1571         SND_PCI_QUIRK(0x103c, 0, "HP nx", AD1981_HP),
1572         SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba U205", AD1981_TOSHIBA),
1573         /* Lenovo Thinkpad T60/X60/Z6xx */
1574         SND_PCI_QUIRK(0x17aa, 0, "Lenovo Thinkpad", AD1981_THINKPAD),
1575         /* HP nx6320 (reversed SSID, H/W bug) */
1576         SND_PCI_QUIRK(0x30b0, 0x103c, "HP nx6320", AD1981_HP),
1577         {}
1578 };
1579
1580 static int patch_ad1981(struct hda_codec *codec)
1581 {
1582         struct ad198x_spec *spec;
1583         int board_config;
1584
1585         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1586         if (spec == NULL)
1587                 return -ENOMEM;
1588
1589         codec->spec = spec;
1590
1591         spec->multiout.max_channels = 2;
1592         spec->multiout.num_dacs = ARRAY_SIZE(ad1981_dac_nids);
1593         spec->multiout.dac_nids = ad1981_dac_nids;
1594         spec->multiout.dig_out_nid = AD1981_SPDIF_OUT;
1595         spec->num_adc_nids = 1;
1596         spec->adc_nids = ad1981_adc_nids;
1597         spec->capsrc_nids = ad1981_capsrc_nids;
1598         spec->input_mux = &ad1981_capture_source;
1599         spec->num_mixers = 1;
1600         spec->mixers[0] = ad1981_mixers;
1601         spec->num_init_verbs = 1;
1602         spec->init_verbs[0] = ad1981_init_verbs;
1603         spec->spdif_route = 0;
1604 #ifdef CONFIG_SND_HDA_POWER_SAVE
1605         spec->loopback.amplist = ad1981_loopbacks;
1606 #endif
1607         spec->vmaster_nid = 0x05;
1608
1609         codec->patch_ops = ad198x_patch_ops;
1610
1611         /* override some parameters */
1612         board_config = snd_hda_check_board_config(codec, AD1981_MODELS,
1613                                                   ad1981_models,
1614                                                   ad1981_cfg_tbl);
1615         switch (board_config) {
1616         case AD1981_HP:
1617                 spec->mixers[0] = ad1981_hp_mixers;
1618                 spec->num_init_verbs = 2;
1619                 spec->init_verbs[1] = ad1981_hp_init_verbs;
1620                 spec->multiout.dig_out_nid = 0;
1621                 spec->input_mux = &ad1981_hp_capture_source;
1622
1623                 codec->patch_ops.init = ad1981_hp_init;
1624                 codec->patch_ops.unsol_event = ad1981_hp_unsol_event;
1625                 break;
1626         case AD1981_THINKPAD:
1627                 spec->mixers[0] = ad1981_thinkpad_mixers;
1628                 spec->input_mux = &ad1981_thinkpad_capture_source;
1629                 break;
1630         case AD1981_TOSHIBA:
1631                 spec->mixers[0] = ad1981_hp_mixers;
1632                 spec->mixers[1] = ad1981_toshiba_mixers;
1633                 spec->num_init_verbs = 2;
1634                 spec->init_verbs[1] = ad1981_toshiba_init_verbs;
1635                 spec->multiout.dig_out_nid = 0;
1636                 spec->input_mux = &ad1981_hp_capture_source;
1637                 codec->patch_ops.init = ad1981_hp_init;
1638                 codec->patch_ops.unsol_event = ad1981_hp_unsol_event;
1639                 break;
1640         }
1641         return 0;
1642 }
1643
1644
1645 /*
1646  * AD1988
1647  *
1648  * Output pins and routes
1649  *
1650  *        Pin               Mix     Sel     DAC (*)
1651  * port-A 0x11 (mute/hp) <- 0x22 <- 0x37 <- 03/04/06
1652  * port-B 0x14 (mute/hp) <- 0x2b <- 0x30 <- 03/04/06
1653  * port-C 0x15 (mute)    <- 0x2c <- 0x31 <- 05/0a
1654  * port-D 0x12 (mute/hp) <- 0x29         <- 04
1655  * port-E 0x17 (mute/hp) <- 0x26 <- 0x32 <- 05/0a
1656  * port-F 0x16 (mute)    <- 0x2a         <- 06
1657  * port-G 0x24 (mute)    <- 0x27         <- 05
1658  * port-H 0x25 (mute)    <- 0x28         <- 0a
1659  * mono   0x13 (mute/amp)<- 0x1e <- 0x36 <- 03/04/06
1660  *
1661  * DAC0 = 03h, DAC1 = 04h, DAC2 = 05h, DAC3 = 06h, DAC4 = 0ah
1662  * (*) DAC2/3/4 are swapped to DAC3/4/2 on AD198A rev.2 due to a h/w bug.
1663  *
1664  * Input pins and routes
1665  *
1666  *        pin     boost   mix input # / adc input #
1667  * port-A 0x11 -> 0x38 -> mix 2, ADC 0
1668  * port-B 0x14 -> 0x39 -> mix 0, ADC 1
1669  * port-C 0x15 -> 0x3a -> 33:0 - mix 1, ADC 2
1670  * port-D 0x12 -> 0x3d -> mix 3, ADC 8
1671  * port-E 0x17 -> 0x3c -> 34:0 - mix 4, ADC 4
1672  * port-F 0x16 -> 0x3b -> mix 5, ADC 3
1673  * port-G 0x24 -> N/A  -> 33:1 - mix 1, 34:1 - mix 4, ADC 6
1674  * port-H 0x25 -> N/A  -> 33:2 - mix 1, 34:2 - mix 4, ADC 7
1675  *
1676  *
1677  * DAC assignment
1678  *   6stack - front/surr/CLFE/side/opt DACs - 04/06/05/0a/03
1679  *   3stack - front/surr/CLFE/opt DACs - 04/05/0a/03
1680  *
1681  * Inputs of Analog Mix (0x20)
1682  *   0:Port-B (front mic)
1683  *   1:Port-C/G/H (line-in)
1684  *   2:Port-A
1685  *   3:Port-D (line-in/2)
1686  *   4:Port-E/G/H (mic-in)
1687  *   5:Port-F (mic2-in)
1688  *   6:CD
1689  *   7:Beep
1690  *
1691  * ADC selection
1692  *   0:Port-A
1693  *   1:Port-B (front mic-in)
1694  *   2:Port-C (line-in)
1695  *   3:Port-F (mic2-in)
1696  *   4:Port-E (mic-in)
1697  *   5:CD
1698  *   6:Port-G
1699  *   7:Port-H
1700  *   8:Port-D (line-in/2)
1701  *   9:Mix
1702  *
1703  * Proposed pin assignments by the datasheet
1704  *
1705  * 6-stack
1706  * Port-A front headphone
1707  *      B front mic-in
1708  *      C rear line-in
1709  *      D rear front-out
1710  *      E rear mic-in
1711  *      F rear surround
1712  *      G rear CLFE
1713  *      H rear side
1714  *
1715  * 3-stack
1716  * Port-A front headphone
1717  *      B front mic
1718  *      C rear line-in/surround
1719  *      D rear front-out
1720  *      E rear mic-in/CLFE
1721  *
1722  * laptop
1723  * Port-A headphone
1724  *      B mic-in
1725  *      C docking station
1726  *      D internal speaker (with EAPD)
1727  *      E/F quad mic array
1728  */
1729
1730
1731 /* models */
1732 enum {
1733         AD1988_6STACK,
1734         AD1988_6STACK_DIG,
1735         AD1988_3STACK,
1736         AD1988_3STACK_DIG,
1737         AD1988_LAPTOP,
1738         AD1988_LAPTOP_DIG,
1739         AD1988_AUTO,
1740         AD1988_MODEL_LAST,
1741 };
1742
1743 /* reivision id to check workarounds */
1744 #define AD1988A_REV2            0x100200
1745
1746 #define is_rev2(codec) \
1747         ((codec)->vendor_id == 0x11d41988 && \
1748          (codec)->revision_id == AD1988A_REV2)
1749
1750 /*
1751  * mixers
1752  */
1753
1754 static hda_nid_t ad1988_6stack_dac_nids[4] = {
1755         0x04, 0x06, 0x05, 0x0a
1756 };
1757
1758 static hda_nid_t ad1988_3stack_dac_nids[3] = {
1759         0x04, 0x05, 0x0a
1760 };
1761
1762 /* for AD1988A revision-2, DAC2-4 are swapped */
1763 static hda_nid_t ad1988_6stack_dac_nids_rev2[4] = {
1764         0x04, 0x05, 0x0a, 0x06
1765 };
1766
1767 static hda_nid_t ad1988_3stack_dac_nids_rev2[3] = {
1768         0x04, 0x0a, 0x06
1769 };
1770
1771 static hda_nid_t ad1988_adc_nids[3] = {
1772         0x08, 0x09, 0x0f
1773 };
1774
1775 static hda_nid_t ad1988_capsrc_nids[3] = {
1776         0x0c, 0x0d, 0x0e
1777 };
1778
1779 #define AD1988_SPDIF_OUT        0x02
1780 #define AD1988_SPDIF_IN         0x07
1781
1782 static struct hda_input_mux ad1988_6stack_capture_source = {
1783         .num_items = 5,
1784         .items = {
1785                 { "Front Mic", 0x1 },   /* port-B */
1786                 { "Line", 0x2 },        /* port-C */
1787                 { "Mic", 0x4 },         /* port-E */
1788                 { "CD", 0x5 },
1789                 { "Mix", 0x9 },
1790         },
1791 };
1792
1793 static struct hda_input_mux ad1988_laptop_capture_source = {
1794         .num_items = 3,
1795         .items = {
1796                 { "Mic/Line", 0x1 },    /* port-B */
1797                 { "CD", 0x5 },
1798                 { "Mix", 0x9 },
1799         },
1800 };
1801
1802 /*
1803  */
1804 static int ad198x_ch_mode_info(struct snd_kcontrol *kcontrol,
1805                                struct snd_ctl_elem_info *uinfo)
1806 {
1807         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1808         struct ad198x_spec *spec = codec->spec;
1809         return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
1810                                     spec->num_channel_mode);
1811 }
1812
1813 static int ad198x_ch_mode_get(struct snd_kcontrol *kcontrol,
1814                               struct snd_ctl_elem_value *ucontrol)
1815 {
1816         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1817         struct ad198x_spec *spec = codec->spec;
1818         return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
1819                                    spec->num_channel_mode, spec->multiout.max_channels);
1820 }
1821
1822 static int ad198x_ch_mode_put(struct snd_kcontrol *kcontrol,
1823                               struct snd_ctl_elem_value *ucontrol)
1824 {
1825         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1826         struct ad198x_spec *spec = codec->spec;
1827         int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
1828                                       spec->num_channel_mode,
1829                                       &spec->multiout.max_channels);
1830         if (err >= 0 && spec->need_dac_fix)
1831                 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
1832         return err;
1833 }
1834
1835 /* 6-stack mode */
1836 static struct snd_kcontrol_new ad1988_6stack_mixers1[] = {
1837         HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
1838         HDA_CODEC_VOLUME("Surround Playback Volume", 0x06, 0x0, HDA_OUTPUT),
1839         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT),
1840         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT),
1841         HDA_CODEC_VOLUME("Side Playback Volume", 0x0a, 0x0, HDA_OUTPUT),
1842         { } /* end */
1843 };
1844
1845 static struct snd_kcontrol_new ad1988_6stack_mixers1_rev2[] = {
1846         HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
1847         HDA_CODEC_VOLUME("Surround Playback Volume", 0x05, 0x0, HDA_OUTPUT),
1848         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
1849         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0a, 2, 0x0, HDA_OUTPUT),
1850         HDA_CODEC_VOLUME("Side Playback Volume", 0x06, 0x0, HDA_OUTPUT),
1851         { } /* end */
1852 };
1853
1854 static struct snd_kcontrol_new ad1988_6stack_mixers2[] = {
1855         HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT),
1856         HDA_BIND_MUTE("Surround Playback Switch", 0x2a, 2, HDA_INPUT),
1857         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x27, 1, 2, HDA_INPUT),
1858         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x27, 2, 2, HDA_INPUT),
1859         HDA_BIND_MUTE("Side Playback Switch", 0x28, 2, HDA_INPUT),
1860         HDA_BIND_MUTE("Headphone Playback Switch", 0x22, 2, HDA_INPUT),
1861         HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT),
1862
1863         HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x6, HDA_INPUT),
1864         HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x6, HDA_INPUT),
1865         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x0, HDA_INPUT),
1866         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x0, HDA_INPUT),
1867         HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT),
1868         HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT),
1869         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x4, HDA_INPUT),
1870         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x4, HDA_INPUT),
1871
1872         HDA_CODEC_VOLUME("Beep Playback Volume", 0x10, 0x0, HDA_OUTPUT),
1873         HDA_CODEC_MUTE("Beep Playback Switch", 0x10, 0x0, HDA_OUTPUT),
1874
1875         HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT),
1876         HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT),
1877
1878         HDA_CODEC_VOLUME("Front Mic Boost", 0x39, 0x0, HDA_OUTPUT),
1879         HDA_CODEC_VOLUME("Mic Boost", 0x3c, 0x0, HDA_OUTPUT),
1880
1881         { } /* end */
1882 };
1883
1884 /* 3-stack mode */
1885 static struct snd_kcontrol_new ad1988_3stack_mixers1[] = {
1886         HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
1887         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0a, 0x0, HDA_OUTPUT),
1888         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT),
1889         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT),
1890         { } /* end */
1891 };
1892
1893 static struct snd_kcontrol_new ad1988_3stack_mixers1_rev2[] = {
1894         HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
1895         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0a, 0x0, HDA_OUTPUT),
1896         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x06, 1, 0x0, HDA_OUTPUT),
1897         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x06, 2, 0x0, HDA_OUTPUT),
1898         { } /* end */
1899 };
1900
1901 static struct snd_kcontrol_new ad1988_3stack_mixers2[] = {
1902         HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT),
1903         HDA_BIND_MUTE("Surround Playback Switch", 0x2c, 2, HDA_INPUT),
1904         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x26, 1, 2, HDA_INPUT),
1905         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x26, 2, 2, HDA_INPUT),
1906         HDA_BIND_MUTE("Headphone Playback Switch", 0x22, 2, HDA_INPUT),
1907         HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT),
1908
1909         HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x6, HDA_INPUT),
1910         HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x6, HDA_INPUT),
1911         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x0, HDA_INPUT),
1912         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x0, HDA_INPUT),
1913         HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT),
1914         HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT),
1915         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x4, HDA_INPUT),
1916         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x4, HDA_INPUT),
1917
1918         HDA_CODEC_VOLUME("Beep Playback Volume", 0x10, 0x0, HDA_OUTPUT),
1919         HDA_CODEC_MUTE("Beep Playback Switch", 0x10, 0x0, HDA_OUTPUT),
1920
1921         HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT),
1922         HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT),
1923
1924         HDA_CODEC_VOLUME("Front Mic Boost", 0x39, 0x0, HDA_OUTPUT),
1925         HDA_CODEC_VOLUME("Mic Boost", 0x3c, 0x0, HDA_OUTPUT),
1926         {
1927                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1928                 .name = "Channel Mode",
1929                 .info = ad198x_ch_mode_info,
1930                 .get = ad198x_ch_mode_get,
1931                 .put = ad198x_ch_mode_put,
1932         },
1933
1934         { } /* end */
1935 };
1936
1937 /* laptop mode */
1938 static struct snd_kcontrol_new ad1988_laptop_mixers[] = {
1939         HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
1940         HDA_CODEC_MUTE("PCM Playback Switch", 0x29, 0x0, HDA_INPUT),
1941         HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT),
1942
1943         HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x6, HDA_INPUT),
1944         HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x6, HDA_INPUT),
1945         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x0, HDA_INPUT),
1946         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x0, HDA_INPUT),
1947         HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT),
1948         HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT),
1949
1950         HDA_CODEC_VOLUME("Beep Playback Volume", 0x10, 0x0, HDA_OUTPUT),
1951         HDA_CODEC_MUTE("Beep Playback Switch", 0x10, 0x0, HDA_OUTPUT),
1952
1953         HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT),
1954         HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT),
1955
1956         HDA_CODEC_VOLUME("Mic Boost", 0x39, 0x0, HDA_OUTPUT),
1957
1958         {
1959                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1960                 .name = "External Amplifier",
1961                 .info = ad198x_eapd_info,
1962                 .get = ad198x_eapd_get,
1963                 .put = ad198x_eapd_put,
1964                 .private_value = 0x12 | (1 << 8), /* port-D, inversed */
1965         },
1966
1967         { } /* end */
1968 };
1969
1970 /* capture */
1971 static struct snd_kcontrol_new ad1988_capture_mixers[] = {
1972         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
1973         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
1974         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
1975         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
1976         HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x0e, 0x0, HDA_OUTPUT),
1977         HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x0e, 0x0, HDA_OUTPUT),
1978         {
1979                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1980                 /* The multiple "Capture Source" controls confuse alsamixer
1981                  * So call somewhat different..
1982                  */
1983                 /* .name = "Capture Source", */
1984                 .name = "Input Source",
1985                 .count = 3,
1986                 .info = ad198x_mux_enum_info,
1987                 .get = ad198x_mux_enum_get,
1988                 .put = ad198x_mux_enum_put,
1989         },
1990         { } /* end */
1991 };
1992
1993 static int ad1988_spdif_playback_source_info(struct snd_kcontrol *kcontrol,
1994                                              struct snd_ctl_elem_info *uinfo)
1995 {
1996         static char *texts[] = {
1997                 "PCM", "ADC1", "ADC2", "ADC3"
1998         };
1999         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2000         uinfo->count = 1;
2001         uinfo->value.enumerated.items = 4;
2002         if (uinfo->value.enumerated.item >= 4)
2003                 uinfo->value.enumerated.item = 3;
2004         strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2005         return 0;
2006 }
2007
2008 static int ad1988_spdif_playback_source_get(struct snd_kcontrol *kcontrol,
2009                                             struct snd_ctl_elem_value *ucontrol)
2010 {
2011         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2012         unsigned int sel;
2013
2014         sel = snd_hda_codec_read(codec, 0x1d, 0, AC_VERB_GET_AMP_GAIN_MUTE,
2015                                  AC_AMP_GET_INPUT);
2016         if (!(sel & 0x80))
2017                 ucontrol->value.enumerated.item[0] = 0;
2018         else {
2019                 sel = snd_hda_codec_read(codec, 0x0b, 0,
2020                                          AC_VERB_GET_CONNECT_SEL, 0);
2021                 if (sel < 3)
2022                         sel++;
2023                 else
2024                         sel = 0;
2025                 ucontrol->value.enumerated.item[0] = sel;
2026         }
2027         return 0;
2028 }
2029
2030 static int ad1988_spdif_playback_source_put(struct snd_kcontrol *kcontrol,
2031                                             struct snd_ctl_elem_value *ucontrol)
2032 {
2033         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2034         unsigned int val, sel;
2035         int change;
2036
2037         val = ucontrol->value.enumerated.item[0];
2038         if (val > 3)
2039                 return -EINVAL;
2040         if (!val) {
2041                 sel = snd_hda_codec_read(codec, 0x1d, 0,
2042                                          AC_VERB_GET_AMP_GAIN_MUTE,
2043                                          AC_AMP_GET_INPUT);
2044                 change = sel & 0x80;
2045                 if (change) {
2046                         snd_hda_codec_write_cache(codec, 0x1d, 0,
2047                                                   AC_VERB_SET_AMP_GAIN_MUTE,
2048                                                   AMP_IN_UNMUTE(0));
2049                         snd_hda_codec_write_cache(codec, 0x1d, 0,
2050                                                   AC_VERB_SET_AMP_GAIN_MUTE,
2051                                                   AMP_IN_MUTE(1));
2052                 }
2053         } else {
2054                 sel = snd_hda_codec_read(codec, 0x1d, 0,
2055                                          AC_VERB_GET_AMP_GAIN_MUTE,
2056                                          AC_AMP_GET_INPUT | 0x01);
2057                 change = sel & 0x80;
2058                 if (change) {
2059                         snd_hda_codec_write_cache(codec, 0x1d, 0,
2060                                                   AC_VERB_SET_AMP_GAIN_MUTE,
2061                                                   AMP_IN_MUTE(0));
2062                         snd_hda_codec_write_cache(codec, 0x1d, 0,
2063                                                   AC_VERB_SET_AMP_GAIN_MUTE,
2064                                                   AMP_IN_UNMUTE(1));
2065                 }
2066                 sel = snd_hda_codec_read(codec, 0x0b, 0,
2067                                          AC_VERB_GET_CONNECT_SEL, 0) + 1;
2068                 change |= sel != val;
2069                 if (change)
2070                         snd_hda_codec_write_cache(codec, 0x0b, 0,
2071                                                   AC_VERB_SET_CONNECT_SEL,
2072                                                   val - 1);
2073         }
2074         return change;
2075 }
2076
2077 static struct snd_kcontrol_new ad1988_spdif_out_mixers[] = {
2078         HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
2079         {
2080                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2081                 .name = "IEC958 Playback Source",
2082                 .info = ad1988_spdif_playback_source_info,
2083                 .get = ad1988_spdif_playback_source_get,
2084                 .put = ad1988_spdif_playback_source_put,
2085         },
2086         { } /* end */
2087 };
2088
2089 static struct snd_kcontrol_new ad1988_spdif_in_mixers[] = {
2090         HDA_CODEC_VOLUME("IEC958 Capture Volume", 0x1c, 0x0, HDA_INPUT),
2091         { } /* end */
2092 };
2093
2094
2095 /*
2096  * initialization verbs
2097  */
2098
2099 /*
2100  * for 6-stack (+dig)
2101  */
2102 static struct hda_verb ad1988_6stack_init_verbs[] = {
2103         /* Front, Surround, CLFE, side DAC; unmute as default */
2104         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2105         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2106         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2107         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2108         /* Port-A front headphon path */
2109         {0x37, AC_VERB_SET_CONNECT_SEL, 0x01}, /* DAC1:04h */
2110         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2111         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2112         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2113         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2114         /* Port-D line-out path */
2115         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2116         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2117         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2118         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2119         /* Port-F surround path */
2120         {0x2a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2121         {0x2a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2122         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2123         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2124         /* Port-G CLFE path */
2125         {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2126         {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2127         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2128         {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2129         /* Port-H side path */
2130         {0x28, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2131         {0x28, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2132         {0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2133         {0x25, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2134         /* Mono out path */
2135         {0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */
2136         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2137         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2138         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2139         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */
2140         /* Port-B front mic-in path */
2141         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2142         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2143         {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2144         /* Port-C line-in path */
2145         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2146         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2147         {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2148         {0x33, AC_VERB_SET_CONNECT_SEL, 0x0},
2149         /* Port-E mic-in path */
2150         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2151         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2152         {0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2153         {0x34, AC_VERB_SET_CONNECT_SEL, 0x0},
2154         /* Analog CD Input */
2155         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2156
2157         { }
2158 };
2159
2160 static struct hda_verb ad1988_capture_init_verbs[] = {
2161         /* mute analog mix */
2162         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2163         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2164         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2165         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2166         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2167         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
2168         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2169         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2170         /* select ADCs - front-mic */
2171         {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1},
2172         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x1},
2173         {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
2174         /* ADCs; muted */
2175         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2176         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2177         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2178
2179         { }
2180 };
2181
2182 static struct hda_verb ad1988_spdif_init_verbs[] = {
2183         /* SPDIF out sel */
2184         {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */
2185         {0x0b, AC_VERB_SET_CONNECT_SEL, 0x0}, /* ADC1 */
2186         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2187         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2188         /* SPDIF out pin */
2189         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
2190
2191         { }
2192 };
2193
2194 /*
2195  * verbs for 3stack (+dig)
2196  */
2197 static struct hda_verb ad1988_3stack_ch2_init[] = {
2198         /* set port-C to line-in */
2199         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2200         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2201         /* set port-E to mic-in */
2202         { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2203         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2204         { } /* end */
2205 };
2206
2207 static struct hda_verb ad1988_3stack_ch6_init[] = {
2208         /* set port-C to surround out */
2209         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2210         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2211         /* set port-E to CLFE out */
2212         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2213         { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2214         { } /* end */
2215 };
2216
2217 static struct hda_channel_mode ad1988_3stack_modes[2] = {
2218         { 2, ad1988_3stack_ch2_init },
2219         { 6, ad1988_3stack_ch6_init },
2220 };
2221
2222 static struct hda_verb ad1988_3stack_init_verbs[] = {
2223         /* Front, Surround, CLFE, side DAC; unmute as default */
2224         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2225         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2226         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2227         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2228         /* Port-A front headphon path */
2229         {0x37, AC_VERB_SET_CONNECT_SEL, 0x01}, /* DAC1:04h */
2230         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2231         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2232         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2233         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2234         /* Port-D line-out path */
2235         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2236         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2237         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2238         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2239         /* Mono out path */
2240         {0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */
2241         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2242         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2243         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2244         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */
2245         /* Port-B front mic-in path */
2246         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2247         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2248         {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2249         /* Port-C line-in/surround path - 6ch mode as default */
2250         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2251         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2252         {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2253         {0x31, AC_VERB_SET_CONNECT_SEL, 0x0}, /* output sel: DAC 0x05 */
2254         {0x33, AC_VERB_SET_CONNECT_SEL, 0x0},
2255         /* Port-E mic-in/CLFE path - 6ch mode as default */
2256         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2257         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2258         {0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2259         {0x32, AC_VERB_SET_CONNECT_SEL, 0x1}, /* output sel: DAC 0x0a */
2260         {0x34, AC_VERB_SET_CONNECT_SEL, 0x0},
2261         /* mute analog mix */
2262         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2263         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2264         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2265         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2266         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2267         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
2268         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2269         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2270         /* select ADCs - front-mic */
2271         {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1},
2272         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x1},
2273         {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
2274         /* ADCs; muted */
2275         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2276         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2277         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2278         { }
2279 };
2280
2281 /*
2282  * verbs for laptop mode (+dig)
2283  */
2284 static struct hda_verb ad1988_laptop_hp_on[] = {
2285         /* unmute port-A and mute port-D */
2286         { 0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2287         { 0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2288         { } /* end */
2289 };
2290 static struct hda_verb ad1988_laptop_hp_off[] = {
2291         /* mute port-A and unmute port-D */
2292         { 0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2293         { 0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2294         { } /* end */
2295 };
2296
2297 #define AD1988_HP_EVENT 0x01
2298
2299 static struct hda_verb ad1988_laptop_init_verbs[] = {
2300         /* Front, Surround, CLFE, side DAC; unmute as default */
2301         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2302         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2303         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2304         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2305         /* Port-A front headphon path */
2306         {0x37, AC_VERB_SET_CONNECT_SEL, 0x01}, /* DAC1:04h */
2307         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2308         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2309         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2310         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2311         /* unsolicited event for pin-sense */
2312         {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1988_HP_EVENT },
2313         /* Port-D line-out path + EAPD */
2314         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2315         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2316         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2317         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2318         {0x12, AC_VERB_SET_EAPD_BTLENABLE, 0x00}, /* EAPD-off */
2319         /* Mono out path */
2320         {0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */
2321         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2322         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2323         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2324         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */
2325         /* Port-B mic-in path */
2326         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2327         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2328         {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2329         /* Port-C docking station - try to output */
2330         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2331         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2332         {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2333         {0x33, AC_VERB_SET_CONNECT_SEL, 0x0},
2334         /* mute analog mix */
2335         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2336         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2337         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2338         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2339         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2340         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
2341         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2342         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2343         /* select ADCs - mic */
2344         {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1},
2345         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x1},
2346         {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
2347         /* ADCs; muted */
2348         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2349         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2350         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2351         { }
2352 };
2353
2354 static void ad1988_laptop_unsol_event(struct hda_codec *codec, unsigned int res)
2355 {
2356         if ((res >> 26) != AD1988_HP_EVENT)
2357                 return;
2358         if (snd_hda_codec_read(codec, 0x11, 0, AC_VERB_GET_PIN_SENSE, 0) & (1 << 31))
2359                 snd_hda_sequence_write(codec, ad1988_laptop_hp_on);
2360         else
2361                 snd_hda_sequence_write(codec, ad1988_laptop_hp_off);
2362
2363
2364 #ifdef CONFIG_SND_HDA_POWER_SAVE
2365 static struct hda_amp_list ad1988_loopbacks[] = {
2366         { 0x20, HDA_INPUT, 0 }, /* Front Mic */
2367         { 0x20, HDA_INPUT, 1 }, /* Line */
2368         { 0x20, HDA_INPUT, 4 }, /* Mic */
2369         { 0x20, HDA_INPUT, 6 }, /* CD */
2370         { } /* end */
2371 };
2372 #endif
2373
2374 /*
2375  * Automatic parse of I/O pins from the BIOS configuration
2376  */
2377
2378 #define NUM_CONTROL_ALLOC       32
2379 #define NUM_VERB_ALLOC          32
2380
2381 enum {
2382         AD_CTL_WIDGET_VOL,
2383         AD_CTL_WIDGET_MUTE,
2384         AD_CTL_BIND_MUTE,
2385 };
2386 static struct snd_kcontrol_new ad1988_control_templates[] = {
2387         HDA_CODEC_VOLUME(NULL, 0, 0, 0),
2388         HDA_CODEC_MUTE(NULL, 0, 0, 0),
2389         HDA_BIND_MUTE(NULL, 0, 0, 0),
2390 };
2391
2392 /* add dynamic controls */
2393 static int add_control(struct ad198x_spec *spec, int type, const char *name,
2394                        unsigned long val)
2395 {
2396         struct snd_kcontrol_new *knew;
2397
2398         if (spec->num_kctl_used >= spec->num_kctl_alloc) {
2399                 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
2400
2401                 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL); /* array + terminator */
2402                 if (! knew)
2403                         return -ENOMEM;
2404                 if (spec->kctl_alloc) {
2405                         memcpy(knew, spec->kctl_alloc, sizeof(*knew) * spec->num_kctl_alloc);
2406                         kfree(spec->kctl_alloc);
2407                 }
2408                 spec->kctl_alloc = knew;
2409                 spec->num_kctl_alloc = num;
2410         }
2411
2412         knew = &spec->kctl_alloc[spec->num_kctl_used];
2413         *knew = ad1988_control_templates[type];
2414         knew->name = kstrdup(name, GFP_KERNEL);
2415         if (! knew->name)
2416                 return -ENOMEM;
2417         knew->private_value = val;
2418         spec->num_kctl_used++;
2419         return 0;
2420 }
2421
2422 #define AD1988_PIN_CD_NID               0x18
2423 #define AD1988_PIN_BEEP_NID             0x10
2424
2425 static hda_nid_t ad1988_mixer_nids[8] = {
2426         /* A     B     C     D     E     F     G     H */
2427         0x22, 0x2b, 0x2c, 0x29, 0x26, 0x2a, 0x27, 0x28
2428 };
2429
2430 static inline hda_nid_t ad1988_idx_to_dac(struct hda_codec *codec, int idx)
2431 {
2432         static hda_nid_t idx_to_dac[8] = {
2433                 /* A     B     C     D     E     F     G     H */
2434                 0x04, 0x06, 0x05, 0x04, 0x0a, 0x06, 0x05, 0x0a
2435         };
2436         static hda_nid_t idx_to_dac_rev2[8] = {
2437                 /* A     B     C     D     E     F     G     H */
2438                 0x04, 0x05, 0x0a, 0x04, 0x06, 0x05, 0x0a, 0x06
2439         };
2440         if (is_rev2(codec))
2441                 return idx_to_dac_rev2[idx];
2442         else
2443                 return idx_to_dac[idx];
2444 }
2445
2446 static hda_nid_t ad1988_boost_nids[8] = {
2447         0x38, 0x39, 0x3a, 0x3d, 0x3c, 0x3b, 0, 0
2448 };
2449
2450 static int ad1988_pin_idx(hda_nid_t nid)
2451 {
2452         static hda_nid_t ad1988_io_pins[8] = {
2453                 0x11, 0x14, 0x15, 0x12, 0x17, 0x16, 0x24, 0x25
2454         };
2455         int i;
2456         for (i = 0; i < ARRAY_SIZE(ad1988_io_pins); i++)
2457                 if (ad1988_io_pins[i] == nid)
2458                         return i;
2459         return 0; /* should be -1 */
2460 }
2461
2462 static int ad1988_pin_to_loopback_idx(hda_nid_t nid)
2463 {
2464         static int loopback_idx[8] = {
2465                 2, 0, 1, 3, 4, 5, 1, 4
2466         };
2467         switch (nid) {
2468         case AD1988_PIN_CD_NID:
2469                 return 6;
2470         default:
2471                 return loopback_idx[ad1988_pin_idx(nid)];
2472         }
2473 }
2474
2475 static int ad1988_pin_to_adc_idx(hda_nid_t nid)
2476 {
2477         static int adc_idx[8] = {
2478                 0, 1, 2, 8, 4, 3, 6, 7
2479         };
2480         switch (nid) {
2481         case AD1988_PIN_CD_NID:
2482                 return 5;
2483         default:
2484                 return adc_idx[ad1988_pin_idx(nid)];
2485         }
2486 }
2487
2488 /* fill in the dac_nids table from the parsed pin configuration */
2489 static int ad1988_auto_fill_dac_nids(struct hda_codec *codec,
2490                                      const struct auto_pin_cfg *cfg)
2491 {
2492         struct ad198x_spec *spec = codec->spec;
2493         int i, idx;
2494
2495         spec->multiout.dac_nids = spec->private_dac_nids;
2496
2497         /* check the pins hardwired to audio widget */
2498         for (i = 0; i < cfg->line_outs; i++) {
2499                 idx = ad1988_pin_idx(cfg->line_out_pins[i]);
2500                 spec->multiout.dac_nids[i] = ad1988_idx_to_dac(codec, idx);
2501         }
2502         spec->multiout.num_dacs = cfg->line_outs;
2503         return 0;
2504 }
2505
2506 /* add playback controls from the parsed DAC table */
2507 static int ad1988_auto_create_multi_out_ctls(struct ad198x_spec *spec,
2508                                              const struct auto_pin_cfg *cfg)
2509 {
2510         char name[32];
2511         static const char *chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" };
2512         hda_nid_t nid;
2513         int i, err;
2514
2515         for (i = 0; i < cfg->line_outs; i++) {
2516                 hda_nid_t dac = spec->multiout.dac_nids[i];
2517                 if (! dac)
2518                         continue;
2519                 nid = ad1988_mixer_nids[ad1988_pin_idx(cfg->line_out_pins[i])];
2520                 if (i == 2) {
2521                         /* Center/LFE */
2522                         err = add_control(spec, AD_CTL_WIDGET_VOL,
2523                                           "Center Playback Volume",
2524                                           HDA_COMPOSE_AMP_VAL(dac, 1, 0, HDA_OUTPUT));
2525                         if (err < 0)
2526                                 return err;
2527                         err = add_control(spec, AD_CTL_WIDGET_VOL,
2528                                           "LFE Playback Volume",
2529                                           HDA_COMPOSE_AMP_VAL(dac, 2, 0, HDA_OUTPUT));
2530                         if (err < 0)
2531                                 return err;
2532                         err = add_control(spec, AD_CTL_BIND_MUTE,
2533                                           "Center Playback Switch",
2534                                           HDA_COMPOSE_AMP_VAL(nid, 1, 2, HDA_INPUT));
2535                         if (err < 0)
2536                                 return err;
2537                         err = add_control(spec, AD_CTL_BIND_MUTE,
2538                                           "LFE Playback Switch",
2539                                           HDA_COMPOSE_AMP_VAL(nid, 2, 2, HDA_INPUT));
2540                         if (err < 0)
2541                                 return err;
2542                 } else {
2543                         sprintf(name, "%s Playback Volume", chname[i]);
2544                         err = add_control(spec, AD_CTL_WIDGET_VOL, name,
2545                                           HDA_COMPOSE_AMP_VAL(dac, 3, 0, HDA_OUTPUT));
2546                         if (err < 0)
2547                                 return err;
2548                         sprintf(name, "%s Playback Switch", chname[i]);
2549                         err = add_control(spec, AD_CTL_BIND_MUTE, name,
2550                                           HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
2551                         if (err < 0)
2552                                 return err;
2553                 }
2554         }
2555         return 0;
2556 }
2557
2558 /* add playback controls for speaker and HP outputs */
2559 static int ad1988_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
2560                                         const char *pfx)
2561 {
2562         struct ad198x_spec *spec = codec->spec;
2563         hda_nid_t nid;
2564         int idx, err;
2565         char name[32];
2566
2567         if (! pin)
2568                 return 0;
2569
2570         idx = ad1988_pin_idx(pin);
2571         nid = ad1988_idx_to_dac(codec, idx);
2572         /* specify the DAC as the extra output */
2573         if (! spec->multiout.hp_nid)
2574                 spec->multiout.hp_nid = nid;
2575         else
2576                 spec->multiout.extra_out_nid[0] = nid;
2577         /* control HP volume/switch on the output mixer amp */
2578         sprintf(name, "%s Playback Volume", pfx);
2579         if ((err = add_control(spec, AD_CTL_WIDGET_VOL, name,
2580                                HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
2581                 return err;
2582         nid = ad1988_mixer_nids[idx];
2583         sprintf(name, "%s Playback Switch", pfx);
2584         if ((err = add_control(spec, AD_CTL_BIND_MUTE, name,
2585                                HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT))) < 0)
2586                 return err;
2587         return 0;
2588 }
2589
2590 /* create input playback/capture controls for the given pin */
2591 static int new_analog_input(struct ad198x_spec *spec, hda_nid_t pin,
2592                             const char *ctlname, int boost)
2593 {
2594         char name[32];
2595         int err, idx;
2596
2597         sprintf(name, "%s Playback Volume", ctlname);
2598         idx = ad1988_pin_to_loopback_idx(pin);
2599         if ((err = add_control(spec, AD_CTL_WIDGET_VOL, name,
2600                                HDA_COMPOSE_AMP_VAL(0x20, 3, idx, HDA_INPUT))) < 0)
2601                 return err;
2602         sprintf(name, "%s Playback Switch", ctlname);
2603         if ((err = add_control(spec, AD_CTL_WIDGET_MUTE, name,
2604                                HDA_COMPOSE_AMP_VAL(0x20, 3, idx, HDA_INPUT))) < 0)
2605                 return err;
2606         if (boost) {
2607                 hda_nid_t bnid;
2608                 idx = ad1988_pin_idx(pin);
2609                 bnid = ad1988_boost_nids[idx];
2610                 if (bnid) {
2611                         sprintf(name, "%s Boost", ctlname);
2612                         return add_control(spec, AD_CTL_WIDGET_VOL, name,
2613                                            HDA_COMPOSE_AMP_VAL(bnid, 3, idx, HDA_OUTPUT));
2614
2615                 }
2616         }
2617         return 0;
2618 }
2619
2620 /* create playback/capture controls for input pins */
2621 static int ad1988_auto_create_analog_input_ctls(struct ad198x_spec *spec,
2622                                                 const struct auto_pin_cfg *cfg)
2623 {
2624         struct hda_input_mux *imux = &spec->private_imux;
2625         int i, err;
2626
2627         for (i = 0; i < AUTO_PIN_LAST; i++) {
2628                 err = new_analog_input(spec, cfg->input_pins[i],
2629                                        auto_pin_cfg_labels[i],
2630                                        i <= AUTO_PIN_FRONT_MIC);
2631                 if (err < 0)
2632                         return err;
2633                 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
2634                 imux->items[imux->num_items].index = ad1988_pin_to_adc_idx(cfg->input_pins[i]);
2635                 imux->num_items++;
2636         }
2637         imux->items[imux->num_items].label = "Mix";
2638         imux->items[imux->num_items].index = 9;
2639         imux->num_items++;
2640
2641         if ((err = add_control(spec, AD_CTL_WIDGET_VOL,
2642                                "Analog Mix Playback Volume",
2643                                HDA_COMPOSE_AMP_VAL(0x21, 3, 0x0, HDA_OUTPUT))) < 0)
2644                 return err;
2645         if ((err = add_control(spec, AD_CTL_WIDGET_MUTE,
2646                                "Analog Mix Playback Switch",
2647                                HDA_COMPOSE_AMP_VAL(0x21, 3, 0x0, HDA_OUTPUT))) < 0)
2648                 return err;
2649
2650         return 0;
2651 }
2652
2653 static void ad1988_auto_set_output_and_unmute(struct hda_codec *codec,
2654                                               hda_nid_t nid, int pin_type,
2655                                               int dac_idx)
2656 {
2657         /* set as output */
2658         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
2659         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
2660         switch (nid) {
2661         case 0x11: /* port-A - DAC 04 */
2662                 snd_hda_codec_write(codec, 0x37, 0, AC_VERB_SET_CONNECT_SEL, 0x01);
2663                 break;
2664         case 0x14: /* port-B - DAC 06 */
2665                 snd_hda_codec_write(codec, 0x30, 0, AC_VERB_SET_CONNECT_SEL, 0x02);
2666                 break;
2667         case 0x15: /* port-C - DAC 05 */
2668                 snd_hda_codec_write(codec, 0x31, 0, AC_VERB_SET_CONNECT_SEL, 0x00);
2669                 break;
2670         case 0x17: /* port-E - DAC 0a */
2671                 snd_hda_codec_write(codec, 0x32, 0, AC_VERB_SET_CONNECT_SEL, 0x01);
2672                 break;
2673         case 0x13: /* mono - DAC 04 */
2674                 snd_hda_codec_write(codec, 0x36, 0, AC_VERB_SET_CONNECT_SEL, 0x01);
2675                 break;
2676         }
2677 }
2678
2679 static void ad1988_auto_init_multi_out(struct hda_codec *codec)
2680 {
2681         struct ad198x_spec *spec = codec->spec;
2682         int i;
2683
2684         for (i = 0; i < spec->autocfg.line_outs; i++) {
2685                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
2686                 ad1988_auto_set_output_and_unmute(codec, nid, PIN_OUT, i);
2687         }
2688 }
2689
2690 static void ad1988_auto_init_extra_out(struct hda_codec *codec)
2691 {
2692         struct ad198x_spec *spec = codec->spec;
2693         hda_nid_t pin;
2694
2695         pin = spec->autocfg.speaker_pins[0];
2696         if (pin) /* connect to front */
2697                 ad1988_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
2698         pin = spec->autocfg.hp_pins[0];
2699         if (pin) /* connect to front */
2700                 ad1988_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
2701 }
2702
2703 static void ad1988_auto_init_analog_input(struct hda_codec *codec)
2704 {
2705         struct ad198x_spec *spec = codec->spec;
2706         int i, idx;
2707
2708         for (i = 0; i < AUTO_PIN_LAST; i++) {
2709                 hda_nid_t nid = spec->autocfg.input_pins[i];
2710                 if (! nid)
2711                         continue;
2712                 switch (nid) {
2713                 case 0x15: /* port-C */
2714                         snd_hda_codec_write(codec, 0x33, 0, AC_VERB_SET_CONNECT_SEL, 0x0);
2715                         break;
2716                 case 0x17: /* port-E */
2717                         snd_hda_codec_write(codec, 0x34, 0, AC_VERB_SET_CONNECT_SEL, 0x0);
2718                         break;
2719                 }
2720                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
2721                                     i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN);
2722                 if (nid != AD1988_PIN_CD_NID)
2723                         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
2724                                             AMP_OUT_MUTE);
2725                 idx = ad1988_pin_idx(nid);
2726                 if (ad1988_boost_nids[idx])
2727                         snd_hda_codec_write(codec, ad1988_boost_nids[idx], 0,
2728                                             AC_VERB_SET_AMP_GAIN_MUTE,
2729                                             AMP_OUT_ZERO);
2730         }
2731 }
2732
2733 /* parse the BIOS configuration and set up the alc_spec */
2734 /* return 1 if successful, 0 if the proper config is not found, or a negative error code */
2735 static int ad1988_parse_auto_config(struct hda_codec *codec)
2736 {
2737         struct ad198x_spec *spec = codec->spec;
2738         int err;
2739
2740         if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL)) < 0)
2741                 return err;
2742         if ((err = ad1988_auto_fill_dac_nids(codec, &spec->autocfg)) < 0)
2743                 return err;
2744         if (! spec->autocfg.line_outs)
2745                 return 0; /* can't find valid BIOS pin config */
2746         if ((err = ad1988_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 ||
2747             (err = ad1988_auto_create_extra_out(codec,
2748                                                 spec->autocfg.speaker_pins[0],
2749                                                 "Speaker")) < 0 ||
2750             (err = ad1988_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
2751                                                 "Headphone")) < 0 ||
2752             (err = ad1988_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0)
2753                 return err;
2754
2755         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
2756
2757         if (spec->autocfg.dig_out_pin)
2758                 spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
2759         if (spec->autocfg.dig_in_pin)
2760                 spec->dig_in_nid = AD1988_SPDIF_IN;
2761
2762         if (spec->kctl_alloc)
2763                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
2764
2765         spec->init_verbs[spec->num_init_verbs++] = ad1988_6stack_init_verbs;
2766
2767         spec->input_mux = &spec->private_imux;
2768
2769         return 1;
2770 }
2771
2772 /* init callback for auto-configuration model -- overriding the default init */
2773 static int ad1988_auto_init(struct hda_codec *codec)
2774 {
2775         ad198x_init(codec);
2776         ad1988_auto_init_multi_out(codec);
2777         ad1988_auto_init_extra_out(codec);
2778         ad1988_auto_init_analog_input(codec);
2779         return 0;
2780 }
2781
2782
2783 /*
2784  */
2785
2786 static const char *ad1988_models[AD1988_MODEL_LAST] = {
2787         [AD1988_6STACK]         = "6stack",
2788         [AD1988_6STACK_DIG]     = "6stack-dig",
2789         [AD1988_3STACK]         = "3stack",
2790         [AD1988_3STACK_DIG]     = "3stack-dig",
2791         [AD1988_LAPTOP]         = "laptop",
2792         [AD1988_LAPTOP_DIG]     = "laptop-dig",
2793         [AD1988_AUTO]           = "auto",
2794 };
2795
2796 static struct snd_pci_quirk ad1988_cfg_tbl[] = {
2797         SND_PCI_QUIRK(0x1043, 0x81ec, "Asus P5B-DLX", AD1988_6STACK_DIG),
2798         SND_PCI_QUIRK(0x1043, 0x81f6, "Asus M2N-SLI", AD1988_6STACK_DIG),
2799         {}
2800 };
2801
2802 static int patch_ad1988(struct hda_codec *codec)
2803 {
2804         struct ad198x_spec *spec;
2805         int board_config;
2806
2807         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2808         if (spec == NULL)
2809                 return -ENOMEM;
2810
2811         codec->spec = spec;
2812
2813         if (is_rev2(codec))
2814                 snd_printk(KERN_INFO "patch_analog: AD1988A rev.2 is detected, enable workarounds\n");
2815
2816         board_config = snd_hda_check_board_config(codec, AD1988_MODEL_LAST,
2817                                                   ad1988_models, ad1988_cfg_tbl);
2818         if (board_config < 0) {
2819                 printk(KERN_INFO "hda_codec: Unknown model for AD1988, trying auto-probe from BIOS...\n");
2820                 board_config = AD1988_AUTO;
2821         }
2822
2823         if (board_config == AD1988_AUTO) {
2824                 /* automatic parse from the BIOS config */
2825                 int err = ad1988_parse_auto_config(codec);
2826                 if (err < 0) {
2827                         ad198x_free(codec);
2828                         return err;
2829                 } else if (! err) {
2830                         printk(KERN_INFO "hda_codec: Cannot set up configuration from BIOS.  Using 6-stack mode...\n");
2831                         board_config = AD1988_6STACK;
2832                 }
2833         }
2834
2835         switch (board_config) {
2836         case AD1988_6STACK:
2837         case AD1988_6STACK_DIG:
2838                 spec->multiout.max_channels = 8;
2839                 spec->multiout.num_dacs = 4;
2840                 if (is_rev2(codec))
2841                         spec->multiout.dac_nids = ad1988_6stack_dac_nids_rev2;
2842                 else
2843                         spec->multiout.dac_nids = ad1988_6stack_dac_nids;
2844                 spec->input_mux = &ad1988_6stack_capture_source;
2845                 spec->num_mixers = 2;
2846                 if (is_rev2(codec))
2847                         spec->mixers[0] = ad1988_6stack_mixers1_rev2;
2848                 else
2849                         spec->mixers[0] = ad1988_6stack_mixers1;
2850                 spec->mixers[1] = ad1988_6stack_mixers2;
2851                 spec->num_init_verbs = 1;
2852                 spec->init_verbs[0] = ad1988_6stack_init_verbs;
2853                 if (board_config == AD1988_6STACK_DIG) {
2854                         spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
2855                         spec->dig_in_nid = AD1988_SPDIF_IN;
2856                 }
2857                 break;
2858         case AD1988_3STACK:
2859         case AD1988_3STACK_DIG:
2860                 spec->multiout.max_channels = 6;
2861                 spec->multiout.num_dacs = 3;
2862                 if (is_rev2(codec))
2863                         spec->multiout.dac_nids = ad1988_3stack_dac_nids_rev2;
2864                 else
2865                         spec->multiout.dac_nids = ad1988_3stack_dac_nids;
2866                 spec->input_mux = &ad1988_6stack_capture_source;
2867                 spec->channel_mode = ad1988_3stack_modes;
2868                 spec->num_channel_mode = ARRAY_SIZE(ad1988_3stack_modes);
2869                 spec->num_mixers = 2;
2870                 if (is_rev2(codec))
2871                         spec->mixers[0] = ad1988_3stack_mixers1_rev2;
2872                 else
2873                         spec->mixers[0] = ad1988_3stack_mixers1;
2874                 spec->mixers[1] = ad1988_3stack_mixers2;
2875                 spec->num_init_verbs = 1;
2876                 spec->init_verbs[0] = ad1988_3stack_init_verbs;
2877                 if (board_config == AD1988_3STACK_DIG)
2878                         spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
2879                 break;
2880         case AD1988_LAPTOP:
2881         case AD1988_LAPTOP_DIG:
2882                 spec->multiout.max_channels = 2;
2883                 spec->multiout.num_dacs = 1;
2884                 spec->multiout.dac_nids = ad1988_3stack_dac_nids;
2885                 spec->input_mux = &ad1988_laptop_capture_source;
2886                 spec->num_mixers = 1;
2887                 spec->mixers[0] = ad1988_laptop_mixers;
2888                 spec->num_init_verbs = 1;
2889                 spec->init_verbs[0] = ad1988_laptop_init_verbs;
2890                 if (board_config == AD1988_LAPTOP_DIG)
2891                         spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
2892                 break;
2893         }
2894
2895         spec->num_adc_nids = ARRAY_SIZE(ad1988_adc_nids);
2896         spec->adc_nids = ad1988_adc_nids;
2897         spec->capsrc_nids = ad1988_capsrc_nids;
2898         spec->mixers[spec->num_mixers++] = ad1988_capture_mixers;
2899         spec->init_verbs[spec->num_init_verbs++] = ad1988_capture_init_verbs;
2900         if (spec->multiout.dig_out_nid) {
2901                 spec->mixers[spec->num_mixers++] = ad1988_spdif_out_mixers;
2902                 spec->init_verbs[spec->num_init_verbs++] = ad1988_spdif_init_verbs;
2903         }
2904         if (spec->dig_in_nid)
2905                 spec->mixers[spec->num_mixers++] = ad1988_spdif_in_mixers;
2906
2907         codec->patch_ops = ad198x_patch_ops;
2908         switch (board_config) {
2909         case AD1988_AUTO:
2910                 codec->patch_ops.init = ad1988_auto_init;
2911                 break;
2912         case AD1988_LAPTOP:
2913         case AD1988_LAPTOP_DIG:
2914                 codec->patch_ops.unsol_event = ad1988_laptop_unsol_event;
2915                 break;
2916         }
2917 #ifdef CONFIG_SND_HDA_POWER_SAVE
2918         spec->loopback.amplist = ad1988_loopbacks;
2919 #endif
2920         spec->vmaster_nid = 0x04;
2921
2922         return 0;
2923 }
2924
2925
2926 /*
2927  * AD1884 / AD1984
2928  *
2929  * port-B - front line/mic-in
2930  * port-E - aux in/out
2931  * port-F - aux in/out
2932  * port-C - rear line/mic-in
2933  * port-D - rear line/hp-out
2934  * port-A - front line/hp-out
2935  *
2936  * AD1984 = AD1884 + two digital mic-ins
2937  *
2938  * FIXME:
2939  * For simplicity, we share the single DAC for both HP and line-outs
2940  * right now.  The inidividual playbacks could be easily implemented,
2941  * but no build-up framework is given, so far.
2942  */
2943
2944 static hda_nid_t ad1884_dac_nids[1] = {
2945         0x04,
2946 };
2947
2948 static hda_nid_t ad1884_adc_nids[2] = {
2949         0x08, 0x09,
2950 };
2951
2952 static hda_nid_t ad1884_capsrc_nids[2] = {
2953         0x0c, 0x0d,
2954 };
2955
2956 #define AD1884_SPDIF_OUT        0x02
2957
2958 static struct hda_input_mux ad1884_capture_source = {
2959         .num_items = 4,
2960         .items = {
2961                 { "Front Mic", 0x0 },
2962                 { "Mic", 0x1 },
2963                 { "CD", 0x2 },
2964                 { "Mix", 0x3 },
2965         },
2966 };
2967
2968 static struct snd_kcontrol_new ad1884_base_mixers[] = {
2969         HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
2970         /* HDA_CODEC_VOLUME_IDX("PCM Playback Volume", 1, 0x03, 0x0, HDA_OUTPUT), */
2971         HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
2972         HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT),
2973         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
2974         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
2975         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
2976         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
2977         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
2978         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
2979         HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x02, HDA_INPUT),
2980         HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x02, HDA_INPUT),
2981         /*
2982         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x20, 0x03, HDA_INPUT),
2983         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x20, 0x03, HDA_INPUT),
2984         HDA_CODEC_VOLUME("Digital Beep Playback Volume", 0x10, 0x0, HDA_OUTPUT),
2985         HDA_CODEC_MUTE("Digital Beep Playback Switch", 0x10, 0x0, HDA_OUTPUT),
2986         */
2987         HDA_CODEC_VOLUME("Mic Boost", 0x15, 0x0, HDA_INPUT),
2988         HDA_CODEC_VOLUME("Front Mic Boost", 0x14, 0x0, HDA_INPUT),
2989         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
2990         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
2991         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
2992         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
2993         {
2994                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2995                 /* The multiple "Capture Source" controls confuse alsamixer
2996                  * So call somewhat different..
2997                  */
2998                 /* .name = "Capture Source", */
2999                 .name = "Input Source",
3000                 .count = 2,
3001                 .info = ad198x_mux_enum_info,
3002                 .get = ad198x_mux_enum_get,
3003                 .put = ad198x_mux_enum_put,
3004         },
3005         /* SPDIF controls */
3006         HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
3007         {
3008                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3009                 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
3010                 /* identical with ad1983 */
3011                 .info = ad1983_spdif_route_info,
3012                 .get = ad1983_spdif_route_get,
3013                 .put = ad1983_spdif_route_put,
3014         },
3015         { } /* end */
3016 };
3017
3018 static struct snd_kcontrol_new ad1984_dmic_mixers[] = {
3019         HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x05, 0x0, HDA_INPUT),
3020         HDA_CODEC_MUTE("Digital Mic Capture Switch", 0x05, 0x0, HDA_INPUT),
3021         HDA_CODEC_VOLUME_IDX("Digital Mic Capture Volume", 1, 0x06, 0x0,
3022                              HDA_INPUT),
3023         HDA_CODEC_MUTE_IDX("Digital Mic Capture Switch", 1, 0x06, 0x0,
3024                            HDA_INPUT),
3025         { } /* end */
3026 };
3027
3028 /*
3029  * initialization verbs
3030  */
3031 static struct hda_verb ad1884_init_verbs[] = {
3032         /* DACs; mute as default */
3033         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3034         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3035         /* Port-A (HP) mixer */
3036         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3037         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3038         /* Port-A pin */
3039         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3040         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3041         /* HP selector - select DAC2 */
3042         {0x22, AC_VERB_SET_CONNECT_SEL, 0x1},
3043         /* Port-D (Line-out) mixer */
3044         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3045         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3046         /* Port-D pin */
3047         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3048         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3049         /* Mono-out mixer */
3050         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3051         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3052         /* Mono-out pin */
3053         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3054         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3055         /* Mono selector */
3056         {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
3057         /* Port-B (front mic) pin */
3058         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3059         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3060         /* Port-C (rear mic) pin */
3061         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3062         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3063         /* Analog mixer; mute as default */
3064         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3065         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3066         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3067         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3068         /* Analog Mix output amp */
3069         {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
3070         /* SPDIF output selector */
3071         {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */
3072         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
3073         { } /* end */
3074 };
3075
3076 #ifdef CONFIG_SND_HDA_POWER_SAVE
3077 static struct hda_amp_list ad1884_loopbacks[] = {
3078         { 0x20, HDA_INPUT, 0 }, /* Front Mic */
3079         { 0x20, HDA_INPUT, 1 }, /* Mic */
3080         { 0x20, HDA_INPUT, 2 }, /* CD */
3081         { 0x20, HDA_INPUT, 4 }, /* Docking */
3082         { } /* end */
3083 };
3084 #endif
3085
3086 static const char *ad1884_slave_vols[] = {
3087         "PCM Playback Volume",
3088         "Mic Playback Volume",
3089         "Mono Playback Volume",
3090         "Front Mic Playback Volume",
3091         "Mic Playback Volume",
3092         "CD Playback Volume",
3093         "Internal Mic Playback Volume",
3094         "Docking Mic Playback Volume"
3095         "Beep Playback Volume",
3096         "IEC958 Playback Volume",
3097         NULL
3098 };
3099
3100 static int patch_ad1884(struct hda_codec *codec)
3101 {
3102         struct ad198x_spec *spec;
3103
3104         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3105         if (spec == NULL)
3106                 return -ENOMEM;
3107
3108         mutex_init(&spec->amp_mutex);
3109         codec->spec = spec;
3110
3111         spec->multiout.max_channels = 2;
3112         spec->multiout.num_dacs = ARRAY_SIZE(ad1884_dac_nids);
3113         spec->multiout.dac_nids = ad1884_dac_nids;
3114         spec->multiout.dig_out_nid = AD1884_SPDIF_OUT;
3115         spec->num_adc_nids = ARRAY_SIZE(ad1884_adc_nids);
3116         spec->adc_nids = ad1884_adc_nids;
3117         spec->capsrc_nids = ad1884_capsrc_nids;
3118         spec->input_mux = &ad1884_capture_source;
3119         spec->num_mixers = 1;
3120         spec->mixers[0] = ad1884_base_mixers;
3121         spec->num_init_verbs = 1;
3122         spec->init_verbs[0] = ad1884_init_verbs;
3123         spec->spdif_route = 0;
3124 #ifdef CONFIG_SND_HDA_POWER_SAVE
3125         spec->loopback.amplist = ad1884_loopbacks;
3126 #endif
3127         spec->vmaster_nid = 0x04;
3128         /* we need to cover all playback volumes */
3129         spec->slave_vols = ad1884_slave_vols;
3130
3131         codec->patch_ops = ad198x_patch_ops;
3132
3133         return 0;
3134 }
3135
3136 /*
3137  * Lenovo Thinkpad T61/X61
3138  */
3139 static struct hda_input_mux ad1984_thinkpad_capture_source = {
3140         .num_items = 3,
3141         .items = {
3142                 { "Mic", 0x0 },
3143                 { "Internal Mic", 0x1 },
3144                 { "Mix", 0x3 },
3145         },
3146 };
3147
3148
3149 /*
3150  * Dell Precision T3400
3151  */
3152 static struct hda_input_mux ad1984_dell_desktop_capture_source = {
3153         .num_items = 3,
3154         .items = {
3155                 { "Front Mic", 0x0 },
3156                 { "Line-In", 0x1 },
3157                 { "Mix", 0x3 },
3158         },
3159 };
3160
3161
3162 static struct snd_kcontrol_new ad1984_thinkpad_mixers[] = {
3163         HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
3164         /* HDA_CODEC_VOLUME_IDX("PCM Playback Volume", 1, 0x03, 0x0, HDA_OUTPUT), */
3165         HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
3166         HDA_CODEC_MUTE("Speaker Playback Switch", 0x12, 0x0, HDA_OUTPUT),
3167         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
3168         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3169         HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
3170         HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
3171         HDA_CODEC_VOLUME("Docking Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
3172         HDA_CODEC_MUTE("Docking Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
3173         HDA_CODEC_VOLUME("Mic Boost", 0x14, 0x0, HDA_INPUT),
3174         HDA_CODEC_VOLUME("Internal Mic Boost", 0x15, 0x0, HDA_INPUT),
3175         HDA_CODEC_VOLUME("Docking Mic Boost", 0x25, 0x0, HDA_OUTPUT),
3176         HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x03, HDA_INPUT),
3177         HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x03, HDA_INPUT),
3178         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3179         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3180         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
3181         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
3182         {
3183                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3184                 /* The multiple "Capture Source" controls confuse alsamixer
3185                  * So call somewhat different..
3186                  */
3187                 /* .name = "Capture Source", */
3188                 .name = "Input Source",
3189                 .count = 2,
3190                 .info = ad198x_mux_enum_info,
3191                 .get = ad198x_mux_enum_get,
3192                 .put = ad198x_mux_enum_put,
3193         },
3194         /* SPDIF controls */
3195         HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
3196         {
3197                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3198                 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
3199                 /* identical with ad1983 */
3200                 .info = ad1983_spdif_route_info,
3201                 .get = ad1983_spdif_route_get,
3202                 .put = ad1983_spdif_route_put,
3203         },
3204         { } /* end */
3205 };
3206
3207 /* additional verbs */
3208 static struct hda_verb ad1984_thinkpad_init_verbs[] = {
3209         /* Port-E (docking station mic) pin */
3210         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3211         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3212         /* docking mic boost */
3213         {0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3214         /* Analog mixer - docking mic; mute as default */
3215         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3216         /* enable EAPD bit */
3217         {0x12, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
3218         { } /* end */
3219 };
3220
3221 /*
3222  * Dell Precision T3400
3223  */
3224 static struct snd_kcontrol_new ad1984_dell_desktop_mixers[] = {
3225         HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
3226         HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
3227         HDA_CODEC_MUTE("Speaker Playback Switch", 0x12, 0x0, HDA_OUTPUT),
3228         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
3229         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
3230         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
3231         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3232         HDA_CODEC_VOLUME("Line-In Playback Volume", 0x20, 0x01, HDA_INPUT),
3233         HDA_CODEC_MUTE("Line-In Playback Switch", 0x20, 0x01, HDA_INPUT),
3234         /*
3235         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x20, 0x03, HDA_INPUT),
3236         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x20, 0x03, HDA_INPUT),
3237         */
3238         HDA_CODEC_VOLUME("Line-In Boost", 0x15, 0x0, HDA_INPUT),
3239         HDA_CODEC_VOLUME("Front Mic Boost", 0x14, 0x0, HDA_INPUT),
3240         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3241         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3242         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
3243         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
3244         {
3245                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3246                 /* The multiple "Capture Source" controls confuse alsamixer
3247                  * So call somewhat different..
3248                  */
3249                 /* .name = "Capture Source", */
3250                 .name = "Input Source",
3251                 .count = 2,
3252                 .info = ad198x_mux_enum_info,
3253                 .get = ad198x_mux_enum_get,
3254                 .put = ad198x_mux_enum_put,
3255         },
3256         { } /* end */
3257 };
3258
3259 /* Digial MIC ADC NID 0x05 + 0x06 */
3260 static int ad1984_pcm_dmic_prepare(struct hda_pcm_stream *hinfo,
3261                                    struct hda_codec *codec,
3262                                    unsigned int stream_tag,
3263                                    unsigned int format,
3264                                    struct snd_pcm_substream *substream)
3265 {
3266         snd_hda_codec_setup_stream(codec, 0x05 + substream->number,
3267                                    stream_tag, 0, format);
3268         return 0;
3269 }
3270
3271 static int ad1984_pcm_dmic_cleanup(struct hda_pcm_stream *hinfo,
3272                                    struct hda_codec *codec,
3273                                    struct snd_pcm_substream *substream)
3274 {
3275         snd_hda_codec_setup_stream(codec, 0x05 + substream->number,
3276                                    0, 0, 0);
3277         return 0;
3278 }
3279
3280 static struct hda_pcm_stream ad1984_pcm_dmic_capture = {
3281         .substreams = 2,
3282         .channels_min = 2,
3283         .channels_max = 2,
3284         .nid = 0x05,
3285         .ops = {
3286                 .prepare = ad1984_pcm_dmic_prepare,
3287                 .cleanup = ad1984_pcm_dmic_cleanup
3288         },
3289 };
3290
3291 static int ad1984_build_pcms(struct hda_codec *codec)
3292 {
3293         struct ad198x_spec *spec = codec->spec;
3294         struct hda_pcm *info;
3295         int err;
3296
3297         err = ad198x_build_pcms(codec);
3298         if (err < 0)
3299                 return err;
3300
3301         info = spec->pcm_rec + codec->num_pcms;
3302         codec->num_pcms++;
3303         info->name = "AD1984 Digital Mic";
3304         info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad1984_pcm_dmic_capture;
3305         return 0;
3306 }
3307
3308 /* models */
3309 enum {
3310         AD1984_BASIC,
3311         AD1984_THINKPAD,
3312         AD1984_DELL_DESKTOP,
3313         AD1984_MODELS
3314 };
3315
3316 static const char *ad1984_models[AD1984_MODELS] = {
3317         [AD1984_BASIC]          = "basic",
3318         [AD1984_THINKPAD]       = "thinkpad",
3319         [AD1984_DELL_DESKTOP]   = "dell_desktop",
3320 };
3321
3322 static struct snd_pci_quirk ad1984_cfg_tbl[] = {
3323         /* Lenovo Thinkpad T61/X61 */
3324         SND_PCI_QUIRK(0x17aa, 0, "Lenovo Thinkpad", AD1984_THINKPAD),
3325         SND_PCI_QUIRK(0x1028, 0x0214, "Dell T3400", AD1984_DELL_DESKTOP),
3326         {}
3327 };
3328
3329 static int patch_ad1984(struct hda_codec *codec)
3330 {
3331         struct ad198x_spec *spec;
3332         int board_config, err;
3333
3334         err = patch_ad1884(codec);
3335         if (err < 0)
3336                 return err;
3337         spec = codec->spec;
3338         board_config = snd_hda_check_board_config(codec, AD1984_MODELS,
3339                                                   ad1984_models, ad1984_cfg_tbl);
3340         switch (board_config) {
3341         case AD1984_BASIC:
3342                 /* additional digital mics */
3343                 spec->mixers[spec->num_mixers++] = ad1984_dmic_mixers;
3344                 codec->patch_ops.build_pcms = ad1984_build_pcms;
3345                 break;
3346         case AD1984_THINKPAD:
3347                 spec->multiout.dig_out_nid = AD1884_SPDIF_OUT;
3348                 spec->input_mux = &ad1984_thinkpad_capture_source;
3349                 spec->mixers[0] = ad1984_thinkpad_mixers;
3350                 spec->init_verbs[spec->num_init_verbs++] = ad1984_thinkpad_init_verbs;
3351                 break;
3352         case AD1984_DELL_DESKTOP:
3353                 spec->multiout.dig_out_nid = 0;
3354                 spec->input_mux = &ad1984_dell_desktop_capture_source;
3355                 spec->mixers[0] = ad1984_dell_desktop_mixers;
3356                 break;
3357         }
3358         return 0;
3359 }
3360
3361
3362 /*
3363  * AD1882
3364  *
3365  * port-A - front hp-out
3366  * port-B - front mic-in
3367  * port-C - rear line-in, shared surr-out (3stack)
3368  * port-D - rear line-out
3369  * port-E - rear mic-in, shared clfe-out (3stack)
3370  * port-F - rear surr-out (6stack)
3371  * port-G - rear clfe-out (6stack)
3372  */
3373
3374 static hda_nid_t ad1882_dac_nids[3] = {
3375         0x04, 0x03, 0x05
3376 };
3377
3378 static hda_nid_t ad1882_adc_nids[2] = {
3379         0x08, 0x09,
3380 };
3381
3382 static hda_nid_t ad1882_capsrc_nids[2] = {
3383         0x0c, 0x0d,
3384 };
3385
3386 #define AD1882_SPDIF_OUT        0x02
3387
3388 /* list: 0x11, 0x39, 0x3a, 0x18, 0x3c, 0x3b, 0x12, 0x20 */
3389 static struct hda_input_mux ad1882_capture_source = {
3390         .num_items = 5,
3391         .items = {
3392                 { "Front Mic", 0x1 },
3393                 { "Mic", 0x4 },
3394                 { "Line", 0x2 },
3395                 { "CD", 0x3 },
3396                 { "Mix", 0x7 },
3397         },
3398 };
3399
3400 static struct snd_kcontrol_new ad1882_base_mixers[] = {
3401         HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
3402         HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
3403         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT),
3404         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT),
3405         HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
3406         HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT),
3407         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
3408         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
3409         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
3410         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3411         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
3412         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
3413         HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x04, HDA_INPUT),
3414         HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x04, HDA_INPUT),
3415         HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x06, HDA_INPUT),
3416         HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x06, HDA_INPUT),
3417         HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x07, HDA_INPUT),
3418         HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x07, HDA_INPUT),
3419         HDA_CODEC_VOLUME("Mic Boost", 0x3c, 0x0, HDA_OUTPUT),
3420         HDA_CODEC_VOLUME("Front Mic Boost", 0x39, 0x0, HDA_OUTPUT),
3421         HDA_CODEC_VOLUME("Line-In Boost", 0x3a, 0x0, HDA_OUTPUT),
3422         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3423         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3424         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
3425         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
3426         {
3427                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3428                 /* The multiple "Capture Source" controls confuse alsamixer
3429                  * So call somewhat different..
3430                  */
3431                 /* .name = "Capture Source", */
3432                 .name = "Input Source",
3433                 .count = 2,
3434                 .info = ad198x_mux_enum_info,
3435                 .get = ad198x_mux_enum_get,
3436                 .put = ad198x_mux_enum_put,
3437         },
3438         /* SPDIF controls */
3439         HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
3440         {
3441                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3442                 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
3443                 /* identical with ad1983 */
3444                 .info = ad1983_spdif_route_info,
3445                 .get = ad1983_spdif_route_get,
3446                 .put = ad1983_spdif_route_put,
3447         },
3448         { } /* end */
3449 };
3450
3451 static struct snd_kcontrol_new ad1882_3stack_mixers[] = {
3452         HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
3453         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x17, 1, 0x0, HDA_OUTPUT),
3454         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x17, 2, 0x0, HDA_OUTPUT),
3455         {
3456                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3457                 .name = "Channel Mode",
3458                 .info = ad198x_ch_mode_info,
3459                 .get = ad198x_ch_mode_get,
3460                 .put = ad198x_ch_mode_put,
3461         },
3462         { } /* end */
3463 };
3464
3465 static struct snd_kcontrol_new ad1882_6stack_mixers[] = {
3466         HDA_CODEC_MUTE("Surround Playback Switch", 0x16, 0x0, HDA_OUTPUT),
3467         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x24, 1, 0x0, HDA_OUTPUT),
3468         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x24, 2, 0x0, HDA_OUTPUT),
3469         { } /* end */
3470 };
3471
3472 static struct hda_verb ad1882_ch2_init[] = {
3473         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3474         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3475         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3476         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3477         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3478         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3479         { } /* end */
3480 };
3481
3482 static struct hda_verb ad1882_ch4_init[] = {
3483         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3484         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3485         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3486         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3487         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3488         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3489         { } /* end */
3490 };
3491
3492 static struct hda_verb ad1882_ch6_init[] = {
3493         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3494         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3495         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3496         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3497         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3498         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3499         { } /* end */
3500 };
3501
3502 static struct hda_channel_mode ad1882_modes[3] = {
3503         { 2, ad1882_ch2_init },
3504         { 4, ad1882_ch4_init },
3505         { 6, ad1882_ch6_init },
3506 };
3507
3508 /*
3509  * initialization verbs
3510  */
3511 static struct hda_verb ad1882_init_verbs[] = {
3512         /* DACs; mute as default */
3513         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3514         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3515         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3516         /* Port-A (HP) mixer */
3517         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3518         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3519         /* Port-A pin */
3520         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3521         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3522         /* HP selector - select DAC2 */
3523         {0x37, AC_VERB_SET_CONNECT_SEL, 0x1},
3524         /* Port-D (Line-out) mixer */
3525         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3526         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3527         /* Port-D pin */
3528         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3529         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3530         /* Mono-out mixer */
3531         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3532         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3533         /* Mono-out pin */
3534         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3535         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3536         /* Port-B (front mic) pin */
3537         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3538         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3539         {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */
3540         /* Port-C (line-in) pin */
3541         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3542         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3543         {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */
3544         /* Port-C mixer - mute as input */
3545         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3546         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3547         /* Port-E (mic-in) pin */
3548         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3549         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3550         {0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */
3551         /* Port-E mixer - mute as input */
3552         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3553         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3554         /* Port-F (surround) */
3555         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3556         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3557         /* Port-G (CLFE) */
3558         {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3559         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3560         /* Analog mixer; mute as default */
3561         /* list: 0x39, 0x3a, 0x11, 0x12, 0x3c, 0x3b, 0x18, 0x1a */
3562         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3563         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3564         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3565         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3566         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3567         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
3568         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3569         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3570         /* Analog Mix output amp */
3571         {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
3572         /* SPDIF output selector */
3573         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
3574         {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */
3575         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
3576         { } /* end */
3577 };
3578
3579 #ifdef CONFIG_SND_HDA_POWER_SAVE
3580 static struct hda_amp_list ad1882_loopbacks[] = {
3581         { 0x20, HDA_INPUT, 0 }, /* Front Mic */
3582         { 0x20, HDA_INPUT, 1 }, /* Mic */
3583         { 0x20, HDA_INPUT, 4 }, /* Line */
3584         { 0x20, HDA_INPUT, 6 }, /* CD */
3585         { } /* end */
3586 };
3587 #endif
3588
3589 /* models */
3590 enum {
3591         AD1882_3STACK,
3592         AD1882_6STACK,
3593         AD1882_MODELS
3594 };
3595
3596 static const char *ad1882_models[AD1986A_MODELS] = {
3597         [AD1882_3STACK]         = "3stack",
3598         [AD1882_6STACK]         = "6stack",
3599 };
3600
3601
3602 static int patch_ad1882(struct hda_codec *codec)
3603 {
3604         struct ad198x_spec *spec;
3605         int board_config;
3606
3607         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3608         if (spec == NULL)
3609                 return -ENOMEM;
3610
3611         mutex_init(&spec->amp_mutex);
3612         codec->spec = spec;
3613
3614         spec->multiout.max_channels = 6;
3615         spec->multiout.num_dacs = 3;
3616         spec->multiout.dac_nids = ad1882_dac_nids;
3617         spec->multiout.dig_out_nid = AD1882_SPDIF_OUT;
3618         spec->num_adc_nids = ARRAY_SIZE(ad1882_adc_nids);
3619         spec->adc_nids = ad1882_adc_nids;
3620         spec->capsrc_nids = ad1882_capsrc_nids;
3621         spec->input_mux = &ad1882_capture_source;
3622         spec->num_mixers = 1;
3623         spec->mixers[0] = ad1882_base_mixers;
3624         spec->num_init_verbs = 1;
3625         spec->init_verbs[0] = ad1882_init_verbs;
3626         spec->spdif_route = 0;
3627 #ifdef CONFIG_SND_HDA_POWER_SAVE
3628         spec->loopback.amplist = ad1882_loopbacks;
3629 #endif
3630         spec->vmaster_nid = 0x04;
3631
3632         codec->patch_ops = ad198x_patch_ops;
3633
3634         /* override some parameters */
3635         board_config = snd_hda_check_board_config(codec, AD1882_MODELS,
3636                                                   ad1882_models, NULL);
3637         switch (board_config) {
3638         default:
3639         case AD1882_3STACK:
3640                 spec->num_mixers = 2;
3641                 spec->mixers[1] = ad1882_3stack_mixers;
3642                 spec->channel_mode = ad1882_modes;
3643                 spec->num_channel_mode = ARRAY_SIZE(ad1882_modes);
3644                 spec->need_dac_fix = 1;
3645                 spec->multiout.max_channels = 2;
3646                 spec->multiout.num_dacs = 1;
3647                 break;
3648         case AD1882_6STACK:
3649                 spec->num_mixers = 2;
3650                 spec->mixers[1] = ad1882_6stack_mixers;
3651                 break;
3652         }
3653         return 0;
3654 }
3655
3656
3657 /*
3658  * patch entries
3659  */
3660 struct hda_codec_preset snd_hda_preset_analog[] = {
3661         { .id = 0x11d41882, .name = "AD1882", .patch = patch_ad1882 },
3662         { .id = 0x11d41884, .name = "AD1884", .patch = patch_ad1884 },
3663         { .id = 0x11d41981, .name = "AD1981", .patch = patch_ad1981 },
3664         { .id = 0x11d41983, .name = "AD1983", .patch = patch_ad1983 },
3665         { .id = 0x11d41984, .name = "AD1984", .patch = patch_ad1984 },
3666         { .id = 0x11d41986, .name = "AD1986A", .patch = patch_ad1986a },
3667         { .id = 0x11d41988, .name = "AD1988", .patch = patch_ad1988 },
3668         { .id = 0x11d4198b, .name = "AD1988B", .patch = patch_ad1988 },
3669         {} /* terminator */
3670 };