[ALSA] Remove sound/driver.h
[sfrench/cifs-2.6.git] / sound / pci / hda / patch_analog.c
1 /*
2  * HD audio interface patch for AD1882, AD1884, AD1981HD, AD1983, AD1984,
3  *   AD1986A, AD1988
4  *
5  * Copyright (c) 2005-2007 Takashi Iwai <tiwai@suse.de>
6  *
7  *  This driver is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation; either version 2 of the License, or
10  *  (at your option) any later version.
11  *
12  *  This driver is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with this program; if not, write to the Free Software
19  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
20  */
21
22 #include <linux/init.h>
23 #include <linux/delay.h>
24 #include <linux/slab.h>
25 #include <linux/pci.h>
26 #include <linux/mutex.h>
27
28 #include <sound/core.h>
29 #include "hda_codec.h"
30 #include "hda_local.h"
31
32 struct ad198x_spec {
33         struct snd_kcontrol_new *mixers[5];
34         int num_mixers;
35
36         const struct hda_verb *init_verbs[5];   /* initialization verbs
37                                                  * don't forget NULL termination!
38                                                  */
39         unsigned int num_init_verbs;
40
41         /* playback */
42         struct hda_multi_out multiout;  /* playback set-up
43                                          * max_channels, dacs must be set
44                                          * dig_out_nid and hp_nid are optional
45                                          */
46         unsigned int cur_eapd;
47         unsigned int need_dac_fix;
48
49         /* capture */
50         unsigned int num_adc_nids;
51         hda_nid_t *adc_nids;
52         hda_nid_t dig_in_nid;           /* digital-in NID; optional */
53
54         /* capture source */
55         const struct hda_input_mux *input_mux;
56         hda_nid_t *capsrc_nids;
57         unsigned int cur_mux[3];
58
59         /* channel model */
60         const struct hda_channel_mode *channel_mode;
61         int num_channel_mode;
62
63         /* PCM information */
64         struct hda_pcm pcm_rec[3];      /* used in alc_build_pcms() */
65
66         struct mutex amp_mutex; /* PCM volume/mute control mutex */
67         unsigned int spdif_route;
68
69         /* dynamic controls, init_verbs and input_mux */
70         struct auto_pin_cfg autocfg;
71         unsigned int num_kctl_alloc, num_kctl_used;
72         struct snd_kcontrol_new *kctl_alloc;
73         struct hda_input_mux private_imux;
74         hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
75
76         unsigned int jack_present :1;
77
78 #ifdef CONFIG_SND_HDA_POWER_SAVE
79         struct hda_loopback_check loopback;
80 #endif
81 };
82
83 /*
84  * input MUX handling (common part)
85  */
86 static int ad198x_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
87 {
88         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
89         struct ad198x_spec *spec = codec->spec;
90
91         return snd_hda_input_mux_info(spec->input_mux, uinfo);
92 }
93
94 static int ad198x_mux_enum_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
95 {
96         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
97         struct ad198x_spec *spec = codec->spec;
98         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
99
100         ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
101         return 0;
102 }
103
104 static int ad198x_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
105 {
106         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
107         struct ad198x_spec *spec = codec->spec;
108         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
109
110         return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
111                                      spec->capsrc_nids[adc_idx],
112                                      &spec->cur_mux[adc_idx]);
113 }
114
115 /*
116  * initialization (common callbacks)
117  */
118 static int ad198x_init(struct hda_codec *codec)
119 {
120         struct ad198x_spec *spec = codec->spec;
121         int i;
122
123         for (i = 0; i < spec->num_init_verbs; i++)
124                 snd_hda_sequence_write(codec, spec->init_verbs[i]);
125         return 0;
126 }
127
128 static int ad198x_build_controls(struct hda_codec *codec)
129 {
130         struct ad198x_spec *spec = codec->spec;
131         unsigned int i;
132         int err;
133
134         for (i = 0; i < spec->num_mixers; i++) {
135                 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
136                 if (err < 0)
137                         return err;
138         }
139         if (spec->multiout.dig_out_nid) {
140                 err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid);
141                 if (err < 0)
142                         return err;
143         } 
144         if (spec->dig_in_nid) {
145                 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
146                 if (err < 0)
147                         return err;
148         }
149         return 0;
150 }
151
152 #ifdef CONFIG_SND_HDA_POWER_SAVE
153 static int ad198x_check_power_status(struct hda_codec *codec, hda_nid_t nid)
154 {
155         struct ad198x_spec *spec = codec->spec;
156         return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
157 }
158 #endif
159
160 /*
161  * Analog playback callbacks
162  */
163 static int ad198x_playback_pcm_open(struct hda_pcm_stream *hinfo,
164                                     struct hda_codec *codec,
165                                     struct snd_pcm_substream *substream)
166 {
167         struct ad198x_spec *spec = codec->spec;
168         return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
169 }
170
171 static int ad198x_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
172                                        struct hda_codec *codec,
173                                        unsigned int stream_tag,
174                                        unsigned int format,
175                                        struct snd_pcm_substream *substream)
176 {
177         struct ad198x_spec *spec = codec->spec;
178         return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag,
179                                                 format, substream);
180 }
181
182 static int ad198x_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
183                                        struct hda_codec *codec,
184                                        struct snd_pcm_substream *substream)
185 {
186         struct ad198x_spec *spec = codec->spec;
187         return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
188 }
189
190 /*
191  * Digital out
192  */
193 static int ad198x_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
194                                         struct hda_codec *codec,
195                                         struct snd_pcm_substream *substream)
196 {
197         struct ad198x_spec *spec = codec->spec;
198         return snd_hda_multi_out_dig_open(codec, &spec->multiout);
199 }
200
201 static int ad198x_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
202                                          struct hda_codec *codec,
203                                          struct snd_pcm_substream *substream)
204 {
205         struct ad198x_spec *spec = codec->spec;
206         return snd_hda_multi_out_dig_close(codec, &spec->multiout);
207 }
208
209 static int ad198x_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
210                                            struct hda_codec *codec,
211                                            unsigned int stream_tag,
212                                            unsigned int format,
213                                            struct snd_pcm_substream *substream)
214 {
215         struct ad198x_spec *spec = codec->spec;
216         return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag,
217                                              format, substream);
218 }
219
220 /*
221  * Analog capture
222  */
223 static int ad198x_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
224                                       struct hda_codec *codec,
225                                       unsigned int stream_tag,
226                                       unsigned int format,
227                                       struct snd_pcm_substream *substream)
228 {
229         struct ad198x_spec *spec = codec->spec;
230         snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
231                                    stream_tag, 0, format);
232         return 0;
233 }
234
235 static int ad198x_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
236                                       struct hda_codec *codec,
237                                       struct snd_pcm_substream *substream)
238 {
239         struct ad198x_spec *spec = codec->spec;
240         snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
241                                    0, 0, 0);
242         return 0;
243 }
244
245
246 /*
247  */
248 static struct hda_pcm_stream ad198x_pcm_analog_playback = {
249         .substreams = 1,
250         .channels_min = 2,
251         .channels_max = 6, /* changed later */
252         .nid = 0, /* fill later */
253         .ops = {
254                 .open = ad198x_playback_pcm_open,
255                 .prepare = ad198x_playback_pcm_prepare,
256                 .cleanup = ad198x_playback_pcm_cleanup
257         },
258 };
259
260 static struct hda_pcm_stream ad198x_pcm_analog_capture = {
261         .substreams = 1,
262         .channels_min = 2,
263         .channels_max = 2,
264         .nid = 0, /* fill later */
265         .ops = {
266                 .prepare = ad198x_capture_pcm_prepare,
267                 .cleanup = ad198x_capture_pcm_cleanup
268         },
269 };
270
271 static struct hda_pcm_stream ad198x_pcm_digital_playback = {
272         .substreams = 1,
273         .channels_min = 2,
274         .channels_max = 2,
275         .nid = 0, /* fill later */
276         .ops = {
277                 .open = ad198x_dig_playback_pcm_open,
278                 .close = ad198x_dig_playback_pcm_close,
279                 .prepare = ad198x_dig_playback_pcm_prepare
280         },
281 };
282
283 static struct hda_pcm_stream ad198x_pcm_digital_capture = {
284         .substreams = 1,
285         .channels_min = 2,
286         .channels_max = 2,
287         /* NID is set in alc_build_pcms */
288 };
289
290 static int ad198x_build_pcms(struct hda_codec *codec)
291 {
292         struct ad198x_spec *spec = codec->spec;
293         struct hda_pcm *info = spec->pcm_rec;
294
295         codec->num_pcms = 1;
296         codec->pcm_info = info;
297
298         info->name = "AD198x Analog";
299         info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad198x_pcm_analog_playback;
300         info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->multiout.max_channels;
301         info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
302         info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad198x_pcm_analog_capture;
303         info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_adc_nids;
304         info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
305
306         if (spec->multiout.dig_out_nid) {
307                 info++;
308                 codec->num_pcms++;
309                 info->name = "AD198x Digital";
310                 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad198x_pcm_digital_playback;
311                 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
312                 if (spec->dig_in_nid) {
313                         info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad198x_pcm_digital_capture;
314                         info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
315                 }
316         }
317
318         return 0;
319 }
320
321 static void ad198x_free(struct hda_codec *codec)
322 {
323         struct ad198x_spec *spec = codec->spec;
324         unsigned int i;
325
326         if (spec->kctl_alloc) {
327                 for (i = 0; i < spec->num_kctl_used; i++)
328                         kfree(spec->kctl_alloc[i].name);
329                 kfree(spec->kctl_alloc);
330         }
331         kfree(codec->spec);
332 }
333
334 static struct hda_codec_ops ad198x_patch_ops = {
335         .build_controls = ad198x_build_controls,
336         .build_pcms = ad198x_build_pcms,
337         .init = ad198x_init,
338         .free = ad198x_free,
339 #ifdef CONFIG_SND_HDA_POWER_SAVE
340         .check_power_status = ad198x_check_power_status,
341 #endif
342 };
343
344
345 /*
346  * EAPD control
347  * the private value = nid | (invert << 8)
348  */
349 #define ad198x_eapd_info        snd_ctl_boolean_mono_info
350
351 static int ad198x_eapd_get(struct snd_kcontrol *kcontrol,
352                            struct snd_ctl_elem_value *ucontrol)
353 {
354         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
355         struct ad198x_spec *spec = codec->spec;
356         int invert = (kcontrol->private_value >> 8) & 1;
357         if (invert)
358                 ucontrol->value.integer.value[0] = ! spec->cur_eapd;
359         else
360                 ucontrol->value.integer.value[0] = spec->cur_eapd;
361         return 0;
362 }
363
364 static int ad198x_eapd_put(struct snd_kcontrol *kcontrol,
365                            struct snd_ctl_elem_value *ucontrol)
366 {
367         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
368         struct ad198x_spec *spec = codec->spec;
369         int invert = (kcontrol->private_value >> 8) & 1;
370         hda_nid_t nid = kcontrol->private_value & 0xff;
371         unsigned int eapd;
372         eapd = !!ucontrol->value.integer.value[0];
373         if (invert)
374                 eapd = !eapd;
375         if (eapd == spec->cur_eapd)
376                 return 0;
377         spec->cur_eapd = eapd;
378         snd_hda_codec_write_cache(codec, nid,
379                                   0, AC_VERB_SET_EAPD_BTLENABLE,
380                                   eapd ? 0x02 : 0x00);
381         return 1;
382 }
383
384 static int ad198x_ch_mode_info(struct snd_kcontrol *kcontrol,
385                                struct snd_ctl_elem_info *uinfo);
386 static int ad198x_ch_mode_get(struct snd_kcontrol *kcontrol,
387                               struct snd_ctl_elem_value *ucontrol);
388 static int ad198x_ch_mode_put(struct snd_kcontrol *kcontrol,
389                               struct snd_ctl_elem_value *ucontrol);
390
391
392 /*
393  * AD1986A specific
394  */
395
396 #define AD1986A_SPDIF_OUT       0x02
397 #define AD1986A_FRONT_DAC       0x03
398 #define AD1986A_SURR_DAC        0x04
399 #define AD1986A_CLFE_DAC        0x05
400 #define AD1986A_ADC             0x06
401
402 static hda_nid_t ad1986a_dac_nids[3] = {
403         AD1986A_FRONT_DAC, AD1986A_SURR_DAC, AD1986A_CLFE_DAC
404 };
405 static hda_nid_t ad1986a_adc_nids[1] = { AD1986A_ADC };
406 static hda_nid_t ad1986a_capsrc_nids[1] = { 0x12 };
407
408 static struct hda_input_mux ad1986a_capture_source = {
409         .num_items = 7,
410         .items = {
411                 { "Mic", 0x0 },
412                 { "CD", 0x1 },
413                 { "Aux", 0x3 },
414                 { "Line", 0x4 },
415                 { "Mix", 0x5 },
416                 { "Mono", 0x6 },
417                 { "Phone", 0x7 },
418         },
419 };
420
421
422 static struct hda_bind_ctls ad1986a_bind_pcm_vol = {
423         .ops = &snd_hda_bind_vol,
424         .values = {
425                 HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT),
426                 HDA_COMPOSE_AMP_VAL(AD1986A_SURR_DAC, 3, 0, HDA_OUTPUT),
427                 HDA_COMPOSE_AMP_VAL(AD1986A_CLFE_DAC, 3, 0, HDA_OUTPUT),
428                 0
429         },
430 };
431
432 static struct hda_bind_ctls ad1986a_bind_pcm_sw = {
433         .ops = &snd_hda_bind_sw,
434         .values = {
435                 HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT),
436                 HDA_COMPOSE_AMP_VAL(AD1986A_SURR_DAC, 3, 0, HDA_OUTPUT),
437                 HDA_COMPOSE_AMP_VAL(AD1986A_CLFE_DAC, 3, 0, HDA_OUTPUT),
438                 0
439         },
440 };
441
442 /*
443  * mixers
444  */
445 static struct snd_kcontrol_new ad1986a_mixers[] = {
446         /*
447          * bind volumes/mutes of 3 DACs as a single PCM control for simplicity
448          */
449         HDA_BIND_VOL("PCM Playback Volume", &ad1986a_bind_pcm_vol),
450         HDA_BIND_SW("PCM Playback Switch", &ad1986a_bind_pcm_sw),
451         HDA_CODEC_VOLUME("Front Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
452         HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
453         HDA_CODEC_VOLUME("Surround Playback Volume", 0x1c, 0x0, HDA_OUTPUT),
454         HDA_CODEC_MUTE("Surround Playback Switch", 0x1c, 0x0, HDA_OUTPUT),
455         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x1d, 1, 0x0, HDA_OUTPUT),
456         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x1d, 2, 0x0, HDA_OUTPUT),
457         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x1d, 1, 0x0, HDA_OUTPUT),
458         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x1d, 2, 0x0, HDA_OUTPUT),
459         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x1a, 0x0, HDA_OUTPUT),
460         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
461         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_OUTPUT),
462         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_OUTPUT),
463         HDA_CODEC_VOLUME("Line Playback Volume", 0x17, 0x0, HDA_OUTPUT),
464         HDA_CODEC_MUTE("Line Playback Switch", 0x17, 0x0, HDA_OUTPUT),
465         HDA_CODEC_VOLUME("Aux Playback Volume", 0x16, 0x0, HDA_OUTPUT),
466         HDA_CODEC_MUTE("Aux Playback Switch", 0x16, 0x0, HDA_OUTPUT),
467         HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
468         HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
469         HDA_CODEC_VOLUME("Mic Boost", 0x0f, 0x0, HDA_OUTPUT),
470         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x18, 0x0, HDA_OUTPUT),
471         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x18, 0x0, HDA_OUTPUT),
472         HDA_CODEC_VOLUME("Mono Playback Volume", 0x1e, 0x0, HDA_OUTPUT),
473         HDA_CODEC_MUTE("Mono Playback Switch", 0x1e, 0x0, HDA_OUTPUT),
474         HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT),
475         HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT),
476         {
477                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
478                 .name = "Capture Source",
479                 .info = ad198x_mux_enum_info,
480                 .get = ad198x_mux_enum_get,
481                 .put = ad198x_mux_enum_put,
482         },
483         HDA_CODEC_MUTE("Stereo Downmix Switch", 0x09, 0x0, HDA_OUTPUT),
484         { } /* end */
485 };
486
487 /* additional mixers for 3stack mode */
488 static struct snd_kcontrol_new ad1986a_3st_mixers[] = {
489         {
490                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
491                 .name = "Channel Mode",
492                 .info = ad198x_ch_mode_info,
493                 .get = ad198x_ch_mode_get,
494                 .put = ad198x_ch_mode_put,
495         },
496         { } /* end */
497 };
498
499 /* laptop model - 2ch only */
500 static hda_nid_t ad1986a_laptop_dac_nids[1] = { AD1986A_FRONT_DAC };
501
502 /* master controls both pins 0x1a and 0x1b */
503 static struct hda_bind_ctls ad1986a_laptop_master_vol = {
504         .ops = &snd_hda_bind_vol,
505         .values = {
506                 HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT),
507                 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
508                 0,
509         },
510 };
511
512 static struct hda_bind_ctls ad1986a_laptop_master_sw = {
513         .ops = &snd_hda_bind_sw,
514         .values = {
515                 HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT),
516                 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
517                 0,
518         },
519 };
520
521 static struct snd_kcontrol_new ad1986a_laptop_mixers[] = {
522         HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT),
523         HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT),
524         HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol),
525         HDA_BIND_SW("Master Playback Switch", &ad1986a_laptop_master_sw),
526         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_OUTPUT),
527         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_OUTPUT),
528         HDA_CODEC_VOLUME("Line Playback Volume", 0x17, 0x0, HDA_OUTPUT),
529         HDA_CODEC_MUTE("Line Playback Switch", 0x17, 0x0, HDA_OUTPUT),
530         HDA_CODEC_VOLUME("Aux Playback Volume", 0x16, 0x0, HDA_OUTPUT),
531         HDA_CODEC_MUTE("Aux Playback Switch", 0x16, 0x0, HDA_OUTPUT),
532         HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
533         HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
534         HDA_CODEC_VOLUME("Mic Boost", 0x0f, 0x0, HDA_OUTPUT),
535         /* HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x18, 0x0, HDA_OUTPUT),
536            HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x18, 0x0, HDA_OUTPUT),
537            HDA_CODEC_VOLUME("Mono Playback Volume", 0x1e, 0x0, HDA_OUTPUT),
538            HDA_CODEC_MUTE("Mono Playback Switch", 0x1e, 0x0, HDA_OUTPUT), */
539         HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT),
540         HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT),
541         {
542                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
543                 .name = "Capture Source",
544                 .info = ad198x_mux_enum_info,
545                 .get = ad198x_mux_enum_get,
546                 .put = ad198x_mux_enum_put,
547         },
548         { } /* end */
549 };
550
551 /* laptop-eapd model - 2ch only */
552
553 static struct hda_input_mux ad1986a_laptop_eapd_capture_source = {
554         .num_items = 3,
555         .items = {
556                 { "Mic", 0x0 },
557                 { "Internal Mic", 0x4 },
558                 { "Mix", 0x5 },
559         },
560 };
561
562 static struct snd_kcontrol_new ad1986a_laptop_eapd_mixers[] = {
563         HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol),
564         HDA_BIND_SW("Master Playback Switch", &ad1986a_laptop_master_sw),
565         HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT),
566         HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT),
567         HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0x0, HDA_OUTPUT),
568         HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0x0, HDA_OUTPUT),
569         HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
570         HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
571         HDA_CODEC_VOLUME("Mic Boost", 0x0f, 0x0, HDA_OUTPUT),
572         HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT),
573         HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT),
574         {
575                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
576                 .name = "Capture Source",
577                 .info = ad198x_mux_enum_info,
578                 .get = ad198x_mux_enum_get,
579                 .put = ad198x_mux_enum_put,
580         },
581         {
582                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
583                 .name = "External Amplifier",
584                 .info = ad198x_eapd_info,
585                 .get = ad198x_eapd_get,
586                 .put = ad198x_eapd_put,
587                 .private_value = 0x1b | (1 << 8), /* port-D, inversed */
588         },
589         { } /* end */
590 };
591
592 /* laptop-automute - 2ch only */
593
594 static void ad1986a_update_hp(struct hda_codec *codec)
595 {
596         struct ad198x_spec *spec = codec->spec;
597         unsigned int mute;
598
599         if (spec->jack_present)
600                 mute = HDA_AMP_MUTE; /* mute internal speaker */
601         else
602                 /* unmute internal speaker if necessary */
603                 mute = snd_hda_codec_amp_read(codec, 0x1a, 0, HDA_OUTPUT, 0);
604         snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
605                                  HDA_AMP_MUTE, mute);
606 }
607
608 static void ad1986a_hp_automute(struct hda_codec *codec)
609 {
610         struct ad198x_spec *spec = codec->spec;
611         unsigned int present;
612
613         present = snd_hda_codec_read(codec, 0x1a, 0, AC_VERB_GET_PIN_SENSE, 0);
614         /* Lenovo N100 seems to report the reversed bit for HP jack-sensing */
615         spec->jack_present = !(present & 0x80000000);
616         ad1986a_update_hp(codec);
617 }
618
619 #define AD1986A_HP_EVENT                0x37
620
621 static void ad1986a_hp_unsol_event(struct hda_codec *codec, unsigned int res)
622 {
623         if ((res >> 26) != AD1986A_HP_EVENT)
624                 return;
625         ad1986a_hp_automute(codec);
626 }
627
628 static int ad1986a_hp_init(struct hda_codec *codec)
629 {
630         ad198x_init(codec);
631         ad1986a_hp_automute(codec);
632         return 0;
633 }
634
635 /* bind hp and internal speaker mute (with plug check) */
636 static int ad1986a_hp_master_sw_put(struct snd_kcontrol *kcontrol,
637                                     struct snd_ctl_elem_value *ucontrol)
638 {
639         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
640         long *valp = ucontrol->value.integer.value;
641         int change;
642
643         change = snd_hda_codec_amp_update(codec, 0x1a, 0, HDA_OUTPUT, 0,
644                                           HDA_AMP_MUTE,
645                                           valp[0] ? 0 : HDA_AMP_MUTE);
646         change |= snd_hda_codec_amp_update(codec, 0x1a, 1, HDA_OUTPUT, 0,
647                                            HDA_AMP_MUTE,
648                                            valp[1] ? 0 : HDA_AMP_MUTE);
649         if (change)
650                 ad1986a_update_hp(codec);
651         return change;
652 }
653
654 static struct snd_kcontrol_new ad1986a_laptop_automute_mixers[] = {
655         HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol),
656         {
657                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
658                 .name = "Master Playback Switch",
659                 .info = snd_hda_mixer_amp_switch_info,
660                 .get = snd_hda_mixer_amp_switch_get,
661                 .put = ad1986a_hp_master_sw_put,
662                 .private_value = HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT),
663         },
664         HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT),
665         HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT),
666         HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0x0, HDA_OUTPUT),
667         HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0x0, HDA_OUTPUT),
668         HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
669         HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
670         HDA_CODEC_VOLUME("Mic Boost", 0x0f, 0x0, HDA_OUTPUT),
671         HDA_CODEC_VOLUME("Beep Playback Volume", 0x18, 0x0, HDA_OUTPUT),
672         HDA_CODEC_MUTE("Beep Playback Switch", 0x18, 0x0, HDA_OUTPUT),
673         HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT),
674         HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT),
675         {
676                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
677                 .name = "Capture Source",
678                 .info = ad198x_mux_enum_info,
679                 .get = ad198x_mux_enum_get,
680                 .put = ad198x_mux_enum_put,
681         },
682         {
683                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
684                 .name = "External Amplifier",
685                 .info = ad198x_eapd_info,
686                 .get = ad198x_eapd_get,
687                 .put = ad198x_eapd_put,
688                 .private_value = 0x1b | (1 << 8), /* port-D, inversed */
689         },
690         { } /* end */
691 };
692
693 /*
694  * initialization verbs
695  */
696 static struct hda_verb ad1986a_init_verbs[] = {
697         /* Front, Surround, CLFE DAC; mute as default */
698         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
699         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
700         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
701         /* Downmix - off */
702         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
703         /* HP, Line-Out, Surround, CLFE selectors */
704         {0x0a, AC_VERB_SET_CONNECT_SEL, 0x0},
705         {0x0b, AC_VERB_SET_CONNECT_SEL, 0x0},
706         {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0},
707         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
708         /* Mono selector */
709         {0x0e, AC_VERB_SET_CONNECT_SEL, 0x0},
710         /* Mic selector: Mic 1/2 pin */
711         {0x0f, AC_VERB_SET_CONNECT_SEL, 0x0},
712         /* Line-in selector: Line-in */
713         {0x10, AC_VERB_SET_CONNECT_SEL, 0x0},
714         /* Mic 1/2 swap */
715         {0x11, AC_VERB_SET_CONNECT_SEL, 0x0},
716         /* Record selector: mic */
717         {0x12, AC_VERB_SET_CONNECT_SEL, 0x0},
718         /* Mic, Phone, CD, Aux, Line-In amp; mute as default */
719         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
720         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
721         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
722         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
723         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
724         /* PC beep */
725         {0x18, AC_VERB_SET_CONNECT_SEL, 0x0},
726         /* HP, Line-Out, Surround, CLFE, Mono pins; mute as default */
727         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
728         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
729         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
730         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
731         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
732         /* HP Pin */
733         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
734         /* Front, Surround, CLFE Pins */
735         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
736         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
737         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
738         /* Mono Pin */
739         {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
740         /* Mic Pin */
741         {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
742         /* Line, Aux, CD, Beep-In Pin */
743         {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
744         {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
745         {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
746         {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
747         {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
748         { } /* end */
749 };
750
751 static struct hda_verb ad1986a_ch2_init[] = {
752         /* Surround out -> Line In */
753         { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
754         /* Line-in selectors */
755         { 0x10, AC_VERB_SET_CONNECT_SEL, 0x1 },
756         /* CLFE -> Mic in */
757         { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
758         /* Mic selector, mix C/LFE (backmic) and Mic (frontmic) */
759         { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x4 },
760         { } /* end */
761 };
762
763 static struct hda_verb ad1986a_ch4_init[] = {
764         /* Surround out -> Surround */
765         { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
766         { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 },
767         /* CLFE -> Mic in */
768         { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
769         { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x4 },
770         { } /* end */
771 };
772
773 static struct hda_verb ad1986a_ch6_init[] = {
774         /* Surround out -> Surround out */
775         { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
776         { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 },
777         /* CLFE -> CLFE */
778         { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
779         { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x0 },
780         { } /* end */
781 };
782
783 static struct hda_channel_mode ad1986a_modes[3] = {
784         { 2, ad1986a_ch2_init },
785         { 4, ad1986a_ch4_init },
786         { 6, ad1986a_ch6_init },
787 };
788
789 /* eapd initialization */
790 static struct hda_verb ad1986a_eapd_init_verbs[] = {
791         {0x1b, AC_VERB_SET_EAPD_BTLENABLE, 0x00 },
792         {}
793 };
794
795 /* Ultra initialization */
796 static struct hda_verb ad1986a_ultra_init[] = {
797         /* eapd initialization */
798         { 0x1b, AC_VERB_SET_EAPD_BTLENABLE, 0x00 },
799         /* CLFE -> Mic in */
800         { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x2 },
801         { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
802         { 0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
803         { } /* end */
804 };
805
806 /* pin sensing on HP jack */
807 static struct hda_verb ad1986a_hp_init_verbs[] = {
808         {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1986A_HP_EVENT},
809         {}
810 };
811
812
813 /* models */
814 enum {
815         AD1986A_6STACK,
816         AD1986A_3STACK,
817         AD1986A_LAPTOP,
818         AD1986A_LAPTOP_EAPD,
819         AD1986A_LAPTOP_AUTOMUTE,
820         AD1986A_ULTRA,
821         AD1986A_MODELS
822 };
823
824 static const char *ad1986a_models[AD1986A_MODELS] = {
825         [AD1986A_6STACK]        = "6stack",
826         [AD1986A_3STACK]        = "3stack",
827         [AD1986A_LAPTOP]        = "laptop",
828         [AD1986A_LAPTOP_EAPD]   = "laptop-eapd",
829         [AD1986A_LAPTOP_AUTOMUTE] = "laptop-automute",
830         [AD1986A_ULTRA]         = "ultra",
831 };
832
833 static struct snd_pci_quirk ad1986a_cfg_tbl[] = {
834         SND_PCI_QUIRK(0x103c, 0x30af, "HP B2800", AD1986A_LAPTOP_EAPD),
835         SND_PCI_QUIRK(0x1043, 0x1153, "ASUS M9", AD1986A_LAPTOP_EAPD),
836         SND_PCI_QUIRK(0x1043, 0x11f7, "ASUS U5A", AD1986A_LAPTOP_EAPD),
837         SND_PCI_QUIRK(0x1043, 0x1213, "ASUS A6J", AD1986A_LAPTOP_EAPD),
838         SND_PCI_QUIRK(0x1043, 0x1263, "ASUS U5F", AD1986A_LAPTOP_EAPD),
839         SND_PCI_QUIRK(0x1043, 0x1297, "ASUS Z62F", AD1986A_LAPTOP_EAPD),
840         SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS V1j", AD1986A_LAPTOP_EAPD),
841         SND_PCI_QUIRK(0x1043, 0x1302, "ASUS W3j", AD1986A_LAPTOP_EAPD),
842         SND_PCI_QUIRK(0x1043, 0x1443, "ASUS VX1", AD1986A_LAPTOP),
843         SND_PCI_QUIRK(0x1043, 0x1447, "ASUS A8J", AD1986A_3STACK),
844         SND_PCI_QUIRK(0x1043, 0x817f, "ASUS P5", AD1986A_3STACK),
845         SND_PCI_QUIRK(0x1043, 0x818f, "ASUS P5", AD1986A_LAPTOP),
846         SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS P5", AD1986A_3STACK),
847         SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS M2N", AD1986A_3STACK),
848         SND_PCI_QUIRK(0x1043, 0x8234, "ASUS M2N", AD1986A_3STACK),
849         SND_PCI_QUIRK(0x10de, 0xcb84, "ASUS A8N-VM", AD1986A_3STACK),
850         SND_PCI_QUIRK(0x1179, 0xff40, "Toshiba", AD1986A_LAPTOP_EAPD),
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, 0xc027, "Samsung Q1", AD1986A_ULTRA),
857         SND_PCI_QUIRK(0x144d, 0xc504, "Samsung Q35", AD1986A_3STACK),
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         SND_PCI_QUIRK(0x1014, 0x0597, "Lenovo Z60", AD1981_THINKPAD),
1503         /* All HP models */
1504         SND_PCI_QUIRK(0x103c, 0, "HP nx", AD1981_HP),
1505         SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba U205", AD1981_TOSHIBA),
1506         /* Lenovo Thinkpad T60/X60/Z6xx */
1507         SND_PCI_QUIRK(0x17aa, 0, "Lenovo Thinkpad", AD1981_THINKPAD),
1508         /* HP nx6320 (reversed SSID, H/W bug) */
1509         SND_PCI_QUIRK(0x30b0, 0x103c, "HP nx6320", AD1981_HP),
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         /* Analog CD Input */
2088         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2089
2090         { }
2091 };
2092
2093 static struct hda_verb ad1988_capture_init_verbs[] = {
2094         /* mute analog mix */
2095         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2096         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2097         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2098         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2099         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2100         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
2101         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2102         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2103         /* select ADCs - front-mic */
2104         {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1},
2105         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x1},
2106         {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
2107         /* ADCs; muted */
2108         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2109         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2110         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2111
2112         { }
2113 };
2114
2115 static struct hda_verb ad1988_spdif_init_verbs[] = {
2116         /* SPDIF out sel */
2117         {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */
2118         {0x0b, AC_VERB_SET_CONNECT_SEL, 0x0}, /* ADC1 */
2119         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2120         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2121         /* SPDIF out pin */
2122         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
2123
2124         { }
2125 };
2126
2127 /*
2128  * verbs for 3stack (+dig)
2129  */
2130 static struct hda_verb ad1988_3stack_ch2_init[] = {
2131         /* set port-C to line-in */
2132         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2133         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2134         /* set port-E to mic-in */
2135         { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2136         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2137         { } /* end */
2138 };
2139
2140 static struct hda_verb ad1988_3stack_ch6_init[] = {
2141         /* set port-C to surround out */
2142         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2143         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2144         /* set port-E to CLFE out */
2145         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2146         { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2147         { } /* end */
2148 };
2149
2150 static struct hda_channel_mode ad1988_3stack_modes[2] = {
2151         { 2, ad1988_3stack_ch2_init },
2152         { 6, ad1988_3stack_ch6_init },
2153 };
2154
2155 static struct hda_verb ad1988_3stack_init_verbs[] = {
2156         /* Front, Surround, CLFE, side DAC; unmute as default */
2157         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2158         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2159         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2160         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2161         /* Port-A front headphon path */
2162         {0x37, AC_VERB_SET_CONNECT_SEL, 0x01}, /* DAC1:04h */
2163         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2164         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2165         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2166         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2167         /* Port-D line-out path */
2168         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2169         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2170         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2171         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2172         /* Mono out path */
2173         {0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */
2174         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2175         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2176         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2177         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */
2178         /* Port-B front mic-in path */
2179         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2180         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2181         {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2182         /* Port-C line-in/surround path - 6ch mode as default */
2183         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2184         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2185         {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2186         {0x31, AC_VERB_SET_CONNECT_SEL, 0x0}, /* output sel: DAC 0x05 */
2187         {0x33, AC_VERB_SET_CONNECT_SEL, 0x0},
2188         /* Port-E mic-in/CLFE path - 6ch mode as default */
2189         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2190         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2191         {0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2192         {0x32, AC_VERB_SET_CONNECT_SEL, 0x1}, /* output sel: DAC 0x0a */
2193         {0x34, AC_VERB_SET_CONNECT_SEL, 0x0},
2194         /* mute analog mix */
2195         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2196         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2197         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2198         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2199         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2200         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
2201         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2202         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2203         /* select ADCs - front-mic */
2204         {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1},
2205         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x1},
2206         {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
2207         /* ADCs; muted */
2208         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2209         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2210         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2211         { }
2212 };
2213
2214 /*
2215  * verbs for laptop mode (+dig)
2216  */
2217 static struct hda_verb ad1988_laptop_hp_on[] = {
2218         /* unmute port-A and mute port-D */
2219         { 0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2220         { 0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2221         { } /* end */
2222 };
2223 static struct hda_verb ad1988_laptop_hp_off[] = {
2224         /* mute port-A and unmute port-D */
2225         { 0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2226         { 0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2227         { } /* end */
2228 };
2229
2230 #define AD1988_HP_EVENT 0x01
2231
2232 static struct hda_verb ad1988_laptop_init_verbs[] = {
2233         /* Front, Surround, CLFE, side DAC; unmute as default */
2234         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2235         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2236         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2237         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2238         /* Port-A front headphon path */
2239         {0x37, AC_VERB_SET_CONNECT_SEL, 0x01}, /* DAC1:04h */
2240         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2241         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2242         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2243         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2244         /* unsolicited event for pin-sense */
2245         {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1988_HP_EVENT },
2246         /* Port-D line-out path + EAPD */
2247         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2248         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2249         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2250         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2251         {0x12, AC_VERB_SET_EAPD_BTLENABLE, 0x00}, /* EAPD-off */
2252         /* Mono out path */
2253         {0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */
2254         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2255         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2256         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2257         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */
2258         /* Port-B mic-in path */
2259         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2260         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2261         {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2262         /* Port-C docking station - try to output */
2263         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2264         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2265         {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2266         {0x33, AC_VERB_SET_CONNECT_SEL, 0x0},
2267         /* mute analog mix */
2268         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2269         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2270         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2271         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2272         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2273         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
2274         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2275         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2276         /* select ADCs - mic */
2277         {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1},
2278         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x1},
2279         {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
2280         /* ADCs; muted */
2281         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2282         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2283         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2284         { }
2285 };
2286
2287 static void ad1988_laptop_unsol_event(struct hda_codec *codec, unsigned int res)
2288 {
2289         if ((res >> 26) != AD1988_HP_EVENT)
2290                 return;
2291         if (snd_hda_codec_read(codec, 0x11, 0, AC_VERB_GET_PIN_SENSE, 0) & (1 << 31))
2292                 snd_hda_sequence_write(codec, ad1988_laptop_hp_on);
2293         else
2294                 snd_hda_sequence_write(codec, ad1988_laptop_hp_off);
2295
2296
2297 #ifdef CONFIG_SND_HDA_POWER_SAVE
2298 static struct hda_amp_list ad1988_loopbacks[] = {
2299         { 0x20, HDA_INPUT, 0 }, /* Front Mic */
2300         { 0x20, HDA_INPUT, 1 }, /* Line */
2301         { 0x20, HDA_INPUT, 4 }, /* Mic */
2302         { 0x20, HDA_INPUT, 6 }, /* CD */
2303         { } /* end */
2304 };
2305 #endif
2306
2307 /*
2308  * Automatic parse of I/O pins from the BIOS configuration
2309  */
2310
2311 #define NUM_CONTROL_ALLOC       32
2312 #define NUM_VERB_ALLOC          32
2313
2314 enum {
2315         AD_CTL_WIDGET_VOL,
2316         AD_CTL_WIDGET_MUTE,
2317         AD_CTL_BIND_MUTE,
2318 };
2319 static struct snd_kcontrol_new ad1988_control_templates[] = {
2320         HDA_CODEC_VOLUME(NULL, 0, 0, 0),
2321         HDA_CODEC_MUTE(NULL, 0, 0, 0),
2322         HDA_BIND_MUTE(NULL, 0, 0, 0),
2323 };
2324
2325 /* add dynamic controls */
2326 static int add_control(struct ad198x_spec *spec, int type, const char *name,
2327                        unsigned long val)
2328 {
2329         struct snd_kcontrol_new *knew;
2330
2331         if (spec->num_kctl_used >= spec->num_kctl_alloc) {
2332                 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
2333
2334                 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL); /* array + terminator */
2335                 if (! knew)
2336                         return -ENOMEM;
2337                 if (spec->kctl_alloc) {
2338                         memcpy(knew, spec->kctl_alloc, sizeof(*knew) * spec->num_kctl_alloc);
2339                         kfree(spec->kctl_alloc);
2340                 }
2341                 spec->kctl_alloc = knew;
2342                 spec->num_kctl_alloc = num;
2343         }
2344
2345         knew = &spec->kctl_alloc[spec->num_kctl_used];
2346         *knew = ad1988_control_templates[type];
2347         knew->name = kstrdup(name, GFP_KERNEL);
2348         if (! knew->name)
2349                 return -ENOMEM;
2350         knew->private_value = val;
2351         spec->num_kctl_used++;
2352         return 0;
2353 }
2354
2355 #define AD1988_PIN_CD_NID               0x18
2356 #define AD1988_PIN_BEEP_NID             0x10
2357
2358 static hda_nid_t ad1988_mixer_nids[8] = {
2359         /* A     B     C     D     E     F     G     H */
2360         0x22, 0x2b, 0x2c, 0x29, 0x26, 0x2a, 0x27, 0x28
2361 };
2362
2363 static inline hda_nid_t ad1988_idx_to_dac(struct hda_codec *codec, int idx)
2364 {
2365         static hda_nid_t idx_to_dac[8] = {
2366                 /* A     B     C     D     E     F     G     H */
2367                 0x04, 0x06, 0x05, 0x04, 0x0a, 0x06, 0x05, 0x0a
2368         };
2369         static hda_nid_t idx_to_dac_rev2[8] = {
2370                 /* A     B     C     D     E     F     G     H */
2371                 0x04, 0x05, 0x0a, 0x04, 0x06, 0x05, 0x0a, 0x06
2372         };
2373         if (is_rev2(codec))
2374                 return idx_to_dac_rev2[idx];
2375         else
2376                 return idx_to_dac[idx];
2377 }
2378
2379 static hda_nid_t ad1988_boost_nids[8] = {
2380         0x38, 0x39, 0x3a, 0x3d, 0x3c, 0x3b, 0, 0
2381 };
2382
2383 static int ad1988_pin_idx(hda_nid_t nid)
2384 {
2385         static hda_nid_t ad1988_io_pins[8] = {
2386                 0x11, 0x14, 0x15, 0x12, 0x17, 0x16, 0x24, 0x25
2387         };
2388         int i;
2389         for (i = 0; i < ARRAY_SIZE(ad1988_io_pins); i++)
2390                 if (ad1988_io_pins[i] == nid)
2391                         return i;
2392         return 0; /* should be -1 */
2393 }
2394
2395 static int ad1988_pin_to_loopback_idx(hda_nid_t nid)
2396 {
2397         static int loopback_idx[8] = {
2398                 2, 0, 1, 3, 4, 5, 1, 4
2399         };
2400         switch (nid) {
2401         case AD1988_PIN_CD_NID:
2402                 return 6;
2403         default:
2404                 return loopback_idx[ad1988_pin_idx(nid)];
2405         }
2406 }
2407
2408 static int ad1988_pin_to_adc_idx(hda_nid_t nid)
2409 {
2410         static int adc_idx[8] = {
2411                 0, 1, 2, 8, 4, 3, 6, 7
2412         };
2413         switch (nid) {
2414         case AD1988_PIN_CD_NID:
2415                 return 5;
2416         default:
2417                 return adc_idx[ad1988_pin_idx(nid)];
2418         }
2419 }
2420
2421 /* fill in the dac_nids table from the parsed pin configuration */
2422 static int ad1988_auto_fill_dac_nids(struct hda_codec *codec,
2423                                      const struct auto_pin_cfg *cfg)
2424 {
2425         struct ad198x_spec *spec = codec->spec;
2426         int i, idx;
2427
2428         spec->multiout.dac_nids = spec->private_dac_nids;
2429
2430         /* check the pins hardwired to audio widget */
2431         for (i = 0; i < cfg->line_outs; i++) {
2432                 idx = ad1988_pin_idx(cfg->line_out_pins[i]);
2433                 spec->multiout.dac_nids[i] = ad1988_idx_to_dac(codec, idx);
2434         }
2435         spec->multiout.num_dacs = cfg->line_outs;
2436         return 0;
2437 }
2438
2439 /* add playback controls from the parsed DAC table */
2440 static int ad1988_auto_create_multi_out_ctls(struct ad198x_spec *spec,
2441                                              const struct auto_pin_cfg *cfg)
2442 {
2443         char name[32];
2444         static const char *chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" };
2445         hda_nid_t nid;
2446         int i, err;
2447
2448         for (i = 0; i < cfg->line_outs; i++) {
2449                 hda_nid_t dac = spec->multiout.dac_nids[i];
2450                 if (! dac)
2451                         continue;
2452                 nid = ad1988_mixer_nids[ad1988_pin_idx(cfg->line_out_pins[i])];
2453                 if (i == 2) {
2454                         /* Center/LFE */
2455                         err = add_control(spec, AD_CTL_WIDGET_VOL,
2456                                           "Center Playback Volume",
2457                                           HDA_COMPOSE_AMP_VAL(dac, 1, 0, HDA_OUTPUT));
2458                         if (err < 0)
2459                                 return err;
2460                         err = add_control(spec, AD_CTL_WIDGET_VOL,
2461                                           "LFE Playback Volume",
2462                                           HDA_COMPOSE_AMP_VAL(dac, 2, 0, HDA_OUTPUT));
2463                         if (err < 0)
2464                                 return err;
2465                         err = add_control(spec, AD_CTL_BIND_MUTE,
2466                                           "Center Playback Switch",
2467                                           HDA_COMPOSE_AMP_VAL(nid, 1, 2, HDA_INPUT));
2468                         if (err < 0)
2469                                 return err;
2470                         err = add_control(spec, AD_CTL_BIND_MUTE,
2471                                           "LFE Playback Switch",
2472                                           HDA_COMPOSE_AMP_VAL(nid, 2, 2, HDA_INPUT));
2473                         if (err < 0)
2474                                 return err;
2475                 } else {
2476                         sprintf(name, "%s Playback Volume", chname[i]);
2477                         err = add_control(spec, AD_CTL_WIDGET_VOL, name,
2478                                           HDA_COMPOSE_AMP_VAL(dac, 3, 0, HDA_OUTPUT));
2479                         if (err < 0)
2480                                 return err;
2481                         sprintf(name, "%s Playback Switch", chname[i]);
2482                         err = add_control(spec, AD_CTL_BIND_MUTE, name,
2483                                           HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
2484                         if (err < 0)
2485                                 return err;
2486                 }
2487         }
2488         return 0;
2489 }
2490
2491 /* add playback controls for speaker and HP outputs */
2492 static int ad1988_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
2493                                         const char *pfx)
2494 {
2495         struct ad198x_spec *spec = codec->spec;
2496         hda_nid_t nid;
2497         int idx, err;
2498         char name[32];
2499
2500         if (! pin)
2501                 return 0;
2502
2503         idx = ad1988_pin_idx(pin);
2504         nid = ad1988_idx_to_dac(codec, idx);
2505         /* specify the DAC as the extra output */
2506         if (! spec->multiout.hp_nid)
2507                 spec->multiout.hp_nid = nid;
2508         else
2509                 spec->multiout.extra_out_nid[0] = nid;
2510         /* control HP volume/switch on the output mixer amp */
2511         sprintf(name, "%s Playback Volume", pfx);
2512         if ((err = add_control(spec, AD_CTL_WIDGET_VOL, name,
2513                                HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
2514                 return err;
2515         nid = ad1988_mixer_nids[idx];
2516         sprintf(name, "%s Playback Switch", pfx);
2517         if ((err = add_control(spec, AD_CTL_BIND_MUTE, name,
2518                                HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT))) < 0)
2519                 return err;
2520         return 0;
2521 }
2522
2523 /* create input playback/capture controls for the given pin */
2524 static int new_analog_input(struct ad198x_spec *spec, hda_nid_t pin,
2525                             const char *ctlname, int boost)
2526 {
2527         char name[32];
2528         int err, idx;
2529
2530         sprintf(name, "%s Playback Volume", ctlname);
2531         idx = ad1988_pin_to_loopback_idx(pin);
2532         if ((err = add_control(spec, AD_CTL_WIDGET_VOL, name,
2533                                HDA_COMPOSE_AMP_VAL(0x20, 3, idx, HDA_INPUT))) < 0)
2534                 return err;
2535         sprintf(name, "%s Playback Switch", ctlname);
2536         if ((err = add_control(spec, AD_CTL_WIDGET_MUTE, name,
2537                                HDA_COMPOSE_AMP_VAL(0x20, 3, idx, HDA_INPUT))) < 0)
2538                 return err;
2539         if (boost) {
2540                 hda_nid_t bnid;
2541                 idx = ad1988_pin_idx(pin);
2542                 bnid = ad1988_boost_nids[idx];
2543                 if (bnid) {
2544                         sprintf(name, "%s Boost", ctlname);
2545                         return add_control(spec, AD_CTL_WIDGET_VOL, name,
2546                                            HDA_COMPOSE_AMP_VAL(bnid, 3, idx, HDA_OUTPUT));
2547
2548                 }
2549         }
2550         return 0;
2551 }
2552
2553 /* create playback/capture controls for input pins */
2554 static int ad1988_auto_create_analog_input_ctls(struct ad198x_spec *spec,
2555                                                 const struct auto_pin_cfg *cfg)
2556 {
2557         struct hda_input_mux *imux = &spec->private_imux;
2558         int i, err;
2559
2560         for (i = 0; i < AUTO_PIN_LAST; i++) {
2561                 err = new_analog_input(spec, cfg->input_pins[i],
2562                                        auto_pin_cfg_labels[i],
2563                                        i <= AUTO_PIN_FRONT_MIC);
2564                 if (err < 0)
2565                         return err;
2566                 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
2567                 imux->items[imux->num_items].index = ad1988_pin_to_adc_idx(cfg->input_pins[i]);
2568                 imux->num_items++;
2569         }
2570         imux->items[imux->num_items].label = "Mix";
2571         imux->items[imux->num_items].index = 9;
2572         imux->num_items++;
2573
2574         if ((err = add_control(spec, AD_CTL_WIDGET_VOL,
2575                                "Analog Mix Playback Volume",
2576                                HDA_COMPOSE_AMP_VAL(0x21, 3, 0x0, HDA_OUTPUT))) < 0)
2577                 return err;
2578         if ((err = add_control(spec, AD_CTL_WIDGET_MUTE,
2579                                "Analog Mix Playback Switch",
2580                                HDA_COMPOSE_AMP_VAL(0x21, 3, 0x0, HDA_OUTPUT))) < 0)
2581                 return err;
2582
2583         return 0;
2584 }
2585
2586 static void ad1988_auto_set_output_and_unmute(struct hda_codec *codec,
2587                                               hda_nid_t nid, int pin_type,
2588                                               int dac_idx)
2589 {
2590         /* set as output */
2591         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
2592         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
2593         switch (nid) {
2594         case 0x11: /* port-A - DAC 04 */
2595                 snd_hda_codec_write(codec, 0x37, 0, AC_VERB_SET_CONNECT_SEL, 0x01);
2596                 break;
2597         case 0x14: /* port-B - DAC 06 */
2598                 snd_hda_codec_write(codec, 0x30, 0, AC_VERB_SET_CONNECT_SEL, 0x02);
2599                 break;
2600         case 0x15: /* port-C - DAC 05 */
2601                 snd_hda_codec_write(codec, 0x31, 0, AC_VERB_SET_CONNECT_SEL, 0x00);
2602                 break;
2603         case 0x17: /* port-E - DAC 0a */
2604                 snd_hda_codec_write(codec, 0x32, 0, AC_VERB_SET_CONNECT_SEL, 0x01);
2605                 break;
2606         case 0x13: /* mono - DAC 04 */
2607                 snd_hda_codec_write(codec, 0x36, 0, AC_VERB_SET_CONNECT_SEL, 0x01);
2608                 break;
2609         }
2610 }
2611
2612 static void ad1988_auto_init_multi_out(struct hda_codec *codec)
2613 {
2614         struct ad198x_spec *spec = codec->spec;
2615         int i;
2616
2617         for (i = 0; i < spec->autocfg.line_outs; i++) {
2618                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
2619                 ad1988_auto_set_output_and_unmute(codec, nid, PIN_OUT, i);
2620         }
2621 }
2622
2623 static void ad1988_auto_init_extra_out(struct hda_codec *codec)
2624 {
2625         struct ad198x_spec *spec = codec->spec;
2626         hda_nid_t pin;
2627
2628         pin = spec->autocfg.speaker_pins[0];
2629         if (pin) /* connect to front */
2630                 ad1988_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
2631         pin = spec->autocfg.hp_pins[0];
2632         if (pin) /* connect to front */
2633                 ad1988_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
2634 }
2635
2636 static void ad1988_auto_init_analog_input(struct hda_codec *codec)
2637 {
2638         struct ad198x_spec *spec = codec->spec;
2639         int i, idx;
2640
2641         for (i = 0; i < AUTO_PIN_LAST; i++) {
2642                 hda_nid_t nid = spec->autocfg.input_pins[i];
2643                 if (! nid)
2644                         continue;
2645                 switch (nid) {
2646                 case 0x15: /* port-C */
2647                         snd_hda_codec_write(codec, 0x33, 0, AC_VERB_SET_CONNECT_SEL, 0x0);
2648                         break;
2649                 case 0x17: /* port-E */
2650                         snd_hda_codec_write(codec, 0x34, 0, AC_VERB_SET_CONNECT_SEL, 0x0);
2651                         break;
2652                 }
2653                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
2654                                     i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN);
2655                 if (nid != AD1988_PIN_CD_NID)
2656                         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
2657                                             AMP_OUT_MUTE);
2658                 idx = ad1988_pin_idx(nid);
2659                 if (ad1988_boost_nids[idx])
2660                         snd_hda_codec_write(codec, ad1988_boost_nids[idx], 0,
2661                                             AC_VERB_SET_AMP_GAIN_MUTE,
2662                                             AMP_OUT_ZERO);
2663         }
2664 }
2665
2666 /* parse the BIOS configuration and set up the alc_spec */
2667 /* return 1 if successful, 0 if the proper config is not found, or a negative error code */
2668 static int ad1988_parse_auto_config(struct hda_codec *codec)
2669 {
2670         struct ad198x_spec *spec = codec->spec;
2671         int err;
2672
2673         if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL)) < 0)
2674                 return err;
2675         if ((err = ad1988_auto_fill_dac_nids(codec, &spec->autocfg)) < 0)
2676                 return err;
2677         if (! spec->autocfg.line_outs)
2678                 return 0; /* can't find valid BIOS pin config */
2679         if ((err = ad1988_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 ||
2680             (err = ad1988_auto_create_extra_out(codec,
2681                                                 spec->autocfg.speaker_pins[0],
2682                                                 "Speaker")) < 0 ||
2683             (err = ad1988_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
2684                                                 "Headphone")) < 0 ||
2685             (err = ad1988_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0)
2686                 return err;
2687
2688         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
2689
2690         if (spec->autocfg.dig_out_pin)
2691                 spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
2692         if (spec->autocfg.dig_in_pin)
2693                 spec->dig_in_nid = AD1988_SPDIF_IN;
2694
2695         if (spec->kctl_alloc)
2696                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
2697
2698         spec->init_verbs[spec->num_init_verbs++] = ad1988_6stack_init_verbs;
2699
2700         spec->input_mux = &spec->private_imux;
2701
2702         return 1;
2703 }
2704
2705 /* init callback for auto-configuration model -- overriding the default init */
2706 static int ad1988_auto_init(struct hda_codec *codec)
2707 {
2708         ad198x_init(codec);
2709         ad1988_auto_init_multi_out(codec);
2710         ad1988_auto_init_extra_out(codec);
2711         ad1988_auto_init_analog_input(codec);
2712         return 0;
2713 }
2714
2715
2716 /*
2717  */
2718
2719 static const char *ad1988_models[AD1988_MODEL_LAST] = {
2720         [AD1988_6STACK]         = "6stack",
2721         [AD1988_6STACK_DIG]     = "6stack-dig",
2722         [AD1988_3STACK]         = "3stack",
2723         [AD1988_3STACK_DIG]     = "3stack-dig",
2724         [AD1988_LAPTOP]         = "laptop",
2725         [AD1988_LAPTOP_DIG]     = "laptop-dig",
2726         [AD1988_AUTO]           = "auto",
2727 };
2728
2729 static struct snd_pci_quirk ad1988_cfg_tbl[] = {
2730         SND_PCI_QUIRK(0x1043, 0x81ec, "Asus P5B-DLX", AD1988_6STACK_DIG),
2731         SND_PCI_QUIRK(0x1043, 0x81f6, "Asus M2N-SLI", AD1988_6STACK_DIG),
2732         {}
2733 };
2734
2735 static int patch_ad1988(struct hda_codec *codec)
2736 {
2737         struct ad198x_spec *spec;
2738         int board_config;
2739
2740         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2741         if (spec == NULL)
2742                 return -ENOMEM;
2743
2744         codec->spec = spec;
2745
2746         if (is_rev2(codec))
2747                 snd_printk(KERN_INFO "patch_analog: AD1988A rev.2 is detected, enable workarounds\n");
2748
2749         board_config = snd_hda_check_board_config(codec, AD1988_MODEL_LAST,
2750                                                   ad1988_models, ad1988_cfg_tbl);
2751         if (board_config < 0) {
2752                 printk(KERN_INFO "hda_codec: Unknown model for AD1988, trying auto-probe from BIOS...\n");
2753                 board_config = AD1988_AUTO;
2754         }
2755
2756         if (board_config == AD1988_AUTO) {
2757                 /* automatic parse from the BIOS config */
2758                 int err = ad1988_parse_auto_config(codec);
2759                 if (err < 0) {
2760                         ad198x_free(codec);
2761                         return err;
2762                 } else if (! err) {
2763                         printk(KERN_INFO "hda_codec: Cannot set up configuration from BIOS.  Using 6-stack mode...\n");
2764                         board_config = AD1988_6STACK;
2765                 }
2766         }
2767
2768         switch (board_config) {
2769         case AD1988_6STACK:
2770         case AD1988_6STACK_DIG:
2771                 spec->multiout.max_channels = 8;
2772                 spec->multiout.num_dacs = 4;
2773                 if (is_rev2(codec))
2774                         spec->multiout.dac_nids = ad1988_6stack_dac_nids_rev2;
2775                 else
2776                         spec->multiout.dac_nids = ad1988_6stack_dac_nids;
2777                 spec->input_mux = &ad1988_6stack_capture_source;
2778                 spec->num_mixers = 2;
2779                 if (is_rev2(codec))
2780                         spec->mixers[0] = ad1988_6stack_mixers1_rev2;
2781                 else
2782                         spec->mixers[0] = ad1988_6stack_mixers1;
2783                 spec->mixers[1] = ad1988_6stack_mixers2;
2784                 spec->num_init_verbs = 1;
2785                 spec->init_verbs[0] = ad1988_6stack_init_verbs;
2786                 if (board_config == AD1988_6STACK_DIG) {
2787                         spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
2788                         spec->dig_in_nid = AD1988_SPDIF_IN;
2789                 }
2790                 break;
2791         case AD1988_3STACK:
2792         case AD1988_3STACK_DIG:
2793                 spec->multiout.max_channels = 6;
2794                 spec->multiout.num_dacs = 3;
2795                 if (is_rev2(codec))
2796                         spec->multiout.dac_nids = ad1988_3stack_dac_nids_rev2;
2797                 else
2798                         spec->multiout.dac_nids = ad1988_3stack_dac_nids;
2799                 spec->input_mux = &ad1988_6stack_capture_source;
2800                 spec->channel_mode = ad1988_3stack_modes;
2801                 spec->num_channel_mode = ARRAY_SIZE(ad1988_3stack_modes);
2802                 spec->num_mixers = 2;
2803                 if (is_rev2(codec))
2804                         spec->mixers[0] = ad1988_3stack_mixers1_rev2;
2805                 else
2806                         spec->mixers[0] = ad1988_3stack_mixers1;
2807                 spec->mixers[1] = ad1988_3stack_mixers2;
2808                 spec->num_init_verbs = 1;
2809                 spec->init_verbs[0] = ad1988_3stack_init_verbs;
2810                 if (board_config == AD1988_3STACK_DIG)
2811                         spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
2812                 break;
2813         case AD1988_LAPTOP:
2814         case AD1988_LAPTOP_DIG:
2815                 spec->multiout.max_channels = 2;
2816                 spec->multiout.num_dacs = 1;
2817                 spec->multiout.dac_nids = ad1988_3stack_dac_nids;
2818                 spec->input_mux = &ad1988_laptop_capture_source;
2819                 spec->num_mixers = 1;
2820                 spec->mixers[0] = ad1988_laptop_mixers;
2821                 spec->num_init_verbs = 1;
2822                 spec->init_verbs[0] = ad1988_laptop_init_verbs;
2823                 if (board_config == AD1988_LAPTOP_DIG)
2824                         spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
2825                 break;
2826         }
2827
2828         spec->num_adc_nids = ARRAY_SIZE(ad1988_adc_nids);
2829         spec->adc_nids = ad1988_adc_nids;
2830         spec->capsrc_nids = ad1988_capsrc_nids;
2831         spec->mixers[spec->num_mixers++] = ad1988_capture_mixers;
2832         spec->init_verbs[spec->num_init_verbs++] = ad1988_capture_init_verbs;
2833         if (spec->multiout.dig_out_nid) {
2834                 spec->mixers[spec->num_mixers++] = ad1988_spdif_out_mixers;
2835                 spec->init_verbs[spec->num_init_verbs++] = ad1988_spdif_init_verbs;
2836         }
2837         if (spec->dig_in_nid)
2838                 spec->mixers[spec->num_mixers++] = ad1988_spdif_in_mixers;
2839
2840         codec->patch_ops = ad198x_patch_ops;
2841         switch (board_config) {
2842         case AD1988_AUTO:
2843                 codec->patch_ops.init = ad1988_auto_init;
2844                 break;
2845         case AD1988_LAPTOP:
2846         case AD1988_LAPTOP_DIG:
2847                 codec->patch_ops.unsol_event = ad1988_laptop_unsol_event;
2848                 break;
2849         }
2850 #ifdef CONFIG_SND_HDA_POWER_SAVE
2851         spec->loopback.amplist = ad1988_loopbacks;
2852 #endif
2853
2854         return 0;
2855 }
2856
2857
2858 /*
2859  * AD1884 / AD1984
2860  *
2861  * port-B - front line/mic-in
2862  * port-E - aux in/out
2863  * port-F - aux in/out
2864  * port-C - rear line/mic-in
2865  * port-D - rear line/hp-out
2866  * port-A - front line/hp-out
2867  *
2868  * AD1984 = AD1884 + two digital mic-ins
2869  *
2870  * FIXME:
2871  * For simplicity, we share the single DAC for both HP and line-outs
2872  * right now.  The inidividual playbacks could be easily implemented,
2873  * but no build-up framework is given, so far.
2874  */
2875
2876 static hda_nid_t ad1884_dac_nids[1] = {
2877         0x04,
2878 };
2879
2880 static hda_nid_t ad1884_adc_nids[2] = {
2881         0x08, 0x09,
2882 };
2883
2884 static hda_nid_t ad1884_capsrc_nids[2] = {
2885         0x0c, 0x0d,
2886 };
2887
2888 #define AD1884_SPDIF_OUT        0x02
2889
2890 static struct hda_input_mux ad1884_capture_source = {
2891         .num_items = 4,
2892         .items = {
2893                 { "Front Mic", 0x0 },
2894                 { "Mic", 0x1 },
2895                 { "CD", 0x2 },
2896                 { "Mix", 0x3 },
2897         },
2898 };
2899
2900 static struct snd_kcontrol_new ad1884_base_mixers[] = {
2901         HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
2902         /* HDA_CODEC_VOLUME_IDX("PCM Playback Volume", 1, 0x03, 0x0, HDA_OUTPUT), */
2903         HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
2904         HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT),
2905         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
2906         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
2907         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
2908         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
2909         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
2910         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
2911         HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x02, HDA_INPUT),
2912         HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x02, HDA_INPUT),
2913         /*
2914         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x20, 0x03, HDA_INPUT),
2915         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x20, 0x03, HDA_INPUT),
2916         HDA_CODEC_VOLUME("Digital Beep Playback Volume", 0x10, 0x0, HDA_OUTPUT),
2917         HDA_CODEC_MUTE("Digital Beep Playback Switch", 0x10, 0x0, HDA_OUTPUT),
2918         */
2919         HDA_CODEC_VOLUME("Mic Boost", 0x15, 0x0, HDA_INPUT),
2920         HDA_CODEC_VOLUME("Front Mic Boost", 0x14, 0x0, HDA_INPUT),
2921         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
2922         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
2923         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
2924         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
2925         {
2926                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2927                 /* The multiple "Capture Source" controls confuse alsamixer
2928                  * So call somewhat different..
2929                  * FIXME: the controls appear in the "playback" view!
2930                  */
2931                 /* .name = "Capture Source", */
2932                 .name = "Input Source",
2933                 .count = 2,
2934                 .info = ad198x_mux_enum_info,
2935                 .get = ad198x_mux_enum_get,
2936                 .put = ad198x_mux_enum_put,
2937         },
2938         /* SPDIF controls */
2939         HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
2940         {
2941                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2942                 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
2943                 /* identical with ad1983 */
2944                 .info = ad1983_spdif_route_info,
2945                 .get = ad1983_spdif_route_get,
2946                 .put = ad1983_spdif_route_put,
2947         },
2948         { } /* end */
2949 };
2950
2951 static struct snd_kcontrol_new ad1984_dmic_mixers[] = {
2952         HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x05, 0x0, HDA_INPUT),
2953         HDA_CODEC_MUTE("Digital Mic Capture Switch", 0x05, 0x0, HDA_INPUT),
2954         HDA_CODEC_VOLUME_IDX("Digital Mic Capture Volume", 1, 0x06, 0x0,
2955                              HDA_INPUT),
2956         HDA_CODEC_MUTE_IDX("Digital Mic Capture Switch", 1, 0x06, 0x0,
2957                            HDA_INPUT),
2958         { } /* end */
2959 };
2960
2961 /*
2962  * initialization verbs
2963  */
2964 static struct hda_verb ad1884_init_verbs[] = {
2965         /* DACs; mute as default */
2966         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2967         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2968         /* Port-A (HP) mixer */
2969         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2970         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2971         /* Port-A pin */
2972         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2973         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2974         /* HP selector - select DAC2 */
2975         {0x22, AC_VERB_SET_CONNECT_SEL, 0x1},
2976         /* Port-D (Line-out) mixer */
2977         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2978         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2979         /* Port-D pin */
2980         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2981         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2982         /* Mono-out mixer */
2983         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2984         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2985         /* Mono-out pin */
2986         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2987         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2988         /* Mono selector */
2989         {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
2990         /* Port-B (front mic) pin */
2991         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2992         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2993         /* Port-C (rear mic) pin */
2994         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2995         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2996         /* Analog mixer; mute as default */
2997         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2998         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2999         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3000         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3001         /* Analog Mix output amp */
3002         {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
3003         /* SPDIF output selector */
3004         {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */
3005         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
3006         { } /* end */
3007 };
3008
3009 #ifdef CONFIG_SND_HDA_POWER_SAVE
3010 static struct hda_amp_list ad1884_loopbacks[] = {
3011         { 0x20, HDA_INPUT, 0 }, /* Front Mic */
3012         { 0x20, HDA_INPUT, 1 }, /* Mic */
3013         { 0x20, HDA_INPUT, 2 }, /* CD */
3014         { 0x20, HDA_INPUT, 4 }, /* Docking */
3015         { } /* end */
3016 };
3017 #endif
3018
3019 static int patch_ad1884(struct hda_codec *codec)
3020 {
3021         struct ad198x_spec *spec;
3022
3023         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3024         if (spec == NULL)
3025                 return -ENOMEM;
3026
3027         mutex_init(&spec->amp_mutex);
3028         codec->spec = spec;
3029
3030         spec->multiout.max_channels = 2;
3031         spec->multiout.num_dacs = ARRAY_SIZE(ad1884_dac_nids);
3032         spec->multiout.dac_nids = ad1884_dac_nids;
3033         spec->multiout.dig_out_nid = AD1884_SPDIF_OUT;
3034         spec->num_adc_nids = ARRAY_SIZE(ad1884_adc_nids);
3035         spec->adc_nids = ad1884_adc_nids;
3036         spec->capsrc_nids = ad1884_capsrc_nids;
3037         spec->input_mux = &ad1884_capture_source;
3038         spec->num_mixers = 1;
3039         spec->mixers[0] = ad1884_base_mixers;
3040         spec->num_init_verbs = 1;
3041         spec->init_verbs[0] = ad1884_init_verbs;
3042         spec->spdif_route = 0;
3043 #ifdef CONFIG_SND_HDA_POWER_SAVE
3044         spec->loopback.amplist = ad1884_loopbacks;
3045 #endif
3046
3047         codec->patch_ops = ad198x_patch_ops;
3048
3049         return 0;
3050 }
3051
3052 /*
3053  * Lenovo Thinkpad T61/X61
3054  */
3055 static struct hda_input_mux ad1984_thinkpad_capture_source = {
3056         .num_items = 3,
3057         .items = {
3058                 { "Mic", 0x0 },
3059                 { "Internal Mic", 0x1 },
3060                 { "Mix", 0x3 },
3061         },
3062 };
3063
3064 static struct snd_kcontrol_new ad1984_thinkpad_mixers[] = {
3065         HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
3066         /* HDA_CODEC_VOLUME_IDX("PCM Playback Volume", 1, 0x03, 0x0, HDA_OUTPUT), */
3067         HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
3068         HDA_CODEC_MUTE("Speaker Playback Switch", 0x12, 0x0, HDA_OUTPUT),
3069         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
3070         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3071         HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
3072         HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
3073         HDA_CODEC_VOLUME("Docking Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
3074         HDA_CODEC_MUTE("Docking Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
3075         HDA_CODEC_VOLUME("Mic Boost", 0x14, 0x0, HDA_INPUT),
3076         HDA_CODEC_VOLUME("Internal Mic Boost", 0x15, 0x0, HDA_INPUT),
3077         HDA_CODEC_VOLUME("Docking Mic Boost", 0x25, 0x0, HDA_OUTPUT),
3078         HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x03, HDA_INPUT),
3079         HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x03, HDA_INPUT),
3080         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3081         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3082         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
3083         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
3084         {
3085                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3086                 /* The multiple "Capture Source" controls confuse alsamixer
3087                  * So call somewhat different..
3088                  * FIXME: the controls appear in the "playback" view!
3089                  */
3090                 /* .name = "Capture Source", */
3091                 .name = "Input Source",
3092                 .count = 2,
3093                 .info = ad198x_mux_enum_info,
3094                 .get = ad198x_mux_enum_get,
3095                 .put = ad198x_mux_enum_put,
3096         },
3097         /* SPDIF controls */
3098         HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
3099         {
3100                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3101                 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
3102                 /* identical with ad1983 */
3103                 .info = ad1983_spdif_route_info,
3104                 .get = ad1983_spdif_route_get,
3105                 .put = ad1983_spdif_route_put,
3106         },
3107         { } /* end */
3108 };
3109
3110 /* additional verbs */
3111 static struct hda_verb ad1984_thinkpad_init_verbs[] = {
3112         /* Port-E (docking station mic) pin */
3113         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3114         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3115         /* docking mic boost */
3116         {0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3117         /* Analog mixer - docking mic; mute as default */
3118         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3119         /* enable EAPD bit */
3120         {0x12, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
3121         { } /* end */
3122 };
3123
3124 /* Digial MIC ADC NID 0x05 + 0x06 */
3125 static int ad1984_pcm_dmic_prepare(struct hda_pcm_stream *hinfo,
3126                                    struct hda_codec *codec,
3127                                    unsigned int stream_tag,
3128                                    unsigned int format,
3129                                    struct snd_pcm_substream *substream)
3130 {
3131         snd_hda_codec_setup_stream(codec, 0x05 + substream->number,
3132                                    stream_tag, 0, format);
3133         return 0;
3134 }
3135
3136 static int ad1984_pcm_dmic_cleanup(struct hda_pcm_stream *hinfo,
3137                                    struct hda_codec *codec,
3138                                    struct snd_pcm_substream *substream)
3139 {
3140         snd_hda_codec_setup_stream(codec, 0x05 + substream->number,
3141                                    0, 0, 0);
3142         return 0;
3143 }
3144
3145 static struct hda_pcm_stream ad1984_pcm_dmic_capture = {
3146         .substreams = 2,
3147         .channels_min = 2,
3148         .channels_max = 2,
3149         .nid = 0x05,
3150         .ops = {
3151                 .prepare = ad1984_pcm_dmic_prepare,
3152                 .cleanup = ad1984_pcm_dmic_cleanup
3153         },
3154 };
3155
3156 static int ad1984_build_pcms(struct hda_codec *codec)
3157 {
3158         struct ad198x_spec *spec = codec->spec;
3159         struct hda_pcm *info;
3160         int err;
3161
3162         err = ad198x_build_pcms(codec);
3163         if (err < 0)
3164                 return err;
3165
3166         info = spec->pcm_rec + codec->num_pcms;
3167         codec->num_pcms++;
3168         info->name = "AD1984 Digital Mic";
3169         info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad1984_pcm_dmic_capture;
3170         return 0;
3171 }
3172
3173 /* models */
3174 enum {
3175         AD1984_BASIC,
3176         AD1984_THINKPAD,
3177         AD1984_MODELS
3178 };
3179
3180 static const char *ad1984_models[AD1984_MODELS] = {
3181         [AD1984_BASIC]          = "basic",
3182         [AD1984_THINKPAD]       = "thinkpad",
3183 };
3184
3185 static struct snd_pci_quirk ad1984_cfg_tbl[] = {
3186         /* Lenovo Thinkpad T61/X61 */
3187         SND_PCI_QUIRK(0x17aa, 0, "Lenovo Thinkpad", AD1984_THINKPAD),
3188         {}
3189 };
3190
3191 static int patch_ad1984(struct hda_codec *codec)
3192 {
3193         struct ad198x_spec *spec;
3194         int board_config, err;
3195
3196         err = patch_ad1884(codec);
3197         if (err < 0)
3198                 return err;
3199         spec = codec->spec;
3200         board_config = snd_hda_check_board_config(codec, AD1984_MODELS,
3201                                                   ad1984_models, ad1984_cfg_tbl);
3202         switch (board_config) {
3203         case AD1984_BASIC:
3204                 /* additional digital mics */
3205                 spec->mixers[spec->num_mixers++] = ad1984_dmic_mixers;
3206                 codec->patch_ops.build_pcms = ad1984_build_pcms;
3207                 break;
3208         case AD1984_THINKPAD:
3209                 spec->multiout.dig_out_nid = AD1884_SPDIF_OUT;
3210                 spec->input_mux = &ad1984_thinkpad_capture_source;
3211                 spec->mixers[0] = ad1984_thinkpad_mixers;
3212                 spec->init_verbs[spec->num_init_verbs++] = ad1984_thinkpad_init_verbs;
3213                 break;
3214         }
3215         return 0;
3216 }
3217
3218
3219 /*
3220  * AD1882
3221  *
3222  * port-A - front hp-out
3223  * port-B - front mic-in
3224  * port-C - rear line-in, shared surr-out (3stack)
3225  * port-D - rear line-out
3226  * port-E - rear mic-in, shared clfe-out (3stack)
3227  * port-F - rear surr-out (6stack)
3228  * port-G - rear clfe-out (6stack)
3229  */
3230
3231 static hda_nid_t ad1882_dac_nids[3] = {
3232         0x04, 0x03, 0x05
3233 };
3234
3235 static hda_nid_t ad1882_adc_nids[2] = {
3236         0x08, 0x09,
3237 };
3238
3239 static hda_nid_t ad1882_capsrc_nids[2] = {
3240         0x0c, 0x0d,
3241 };
3242
3243 #define AD1882_SPDIF_OUT        0x02
3244
3245 /* list: 0x11, 0x39, 0x3a, 0x18, 0x3c, 0x3b, 0x12, 0x20 */
3246 static struct hda_input_mux ad1882_capture_source = {
3247         .num_items = 5,
3248         .items = {
3249                 { "Front Mic", 0x1 },
3250                 { "Mic", 0x4 },
3251                 { "Line", 0x2 },
3252                 { "CD", 0x3 },
3253                 { "Mix", 0x7 },
3254         },
3255 };
3256
3257 static struct snd_kcontrol_new ad1882_base_mixers[] = {
3258         HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
3259         HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
3260         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT),
3261         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT),
3262         HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
3263         HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT),
3264         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
3265         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
3266         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
3267         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3268         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
3269         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
3270         HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x04, HDA_INPUT),
3271         HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x04, HDA_INPUT),
3272         HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x06, HDA_INPUT),
3273         HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x06, HDA_INPUT),
3274         HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x07, HDA_INPUT),
3275         HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x07, HDA_INPUT),
3276         HDA_CODEC_VOLUME("Mic Boost", 0x3c, 0x0, HDA_OUTPUT),
3277         HDA_CODEC_VOLUME("Front Mic Boost", 0x39, 0x0, HDA_OUTPUT),
3278         HDA_CODEC_VOLUME("Line-In Boost", 0x3a, 0x0, HDA_OUTPUT),
3279         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3280         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3281         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
3282         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
3283         {
3284                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3285                 /* The multiple "Capture Source" controls confuse alsamixer
3286                  * So call somewhat different..
3287                  * FIXME: the controls appear in the "playback" view!
3288                  */
3289                 /* .name = "Capture Source", */
3290                 .name = "Input Source",
3291                 .count = 2,
3292                 .info = ad198x_mux_enum_info,
3293                 .get = ad198x_mux_enum_get,
3294                 .put = ad198x_mux_enum_put,
3295         },
3296         /* SPDIF controls */
3297         HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
3298         {
3299                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3300                 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
3301                 /* identical with ad1983 */
3302                 .info = ad1983_spdif_route_info,
3303                 .get = ad1983_spdif_route_get,
3304                 .put = ad1983_spdif_route_put,
3305         },
3306         { } /* end */
3307 };
3308
3309 static struct snd_kcontrol_new ad1882_3stack_mixers[] = {
3310         HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
3311         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x17, 1, 0x0, HDA_OUTPUT),
3312         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x17, 2, 0x0, HDA_OUTPUT),
3313         {
3314                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3315                 .name = "Channel Mode",
3316                 .info = ad198x_ch_mode_info,
3317                 .get = ad198x_ch_mode_get,
3318                 .put = ad198x_ch_mode_put,
3319         },
3320         { } /* end */
3321 };
3322
3323 static struct snd_kcontrol_new ad1882_6stack_mixers[] = {
3324         HDA_CODEC_MUTE("Surround Playback Switch", 0x16, 0x0, HDA_OUTPUT),
3325         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x24, 1, 0x0, HDA_OUTPUT),
3326         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x24, 2, 0x0, HDA_OUTPUT),
3327         { } /* end */
3328 };
3329
3330 static struct hda_verb ad1882_ch2_init[] = {
3331         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3332         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3333         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3334         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3335         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3336         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3337         { } /* end */
3338 };
3339
3340 static struct hda_verb ad1882_ch4_init[] = {
3341         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3342         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3343         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3344         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3345         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3346         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3347         { } /* end */
3348 };
3349
3350 static struct hda_verb ad1882_ch6_init[] = {
3351         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3352         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3353         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3354         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3355         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3356         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3357         { } /* end */
3358 };
3359
3360 static struct hda_channel_mode ad1882_modes[3] = {
3361         { 2, ad1882_ch2_init },
3362         { 4, ad1882_ch4_init },
3363         { 6, ad1882_ch6_init },
3364 };
3365
3366 /*
3367  * initialization verbs
3368  */
3369 static struct hda_verb ad1882_init_verbs[] = {
3370         /* DACs; mute as default */
3371         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3372         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3373         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3374         /* Port-A (HP) mixer */
3375         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3376         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3377         /* Port-A pin */
3378         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3379         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3380         /* HP selector - select DAC2 */
3381         {0x37, AC_VERB_SET_CONNECT_SEL, 0x1},
3382         /* Port-D (Line-out) mixer */
3383         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3384         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3385         /* Port-D pin */
3386         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3387         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3388         /* Mono-out mixer */
3389         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3390         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3391         /* Mono-out pin */
3392         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3393         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3394         /* Port-B (front mic) pin */
3395         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3396         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3397         {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */
3398         /* Port-C (line-in) pin */
3399         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3400         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3401         {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */
3402         /* Port-C mixer - mute as input */
3403         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3404         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3405         /* Port-E (mic-in) pin */
3406         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3407         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3408         {0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */
3409         /* Port-E mixer - mute as input */
3410         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3411         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3412         /* Port-F (surround) */
3413         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3414         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3415         /* Port-G (CLFE) */
3416         {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3417         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3418         /* Analog mixer; mute as default */
3419         /* list: 0x39, 0x3a, 0x11, 0x12, 0x3c, 0x3b, 0x18, 0x1a */
3420         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3421         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3422         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3423         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3424         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3425         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
3426         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3427         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3428         /* Analog Mix output amp */
3429         {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
3430         /* SPDIF output selector */
3431         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
3432         {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */
3433         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
3434         { } /* end */
3435 };
3436
3437 #ifdef CONFIG_SND_HDA_POWER_SAVE
3438 static struct hda_amp_list ad1882_loopbacks[] = {
3439         { 0x20, HDA_INPUT, 0 }, /* Front Mic */
3440         { 0x20, HDA_INPUT, 1 }, /* Mic */
3441         { 0x20, HDA_INPUT, 4 }, /* Line */
3442         { 0x20, HDA_INPUT, 6 }, /* CD */
3443         { } /* end */
3444 };
3445 #endif
3446
3447 /* models */
3448 enum {
3449         AD1882_3STACK,
3450         AD1882_6STACK,
3451         AD1882_MODELS
3452 };
3453
3454 static const char *ad1882_models[AD1986A_MODELS] = {
3455         [AD1882_3STACK]         = "3stack",
3456         [AD1882_6STACK]         = "6stack",
3457 };
3458
3459
3460 static int patch_ad1882(struct hda_codec *codec)
3461 {
3462         struct ad198x_spec *spec;
3463         int board_config;
3464
3465         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3466         if (spec == NULL)
3467                 return -ENOMEM;
3468
3469         mutex_init(&spec->amp_mutex);
3470         codec->spec = spec;
3471
3472         spec->multiout.max_channels = 6;
3473         spec->multiout.num_dacs = 3;
3474         spec->multiout.dac_nids = ad1882_dac_nids;
3475         spec->multiout.dig_out_nid = AD1882_SPDIF_OUT;
3476         spec->num_adc_nids = ARRAY_SIZE(ad1882_adc_nids);
3477         spec->adc_nids = ad1882_adc_nids;
3478         spec->capsrc_nids = ad1882_capsrc_nids;
3479         spec->input_mux = &ad1882_capture_source;
3480         spec->num_mixers = 1;
3481         spec->mixers[0] = ad1882_base_mixers;
3482         spec->num_init_verbs = 1;
3483         spec->init_verbs[0] = ad1882_init_verbs;
3484         spec->spdif_route = 0;
3485 #ifdef CONFIG_SND_HDA_POWER_SAVE
3486         spec->loopback.amplist = ad1882_loopbacks;
3487 #endif
3488
3489         codec->patch_ops = ad198x_patch_ops;
3490
3491         /* override some parameters */
3492         board_config = snd_hda_check_board_config(codec, AD1882_MODELS,
3493                                                   ad1882_models, NULL);
3494         switch (board_config) {
3495         default:
3496         case AD1882_3STACK:
3497                 spec->num_mixers = 2;
3498                 spec->mixers[1] = ad1882_3stack_mixers;
3499                 spec->channel_mode = ad1882_modes;
3500                 spec->num_channel_mode = ARRAY_SIZE(ad1882_modes);
3501                 spec->need_dac_fix = 1;
3502                 spec->multiout.max_channels = 2;
3503                 spec->multiout.num_dacs = 1;
3504                 break;
3505         case AD1882_6STACK:
3506                 spec->num_mixers = 2;
3507                 spec->mixers[1] = ad1882_6stack_mixers;
3508                 break;
3509         }
3510         return 0;
3511 }
3512
3513
3514 /*
3515  * patch entries
3516  */
3517 struct hda_codec_preset snd_hda_preset_analog[] = {
3518         { .id = 0x11d41882, .name = "AD1882", .patch = patch_ad1882 },
3519         { .id = 0x11d41884, .name = "AD1884", .patch = patch_ad1884 },
3520         { .id = 0x11d41981, .name = "AD1981", .patch = patch_ad1981 },
3521         { .id = 0x11d41983, .name = "AD1983", .patch = patch_ad1983 },
3522         { .id = 0x11d41984, .name = "AD1984", .patch = patch_ad1984 },
3523         { .id = 0x11d41986, .name = "AD1986A", .patch = patch_ad1986a },
3524         { .id = 0x11d41988, .name = "AD1988", .patch = patch_ad1988 },
3525         { .id = 0x11d4198b, .name = "AD1988B", .patch = patch_ad1988 },
3526         {} /* terminator */
3527 };