[ALSA] hda-codec - Fix AD1988 support
[linux-2.6.git] / sound / pci / hda / patch_analog.c
1 /*
2  * HD audio interface patch for AD1981HD, AD1983, AD1986A
3  *
4  * Copyright (c) 2005 Takashi Iwai <tiwai@suse.de>
5  *
6  *  This driver is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This driver is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19  */
20
21 #include <sound/driver.h>
22 #include <linux/init.h>
23 #include <linux/delay.h>
24 #include <linux/slab.h>
25 #include <linux/pci.h>
26 #include <sound/core.h>
27 #include "hda_codec.h"
28 #include "hda_local.h"
29
30 struct ad198x_spec {
31         struct snd_kcontrol_new *mixers[5];
32         int num_mixers;
33
34         const struct hda_verb *init_verbs[3];   /* initialization verbs
35                                                  * don't forget NULL termination!
36                                                  */
37         unsigned int num_init_verbs;
38
39         /* playback */
40         struct hda_multi_out multiout;  /* playback set-up
41                                          * max_channels, dacs must be set
42                                          * dig_out_nid and hp_nid are optional
43                                          */
44         unsigned int cur_eapd;
45
46         /* capture */
47         unsigned int num_adc_nids;
48         hda_nid_t *adc_nids;
49         hda_nid_t dig_in_nid;           /* digital-in NID; optional */
50
51         /* capture source */
52         const struct hda_input_mux *input_mux;
53         hda_nid_t *capsrc_nids;
54         unsigned int cur_mux[3];
55
56         /* channel model */
57         const struct hda_channel_mode *channel_mode;
58         int num_channel_mode;
59
60         /* PCM information */
61         struct hda_pcm pcm_rec[2];      /* used in alc_build_pcms() */
62
63         struct semaphore amp_mutex;     /* PCM volume/mute control mutex */
64         unsigned int spdif_route;
65 };
66
67 /*
68  * input MUX handling (common part)
69  */
70 static int ad198x_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
71 {
72         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
73         struct ad198x_spec *spec = codec->spec;
74
75         return snd_hda_input_mux_info(spec->input_mux, uinfo);
76 }
77
78 static int ad198x_mux_enum_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
79 {
80         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
81         struct ad198x_spec *spec = codec->spec;
82         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
83
84         ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
85         return 0;
86 }
87
88 static int ad198x_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
89 {
90         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
91         struct ad198x_spec *spec = codec->spec;
92         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
93
94         return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
95                                      spec->capsrc_nids[adc_idx],
96                                      &spec->cur_mux[adc_idx]);
97 }
98
99 /*
100  * initialization (common callbacks)
101  */
102 static int ad198x_init(struct hda_codec *codec)
103 {
104         struct ad198x_spec *spec = codec->spec;
105         int i;
106
107         for (i = 0; i < spec->num_init_verbs; i++)
108                 snd_hda_sequence_write(codec, spec->init_verbs[i]);
109         return 0;
110 }
111
112 static int ad198x_build_controls(struct hda_codec *codec)
113 {
114         struct ad198x_spec *spec = codec->spec;
115         unsigned int i;
116         int err;
117
118         for (i = 0; i < spec->num_mixers; i++) {
119                 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
120                 if (err < 0)
121                         return err;
122         }
123         if (spec->multiout.dig_out_nid) {
124                 err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid);
125                 if (err < 0)
126                         return err;
127         } 
128         if (spec->dig_in_nid) {
129                 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
130                 if (err < 0)
131                         return err;
132         }
133         return 0;
134 }
135
136 /*
137  * Analog playback callbacks
138  */
139 static int ad198x_playback_pcm_open(struct hda_pcm_stream *hinfo,
140                                     struct hda_codec *codec,
141                                     struct snd_pcm_substream *substream)
142 {
143         struct ad198x_spec *spec = codec->spec;
144         return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
145 }
146
147 static int ad198x_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
148                                        struct hda_codec *codec,
149                                        unsigned int stream_tag,
150                                        unsigned int format,
151                                        struct snd_pcm_substream *substream)
152 {
153         struct ad198x_spec *spec = codec->spec;
154         return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag,
155                                                 format, substream);
156 }
157
158 static int ad198x_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
159                                        struct hda_codec *codec,
160                                        struct snd_pcm_substream *substream)
161 {
162         struct ad198x_spec *spec = codec->spec;
163         return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
164 }
165
166 /*
167  * Digital out
168  */
169 static int ad198x_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
170                                         struct hda_codec *codec,
171                                         struct snd_pcm_substream *substream)
172 {
173         struct ad198x_spec *spec = codec->spec;
174         return snd_hda_multi_out_dig_open(codec, &spec->multiout);
175 }
176
177 static int ad198x_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
178                                          struct hda_codec *codec,
179                                          struct snd_pcm_substream *substream)
180 {
181         struct ad198x_spec *spec = codec->spec;
182         return snd_hda_multi_out_dig_close(codec, &spec->multiout);
183 }
184
185 /*
186  * Analog capture
187  */
188 static int ad198x_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
189                                       struct hda_codec *codec,
190                                       unsigned int stream_tag,
191                                       unsigned int format,
192                                       struct snd_pcm_substream *substream)
193 {
194         struct ad198x_spec *spec = codec->spec;
195         snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
196                                    stream_tag, 0, format);
197         return 0;
198 }
199
200 static int ad198x_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
201                                       struct hda_codec *codec,
202                                       struct snd_pcm_substream *substream)
203 {
204         struct ad198x_spec *spec = codec->spec;
205         snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
206                                    0, 0, 0);
207         return 0;
208 }
209
210
211 /*
212  */
213 static struct hda_pcm_stream ad198x_pcm_analog_playback = {
214         .substreams = 1,
215         .channels_min = 2,
216         .channels_max = 6, /* changed later */
217         .nid = 0, /* fill later */
218         .ops = {
219                 .open = ad198x_playback_pcm_open,
220                 .prepare = ad198x_playback_pcm_prepare,
221                 .cleanup = ad198x_playback_pcm_cleanup
222         },
223 };
224
225 static struct hda_pcm_stream ad198x_pcm_analog_capture = {
226         .substreams = 1,
227         .channels_min = 2,
228         .channels_max = 2,
229         .nid = 0, /* fill later */
230         .ops = {
231                 .prepare = ad198x_capture_pcm_prepare,
232                 .cleanup = ad198x_capture_pcm_cleanup
233         },
234 };
235
236 static struct hda_pcm_stream ad198x_pcm_digital_playback = {
237         .substreams = 1,
238         .channels_min = 2,
239         .channels_max = 2,
240         .nid = 0, /* fill later */
241         .ops = {
242                 .open = ad198x_dig_playback_pcm_open,
243                 .close = ad198x_dig_playback_pcm_close
244         },
245 };
246
247 static struct hda_pcm_stream ad198x_pcm_digital_capture = {
248         .substreams = 1,
249         .channels_min = 2,
250         .channels_max = 2,
251         /* NID is set in alc_build_pcms */
252 };
253
254 static int ad198x_build_pcms(struct hda_codec *codec)
255 {
256         struct ad198x_spec *spec = codec->spec;
257         struct hda_pcm *info = spec->pcm_rec;
258
259         codec->num_pcms = 1;
260         codec->pcm_info = info;
261
262         info->name = "AD198x Analog";
263         info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad198x_pcm_analog_playback;
264         info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->multiout.max_channels;
265         info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
266         info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad198x_pcm_analog_capture;
267         info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_adc_nids;
268         info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
269
270         if (spec->multiout.dig_out_nid) {
271                 info++;
272                 codec->num_pcms++;
273                 info->name = "AD198x Digital";
274                 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad198x_pcm_digital_playback;
275                 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
276                 if (spec->dig_in_nid) {
277                         info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad198x_pcm_digital_capture;
278                         info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
279                 }
280         }
281
282         return 0;
283 }
284
285 static void ad198x_free(struct hda_codec *codec)
286 {
287         kfree(codec->spec);
288 }
289
290 #ifdef CONFIG_PM
291 static int ad198x_resume(struct hda_codec *codec)
292 {
293         struct ad198x_spec *spec = codec->spec;
294         int i;
295
296         ad198x_init(codec);
297         for (i = 0; i < spec->num_mixers; i++)
298                 snd_hda_resume_ctls(codec, spec->mixers[i]);
299         if (spec->multiout.dig_out_nid)
300                 snd_hda_resume_spdif_out(codec);
301         if (spec->dig_in_nid)
302                 snd_hda_resume_spdif_in(codec);
303         return 0;
304 }
305 #endif
306
307 static struct hda_codec_ops ad198x_patch_ops = {
308         .build_controls = ad198x_build_controls,
309         .build_pcms = ad198x_build_pcms,
310         .init = ad198x_init,
311         .free = ad198x_free,
312 #ifdef CONFIG_PM
313         .resume = ad198x_resume,
314 #endif
315 };
316
317
318 /*
319  * AD1986A specific
320  */
321
322 #define AD1986A_SPDIF_OUT       0x02
323 #define AD1986A_FRONT_DAC       0x03
324 #define AD1986A_SURR_DAC        0x04
325 #define AD1986A_CLFE_DAC        0x05
326 #define AD1986A_ADC             0x06
327
328 static hda_nid_t ad1986a_dac_nids[3] = {
329         AD1986A_FRONT_DAC, AD1986A_SURR_DAC, AD1986A_CLFE_DAC
330 };
331 static hda_nid_t ad1986a_adc_nids[1] = { AD1986A_ADC };
332
333 static struct hda_input_mux ad1986a_capture_source = {
334         .num_items = 7,
335         .items = {
336                 { "Mic", 0x0 },
337                 { "CD", 0x1 },
338                 { "Aux", 0x3 },
339                 { "Line", 0x4 },
340                 { "Mix", 0x5 },
341                 { "Mono", 0x6 },
342                 { "Phone", 0x7 },
343         },
344 };
345
346 /*
347  * PCM control
348  *
349  * bind volumes/mutes of 3 DACs as a single PCM control for simplicity
350  */
351
352 #define ad1986a_pcm_amp_vol_info        snd_hda_mixer_amp_volume_info
353
354 static int ad1986a_pcm_amp_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
355 {
356         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
357         struct ad198x_spec *ad = codec->spec;
358
359         down(&ad->amp_mutex);
360         snd_hda_mixer_amp_volume_get(kcontrol, ucontrol);
361         up(&ad->amp_mutex);
362         return 0;
363 }
364
365 static int ad1986a_pcm_amp_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
366 {
367         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
368         struct ad198x_spec *ad = codec->spec;
369         int i, change = 0;
370
371         down(&ad->amp_mutex);
372         for (i = 0; i < ARRAY_SIZE(ad1986a_dac_nids); i++) {
373                 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(ad1986a_dac_nids[i], 3, 0, HDA_OUTPUT);
374                 change |= snd_hda_mixer_amp_volume_put(kcontrol, ucontrol);
375         }
376         kcontrol->private_value = HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT);
377         up(&ad->amp_mutex);
378         return change;
379 }
380
381 #define ad1986a_pcm_amp_sw_info         snd_hda_mixer_amp_switch_info
382
383 static int ad1986a_pcm_amp_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
384 {
385         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
386         struct ad198x_spec *ad = codec->spec;
387
388         down(&ad->amp_mutex);
389         snd_hda_mixer_amp_switch_get(kcontrol, ucontrol);
390         up(&ad->amp_mutex);
391         return 0;
392 }
393
394 static int ad1986a_pcm_amp_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
395 {
396         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
397         struct ad198x_spec *ad = codec->spec;
398         int i, change = 0;
399
400         down(&ad->amp_mutex);
401         for (i = 0; i < ARRAY_SIZE(ad1986a_dac_nids); i++) {
402                 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(ad1986a_dac_nids[i], 3, 0, HDA_OUTPUT);
403                 change |= snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
404         }
405         kcontrol->private_value = HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT);
406         up(&ad->amp_mutex);
407         return change;
408 }
409
410 /*
411  * mixers
412  */
413 static struct snd_kcontrol_new ad1986a_mixers[] = {
414         {
415                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
416                 .name = "PCM Playback Volume",
417                 .info = ad1986a_pcm_amp_vol_info,
418                 .get = ad1986a_pcm_amp_vol_get,
419                 .put = ad1986a_pcm_amp_vol_put,
420                 .private_value = HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT)
421         },
422         {
423                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
424                 .name = "PCM Playback Switch",
425                 .info = ad1986a_pcm_amp_sw_info,
426                 .get = ad1986a_pcm_amp_sw_get,
427                 .put = ad1986a_pcm_amp_sw_put,
428                 .private_value = HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT)
429         },
430         HDA_CODEC_VOLUME("Front Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
431         HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
432         HDA_CODEC_VOLUME("Surround Playback Volume", 0x1c, 0x0, HDA_OUTPUT),
433         HDA_CODEC_MUTE("Surround Playback Switch", 0x1c, 0x0, HDA_OUTPUT),
434         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x1d, 1, 0x0, HDA_OUTPUT),
435         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x1d, 2, 0x0, HDA_OUTPUT),
436         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x1d, 1, 0x0, HDA_OUTPUT),
437         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x1d, 2, 0x0, HDA_OUTPUT),
438         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x1a, 0x0, HDA_OUTPUT),
439         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
440         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_OUTPUT),
441         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_OUTPUT),
442         HDA_CODEC_VOLUME("Line Playback Volume", 0x17, 0x0, HDA_OUTPUT),
443         HDA_CODEC_MUTE("Line Playback Switch", 0x17, 0x0, HDA_OUTPUT),
444         HDA_CODEC_VOLUME("Aux Playback Volume", 0x16, 0x0, HDA_OUTPUT),
445         HDA_CODEC_MUTE("Aux Playback Switch", 0x16, 0x0, HDA_OUTPUT),
446         HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
447         HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
448         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x18, 0x0, HDA_OUTPUT),
449         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x18, 0x0, HDA_OUTPUT),
450         HDA_CODEC_VOLUME("Mono Playback Volume", 0x1e, 0x0, HDA_OUTPUT),
451         HDA_CODEC_MUTE("Mono Playback Switch", 0x1e, 0x0, HDA_OUTPUT),
452         HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT),
453         HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT),
454         {
455                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
456                 .name = "Capture Source",
457                 .info = ad198x_mux_enum_info,
458                 .get = ad198x_mux_enum_get,
459                 .put = ad198x_mux_enum_put,
460         },
461         HDA_CODEC_MUTE("Stereo Downmix Switch", 0x09, 0x0, HDA_OUTPUT),
462         { } /* end */
463 };
464
465 /*
466  * initialization verbs
467  */
468 static struct hda_verb ad1986a_init_verbs[] = {
469         /* Front, Surround, CLFE DAC; mute as default */
470         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
471         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
472         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
473         /* Downmix - off */
474         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
475         /* HP, Line-Out, Surround, CLFE selectors */
476         {0x0a, AC_VERB_SET_CONNECT_SEL, 0x0},
477         {0x0b, AC_VERB_SET_CONNECT_SEL, 0x0},
478         {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0},
479         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
480         /* Mono selector */
481         {0x0e, AC_VERB_SET_CONNECT_SEL, 0x0},
482         /* Mic selector: Mic 1/2 pin */
483         {0x0f, AC_VERB_SET_CONNECT_SEL, 0x0},
484         /* Line-in selector: Line-in */
485         {0x10, AC_VERB_SET_CONNECT_SEL, 0x0},
486         /* Mic 1/2 swap */
487         {0x11, AC_VERB_SET_CONNECT_SEL, 0x0},
488         /* Record selector: mic */
489         {0x12, AC_VERB_SET_CONNECT_SEL, 0x0},
490         /* Mic, Phone, CD, Aux, Line-In amp; mute as default */
491         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
492         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
493         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
494         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
495         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
496         /* PC beep */
497         {0x18, AC_VERB_SET_CONNECT_SEL, 0x0},
498         /* HP, Line-Out, Surround, CLFE, Mono pins; mute as default */
499         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
500         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
501         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
502         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
503         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
504         /* HP Pin */
505         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
506         /* Front, Surround, CLFE Pins */
507         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
508         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
509         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
510         /* Mono Pin */
511         {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
512         /* Mic Pin */
513         {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
514         /* Line, Aux, CD, Beep-In Pin */
515         {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
516         {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
517         {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
518         {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
519         {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
520         { } /* end */
521 };
522
523
524 static int patch_ad1986a(struct hda_codec *codec)
525 {
526         struct ad198x_spec *spec;
527
528         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
529         if (spec == NULL)
530                 return -ENOMEM;
531
532         init_MUTEX(&spec->amp_mutex);
533         codec->spec = spec;
534
535         spec->multiout.max_channels = 6;
536         spec->multiout.num_dacs = ARRAY_SIZE(ad1986a_dac_nids);
537         spec->multiout.dac_nids = ad1986a_dac_nids;
538         spec->multiout.dig_out_nid = AD1986A_SPDIF_OUT;
539         spec->num_adc_nids = 1;
540         spec->adc_nids = ad1986a_adc_nids;
541         spec->capsrc_nids = ad1986a_adc_nids;
542         spec->input_mux = &ad1986a_capture_source;
543         spec->num_mixers = 1;
544         spec->mixers[0] = ad1986a_mixers;
545         spec->num_init_verbs = 1;
546         spec->init_verbs[0] = ad1986a_init_verbs;
547
548         codec->patch_ops = ad198x_patch_ops;
549
550         return 0;
551 }
552
553 /*
554  * AD1983 specific
555  */
556
557 #define AD1983_SPDIF_OUT        0x02
558 #define AD1983_DAC              0x03
559 #define AD1983_ADC              0x04
560
561 static hda_nid_t ad1983_dac_nids[1] = { AD1983_DAC };
562 static hda_nid_t ad1983_adc_nids[1] = { AD1983_ADC };
563
564 static struct hda_input_mux ad1983_capture_source = {
565         .num_items = 4,
566         .items = {
567                 { "Mic", 0x0 },
568                 { "Line", 0x1 },
569                 { "Mix", 0x2 },
570                 { "Mix Mono", 0x3 },
571         },
572 };
573
574 /*
575  * SPDIF playback route
576  */
577 static int ad1983_spdif_route_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
578 {
579         static char *texts[] = { "PCM", "ADC" };
580
581         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
582         uinfo->count = 1;
583         uinfo->value.enumerated.items = 2;
584         if (uinfo->value.enumerated.item > 1)
585                 uinfo->value.enumerated.item = 1;
586         strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
587         return 0;
588 }
589
590 static int ad1983_spdif_route_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
591 {
592         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
593         struct ad198x_spec *spec = codec->spec;
594
595         ucontrol->value.enumerated.item[0] = spec->spdif_route;
596         return 0;
597 }
598
599 static int ad1983_spdif_route_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
600 {
601         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
602         struct ad198x_spec *spec = codec->spec;
603
604         if (spec->spdif_route != ucontrol->value.enumerated.item[0]) {
605                 spec->spdif_route = ucontrol->value.enumerated.item[0];
606                 snd_hda_codec_write(codec, spec->multiout.dig_out_nid, 0,
607                                     AC_VERB_SET_CONNECT_SEL, spec->spdif_route);
608                 return 1;
609         }
610         return 0;
611 }
612
613 static struct snd_kcontrol_new ad1983_mixers[] = {
614         HDA_CODEC_VOLUME("Front Playback Volume", 0x05, 0x0, HDA_OUTPUT),
615         HDA_CODEC_MUTE("Front Playback Switch", 0x05, 0x0, HDA_OUTPUT),
616         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x06, 0x0, HDA_OUTPUT),
617         HDA_CODEC_MUTE("Headphone Playback Switch", 0x06, 0x0, HDA_OUTPUT),
618         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x07, 1, 0x0, HDA_OUTPUT),
619         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x07, 1, 0x0, HDA_OUTPUT),
620         HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
621         HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT),
622         HDA_CODEC_VOLUME("Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
623         HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
624         HDA_CODEC_VOLUME("Line Playback Volume", 0x13, 0x0, HDA_OUTPUT),
625         HDA_CODEC_MUTE("Line Playback Switch", 0x13, 0x0, HDA_OUTPUT),
626         HDA_CODEC_VOLUME_MONO("PC Speaker Playback Volume", 0x10, 1, 0x0, HDA_OUTPUT),
627         HDA_CODEC_MUTE_MONO("PC Speaker Playback Switch", 0x10, 1, 0x0, HDA_OUTPUT),
628         HDA_CODEC_VOLUME("Mic Boost", 0x0c, 0x0, HDA_OUTPUT),
629         HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
630         HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
631         {
632                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
633                 .name = "Capture Source",
634                 .info = ad198x_mux_enum_info,
635                 .get = ad198x_mux_enum_get,
636                 .put = ad198x_mux_enum_put,
637         },
638         {
639                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
640                 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Route",
641                 .info = ad1983_spdif_route_info,
642                 .get = ad1983_spdif_route_get,
643                 .put = ad1983_spdif_route_put,
644         },
645         { } /* end */
646 };
647
648 static struct hda_verb ad1983_init_verbs[] = {
649         /* Front, HP, Mono; mute as default */
650         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
651         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
652         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
653         /* Beep, PCM, Mic, Line-In: mute */
654         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
655         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
656         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
657         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
658         /* Front, HP selectors; from Mix */
659         {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
660         {0x06, AC_VERB_SET_CONNECT_SEL, 0x01},
661         /* Mono selector; from Mix */
662         {0x0b, AC_VERB_SET_CONNECT_SEL, 0x03},
663         /* Mic selector; Mic */
664         {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0},
665         /* Line-in selector: Line-in */
666         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
667         /* Mic boost: 0dB */
668         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
669         /* Record selector: mic */
670         {0x15, AC_VERB_SET_CONNECT_SEL, 0x0},
671         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
672         /* SPDIF route: PCM */
673         {0x02, AC_VERB_SET_CONNECT_SEL, 0x0},
674         /* Front Pin */
675         {0x05, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
676         /* HP Pin */
677         {0x06, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
678         /* Mono Pin */
679         {0x07, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
680         /* Mic Pin */
681         {0x08, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
682         /* Line Pin */
683         {0x09, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
684         { } /* end */
685 };
686
687
688 static int patch_ad1983(struct hda_codec *codec)
689 {
690         struct ad198x_spec *spec;
691
692         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
693         if (spec == NULL)
694                 return -ENOMEM;
695
696         init_MUTEX(&spec->amp_mutex);
697         codec->spec = spec;
698
699         spec->multiout.max_channels = 2;
700         spec->multiout.num_dacs = ARRAY_SIZE(ad1983_dac_nids);
701         spec->multiout.dac_nids = ad1983_dac_nids;
702         spec->multiout.dig_out_nid = AD1983_SPDIF_OUT;
703         spec->num_adc_nids = 1;
704         spec->adc_nids = ad1983_adc_nids;
705         spec->capsrc_nids = ad1983_adc_nids;
706         spec->input_mux = &ad1983_capture_source;
707         spec->num_mixers = 1;
708         spec->mixers[0] = ad1983_mixers;
709         spec->num_init_verbs = 1;
710         spec->init_verbs[0] = ad1983_init_verbs;
711         spec->spdif_route = 0;
712
713         codec->patch_ops = ad198x_patch_ops;
714
715         return 0;
716 }
717
718
719 /*
720  * AD1981 HD specific
721  */
722
723 #define AD1981_SPDIF_OUT        0x02
724 #define AD1981_DAC              0x03
725 #define AD1981_ADC              0x04
726
727 static hda_nid_t ad1981_dac_nids[1] = { AD1981_DAC };
728 static hda_nid_t ad1981_adc_nids[1] = { AD1981_ADC };
729
730 /* 0x0c, 0x09, 0x0e, 0x0f, 0x19, 0x05, 0x18, 0x17 */
731 static struct hda_input_mux ad1981_capture_source = {
732         .num_items = 7,
733         .items = {
734                 { "Front Mic", 0x0 },
735                 { "Line", 0x1 },
736                 { "Mix", 0x2 },
737                 { "Mix Mono", 0x3 },
738                 { "CD", 0x4 },
739                 { "Mic", 0x6 },
740                 { "Aux", 0x7 },
741         },
742 };
743
744 static struct snd_kcontrol_new ad1981_mixers[] = {
745         HDA_CODEC_VOLUME("Front Playback Volume", 0x05, 0x0, HDA_OUTPUT),
746         HDA_CODEC_MUTE("Front Playback Switch", 0x05, 0x0, HDA_OUTPUT),
747         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x06, 0x0, HDA_OUTPUT),
748         HDA_CODEC_MUTE("Headphone Playback Switch", 0x06, 0x0, HDA_OUTPUT),
749         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x07, 1, 0x0, HDA_OUTPUT),
750         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x07, 1, 0x0, HDA_OUTPUT),
751         HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
752         HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT),
753         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
754         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
755         HDA_CODEC_VOLUME("Line Playback Volume", 0x13, 0x0, HDA_OUTPUT),
756         HDA_CODEC_MUTE("Line Playback Switch", 0x13, 0x0, HDA_OUTPUT),
757         HDA_CODEC_VOLUME("Aux Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
758         HDA_CODEC_MUTE("Aux Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
759         HDA_CODEC_VOLUME("Mic Playback Volume", 0x1c, 0x0, HDA_OUTPUT),
760         HDA_CODEC_MUTE("Mic Playback Switch", 0x1c, 0x0, HDA_OUTPUT),
761         HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
762         HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
763         HDA_CODEC_VOLUME_MONO("PC Speaker Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
764         HDA_CODEC_MUTE_MONO("PC Speaker Playback Switch", 0x0d, 1, 0x0, HDA_OUTPUT),
765         HDA_CODEC_VOLUME("Front Mic Boost", 0x08, 0x0, HDA_INPUT),
766         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x0, HDA_INPUT),
767         HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
768         HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
769         {
770                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
771                 .name = "Capture Source",
772                 .info = ad198x_mux_enum_info,
773                 .get = ad198x_mux_enum_get,
774                 .put = ad198x_mux_enum_put,
775         },
776         /* identical with AD1983 */
777         {
778                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
779                 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Route",
780                 .info = ad1983_spdif_route_info,
781                 .get = ad1983_spdif_route_get,
782                 .put = ad1983_spdif_route_put,
783         },
784         { } /* end */
785 };
786
787 static struct hda_verb ad1981_init_verbs[] = {
788         /* Front, HP, Mono; mute as default */
789         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
790         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
791         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
792         /* Beep, PCM, Front Mic, Line, Rear Mic, Aux, CD-In: mute */
793         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
794         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
795         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
796         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
797         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
798         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
799         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
800         /* Front, HP selectors; from Mix */
801         {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
802         {0x06, AC_VERB_SET_CONNECT_SEL, 0x01},
803         /* Mono selector; from Mix */
804         {0x0b, AC_VERB_SET_CONNECT_SEL, 0x03},
805         /* Mic Mixer; select Front Mic */
806         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
807         {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
808         /* Mic boost: 0dB */
809         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
810         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
811         /* Record selector: Front mic */
812         {0x15, AC_VERB_SET_CONNECT_SEL, 0x0},
813         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
814         /* SPDIF route: PCM */
815         {0x02, AC_VERB_SET_CONNECT_SEL, 0x0},
816         /* Front Pin */
817         {0x05, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
818         /* HP Pin */
819         {0x06, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
820         /* Mono Pin */
821         {0x07, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
822         /* Front & Rear Mic Pins */
823         {0x08, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
824         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
825         /* Line Pin */
826         {0x09, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
827         /* Digital Beep */
828         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
829         /* Line-Out as Input: disabled */
830         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
831         { } /* end */
832 };
833
834 static int patch_ad1981(struct hda_codec *codec)
835 {
836         struct ad198x_spec *spec;
837
838         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
839         if (spec == NULL)
840                 return -ENOMEM;
841
842         init_MUTEX(&spec->amp_mutex);
843         codec->spec = spec;
844
845         spec->multiout.max_channels = 2;
846         spec->multiout.num_dacs = ARRAY_SIZE(ad1981_dac_nids);
847         spec->multiout.dac_nids = ad1981_dac_nids;
848         spec->multiout.dig_out_nid = AD1981_SPDIF_OUT;
849         spec->num_adc_nids = 1;
850         spec->adc_nids = ad1981_adc_nids;
851         spec->capsrc_nids = ad1981_adc_nids;
852         spec->input_mux = &ad1981_capture_source;
853         spec->num_mixers = 1;
854         spec->mixers[0] = ad1981_mixers;
855         spec->num_init_verbs = 1;
856         spec->init_verbs[0] = ad1981_init_verbs;
857         spec->spdif_route = 0;
858
859         codec->patch_ops = ad198x_patch_ops;
860
861         return 0;
862 }
863
864
865 /*
866  * AD1988
867  *
868  * Output pins and routes
869  *
870  *        Pin               Mix     Sel     DAC
871  * port-A 0x11 (mute/hp) <- 0x22 <- 0x37 <- 03/04/06
872  * port-B 0x14 (mute/hp) <- 0x2b <- 0x30 <- 03/04/06
873  * port-C 0x15 (mute)    <- 0x2c <- 0x31 <- 05/0a
874  * port-D 0x12 (mute/hp) <- 0x29         <- 04
875  * port-E 0x17 (mute/hp) <- 0x26 <- 0x32 <- 05/0a
876  * port-F 0x16 (mute)    <- 0x2a         <- 06
877  * port-G 0x24 (mute)    <- 0x27         <- 05
878  * port-H 0x25 (mute)    <- 0x28         <- 0a
879  * mono   0x13 (mute/amp)<- 0x1e <- 0x36 <- 03/04/06
880  *
881  *
882  * Input pins and routes
883  *
884  *        pin     boost   mix input # / adc input #
885  * port-A 0x11 -> 0x38 -> mix 2, ADC 0
886  * port-B 0x14 -> 0x39 -> mix 0, ADC 1
887  * port-C 0x15 -> 0x3a -> 33:0 - mix 1, ADC 2
888  * port-D 0x12 -> 0x3d -> mix 3, ADC 8
889  * port-E 0x17 -> 0x3c -> 34:0 - mix 4, ADC 4
890  * port-F 0x16 -> 0x3b -> mix 5, ADC 3
891  * port-G 0x24 -> N/A  -> 33:1 - mix 1, 34:1 - mix 4, ADC 6
892  * port-H 0x25 -> N/A  -> 33:2 - mix 1, 34:2 - mix 4, ADC 7
893  *
894  *
895  * DAC assignment
896  *   front DAC - 04
897  *   surr DAC  - 06
898  *   CLFE DAC  - 05
899  *   side DAC  - 0a
900  *   opt DAC   - 03
901  *
902  * Inputs of Analog Mix (0x20)
903  *   0:Port-B (front mic)
904  *   1:Port-C/G/H (line-in)
905  *   2:Port-A
906  *   3:Port-D (line-in/2)
907  *   4:Port-E/G/H (mic-in)
908  *   5:Port-F (mic2-in)
909  *   6:CD
910  *   7:Beep
911  *
912  * ADC selection
913  *   0:Port-A
914  *   1:Port-B (front mic-in)
915  *   2:Port-C (line-in)
916  *   3:Port-F (mic2-in)
917  *   4:Port-E (mic-in)
918  *   5:CD
919  *   6:Port-G
920  *   7:Port-H
921  *   8:Port-D (line-in/2)
922  *   9:Mix
923  *
924  * Proposed pin assignments by the datasheet
925  *
926  * 6-stack
927  * Port-A front headphone
928  *      B front mic-in
929  *      C rear line-in
930  *      D rear front-out
931  *      E rear mic-in
932  *      F rear surround
933  *      G rear CLFE
934  *      H rear side
935  *
936  * 3-stack
937  * Port-A front headphone
938  *      B front mic
939  *      C rear line-in/surround
940  *      D rear front-out
941  *      E rear mic-in/CLFE
942  *
943  * laptop
944  * Port-A headphone
945  *      B mic-in
946  *      C docking station
947  *      D internal speaker (with EAPD)
948  *      E/F quad mic array
949  */
950
951
952 /* models */
953 enum {
954         AD1988_6STACK,
955         AD1988_6STACK_DIG,
956         AD1988_3STACK,
957         AD1988_3STACK_DIG,
958         AD1988_LAPTOP,
959         AD1988_LAPTOP_DIG,
960         AD1988_MODEL_LAST,
961 };
962
963
964 /*
965  * mixers
966  */
967
968 static hda_nid_t ad1988_dac_nids[4] = {
969         0x04, 0x06, 0x05, 0x0a
970 };
971
972 static hda_nid_t ad1988_adc_nids[3] = {
973         0x08, 0x09, 0x0f
974 };
975
976 static hda_nid_t ad1988_capsrc_nids[3] = {
977         0x0c, 0x0d, 0x0e
978 };
979
980 #define AD1988_SPDIF_OUT        0x02
981 #define AD1988_SPDIF_IN         0x07
982
983 static struct hda_input_mux ad1988_6stack_capture_source = {
984         .num_items = 5,
985         .items = {
986                 { "Front Mic", 0x0 },
987                 { "Line", 0x1 },
988                 { "Mic", 0x4 },
989                 { "CD", 0x5 },
990                 { "Mix", 0x9 },
991         },
992 };
993
994 static struct hda_input_mux ad1988_laptop_capture_source = {
995         .num_items = 3,
996         .items = {
997                 { "Mic/Line", 0x0 },
998                 { "CD", 0x5 },
999                 { "Mix", 0x9 },
1000         },
1001 };
1002
1003 /*
1004  */
1005 static int ad198x_ch_mode_info(struct snd_kcontrol *kcontrol,
1006                                struct snd_ctl_elem_info *uinfo)
1007 {
1008         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1009         struct ad198x_spec *spec = codec->spec;
1010         return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
1011                                     spec->num_channel_mode);
1012 }
1013
1014 static int ad198x_ch_mode_get(struct snd_kcontrol *kcontrol,
1015                               struct snd_ctl_elem_value *ucontrol)
1016 {
1017         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1018         struct ad198x_spec *spec = codec->spec;
1019         return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
1020                                    spec->num_channel_mode, spec->multiout.max_channels);
1021 }
1022
1023 static int ad198x_ch_mode_put(struct snd_kcontrol *kcontrol,
1024                               struct snd_ctl_elem_value *ucontrol)
1025 {
1026         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1027         struct ad198x_spec *spec = codec->spec;
1028         return snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
1029                                    spec->num_channel_mode, &spec->multiout.max_channels);
1030 }
1031
1032 /*
1033  * EAPD control
1034  */
1035 static int ad1988_eapd_info(struct snd_kcontrol *kcontrol,
1036                             struct snd_ctl_elem_info *uinfo)
1037 {
1038         uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1039         uinfo->count = 1;
1040         uinfo->value.integer.min = 0;
1041         uinfo->value.integer.max = 1;
1042         return 0;
1043 }
1044
1045 static int ad1988_eapd_get(struct snd_kcontrol *kcontrol,
1046                            struct snd_ctl_elem_value *ucontrol)
1047 {
1048         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1049         struct ad198x_spec *spec = codec->spec;
1050         ucontrol->value.enumerated.item[0] = ! spec->cur_eapd;
1051         return 0;
1052 }
1053
1054 static int ad1988_eapd_put(struct snd_kcontrol *kcontrol,
1055                            struct snd_ctl_elem_value *ucontrol)
1056 {
1057         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1058         struct ad198x_spec *spec = codec->spec;
1059         unsigned int eapd;
1060         eapd = ! ucontrol->value.enumerated.item[0];
1061         if (eapd == spec->cur_eapd && ! codec->in_resume)
1062                 return 0;
1063         spec->cur_eapd = eapd;
1064         snd_hda_codec_write(codec, 0x12 /* port-D */,
1065                             0, AC_VERB_SET_EAPD_BTLENABLE,
1066                             eapd ? 0x02 : 0x00);
1067         return 0;
1068 }
1069
1070 /* 6-stack mode */
1071 static struct snd_kcontrol_new ad1988_6stack_mixers[] = {
1072         HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
1073         HDA_CODEC_VOLUME("Surround Playback Volume", 0x06, 0x0, HDA_OUTPUT),
1074         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT),
1075         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT),
1076         HDA_CODEC_VOLUME("Side Playback Volume", 0x0a, 0x0, HDA_OUTPUT),
1077
1078         HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT),
1079         HDA_BIND_MUTE("Surround Playback Switch", 0x2a, 2, HDA_INPUT),
1080         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x27, 1, 2, HDA_INPUT),
1081         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x27, 2, 2, HDA_INPUT),
1082         HDA_BIND_MUTE("Side Playback Switch", 0x28, 2, HDA_INPUT),
1083         HDA_BIND_MUTE("Headphone Playback Switch", 0x22, 2, HDA_INPUT),
1084         HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT),
1085
1086         HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x6, HDA_INPUT),
1087         HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x6, HDA_INPUT),
1088         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x0, HDA_INPUT),
1089         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x0, HDA_INPUT),
1090         HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT),
1091         HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT),
1092         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x4, HDA_INPUT),
1093         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x4, HDA_INPUT),
1094
1095         HDA_CODEC_VOLUME("Beep Playback Volume", 0x10, 0x0, HDA_OUTPUT),
1096         HDA_CODEC_MUTE("Beep Playback Switch", 0x10, 0x0, HDA_OUTPUT),
1097
1098         HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT),
1099         HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT),
1100
1101         HDA_CODEC_VOLUME("Front Mic Boost", 0x39, 0x0, HDA_OUTPUT),
1102         HDA_CODEC_VOLUME("Mic Boost", 0x3c, 0x0, HDA_OUTPUT),
1103
1104         { } /* end */
1105 };
1106
1107 /* 3-stack mode */
1108 static struct snd_kcontrol_new ad1988_3stack_mixers[] = {
1109         HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
1110         HDA_CODEC_VOLUME("Surround Playback Volume", 0x06, 0x0, HDA_OUTPUT),
1111         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT),
1112         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT),
1113
1114         HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT),
1115         HDA_BIND_MUTE("Surround Playback Switch", 0x2a, 2, HDA_INPUT),
1116         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x27, 1, 2, HDA_INPUT),
1117         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x27, 2, 2, HDA_INPUT),
1118         HDA_BIND_MUTE("Headphone Playback Switch", 0x22, 2, HDA_INPUT),
1119         HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT),
1120
1121         HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x6, HDA_INPUT),
1122         HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x6, HDA_INPUT),
1123         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x0, HDA_INPUT),
1124         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x0, HDA_INPUT),
1125         HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT),
1126         HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT),
1127         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x4, HDA_INPUT),
1128         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x4, HDA_INPUT),
1129
1130         HDA_CODEC_VOLUME("Beep Playback Volume", 0x10, 0x0, HDA_OUTPUT),
1131         HDA_CODEC_MUTE("Beep Playback Switch", 0x10, 0x0, HDA_OUTPUT),
1132
1133         HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT),
1134         HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT),
1135
1136         HDA_CODEC_VOLUME("Front Mic Boost", 0x39, 0x0, HDA_OUTPUT),
1137         HDA_CODEC_VOLUME("Mic Boost", 0x3c, 0x0, HDA_OUTPUT),
1138         {
1139                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1140                 .name = "Channel Mode",
1141                 .info = ad198x_ch_mode_info,
1142                 .get = ad198x_ch_mode_get,
1143                 .put = ad198x_ch_mode_put,
1144         },
1145
1146         { } /* end */
1147 };
1148
1149 /* laptop mode */
1150 static struct snd_kcontrol_new ad1988_laptop_mixers[] = {
1151         HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
1152         HDA_CODEC_MUTE("PCM Playback Switch", 0x29, 0x0, HDA_INPUT),
1153         HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT),
1154
1155         HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x6, HDA_INPUT),
1156         HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x6, HDA_INPUT),
1157         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x0, HDA_INPUT),
1158         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x0, HDA_INPUT),
1159         HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT),
1160         HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT),
1161
1162         HDA_CODEC_VOLUME("Beep Playback Volume", 0x10, 0x0, HDA_OUTPUT),
1163         HDA_CODEC_MUTE("Beep Playback Switch", 0x10, 0x0, HDA_OUTPUT),
1164
1165         HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT),
1166         HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT),
1167
1168         HDA_CODEC_VOLUME("Mic Boost", 0x39, 0x0, HDA_OUTPUT),
1169
1170         {
1171                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1172                 .name = "External Amplifier",
1173                 .info = ad1988_eapd_info,
1174                 .get = ad1988_eapd_get,
1175                 .put = ad1988_eapd_put,
1176         },
1177
1178         { } /* end */
1179 };
1180
1181 /* capture */
1182 static struct snd_kcontrol_new ad1988_capture_mixers[] = {
1183         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
1184         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
1185         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
1186         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
1187         HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x0e, 0x0, HDA_OUTPUT),
1188         HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x0e, 0x0, HDA_OUTPUT),
1189         {
1190                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1191                 /* The multiple "Capture Source" controls confuse alsamixer
1192                  * So call somewhat different..
1193                  * FIXME: the controls appear in the "playback" view!
1194                  */
1195                 /* .name = "Capture Source", */
1196                 .name = "Input Source",
1197                 .count = 3,
1198                 .info = ad198x_mux_enum_info,
1199                 .get = ad198x_mux_enum_get,
1200                 .put = ad198x_mux_enum_put,
1201         },
1202         { } /* end */
1203 };
1204
1205 static int ad1988_spdif_playback_source_info(struct snd_kcontrol *kcontrol,
1206                                              struct snd_ctl_elem_info *uinfo)
1207 {
1208         static char *texts[] = {
1209                 "PCM", "ADC1", "ADC2", "ADC3"
1210         };
1211         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1212         uinfo->count = 1;
1213         uinfo->value.enumerated.items = 4;
1214         if (uinfo->value.enumerated.item >= 4)
1215                 uinfo->value.enumerated.item = 3;
1216         strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1217         return 0;
1218 }
1219
1220 static int ad1988_spdif_playback_source_get(struct snd_kcontrol *kcontrol,
1221                                             struct snd_ctl_elem_value *ucontrol)
1222 {
1223         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1224         unsigned int sel;
1225
1226         sel = snd_hda_codec_read(codec, 0x02, 0, AC_VERB_GET_CONNECT_SEL, 0);
1227         if (sel > 0) {
1228                 sel = snd_hda_codec_read(codec, 0x0b, 0, AC_VERB_GET_CONNECT_SEL, 0);
1229                 if (sel <= 3)
1230                         sel++;
1231                 else
1232                         sel = 0;
1233         }
1234         ucontrol->value.enumerated.item[0] = sel;
1235         return 0;
1236 }
1237
1238 static int ad1988_spdif_playback_source_put(struct snd_kcontrol *kcontrol,
1239                                             struct snd_ctl_elem_value *ucontrol)
1240 {
1241         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1242         unsigned int sel;
1243         int change;
1244
1245         sel = snd_hda_codec_read(codec, 0x02, 0, AC_VERB_GET_CONNECT_SEL, 0);
1246         if (! ucontrol->value.enumerated.item[0]) {
1247                 change = sel != 0;
1248                 if (change)
1249                         snd_hda_codec_write(codec, 0x02, 0, AC_VERB_SET_CONNECT_SEL, 0);
1250         } else {
1251                 change = sel == 0;
1252                 if (change)
1253                         snd_hda_codec_write(codec, 0x02, 0, AC_VERB_SET_CONNECT_SEL, 1);
1254                 sel = snd_hda_codec_read(codec, 0x0b, 0, AC_VERB_GET_CONNECT_SEL, 0) + 1;
1255                 change |= sel == ucontrol->value.enumerated.item[0];
1256                 if (change)
1257                         snd_hda_codec_write(codec, 0x02, 0, AC_VERB_SET_CONNECT_SEL,
1258                                             ucontrol->value.enumerated.item[0] - 1);
1259         }
1260         return change;
1261 }
1262
1263 static struct snd_kcontrol_new ad1988_spdif_out_mixers[] = {
1264         HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
1265         {
1266                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1267                 .name = "IEC958 Playback Source",
1268                 .info = ad1988_spdif_playback_source_info,
1269                 .get = ad1988_spdif_playback_source_get,
1270                 .put = ad1988_spdif_playback_source_put,
1271         },
1272         { } /* end */
1273 };
1274
1275 static struct snd_kcontrol_new ad1988_spdif_in_mixers[] = {
1276         HDA_CODEC_VOLUME("IEC958 Capture Volume", 0x1c, 0x0, HDA_INPUT),
1277         { } /* end */
1278 };
1279
1280
1281 /*
1282  * initialization verbs
1283  */
1284
1285 /*
1286  * for 6-stack (+dig)
1287  */
1288 static struct hda_verb ad1988_6stack_init_verbs[] = {
1289         /* Front, Surround, CLFE, side DAC; unmute as default */
1290         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1291         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1292         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1293         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1294         /* Port-A front headphon path */
1295         {0x37, AC_VERB_SET_CONNECT_SEL, 0x01}, /* DAC1:04h */
1296         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1297         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1298         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1299         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1300         /* Port-D line-out path */
1301         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1302         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1303         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1304         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1305         /* Port-F surround path */
1306         {0x2a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1307         {0x2a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1308         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1309         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1310         /* Port-G CLFE path */
1311         {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1312         {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1313         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1314         {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1315         /* Port-H side path */
1316         {0x28, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1317         {0x28, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1318         {0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1319         {0x25, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1320         /* Mono out path */
1321         {0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */
1322         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1323         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1324         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1325         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */
1326         /* Port-B front mic-in path */
1327         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1328         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1329         {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1330         /* Port-C line-in path */
1331         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1332         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1333         {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1334         {0x33, AC_VERB_SET_CONNECT_SEL, 0x0},
1335         /* Port-E mic-in path */
1336         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1337         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1338         {0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1339         {0x34, AC_VERB_SET_CONNECT_SEL, 0x0},
1340
1341         { }
1342 };
1343
1344 static struct hda_verb ad1988_capture_init_verbs[] = {
1345         /* mute analog mix */
1346         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1347         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1348         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1349         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1350         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1351         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
1352         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
1353         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1354         /* select ADCs - front-mic */
1355         {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1},
1356         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x1},
1357         {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
1358         /* ADCs; muted */
1359         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1360         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1361         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1362
1363         { }
1364 };
1365
1366 static struct hda_verb ad1988_spdif_init_verbs[] = {
1367         /* SPDIF out sel */
1368         {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */
1369         {0x0b, AC_VERB_SET_CONNECT_SEL, 0x0}, /* ADC1 */
1370         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1371         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1372         /* SPDIF out pin */
1373         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
1374         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x17}, /* 0dB */
1375
1376         { }
1377 };
1378
1379 /*
1380  * verbs for 3stack (+dig)
1381  */
1382 static struct hda_verb ad1988_3stack_ch2_init[] = {
1383         /* set port-C to line-in */
1384         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1385         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1386         /* set port-E to mic-in */
1387         { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1388         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1389         { } /* end */
1390 };
1391
1392 static struct hda_verb ad1988_3stack_ch6_init[] = {
1393         /* set port-C to surround out */
1394         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1395         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1396         /* set port-E to CLFE out */
1397         { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1398         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1399         { } /* end */
1400 };
1401
1402 static struct hda_channel_mode ad1988_3stack_modes[2] = {
1403         { 2, ad1988_3stack_ch2_init },
1404         { 6, ad1988_3stack_ch6_init },
1405 };
1406
1407 static struct hda_verb ad1988_3stack_init_verbs[] = {
1408         /* Front, Surround, CLFE, side DAC; unmute as default */
1409         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1410         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1411         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1412         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1413         /* Port-A front headphon path */
1414         {0x37, AC_VERB_SET_CONNECT_SEL, 0x01}, /* DAC1:04h */
1415         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1416         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1417         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1418         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1419         /* Port-D line-out path */
1420         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1421         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1422         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1423         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1424         /* Mono out path */
1425         {0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */
1426         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1427         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1428         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1429         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */
1430         /* Port-B front mic-in path */
1431         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1432         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1433         {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1434         /* Port-C line-in/surround path */
1435         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1436         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1437         {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1438         {0x33, AC_VERB_SET_CONNECT_SEL, 0x0},
1439         /* Port-E mic-in/CLFE path */
1440         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1441         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1442         {0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1443         {0x34, AC_VERB_SET_CONNECT_SEL, 0x0},
1444         /* mute analog mix */
1445         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1446         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1447         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1448         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1449         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1450         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
1451         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
1452         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1453         /* select ADCs - front-mic */
1454         {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1},
1455         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x1},
1456         {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
1457         /* ADCs; muted */
1458         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1459         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1460         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1461         { }
1462 };
1463
1464 /*
1465  * verbs for laptop mode (+dig)
1466  */
1467 static struct hda_verb ad1988_laptop_hp_on[] = {
1468         /* unmute port-A and mute port-D */
1469         { 0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1470         { 0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1471         { } /* end */
1472 };
1473 static struct hda_verb ad1988_laptop_hp_off[] = {
1474         /* mute port-A and unmute port-D */
1475         { 0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1476         { 0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1477         { } /* end */
1478 };
1479
1480 #define AD1988_HP_EVENT 0x01
1481
1482 static struct hda_verb ad1988_laptop_init_verbs[] = {
1483         /* Front, Surround, CLFE, side DAC; unmute as default */
1484         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1485         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1486         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1487         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1488         /* Port-A front headphon path */
1489         {0x37, AC_VERB_SET_CONNECT_SEL, 0x01}, /* DAC1:04h */
1490         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1491         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1492         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1493         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1494         /* unsolicited event for pin-sense */
1495         {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1988_HP_EVENT },
1496         /* Port-D line-out path + EAPD */
1497         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1498         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1499         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1500         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1501         {0x12, AC_VERB_SET_EAPD_BTLENABLE, 0x00}, /* EAPD-off */
1502         /* Mono out path */
1503         {0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */
1504         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1505         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1506         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1507         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */
1508         /* Port-B mic-in path */
1509         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1510         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1511         {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1512         /* Port-C docking station - try to output */
1513         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1514         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1515         {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1516         {0x33, AC_VERB_SET_CONNECT_SEL, 0x0},
1517         /* mute analog mix */
1518         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1519         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1520         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1521         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1522         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1523         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
1524         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
1525         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1526         /* select ADCs - mic */
1527         {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1},
1528         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x1},
1529         {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
1530         /* ADCs; muted */
1531         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1532         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1533         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1534         { }
1535 };
1536
1537 static void ad1988_laptop_unsol_event(struct hda_codec *codec, unsigned int res)
1538 {
1539         if ((res >> 26) != AD1988_HP_EVENT)
1540                 return;
1541         if (snd_hda_codec_read(codec, 0x11, 0, AC_VERB_GET_PIN_SENSE, 0) & (1 << 31))
1542                 snd_hda_sequence_write(codec, ad1988_laptop_hp_on);
1543         else
1544                 snd_hda_sequence_write(codec, ad1988_laptop_hp_off);
1545
1546
1547
1548 /*
1549  */
1550
1551 static struct hda_board_config ad1988_cfg_tbl[] = {
1552         { .modelname = "6stack",        .config = AD1988_6STACK },
1553         { .modelname = "6stack-dig",    .config = AD1988_6STACK_DIG },
1554         { .modelname = "3stack",        .config = AD1988_3STACK },
1555         { .modelname = "3stack-dig",    .config = AD1988_3STACK_DIG },
1556         { .modelname = "laptop",        .config = AD1988_LAPTOP },
1557         { .modelname = "laptop-dig",    .config = AD1988_LAPTOP_DIG },
1558         {}
1559 };
1560
1561 static int patch_ad1988(struct hda_codec *codec)
1562 {
1563         struct ad198x_spec *spec;
1564         int board_config;
1565
1566         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1567         if (spec == NULL)
1568                 return -ENOMEM;
1569
1570         init_MUTEX(&spec->amp_mutex);
1571         codec->spec = spec;
1572
1573         board_config = snd_hda_check_board_config(codec, ad1988_cfg_tbl);
1574         if (board_config < 0 || board_config >= AD1988_MODEL_LAST) {
1575                 printk(KERN_INFO "hda_codec: Unknown model for AD1988, using 6stack model...\n");
1576                 board_config = AD1988_6STACK;
1577         }
1578
1579         switch (board_config) {
1580         case AD1988_6STACK:
1581         case AD1988_6STACK_DIG:
1582                 spec->multiout.max_channels = 8;
1583                 spec->multiout.num_dacs = 4;
1584                 spec->multiout.dac_nids = ad1988_dac_nids;
1585                 spec->num_adc_nids = ARRAY_SIZE(ad1988_adc_nids);
1586                 spec->adc_nids = ad1988_adc_nids;
1587                 spec->capsrc_nids = ad1988_capsrc_nids;
1588                 spec->input_mux = &ad1988_6stack_capture_source;
1589                 spec->num_mixers = 1;
1590                 spec->mixers[0] = ad1988_6stack_mixers;
1591                 spec->num_init_verbs = 1;
1592                 spec->init_verbs[0] = ad1988_6stack_init_verbs;
1593                 if (board_config == AD1988_6STACK_DIG) {
1594                         spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
1595                         spec->dig_in_nid = AD1988_SPDIF_IN;
1596                 }
1597                 break;
1598         case AD1988_3STACK:
1599         case AD1988_3STACK_DIG:
1600                 spec->multiout.max_channels = 6;
1601                 spec->multiout.num_dacs = 3;
1602                 spec->multiout.dac_nids = ad1988_dac_nids;
1603                 spec->num_adc_nids = ARRAY_SIZE(ad1988_adc_nids);
1604                 spec->adc_nids = ad1988_adc_nids;
1605                 spec->capsrc_nids = ad1988_capsrc_nids;
1606                 spec->input_mux = &ad1988_6stack_capture_source;
1607                 spec->channel_mode = ad1988_3stack_modes;
1608                 spec->num_channel_mode = ARRAY_SIZE(ad1988_3stack_modes);
1609                 spec->num_mixers = 1;
1610                 spec->mixers[0] = ad1988_3stack_mixers;
1611                 spec->num_init_verbs = 1;
1612                 spec->init_verbs[0] = ad1988_3stack_init_verbs;
1613                 if (board_config == AD1988_3STACK_DIG)
1614                         spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
1615                 break;
1616         case AD1988_LAPTOP:
1617         case AD1988_LAPTOP_DIG:
1618                 spec->multiout.max_channels = 2;
1619                 spec->multiout.num_dacs = 1;
1620                 spec->multiout.dac_nids = ad1988_dac_nids;
1621                 spec->num_adc_nids = ARRAY_SIZE(ad1988_adc_nids);
1622                 spec->adc_nids = ad1988_adc_nids;
1623                 spec->capsrc_nids = ad1988_capsrc_nids;
1624                 spec->input_mux = &ad1988_laptop_capture_source;
1625                 spec->num_mixers = 1;
1626                 spec->mixers[0] = ad1988_laptop_mixers;
1627                 spec->num_init_verbs = 1;
1628                 spec->init_verbs[0] = ad1988_laptop_init_verbs;
1629                 if (board_config == AD1988_LAPTOP_DIG)
1630                         spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
1631                 break;
1632         }
1633
1634         spec->mixers[spec->num_mixers++] = ad1988_capture_mixers;
1635         spec->init_verbs[spec->num_init_verbs++] = ad1988_capture_init_verbs;
1636         if (spec->multiout.dig_out_nid) {
1637                 spec->mixers[spec->num_mixers++] = ad1988_spdif_out_mixers;
1638                 spec->init_verbs[spec->num_init_verbs++] = ad1988_spdif_init_verbs;
1639         }
1640         if (spec->dig_in_nid)
1641                 spec->mixers[spec->num_mixers++] = ad1988_spdif_in_mixers;
1642
1643         codec->patch_ops = ad198x_patch_ops;
1644         switch (board_config) {
1645         case AD1988_LAPTOP:
1646         case AD1988_LAPTOP_DIG:
1647                 codec->patch_ops.unsol_event = ad1988_laptop_unsol_event;
1648                 break;
1649         }
1650
1651         return 0;
1652 }
1653
1654
1655 /*
1656  * patch entries
1657  */
1658 struct hda_codec_preset snd_hda_preset_analog[] = {
1659         { .id = 0x11d41981, .name = "AD1981", .patch = patch_ad1981 },
1660         { .id = 0x11d41983, .name = "AD1983", .patch = patch_ad1983 },
1661         { .id = 0x11d41986, .name = "AD1986A", .patch = patch_ad1986a },
1662         { .id = 0x11d41988, .name = "AD1988", .patch = patch_ad1988 },
1663         {} /* terminator */
1664 };