1 /* 2 * HD audio interface patch for 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 ad1986a_spec { 31 struct semaphore amp_mutex; /* PCM volume/mute control mutex */ 32 struct hda_multi_out multiout; /* playback */ 33 unsigned int cur_mux; /* capture source */ 34 struct hda_pcm pcm_rec[2]; /* PCM information */ 35 }; 36 37 #define AD1986A_SPDIF_OUT 0x02 38 #define AD1986A_FRONT_DAC 0x03 39 #define AD1986A_SURR_DAC 0x04 40 #define AD1986A_CLFE_DAC 0x05 41 #define AD1986A_ADC 0x06 42 43 static hda_nid_t ad1986a_dac_nids[3] = { 44 AD1986A_FRONT_DAC, AD1986A_SURR_DAC, AD1986A_CLFE_DAC 45 }; 46 47 static struct hda_input_mux ad1986a_capture_source = { 48 .num_items = 7, 49 .items = { 50 { "Mic", 0x0 }, 51 { "CD", 0x1 }, 52 { "Aux", 0x3 }, 53 { "Line", 0x4 }, 54 { "Mix", 0x5 }, 55 { "Mono", 0x6 }, 56 { "Phone", 0x7 }, 57 }, 58 }; 59 60 /* 61 * PCM control 62 * 63 * bind volumes/mutes of 3 DACs as a single PCM control for simplicity 64 */ 65 66 #define ad1986a_pcm_amp_vol_info snd_hda_mixer_amp_volume_info 67 68 static int ad1986a_pcm_amp_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) 69 { 70 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 71 struct ad1986a_spec *ad = codec->spec; 72 73 down(&ad->amp_mutex); 74 snd_hda_mixer_amp_volume_get(kcontrol, ucontrol); 75 up(&ad->amp_mutex); 76 return 0; 77 } 78 79 static int ad1986a_pcm_amp_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) 80 { 81 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 82 struct ad1986a_spec *ad = codec->spec; 83 int i, change = 0; 84 85 down(&ad->amp_mutex); 86 for (i = 0; i < ARRAY_SIZE(ad1986a_dac_nids); i++) { 87 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(ad1986a_dac_nids[i], 3, 0, HDA_OUTPUT); 88 change |= snd_hda_mixer_amp_volume_put(kcontrol, ucontrol); 89 } 90 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT); 91 up(&ad->amp_mutex); 92 return change; 93 } 94 95 #define ad1986a_pcm_amp_sw_info snd_hda_mixer_amp_volume_info 96 97 static int ad1986a_pcm_amp_sw_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) 98 { 99 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 100 struct ad1986a_spec *ad = codec->spec; 101 102 down(&ad->amp_mutex); 103 snd_hda_mixer_amp_switch_get(kcontrol, ucontrol); 104 up(&ad->amp_mutex); 105 return 0; 106 } 107 108 static int ad1986a_pcm_amp_sw_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) 109 { 110 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 111 struct ad1986a_spec *ad = codec->spec; 112 int i, change = 0; 113 114 down(&ad->amp_mutex); 115 for (i = 0; i < ARRAY_SIZE(ad1986a_dac_nids); i++) { 116 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(ad1986a_dac_nids[i], 3, 0, HDA_OUTPUT); 117 change |= snd_hda_mixer_amp_switch_put(kcontrol, ucontrol); 118 } 119 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT); 120 up(&ad->amp_mutex); 121 return change; 122 } 123 124 /* 125 * input MUX handling 126 */ 127 static int ad1986a_mux_enum_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) 128 { 129 return snd_hda_input_mux_info(&ad1986a_capture_source, uinfo); 130 } 131 132 static int ad1986a_mux_enum_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) 133 { 134 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 135 struct ad1986a_spec *spec = codec->spec; 136 137 ucontrol->value.enumerated.item[0] = spec->cur_mux; 138 return 0; 139 } 140 141 static int ad1986a_mux_enum_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) 142 { 143 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 144 struct ad1986a_spec *spec = codec->spec; 145 146 return snd_hda_input_mux_put(codec, &ad1986a_capture_source, ucontrol, 147 AD1986A_ADC, &spec->cur_mux); 148 } 149 150 /* 151 * mixers 152 */ 153 static snd_kcontrol_new_t ad1986a_mixers[] = { 154 { 155 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 156 .name = "PCM Playback Volume", 157 .info = ad1986a_pcm_amp_vol_info, 158 .get = ad1986a_pcm_amp_vol_get, 159 .put = ad1986a_pcm_amp_vol_put, 160 .private_value = HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT) 161 }, 162 { 163 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 164 .name = "PCM Playback Switch", 165 .info = ad1986a_pcm_amp_sw_info, 166 .get = ad1986a_pcm_amp_sw_get, 167 .put = ad1986a_pcm_amp_sw_put, 168 .private_value = HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT) 169 }, 170 HDA_CODEC_VOLUME("Front Playback Volume", 0x1b, 0x0, HDA_OUTPUT), 171 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 172 HDA_CODEC_VOLUME("Surround Playback Volume", 0x1c, 0x0, HDA_OUTPUT), 173 HDA_CODEC_MUTE("Surround Playback Switch", 0x1c, 0x0, HDA_OUTPUT), 174 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x1d, 1, 0x0, HDA_OUTPUT), 175 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x1d, 2, 0x0, HDA_OUTPUT), 176 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x1d, 1, 0x0, HDA_OUTPUT), 177 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x1d, 2, 0x0, HDA_OUTPUT), 178 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x1a, 0x0, HDA_OUTPUT), 179 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT), 180 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_OUTPUT), 181 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_OUTPUT), 182 HDA_CODEC_VOLUME("Line Playback Volume", 0x17, 0x0, HDA_OUTPUT), 183 HDA_CODEC_MUTE("Line Playback Switch", 0x17, 0x0, HDA_OUTPUT), 184 HDA_CODEC_VOLUME("Aux Playback Volume", 0x16, 0x0, HDA_OUTPUT), 185 HDA_CODEC_MUTE("Aux Playback Switch", 0x16, 0x0, HDA_OUTPUT), 186 HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT), 187 HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT), 188 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x18, 0x0, HDA_OUTPUT), 189 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x18, 0x0, HDA_OUTPUT), 190 HDA_CODEC_VOLUME("Mono Playback Volume", 0x1e, 0x0, HDA_OUTPUT), 191 HDA_CODEC_MUTE("Mono Playback Switch", 0x1e, 0x0, HDA_OUTPUT), 192 HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT), 193 HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT), 194 { 195 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 196 .name = "Capture Source", 197 .info = ad1986a_mux_enum_info, 198 .get = ad1986a_mux_enum_get, 199 .put = ad1986a_mux_enum_put, 200 }, 201 HDA_CODEC_MUTE("Stereo Downmix Switch", 0x09, 0x0, HDA_OUTPUT), 202 { } /* end */ 203 }; 204 205 /* 206 * initialization verbs 207 */ 208 static struct hda_verb ad1986a_init_verbs[] = { 209 /* Front, Surround, CLFE DAC; mute as default */ 210 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 211 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 212 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 213 /* Downmix - off */ 214 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 215 /* HP, Line-Out, Surround, CLFE selectors */ 216 {0x0a, AC_VERB_SET_CONNECT_SEL, 0x0}, 217 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x0}, 218 {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0}, 219 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0}, 220 /* Mono selector */ 221 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x0}, 222 /* Mic selector: Mic 1/2 pin */ 223 {0x0f, AC_VERB_SET_CONNECT_SEL, 0x0}, 224 /* Line-in selector: Line-in */ 225 {0x10, AC_VERB_SET_CONNECT_SEL, 0x0}, 226 /* Mic 1/2 swap */ 227 {0x11, AC_VERB_SET_CONNECT_SEL, 0x0}, 228 /* Record selector: mic */ 229 {0x12, AC_VERB_SET_CONNECT_SEL, 0x0}, 230 /* Mic, Phone, CD, Aux, Line-In amp; mute as default */ 231 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 232 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 233 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 234 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 235 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 236 /* PC beep */ 237 {0x18, AC_VERB_SET_CONNECT_SEL, 0x0}, 238 /* HP, Line-Out, Surround, CLFE, Mono pins; mute as default */ 239 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 240 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 241 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 242 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 243 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 244 { } /* end */ 245 }; 246 247 248 static int ad1986a_init(struct hda_codec *codec) 249 { 250 snd_hda_sequence_write(codec, ad1986a_init_verbs); 251 return 0; 252 } 253 254 static int ad1986a_build_controls(struct hda_codec *codec) 255 { 256 int err; 257 258 err = snd_hda_add_new_ctls(codec, ad1986a_mixers); 259 if (err < 0) 260 return err; 261 err = snd_hda_create_spdif_out_ctls(codec, AD1986A_SPDIF_OUT); 262 if (err < 0) 263 return err; 264 return 0; 265 } 266 267 /* 268 * Analog playback callbacks 269 */ 270 static int ad1986a_playback_pcm_open(struct hda_pcm_stream *hinfo, 271 struct hda_codec *codec, 272 snd_pcm_substream_t *substream) 273 { 274 struct ad1986a_spec *spec = codec->spec; 275 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream); 276 } 277 278 static int ad1986a_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 279 struct hda_codec *codec, 280 unsigned int stream_tag, 281 unsigned int format, 282 snd_pcm_substream_t *substream) 283 { 284 struct ad1986a_spec *spec = codec->spec; 285 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag, 286 format, substream); 287 } 288 289 static int ad1986a_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, 290 struct hda_codec *codec, 291 snd_pcm_substream_t *substream) 292 { 293 struct ad1986a_spec *spec = codec->spec; 294 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); 295 } 296 297 /* 298 * Digital out 299 */ 300 static int ad1986a_dig_playback_pcm_open(struct hda_pcm_stream *hinfo, 301 struct hda_codec *codec, 302 snd_pcm_substream_t *substream) 303 { 304 struct ad1986a_spec *spec = codec->spec; 305 return snd_hda_multi_out_dig_open(codec, &spec->multiout); 306 } 307 308 static int ad1986a_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, 309 struct hda_codec *codec, 310 snd_pcm_substream_t *substream) 311 { 312 struct ad1986a_spec *spec = codec->spec; 313 return snd_hda_multi_out_dig_close(codec, &spec->multiout); 314 } 315 316 /* 317 * Analog capture 318 */ 319 static int ad1986a_capture_pcm_prepare(struct hda_pcm_stream *hinfo, 320 struct hda_codec *codec, 321 unsigned int stream_tag, 322 unsigned int format, 323 snd_pcm_substream_t *substream) 324 { 325 snd_hda_codec_setup_stream(codec, AD1986A_ADC, stream_tag, 0, format); 326 return 0; 327 } 328 329 static int ad1986a_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, 330 struct hda_codec *codec, 331 snd_pcm_substream_t *substream) 332 { 333 snd_hda_codec_setup_stream(codec, AD1986A_ADC, 0, 0, 0); 334 return 0; 335 } 336 337 338 /* 339 */ 340 static struct hda_pcm_stream ad1986a_pcm_analog_playback = { 341 .substreams = 1, 342 .channels_min = 2, 343 .channels_max = 6, 344 .nid = AD1986A_FRONT_DAC, /* NID to query formats and rates */ 345 .ops = { 346 .open = ad1986a_playback_pcm_open, 347 .prepare = ad1986a_playback_pcm_prepare, 348 .cleanup = ad1986a_playback_pcm_cleanup 349 }, 350 }; 351 352 static struct hda_pcm_stream ad1986a_pcm_analog_capture = { 353 .substreams = 2, 354 .channels_min = 2, 355 .channels_max = 2, 356 .nid = AD1986A_ADC, /* NID to query formats and rates */ 357 .ops = { 358 .prepare = ad1986a_capture_pcm_prepare, 359 .cleanup = ad1986a_capture_pcm_cleanup 360 }, 361 }; 362 363 static struct hda_pcm_stream ad1986a_pcm_digital_playback = { 364 .substreams = 1, 365 .channels_min = 2, 366 .channels_max = 2, 367 .nid = AD1986A_SPDIF_OUT, 368 .ops = { 369 .open = ad1986a_dig_playback_pcm_open, 370 .close = ad1986a_dig_playback_pcm_close 371 }, 372 }; 373 374 static int ad1986a_build_pcms(struct hda_codec *codec) 375 { 376 struct ad1986a_spec *spec = codec->spec; 377 struct hda_pcm *info = spec->pcm_rec; 378 379 codec->num_pcms = 2; 380 codec->pcm_info = info; 381 382 info->name = "AD1986A Analog"; 383 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad1986a_pcm_analog_playback; 384 info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad1986a_pcm_analog_capture; 385 info++; 386 387 info->name = "AD1986A Digital"; 388 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad1986a_pcm_digital_playback; 389 390 return 0; 391 } 392 393 static void ad1986a_free(struct hda_codec *codec) 394 { 395 kfree(codec->spec); 396 } 397 398 #ifdef CONFIG_PM 399 static int ad1986a_resume(struct hda_codec *codec) 400 { 401 ad1986a_init(codec); 402 snd_hda_resume_ctls(codec, ad1986a_mixers); 403 snd_hda_resume_spdif_out(codec); 404 return 0; 405 } 406 #endif 407 408 static struct hda_codec_ops ad1986a_patch_ops = { 409 .build_controls = ad1986a_build_controls, 410 .build_pcms = ad1986a_build_pcms, 411 .init = ad1986a_init, 412 .free = ad1986a_free, 413 #ifdef CONFIG_PM 414 .resume = ad1986a_resume, 415 #endif 416 }; 417 418 static int patch_ad1986a(struct hda_codec *codec) 419 { 420 struct ad1986a_spec *spec; 421 422 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); 423 if (spec == NULL) 424 return -ENOMEM; 425 426 init_MUTEX(&spec->amp_mutex); 427 codec->spec = spec; 428 429 spec->multiout.max_channels = 6; 430 spec->multiout.num_dacs = ARRAY_SIZE(ad1986a_dac_nids); 431 spec->multiout.dac_nids = ad1986a_dac_nids; 432 spec->multiout.dig_out_nid = AD1986A_SPDIF_OUT; 433 434 codec->patch_ops = ad1986a_patch_ops; 435 436 return 0; 437 } 438 439 /* 440 * patch entries 441 */ 442 struct hda_codec_preset snd_hda_preset_analog[] = { 443 { .id = 0x11d41986, .name = "AD1986A", .patch = patch_ad1986a }, 444 {} /* terminator */ 445 }; 446