da6874d3988cfdb44dd3d11ec07cbfaf97f3890b
[pandora-kernel.git] / sound / pci / hda / patch_analog.c
1 /*
2  * HD audio interface patch for AD1981HD, AD1983, AD1986A
3  *
4  * Copyright (c) 2005 Takashi Iwai <tiwai@suse.de>
5  *
6  *  This driver is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This driver is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19  */
20
21 #include <sound/driver.h>
22 #include <linux/init.h>
23 #include <linux/delay.h>
24 #include <linux/slab.h>
25 #include <linux/pci.h>
26 #include <sound/core.h>
27 #include "hda_codec.h"
28 #include "hda_local.h"
29
30 struct ad198x_spec {
31         struct semaphore amp_mutex;     /* PCM volume/mute control mutex */
32         struct hda_multi_out multiout;  /* playback */
33         hda_nid_t adc_nid;
34         const struct hda_input_mux *input_mux;
35         unsigned int cur_mux;           /* capture source */
36         unsigned int spdif_route;
37         snd_kcontrol_new_t *mixers;
38         const struct hda_verb *init_verbs;
39         struct hda_pcm pcm_rec[2];      /* PCM information */
40 };
41
42 /*
43  * input MUX handling (common part)
44  */
45 static int ad198x_mux_enum_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
46 {
47         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
48         struct ad198x_spec *spec = codec->spec;
49
50         return snd_hda_input_mux_info(spec->input_mux, uinfo);
51 }
52
53 static int ad198x_mux_enum_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
54 {
55         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
56         struct ad198x_spec *spec = codec->spec;
57
58         ucontrol->value.enumerated.item[0] = spec->cur_mux;
59         return 0;
60 }
61
62 static int ad198x_mux_enum_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
63 {
64         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
65         struct ad198x_spec *spec = codec->spec;
66
67         return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
68                                      spec->adc_nid, &spec->cur_mux);
69 }
70
71 /*
72  * initialization (common callbacks)
73  */
74 static int ad198x_init(struct hda_codec *codec)
75 {
76         struct ad198x_spec *spec = codec->spec;
77         snd_hda_sequence_write(codec, spec->init_verbs);
78         return 0;
79 }
80
81 static int ad198x_build_controls(struct hda_codec *codec)
82 {
83         struct ad198x_spec *spec = codec->spec;
84         int err;
85
86         err = snd_hda_add_new_ctls(codec, spec->mixers);
87         if (err < 0)
88                 return err;
89         if (spec->multiout.dig_out_nid)
90                 err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid);
91         if (err < 0)
92                 return err;
93         return 0;
94 }
95
96 /*
97  * Analog playback callbacks
98  */
99 static int ad198x_playback_pcm_open(struct hda_pcm_stream *hinfo,
100                                     struct hda_codec *codec,
101                                     snd_pcm_substream_t *substream)
102 {
103         struct ad198x_spec *spec = codec->spec;
104         return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
105 }
106
107 static int ad198x_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
108                                        struct hda_codec *codec,
109                                        unsigned int stream_tag,
110                                        unsigned int format,
111                                        snd_pcm_substream_t *substream)
112 {
113         struct ad198x_spec *spec = codec->spec;
114         return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag,
115                                                 format, substream);
116 }
117
118 static int ad198x_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
119                                        struct hda_codec *codec,
120                                        snd_pcm_substream_t *substream)
121 {
122         struct ad198x_spec *spec = codec->spec;
123         return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
124 }
125
126 /*
127  * Digital out
128  */
129 static int ad198x_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
130                                         struct hda_codec *codec,
131                                         snd_pcm_substream_t *substream)
132 {
133         struct ad198x_spec *spec = codec->spec;
134         return snd_hda_multi_out_dig_open(codec, &spec->multiout);
135 }
136
137 static int ad198x_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
138                                          struct hda_codec *codec,
139                                          snd_pcm_substream_t *substream)
140 {
141         struct ad198x_spec *spec = codec->spec;
142         return snd_hda_multi_out_dig_close(codec, &spec->multiout);
143 }
144
145 /*
146  * Analog capture
147  */
148 static int ad198x_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
149                                       struct hda_codec *codec,
150                                       unsigned int stream_tag,
151                                       unsigned int format,
152                                       snd_pcm_substream_t *substream)
153 {
154         struct ad198x_spec *spec = codec->spec;
155         snd_hda_codec_setup_stream(codec, spec->adc_nid, stream_tag, 0, format);
156         return 0;
157 }
158
159 static int ad198x_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
160                                       struct hda_codec *codec,
161                                       snd_pcm_substream_t *substream)
162 {
163         struct ad198x_spec *spec = codec->spec;
164         snd_hda_codec_setup_stream(codec, spec->adc_nid, 0, 0, 0);
165         return 0;
166 }
167
168
169 /*
170  */
171 static struct hda_pcm_stream ad198x_pcm_analog_playback = {
172         .substreams = 1,
173         .channels_min = 2,
174         .channels_max = 6,
175         .nid = 0, /* fill later */
176         .ops = {
177                 .open = ad198x_playback_pcm_open,
178                 .prepare = ad198x_playback_pcm_prepare,
179                 .cleanup = ad198x_playback_pcm_cleanup
180         },
181 };
182
183 static struct hda_pcm_stream ad198x_pcm_analog_capture = {
184         .substreams = 2,
185         .channels_min = 2,
186         .channels_max = 2,
187         .nid = 0, /* fill later */
188         .ops = {
189                 .prepare = ad198x_capture_pcm_prepare,
190                 .cleanup = ad198x_capture_pcm_cleanup
191         },
192 };
193
194 static struct hda_pcm_stream ad198x_pcm_digital_playback = {
195         .substreams = 1,
196         .channels_min = 2,
197         .channels_max = 2,
198         .nid = 0, /* fill later */
199         .ops = {
200                 .open = ad198x_dig_playback_pcm_open,
201                 .close = ad198x_dig_playback_pcm_close
202         },
203 };
204
205 static int ad198x_build_pcms(struct hda_codec *codec)
206 {
207         struct ad198x_spec *spec = codec->spec;
208         struct hda_pcm *info = spec->pcm_rec;
209
210         codec->num_pcms = 1;
211         codec->pcm_info = info;
212
213         info->name = "AD198x Analog";
214         info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad198x_pcm_analog_playback;
215         info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->multiout.max_channels;
216         info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
217         info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad198x_pcm_analog_capture;
218         info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nid;
219
220         if (spec->multiout.dig_out_nid) {
221                 info++;
222                 codec->num_pcms++;
223                 info->name = "AD198x Digital";
224                 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad198x_pcm_digital_playback;
225                 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
226         }
227
228         return 0;
229 }
230
231 static void ad198x_free(struct hda_codec *codec)
232 {
233         kfree(codec->spec);
234 }
235
236 #ifdef CONFIG_PM
237 static int ad198x_resume(struct hda_codec *codec)
238 {
239         struct ad198x_spec *spec = codec->spec;
240
241         ad198x_init(codec);
242         snd_hda_resume_ctls(codec, spec->mixers);
243         snd_hda_resume_spdif_out(codec);
244         return 0;
245 }
246 #endif
247
248 static struct hda_codec_ops ad198x_patch_ops = {
249         .build_controls = ad198x_build_controls,
250         .build_pcms = ad198x_build_pcms,
251         .init = ad198x_init,
252         .free = ad198x_free,
253 #ifdef CONFIG_PM
254         .resume = ad198x_resume,
255 #endif
256 };
257
258
259 /*
260  * AD1986A specific
261  */
262
263 #define AD1986A_SPDIF_OUT       0x02
264 #define AD1986A_FRONT_DAC       0x03
265 #define AD1986A_SURR_DAC        0x04
266 #define AD1986A_CLFE_DAC        0x05
267 #define AD1986A_ADC             0x06
268
269 static hda_nid_t ad1986a_dac_nids[3] = {
270         AD1986A_FRONT_DAC, AD1986A_SURR_DAC, AD1986A_CLFE_DAC
271 };
272
273 static struct hda_input_mux ad1986a_capture_source = {
274         .num_items = 7,
275         .items = {
276                 { "Mic", 0x0 },
277                 { "CD", 0x1 },
278                 { "Aux", 0x3 },
279                 { "Line", 0x4 },
280                 { "Mix", 0x5 },
281                 { "Mono", 0x6 },
282                 { "Phone", 0x7 },
283         },
284 };
285
286 /*
287  * PCM control
288  *
289  * bind volumes/mutes of 3 DACs as a single PCM control for simplicity
290  */
291
292 #define ad1986a_pcm_amp_vol_info        snd_hda_mixer_amp_volume_info
293
294 static int ad1986a_pcm_amp_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
295 {
296         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
297         struct ad198x_spec *ad = codec->spec;
298
299         down(&ad->amp_mutex);
300         snd_hda_mixer_amp_volume_get(kcontrol, ucontrol);
301         up(&ad->amp_mutex);
302         return 0;
303 }
304
305 static int ad1986a_pcm_amp_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
306 {
307         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
308         struct ad198x_spec *ad = codec->spec;
309         int i, change = 0;
310
311         down(&ad->amp_mutex);
312         for (i = 0; i < ARRAY_SIZE(ad1986a_dac_nids); i++) {
313                 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(ad1986a_dac_nids[i], 3, 0, HDA_OUTPUT);
314                 change |= snd_hda_mixer_amp_volume_put(kcontrol, ucontrol);
315         }
316         kcontrol->private_value = HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT);
317         up(&ad->amp_mutex);
318         return change;
319 }
320
321 #define ad1986a_pcm_amp_sw_info         snd_hda_mixer_amp_switch_info
322
323 static int ad1986a_pcm_amp_sw_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
324 {
325         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
326         struct ad198x_spec *ad = codec->spec;
327
328         down(&ad->amp_mutex);
329         snd_hda_mixer_amp_switch_get(kcontrol, ucontrol);
330         up(&ad->amp_mutex);
331         return 0;
332 }
333
334 static int ad1986a_pcm_amp_sw_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
335 {
336         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
337         struct ad198x_spec *ad = codec->spec;
338         int i, change = 0;
339
340         down(&ad->amp_mutex);
341         for (i = 0; i < ARRAY_SIZE(ad1986a_dac_nids); i++) {
342                 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(ad1986a_dac_nids[i], 3, 0, HDA_OUTPUT);
343                 change |= snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
344         }
345         kcontrol->private_value = HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT);
346         up(&ad->amp_mutex);
347         return change;
348 }
349
350 /*
351  * mixers
352  */
353 static snd_kcontrol_new_t ad1986a_mixers[] = {
354         {
355                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
356                 .name = "PCM Playback Volume",
357                 .info = ad1986a_pcm_amp_vol_info,
358                 .get = ad1986a_pcm_amp_vol_get,
359                 .put = ad1986a_pcm_amp_vol_put,
360                 .private_value = HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT)
361         },
362         {
363                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
364                 .name = "PCM Playback Switch",
365                 .info = ad1986a_pcm_amp_sw_info,
366                 .get = ad1986a_pcm_amp_sw_get,
367                 .put = ad1986a_pcm_amp_sw_put,
368                 .private_value = HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT)
369         },
370         HDA_CODEC_VOLUME("Front Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
371         HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
372         HDA_CODEC_VOLUME("Surround Playback Volume", 0x1c, 0x0, HDA_OUTPUT),
373         HDA_CODEC_MUTE("Surround Playback Switch", 0x1c, 0x0, HDA_OUTPUT),
374         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x1d, 1, 0x0, HDA_OUTPUT),
375         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x1d, 2, 0x0, HDA_OUTPUT),
376         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x1d, 1, 0x0, HDA_OUTPUT),
377         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x1d, 2, 0x0, HDA_OUTPUT),
378         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x1a, 0x0, HDA_OUTPUT),
379         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
380         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_OUTPUT),
381         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_OUTPUT),
382         HDA_CODEC_VOLUME("Line Playback Volume", 0x17, 0x0, HDA_OUTPUT),
383         HDA_CODEC_MUTE("Line Playback Switch", 0x17, 0x0, HDA_OUTPUT),
384         HDA_CODEC_VOLUME("Aux Playback Volume", 0x16, 0x0, HDA_OUTPUT),
385         HDA_CODEC_MUTE("Aux Playback Switch", 0x16, 0x0, HDA_OUTPUT),
386         HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
387         HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
388         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x18, 0x0, HDA_OUTPUT),
389         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x18, 0x0, HDA_OUTPUT),
390         HDA_CODEC_VOLUME("Mono Playback Volume", 0x1e, 0x0, HDA_OUTPUT),
391         HDA_CODEC_MUTE("Mono Playback Switch", 0x1e, 0x0, HDA_OUTPUT),
392         HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT),
393         HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT),
394         {
395                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
396                 .name = "Capture Source",
397                 .info = ad198x_mux_enum_info,
398                 .get = ad198x_mux_enum_get,
399                 .put = ad198x_mux_enum_put,
400         },
401         HDA_CODEC_MUTE("Stereo Downmix Switch", 0x09, 0x0, HDA_OUTPUT),
402         { } /* end */
403 };
404
405 /*
406  * initialization verbs
407  */
408 static struct hda_verb ad1986a_init_verbs[] = {
409         /* Front, Surround, CLFE DAC; mute as default */
410         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
411         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
412         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
413         /* Downmix - off */
414         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
415         /* HP, Line-Out, Surround, CLFE selectors */
416         {0x0a, AC_VERB_SET_CONNECT_SEL, 0x0},
417         {0x0b, AC_VERB_SET_CONNECT_SEL, 0x0},
418         {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0},
419         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
420         /* Mono selector */
421         {0x0e, AC_VERB_SET_CONNECT_SEL, 0x0},
422         /* Mic selector: Mic 1/2 pin */
423         {0x0f, AC_VERB_SET_CONNECT_SEL, 0x0},
424         /* Line-in selector: Line-in */
425         {0x10, AC_VERB_SET_CONNECT_SEL, 0x0},
426         /* Mic 1/2 swap */
427         {0x11, AC_VERB_SET_CONNECT_SEL, 0x0},
428         /* Record selector: mic */
429         {0x12, AC_VERB_SET_CONNECT_SEL, 0x0},
430         /* Mic, Phone, CD, Aux, Line-In amp; mute as default */
431         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
432         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
433         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
434         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
435         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
436         /* PC beep */
437         {0x18, AC_VERB_SET_CONNECT_SEL, 0x0},
438         /* HP, Line-Out, Surround, CLFE, Mono pins; mute as default */
439         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
440         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
441         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
442         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
443         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
444         /* HP Pin */
445         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
446         /* Front, Surround, CLFE Pins */
447         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
448         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
449         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
450         /* Mono Pin */
451         {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
452         /* Mic Pin */
453         {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
454         /* Line, Aux, CD, Beep-In Pin */
455         {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
456         {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
457         {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
458         {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
459         {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
460         { } /* end */
461 };
462
463
464 static int patch_ad1986a(struct hda_codec *codec)
465 {
466         struct ad198x_spec *spec;
467
468         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
469         if (spec == NULL)
470                 return -ENOMEM;
471
472         init_MUTEX(&spec->amp_mutex);
473         codec->spec = spec;
474
475         spec->multiout.max_channels = 6;
476         spec->multiout.num_dacs = ARRAY_SIZE(ad1986a_dac_nids);
477         spec->multiout.dac_nids = ad1986a_dac_nids;
478         spec->multiout.dig_out_nid = AD1986A_SPDIF_OUT;
479         spec->adc_nid = AD1986A_ADC;
480         spec->input_mux = &ad1986a_capture_source;
481         spec->mixers = ad1986a_mixers;
482         spec->init_verbs = ad1986a_init_verbs;
483
484         codec->patch_ops = ad198x_patch_ops;
485
486         return 0;
487 }
488
489 /*
490  * AD1983 specific
491  */
492
493 #define AD1983_SPDIF_OUT        0x02
494 #define AD1983_DAC              0x03
495 #define AD1983_ADC              0x04
496
497 static hda_nid_t ad1983_dac_nids[1] = { AD1983_DAC };
498
499 static struct hda_input_mux ad1983_capture_source = {
500         .num_items = 4,
501         .items = {
502                 { "Mic", 0x0 },
503                 { "Line", 0x1 },
504                 { "Mix", 0x2 },
505                 { "Mix Mono", 0x3 },
506         },
507 };
508
509 /*
510  * SPDIF playback route
511  */
512 static int ad1983_spdif_route_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
513 {
514         static char *texts[] = { "PCM", "ADC" };
515
516         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
517         uinfo->count = 1;
518         uinfo->value.enumerated.items = 2;
519         if (uinfo->value.enumerated.item > 1)
520                 uinfo->value.enumerated.item = 1;
521         strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
522         return 0;
523 }
524
525 static int ad1983_spdif_route_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
526 {
527         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
528         struct ad198x_spec *spec = codec->spec;
529
530         ucontrol->value.enumerated.item[0] = spec->spdif_route;
531         return 0;
532 }
533
534 static int ad1983_spdif_route_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
535 {
536         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
537         struct ad198x_spec *spec = codec->spec;
538
539         if (spec->spdif_route != ucontrol->value.enumerated.item[0]) {
540                 spec->spdif_route = ucontrol->value.enumerated.item[0];
541                 snd_hda_codec_write(codec, spec->multiout.dig_out_nid, 0,
542                                     AC_VERB_SET_CONNECT_SEL, spec->spdif_route);
543                 return 1;
544         }
545         return 0;
546 }
547
548 static snd_kcontrol_new_t ad1983_mixers[] = {
549         HDA_CODEC_VOLUME("Front Playback Volume", 0x05, 0x0, HDA_OUTPUT),
550         HDA_CODEC_MUTE("Front Playback Switch", 0x05, 0x0, HDA_OUTPUT),
551         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x06, 0x0, HDA_OUTPUT),
552         HDA_CODEC_MUTE("Headphone Playback Switch", 0x06, 0x0, HDA_OUTPUT),
553         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x07, 1, 0x0, HDA_OUTPUT),
554         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x07, 1, 0x0, HDA_OUTPUT),
555         HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
556         HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT),
557         HDA_CODEC_VOLUME("Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
558         HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
559         HDA_CODEC_VOLUME("Line Playback Volume", 0x13, 0x0, HDA_OUTPUT),
560         HDA_CODEC_MUTE("Line Playback Switch", 0x13, 0x0, HDA_OUTPUT),
561         HDA_CODEC_VOLUME_MONO("PC Speaker Playback Volume", 0x10, 1, 0x0, HDA_OUTPUT),
562         HDA_CODEC_MUTE_MONO("PC Speaker Playback Switch", 0x10, 1, 0x0, HDA_OUTPUT),
563         HDA_CODEC_VOLUME("Mic Boost", 0x0c, 0x0, HDA_OUTPUT),
564         HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
565         HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
566         {
567                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
568                 .name = "Capture Source",
569                 .info = ad198x_mux_enum_info,
570                 .get = ad198x_mux_enum_get,
571                 .put = ad198x_mux_enum_put,
572         },
573         {
574                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
575                 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Route",
576                 .info = ad1983_spdif_route_info,
577                 .get = ad1983_spdif_route_get,
578                 .put = ad1983_spdif_route_put,
579         },
580         { } /* end */
581 };
582
583 static struct hda_verb ad1983_init_verbs[] = {
584         /* Front, HP, Mono; mute as default */
585         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
586         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
587         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
588         /* Beep, PCM, Mic, Line-In: mute */
589         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
590         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
591         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
592         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
593         /* Front, HP selectors; from Mix */
594         {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
595         {0x06, AC_VERB_SET_CONNECT_SEL, 0x01},
596         /* Mono selector; from Mix */
597         {0x0b, AC_VERB_SET_CONNECT_SEL, 0x03},
598         /* Mic selector; Mic */
599         {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0},
600         /* Line-in selector: Line-in */
601         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
602         /* Mic boost: 0dB */
603         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
604         /* Record selector: mic */
605         {0x15, AC_VERB_SET_CONNECT_SEL, 0x0},
606         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
607         /* SPDIF route: PCM */
608         {0x02, AC_VERB_SET_CONNECT_SEL, 0x0},
609         /* Front Pin */
610         {0x05, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
611         /* HP Pin */
612         {0x06, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
613         /* Mono Pin */
614         {0x07, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
615         /* Mic Pin */
616         {0x08, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
617         /* Line Pin */
618         {0x09, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
619         { } /* end */
620 };
621
622 static int patch_ad1983(struct hda_codec *codec)
623 {
624         struct ad198x_spec *spec;
625
626         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
627         if (spec == NULL)
628                 return -ENOMEM;
629
630         init_MUTEX(&spec->amp_mutex);
631         codec->spec = spec;
632
633         spec->multiout.max_channels = 2;
634         spec->multiout.num_dacs = ARRAY_SIZE(ad1983_dac_nids);
635         spec->multiout.dac_nids = ad1983_dac_nids;
636         spec->multiout.dig_out_nid = AD1983_SPDIF_OUT;
637         spec->adc_nid = AD1983_ADC;
638         spec->input_mux = &ad1983_capture_source;
639         spec->mixers = ad1983_mixers;
640         spec->init_verbs = ad1983_init_verbs;
641         spec->spdif_route = 0;
642
643         codec->patch_ops = ad198x_patch_ops;
644
645         return 0;
646 }
647
648
649 /*
650  * AD1981 HD specific
651  */
652
653 #define AD1981_SPDIF_OUT        0x02
654 #define AD1981_DAC              0x03
655 #define AD1981_ADC              0x04
656
657 static hda_nid_t ad1981_dac_nids[1] = { AD1981_DAC };
658
659 /* 0x0c, 0x09, 0x0e, 0x0f, 0x19, 0x05, 0x18, 0x17 */
660 static struct hda_input_mux ad1981_capture_source = {
661         .num_items = 7,
662         .items = {
663                 { "Front Mic", 0x0 },
664                 { "Line", 0x1 },
665                 { "Mix", 0x2 },
666                 { "Mix Mono", 0x3 },
667                 { "CD", 0x4 },
668                 { "Mic", 0x6 },
669                 { "Aux", 0x7 },
670         },
671 };
672
673 static snd_kcontrol_new_t ad1981_mixers[] = {
674         HDA_CODEC_VOLUME("Front Playback Volume", 0x05, 0x0, HDA_OUTPUT),
675         HDA_CODEC_MUTE("Front Playback Switch", 0x05, 0x0, HDA_OUTPUT),
676         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x06, 0x0, HDA_OUTPUT),
677         HDA_CODEC_MUTE("Headphone Playback Switch", 0x06, 0x0, HDA_OUTPUT),
678         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x07, 1, 0x0, HDA_OUTPUT),
679         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x07, 1, 0x0, HDA_OUTPUT),
680         HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
681         HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT),
682         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
683         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
684         HDA_CODEC_VOLUME("Line Playback Volume", 0x13, 0x0, HDA_OUTPUT),
685         HDA_CODEC_MUTE("Line Playback Switch", 0x13, 0x0, HDA_OUTPUT),
686         HDA_CODEC_VOLUME("Aux Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
687         HDA_CODEC_MUTE("Aux Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
688         HDA_CODEC_VOLUME("Mic Playback Volume", 0x1c, 0x0, HDA_OUTPUT),
689         HDA_CODEC_MUTE("Mic Playback Switch", 0x1c, 0x0, HDA_OUTPUT),
690         HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
691         HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
692         HDA_CODEC_VOLUME_MONO("PC Speaker Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
693         HDA_CODEC_MUTE_MONO("PC Speaker Playback Switch", 0x0d, 1, 0x0, HDA_OUTPUT),
694         HDA_CODEC_VOLUME("Front Mic Boost", 0x08, 0x0, HDA_INPUT),
695         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x0, HDA_INPUT),
696         HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
697         HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
698         {
699                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
700                 .name = "Capture Source",
701                 .info = ad198x_mux_enum_info,
702                 .get = ad198x_mux_enum_get,
703                 .put = ad198x_mux_enum_put,
704         },
705         /* identical with AD1983 */
706         {
707                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
708                 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Route",
709                 .info = ad1983_spdif_route_info,
710                 .get = ad1983_spdif_route_get,
711                 .put = ad1983_spdif_route_put,
712         },
713         { } /* end */
714 };
715
716 static struct hda_verb ad1981_init_verbs[] = {
717         /* Front, HP, Mono; mute as default */
718         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
719         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
720         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
721         /* Beep, PCM, Front Mic, Line, Rear Mic, Aux, CD-In: mute */
722         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
723         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
724         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
725         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
726         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
727         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
728         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
729         /* Front, HP selectors; from Mix */
730         {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
731         {0x06, AC_VERB_SET_CONNECT_SEL, 0x01},
732         /* Mono selector; from Mix */
733         {0x0b, AC_VERB_SET_CONNECT_SEL, 0x03},
734         /* Mic Mixer; select Front Mic */
735         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
736         {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
737         /* Mic boost: 0dB */
738         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
739         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
740         /* Record selector: Front mic */
741         {0x15, AC_VERB_SET_CONNECT_SEL, 0x0},
742         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
743         /* SPDIF route: PCM */
744         {0x02, AC_VERB_SET_CONNECT_SEL, 0x0},
745         /* Front Pin */
746         {0x05, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
747         /* HP Pin */
748         {0x06, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
749         /* Mono Pin */
750         {0x07, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
751         /* Front & Rear Mic Pins */
752         {0x08, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
753         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
754         /* Line Pin */
755         {0x09, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
756         /* Digital Beep */
757         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
758         /* Line-Out as Input: disabled */
759         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
760         { } /* end */
761 };
762
763 static int patch_ad1981(struct hda_codec *codec)
764 {
765         struct ad198x_spec *spec;
766
767         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
768         if (spec == NULL)
769                 return -ENOMEM;
770
771         init_MUTEX(&spec->amp_mutex);
772         codec->spec = spec;
773
774         spec->multiout.max_channels = 2;
775         spec->multiout.num_dacs = ARRAY_SIZE(ad1981_dac_nids);
776         spec->multiout.dac_nids = ad1981_dac_nids;
777         spec->multiout.dig_out_nid = AD1981_SPDIF_OUT;
778         spec->adc_nid = AD1981_ADC;
779         spec->input_mux = &ad1981_capture_source;
780         spec->mixers = ad1981_mixers;
781         spec->init_verbs = ad1981_init_verbs;
782         spec->spdif_route = 0;
783
784         codec->patch_ops = ad198x_patch_ops;
785
786         return 0;
787 }
788
789
790 /*
791  * patch entries
792  */
793 struct hda_codec_preset snd_hda_preset_analog[] = {
794         { .id = 0x11d41981, .name = "AD1981", .patch = patch_ad1981 },
795         { .id = 0x11d41983, .name = "AD1983", .patch = patch_ad1983 },
796         { .id = 0x11d41986, .name = "AD1986A", .patch = patch_ad1986a },
797         {} /* terminator */
798 };