2 * HD audio interface patch for AD1981HD, AD1983, AD1986A
4 * Copyright (c) 2005 Takashi Iwai <tiwai@suse.de>
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.
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.
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
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"
31 snd_kcontrol_new_t *mixers[5];
34 const struct hda_verb *init_verbs[3]; /* initialization verbs
35 * don't forget NULL termination!
37 unsigned int num_init_verbs;
40 struct hda_multi_out multiout; /* playback set-up
41 * max_channels, dacs must be set
42 * dig_out_nid and hp_nid are optional
46 unsigned int num_adc_nids;
48 hda_nid_t dig_in_nid; /* digital-in NID; optional */
51 const struct hda_input_mux *input_mux;
52 unsigned int cur_mux[3];
55 const struct alc_channel_mode *channel_mode;
59 struct hda_pcm pcm_rec[2]; /* used in alc_build_pcms() */
61 struct semaphore amp_mutex; /* PCM volume/mute control mutex */
62 unsigned int spdif_route;
66 * input MUX handling (common part)
68 static int ad198x_mux_enum_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
70 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
71 struct ad198x_spec *spec = codec->spec;
73 return snd_hda_input_mux_info(spec->input_mux, uinfo);
76 static int ad198x_mux_enum_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
78 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
79 struct ad198x_spec *spec = codec->spec;
80 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
82 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
86 static int ad198x_mux_enum_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
88 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
89 struct ad198x_spec *spec = codec->spec;
90 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
92 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
93 spec->adc_nids[adc_idx], &spec->cur_mux[adc_idx]);
97 * initialization (common callbacks)
99 static int ad198x_init(struct hda_codec *codec)
101 struct ad198x_spec *spec = codec->spec;
104 for (i = 0; i < spec->num_init_verbs; i++)
105 snd_hda_sequence_write(codec, spec->init_verbs[i]);
109 static int ad198x_build_controls(struct hda_codec *codec)
111 struct ad198x_spec *spec = codec->spec;
115 for (i = 0; i < spec->num_mixers; i++) {
116 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
120 if (spec->multiout.dig_out_nid) {
121 err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid);
125 if (spec->dig_in_nid) {
126 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
134 * Analog playback callbacks
136 static int ad198x_playback_pcm_open(struct hda_pcm_stream *hinfo,
137 struct hda_codec *codec,
138 snd_pcm_substream_t *substream)
140 struct ad198x_spec *spec = codec->spec;
141 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
144 static int ad198x_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
145 struct hda_codec *codec,
146 unsigned int stream_tag,
148 snd_pcm_substream_t *substream)
150 struct ad198x_spec *spec = codec->spec;
151 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag,
155 static int ad198x_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
156 struct hda_codec *codec,
157 snd_pcm_substream_t *substream)
159 struct ad198x_spec *spec = codec->spec;
160 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
166 static int ad198x_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
167 struct hda_codec *codec,
168 snd_pcm_substream_t *substream)
170 struct ad198x_spec *spec = codec->spec;
171 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
174 static int ad198x_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
175 struct hda_codec *codec,
176 snd_pcm_substream_t *substream)
178 struct ad198x_spec *spec = codec->spec;
179 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
185 static int ad198x_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
186 struct hda_codec *codec,
187 unsigned int stream_tag,
189 snd_pcm_substream_t *substream)
191 struct ad198x_spec *spec = codec->spec;
192 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
193 stream_tag, 0, format);
197 static int ad198x_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
198 struct hda_codec *codec,
199 snd_pcm_substream_t *substream)
201 struct ad198x_spec *spec = codec->spec;
202 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
210 static struct hda_pcm_stream ad198x_pcm_analog_playback = {
213 .channels_max = 6, /* changed later */
214 .nid = 0, /* fill later */
216 .open = ad198x_playback_pcm_open,
217 .prepare = ad198x_playback_pcm_prepare,
218 .cleanup = ad198x_playback_pcm_cleanup
222 static struct hda_pcm_stream ad198x_pcm_analog_capture = {
226 .nid = 0, /* fill later */
228 .prepare = ad198x_capture_pcm_prepare,
229 .cleanup = ad198x_capture_pcm_cleanup
233 static struct hda_pcm_stream ad198x_pcm_digital_playback = {
237 .nid = 0, /* fill later */
239 .open = ad198x_dig_playback_pcm_open,
240 .close = ad198x_dig_playback_pcm_close
244 static struct hda_pcm_stream ad198x_pcm_digital_capture = {
248 /* NID is set in alc_build_pcms */
251 static int ad198x_build_pcms(struct hda_codec *codec)
253 struct ad198x_spec *spec = codec->spec;
254 struct hda_pcm *info = spec->pcm_rec;
257 codec->pcm_info = info;
259 info->name = "AD198x Analog";
260 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad198x_pcm_analog_playback;
261 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->multiout.max_channels;
262 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
263 info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad198x_pcm_analog_capture;
264 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_adc_nids;
265 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
267 if (spec->multiout.dig_out_nid) {
270 info->name = "AD198x Digital";
271 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad198x_pcm_digital_playback;
272 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
273 if (spec->dig_in_nid) {
274 info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad198x_pcm_digital_capture;
275 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
282 static void ad198x_free(struct hda_codec *codec)
288 static int ad198x_resume(struct hda_codec *codec)
290 struct ad198x_spec *spec = codec->spec;
294 for (i = 0; i < spec->num_mixers; i++)
295 snd_hda_resume_ctls(codec, spec->mixers[i]);
296 if (spec->multiout.dig_out_nid)
297 snd_hda_resume_spdif_out(codec);
298 if (spec->dig_in_nid)
299 snd_hda_resume_spdif_in(codec);
304 static struct hda_codec_ops ad198x_patch_ops = {
305 .build_controls = ad198x_build_controls,
306 .build_pcms = ad198x_build_pcms,
310 .resume = ad198x_resume,
319 #define AD1986A_SPDIF_OUT 0x02
320 #define AD1986A_FRONT_DAC 0x03
321 #define AD1986A_SURR_DAC 0x04
322 #define AD1986A_CLFE_DAC 0x05
323 #define AD1986A_ADC 0x06
325 static hda_nid_t ad1986a_dac_nids[3] = {
326 AD1986A_FRONT_DAC, AD1986A_SURR_DAC, AD1986A_CLFE_DAC
328 static hda_nid_t ad1986a_adc_nids[1] = { AD1986A_ADC };
330 static struct hda_input_mux ad1986a_capture_source = {
346 * bind volumes/mutes of 3 DACs as a single PCM control for simplicity
349 #define ad1986a_pcm_amp_vol_info snd_hda_mixer_amp_volume_info
351 static int ad1986a_pcm_amp_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
353 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
354 struct ad198x_spec *ad = codec->spec;
356 down(&ad->amp_mutex);
357 snd_hda_mixer_amp_volume_get(kcontrol, ucontrol);
362 static int ad1986a_pcm_amp_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
364 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
365 struct ad198x_spec *ad = codec->spec;
368 down(&ad->amp_mutex);
369 for (i = 0; i < ARRAY_SIZE(ad1986a_dac_nids); i++) {
370 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(ad1986a_dac_nids[i], 3, 0, HDA_OUTPUT);
371 change |= snd_hda_mixer_amp_volume_put(kcontrol, ucontrol);
373 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT);
378 #define ad1986a_pcm_amp_sw_info snd_hda_mixer_amp_switch_info
380 static int ad1986a_pcm_amp_sw_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
382 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
383 struct ad198x_spec *ad = codec->spec;
385 down(&ad->amp_mutex);
386 snd_hda_mixer_amp_switch_get(kcontrol, ucontrol);
391 static int ad1986a_pcm_amp_sw_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
393 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
394 struct ad198x_spec *ad = codec->spec;
397 down(&ad->amp_mutex);
398 for (i = 0; i < ARRAY_SIZE(ad1986a_dac_nids); i++) {
399 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(ad1986a_dac_nids[i], 3, 0, HDA_OUTPUT);
400 change |= snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
402 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT);
410 static snd_kcontrol_new_t ad1986a_mixers[] = {
412 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
413 .name = "PCM Playback Volume",
414 .info = ad1986a_pcm_amp_vol_info,
415 .get = ad1986a_pcm_amp_vol_get,
416 .put = ad1986a_pcm_amp_vol_put,
417 .private_value = HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT)
420 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
421 .name = "PCM Playback Switch",
422 .info = ad1986a_pcm_amp_sw_info,
423 .get = ad1986a_pcm_amp_sw_get,
424 .put = ad1986a_pcm_amp_sw_put,
425 .private_value = HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT)
427 HDA_CODEC_VOLUME("Front Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
428 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
429 HDA_CODEC_VOLUME("Surround Playback Volume", 0x1c, 0x0, HDA_OUTPUT),
430 HDA_CODEC_MUTE("Surround Playback Switch", 0x1c, 0x0, HDA_OUTPUT),
431 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x1d, 1, 0x0, HDA_OUTPUT),
432 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x1d, 2, 0x0, HDA_OUTPUT),
433 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x1d, 1, 0x0, HDA_OUTPUT),
434 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x1d, 2, 0x0, HDA_OUTPUT),
435 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x1a, 0x0, HDA_OUTPUT),
436 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
437 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_OUTPUT),
438 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_OUTPUT),
439 HDA_CODEC_VOLUME("Line Playback Volume", 0x17, 0x0, HDA_OUTPUT),
440 HDA_CODEC_MUTE("Line Playback Switch", 0x17, 0x0, HDA_OUTPUT),
441 HDA_CODEC_VOLUME("Aux Playback Volume", 0x16, 0x0, HDA_OUTPUT),
442 HDA_CODEC_MUTE("Aux Playback Switch", 0x16, 0x0, HDA_OUTPUT),
443 HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
444 HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
445 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x18, 0x0, HDA_OUTPUT),
446 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x18, 0x0, HDA_OUTPUT),
447 HDA_CODEC_VOLUME("Mono Playback Volume", 0x1e, 0x0, HDA_OUTPUT),
448 HDA_CODEC_MUTE("Mono Playback Switch", 0x1e, 0x0, HDA_OUTPUT),
449 HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT),
450 HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT),
452 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
453 .name = "Capture Source",
454 .info = ad198x_mux_enum_info,
455 .get = ad198x_mux_enum_get,
456 .put = ad198x_mux_enum_put,
458 HDA_CODEC_MUTE("Stereo Downmix Switch", 0x09, 0x0, HDA_OUTPUT),
463 * initialization verbs
465 static struct hda_verb ad1986a_init_verbs[] = {
466 /* Front, Surround, CLFE DAC; mute as default */
467 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
468 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
469 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
471 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
472 /* HP, Line-Out, Surround, CLFE selectors */
473 {0x0a, AC_VERB_SET_CONNECT_SEL, 0x0},
474 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x0},
475 {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0},
476 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
478 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x0},
479 /* Mic selector: Mic 1/2 pin */
480 {0x0f, AC_VERB_SET_CONNECT_SEL, 0x0},
481 /* Line-in selector: Line-in */
482 {0x10, AC_VERB_SET_CONNECT_SEL, 0x0},
484 {0x11, AC_VERB_SET_CONNECT_SEL, 0x0},
485 /* Record selector: mic */
486 {0x12, AC_VERB_SET_CONNECT_SEL, 0x0},
487 /* Mic, Phone, CD, Aux, Line-In amp; mute as default */
488 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
489 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
490 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
491 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
492 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
494 {0x18, AC_VERB_SET_CONNECT_SEL, 0x0},
495 /* HP, Line-Out, Surround, CLFE, Mono pins; mute as default */
496 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
497 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
498 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
499 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
500 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
502 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
503 /* Front, Surround, CLFE Pins */
504 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
505 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
506 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
508 {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
510 {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
511 /* Line, Aux, CD, Beep-In Pin */
512 {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
513 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
514 {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
515 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
516 {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
521 static int patch_ad1986a(struct hda_codec *codec)
523 struct ad198x_spec *spec;
525 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
529 init_MUTEX(&spec->amp_mutex);
532 spec->multiout.max_channels = 6;
533 spec->multiout.num_dacs = ARRAY_SIZE(ad1986a_dac_nids);
534 spec->multiout.dac_nids = ad1986a_dac_nids;
535 spec->multiout.dig_out_nid = AD1986A_SPDIF_OUT;
536 spec->num_adc_nids = 1;
537 spec->adc_nids = ad1986a_adc_nids;
538 spec->input_mux = &ad1986a_capture_source;
539 spec->num_mixers = 1;
540 spec->mixers[0] = ad1986a_mixers;
541 spec->num_init_verbs = 1;
542 spec->init_verbs[0] = ad1986a_init_verbs;
544 codec->patch_ops = ad198x_patch_ops;
553 #define AD1983_SPDIF_OUT 0x02
554 #define AD1983_DAC 0x03
555 #define AD1983_ADC 0x04
557 static hda_nid_t ad1983_dac_nids[1] = { AD1983_DAC };
558 static hda_nid_t ad1983_adc_nids[1] = { AD1983_ADC };
560 static struct hda_input_mux ad1983_capture_source = {
571 * SPDIF playback route
573 static int ad1983_spdif_route_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
575 static char *texts[] = { "PCM", "ADC" };
577 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
579 uinfo->value.enumerated.items = 2;
580 if (uinfo->value.enumerated.item > 1)
581 uinfo->value.enumerated.item = 1;
582 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
586 static int ad1983_spdif_route_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
588 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
589 struct ad198x_spec *spec = codec->spec;
591 ucontrol->value.enumerated.item[0] = spec->spdif_route;
595 static int ad1983_spdif_route_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
597 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
598 struct ad198x_spec *spec = codec->spec;
600 if (spec->spdif_route != ucontrol->value.enumerated.item[0]) {
601 spec->spdif_route = ucontrol->value.enumerated.item[0];
602 snd_hda_codec_write(codec, spec->multiout.dig_out_nid, 0,
603 AC_VERB_SET_CONNECT_SEL, spec->spdif_route);
609 static snd_kcontrol_new_t ad1983_mixers[] = {
610 HDA_CODEC_VOLUME("Front Playback Volume", 0x05, 0x0, HDA_OUTPUT),
611 HDA_CODEC_MUTE("Front Playback Switch", 0x05, 0x0, HDA_OUTPUT),
612 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x06, 0x0, HDA_OUTPUT),
613 HDA_CODEC_MUTE("Headphone Playback Switch", 0x06, 0x0, HDA_OUTPUT),
614 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x07, 1, 0x0, HDA_OUTPUT),
615 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x07, 1, 0x0, HDA_OUTPUT),
616 HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
617 HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT),
618 HDA_CODEC_VOLUME("Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
619 HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
620 HDA_CODEC_VOLUME("Line Playback Volume", 0x13, 0x0, HDA_OUTPUT),
621 HDA_CODEC_MUTE("Line Playback Switch", 0x13, 0x0, HDA_OUTPUT),
622 HDA_CODEC_VOLUME_MONO("PC Speaker Playback Volume", 0x10, 1, 0x0, HDA_OUTPUT),
623 HDA_CODEC_MUTE_MONO("PC Speaker Playback Switch", 0x10, 1, 0x0, HDA_OUTPUT),
624 HDA_CODEC_VOLUME("Mic Boost", 0x0c, 0x0, HDA_OUTPUT),
625 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
626 HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
628 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
629 .name = "Capture Source",
630 .info = ad198x_mux_enum_info,
631 .get = ad198x_mux_enum_get,
632 .put = ad198x_mux_enum_put,
635 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
636 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Route",
637 .info = ad1983_spdif_route_info,
638 .get = ad1983_spdif_route_get,
639 .put = ad1983_spdif_route_put,
644 static struct hda_verb ad1983_init_verbs[] = {
645 /* Front, HP, Mono; mute as default */
646 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
647 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
648 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
649 /* Beep, PCM, Mic, Line-In: mute */
650 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
651 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
652 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
653 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
654 /* Front, HP selectors; from Mix */
655 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
656 {0x06, AC_VERB_SET_CONNECT_SEL, 0x01},
657 /* Mono selector; from Mix */
658 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x03},
659 /* Mic selector; Mic */
660 {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0},
661 /* Line-in selector: Line-in */
662 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
664 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
665 /* Record selector: mic */
666 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0},
667 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
668 /* SPDIF route: PCM */
669 {0x02, AC_VERB_SET_CONNECT_SEL, 0x0},
671 {0x05, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
673 {0x06, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
675 {0x07, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
677 {0x08, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
679 {0x09, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
684 static int patch_ad1983(struct hda_codec *codec)
686 struct ad198x_spec *spec;
688 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
692 init_MUTEX(&spec->amp_mutex);
695 spec->multiout.max_channels = 2;
696 spec->multiout.num_dacs = ARRAY_SIZE(ad1983_dac_nids);
697 spec->multiout.dac_nids = ad1983_dac_nids;
698 spec->multiout.dig_out_nid = AD1983_SPDIF_OUT;
699 spec->num_adc_nids = 1;
700 spec->adc_nids = ad1983_adc_nids;
701 spec->input_mux = &ad1983_capture_source;
702 spec->num_mixers = 1;
703 spec->mixers[0] = ad1983_mixers;
704 spec->num_init_verbs = 1;
705 spec->init_verbs[0] = ad1983_init_verbs;
706 spec->spdif_route = 0;
708 codec->patch_ops = ad198x_patch_ops;
718 #define AD1981_SPDIF_OUT 0x02
719 #define AD1981_DAC 0x03
720 #define AD1981_ADC 0x04
722 static hda_nid_t ad1981_dac_nids[1] = { AD1981_DAC };
723 static hda_nid_t ad1981_adc_nids[1] = { AD1981_ADC };
725 /* 0x0c, 0x09, 0x0e, 0x0f, 0x19, 0x05, 0x18, 0x17 */
726 static struct hda_input_mux ad1981_capture_source = {
729 { "Front Mic", 0x0 },
739 static snd_kcontrol_new_t ad1981_mixers[] = {
740 HDA_CODEC_VOLUME("Front Playback Volume", 0x05, 0x0, HDA_OUTPUT),
741 HDA_CODEC_MUTE("Front Playback Switch", 0x05, 0x0, HDA_OUTPUT),
742 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x06, 0x0, HDA_OUTPUT),
743 HDA_CODEC_MUTE("Headphone Playback Switch", 0x06, 0x0, HDA_OUTPUT),
744 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x07, 1, 0x0, HDA_OUTPUT),
745 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x07, 1, 0x0, HDA_OUTPUT),
746 HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
747 HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT),
748 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
749 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
750 HDA_CODEC_VOLUME("Line Playback Volume", 0x13, 0x0, HDA_OUTPUT),
751 HDA_CODEC_MUTE("Line Playback Switch", 0x13, 0x0, HDA_OUTPUT),
752 HDA_CODEC_VOLUME("Aux Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
753 HDA_CODEC_MUTE("Aux Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
754 HDA_CODEC_VOLUME("Mic Playback Volume", 0x1c, 0x0, HDA_OUTPUT),
755 HDA_CODEC_MUTE("Mic Playback Switch", 0x1c, 0x0, HDA_OUTPUT),
756 HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
757 HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
758 HDA_CODEC_VOLUME_MONO("PC Speaker Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
759 HDA_CODEC_MUTE_MONO("PC Speaker Playback Switch", 0x0d, 1, 0x0, HDA_OUTPUT),
760 HDA_CODEC_VOLUME("Front Mic Boost", 0x08, 0x0, HDA_INPUT),
761 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x0, HDA_INPUT),
762 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
763 HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
765 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
766 .name = "Capture Source",
767 .info = ad198x_mux_enum_info,
768 .get = ad198x_mux_enum_get,
769 .put = ad198x_mux_enum_put,
771 /* identical with AD1983 */
773 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
774 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Route",
775 .info = ad1983_spdif_route_info,
776 .get = ad1983_spdif_route_get,
777 .put = ad1983_spdif_route_put,
782 static struct hda_verb ad1981_init_verbs[] = {
783 /* Front, HP, Mono; mute as default */
784 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
785 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
786 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
787 /* Beep, PCM, Front Mic, Line, Rear Mic, Aux, CD-In: mute */
788 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
789 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
790 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
791 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
792 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
793 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
794 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
795 /* Front, HP selectors; from Mix */
796 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
797 {0x06, AC_VERB_SET_CONNECT_SEL, 0x01},
798 /* Mono selector; from Mix */
799 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x03},
800 /* Mic Mixer; select Front Mic */
801 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
802 {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
804 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
805 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
806 /* Record selector: Front mic */
807 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0},
808 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
809 /* SPDIF route: PCM */
810 {0x02, AC_VERB_SET_CONNECT_SEL, 0x0},
812 {0x05, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
814 {0x06, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
816 {0x07, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
817 /* Front & Rear Mic Pins */
818 {0x08, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
819 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
821 {0x09, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
823 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
824 /* Line-Out as Input: disabled */
825 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
829 static int patch_ad1981(struct hda_codec *codec)
831 struct ad198x_spec *spec;
833 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
837 init_MUTEX(&spec->amp_mutex);
840 spec->multiout.max_channels = 2;
841 spec->multiout.num_dacs = ARRAY_SIZE(ad1981_dac_nids);
842 spec->multiout.dac_nids = ad1981_dac_nids;
843 spec->multiout.dig_out_nid = AD1981_SPDIF_OUT;
844 spec->num_adc_nids = 1;
845 spec->adc_nids = ad1981_adc_nids;
846 spec->input_mux = &ad1981_capture_source;
847 spec->num_mixers = 1;
848 spec->mixers[0] = ad1981_mixers;
849 spec->num_init_verbs = 1;
850 spec->init_verbs[0] = ad1981_init_verbs;
851 spec->spdif_route = 0;
853 codec->patch_ops = ad198x_patch_ops;
862 struct hda_codec_preset snd_hda_preset_analog[] = {
863 { .id = 0x11d41981, .name = "AD1981", .patch = patch_ad1981 },
864 { .id = 0x11d41983, .name = "AD1983", .patch = patch_ad1983 },
865 { .id = 0x11d41986, .name = "AD1986A", .patch = patch_ad1986a },