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