1 /* $NetBSD: ac97.c,v 1.81 2006/05/10 09:07:57 uebayasi Exp $ */ 2 /* $OpenBSD: ac97.c,v 1.8 2000/07/19 09:01:35 csapuntz Exp $ */ 3 4 /* 5 * Copyright (c) 1999, 2000 Constantine Sapuntzakis 6 * 7 * Author: Constantine Sapuntzakis <csapuntz@stanford.edu> 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. The name of the author may not be used to endorse or promote 18 * products derived from this software without specific prior written 19 * permission. 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS 21 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 22 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE 24 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 26 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 27 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 30 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 31 * DAMAGE 32 */ 33 34 /* Partially inspired by FreeBSD's sys/dev/pcm/ac97.c. It came with 35 the following copyright */ 36 37 /* 38 * Copyright (c) 1999 Cameron Grant <gandalf@vilnya.demon.co.uk> 39 * All rights reserved. 40 * 41 * Redistribution and use in source and binary forms, with or without 42 * modification, are permitted provided that the following conditions 43 * are met: 44 * 1. Redistributions of source code must retain the above copyright 45 * notice, this list of conditions and the following disclaimer. 46 * 2. Redistributions in binary form must reproduce the above copyright 47 * notice, this list of conditions and the following disclaimer in the 48 * documentation and/or other materials provided with the distribution. 49 * 50 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 51 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 52 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 53 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 54 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 55 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 56 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 57 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 58 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 59 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 60 * SUCH DAMAGE. 61 * 62 * $FreeBSD$ 63 */ 64 65 #include <sys/cdefs.h> 66 __KERNEL_RCSID(0, "$NetBSD: ac97.c,v 1.81 2006/05/10 09:07:57 uebayasi Exp $"); 67 68 #include <sys/param.h> 69 #include <sys/systm.h> 70 #include <sys/kernel.h> 71 #include <sys/malloc.h> 72 #include <sys/device.h> 73 #include <sys/sysctl.h> 74 75 #include <sys/audioio.h> 76 #include <dev/audio_if.h> 77 78 #include <dev/ic/ac97reg.h> 79 #include <dev/ic/ac97var.h> 80 81 struct ac97_softc; 82 struct ac97_source_info; 83 static int ac97_mixer_get_port(struct ac97_codec_if *, mixer_ctrl_t *); 84 static int ac97_mixer_set_port(struct ac97_codec_if *, mixer_ctrl_t *); 85 static void ac97_detach(struct ac97_codec_if *); 86 static int ac97_query_devinfo(struct ac97_codec_if *, mixer_devinfo_t *); 87 static int ac97_get_portnum_by_name(struct ac97_codec_if *, const char *, 88 const char *, const char *); 89 static void ac97_restore_shadow(struct ac97_codec_if *); 90 static int ac97_set_rate(struct ac97_codec_if *, int, u_int *); 91 static void ac97_set_clock(struct ac97_codec_if *, unsigned int); 92 static uint16_t ac97_get_extcaps(struct ac97_codec_if *); 93 static int ac97_add_port(struct ac97_softc *, 94 const struct ac97_source_info *); 95 static int ac97_str_equal(const char *, const char *); 96 static int ac97_check_capability(struct ac97_softc *, int); 97 static void ac97_setup_source_info(struct ac97_softc *); 98 static void ac97_read(struct ac97_softc *, uint8_t, uint16_t *); 99 static void ac97_setup_defaults(struct ac97_softc *); 100 static int ac97_write(struct ac97_softc *, uint8_t, uint16_t); 101 102 static void ac97_ad198x_init(struct ac97_softc *); 103 static void ac97_alc650_init(struct ac97_softc *); 104 static void ac97_vt1616_init(struct ac97_softc *); 105 106 static int ac97_modem_offhook_set(struct ac97_softc *, int, int); 107 static int ac97_sysctl_verify(SYSCTLFN_ARGS); 108 109 #define Ac97Nphone "phone" 110 #define Ac97Nline1 "line1" 111 #define Ac97Nline2 "line2" 112 #define Ac97Nhandset "handset" 113 114 static const struct audio_mixer_enum 115 ac97_on_off = { 2, { { { AudioNoff } , 0 }, 116 { { AudioNon } , 1 } } }; 117 118 static const struct audio_mixer_enum 119 ac97_mic_select = { 2, { { { AudioNmicrophone "0" }, 0 }, 120 { { AudioNmicrophone "1" }, 1 } } }; 121 122 static const struct audio_mixer_enum 123 ac97_mono_select = { 2, { { { AudioNmixerout }, 0 }, 124 { { AudioNmicrophone }, 1 } } }; 125 126 static const struct audio_mixer_enum 127 ac97_source = { 8, { { { AudioNmicrophone } , 0 }, 128 { { AudioNcd }, 1 }, 129 { { AudioNvideo }, 2 }, 130 { { AudioNaux }, 3 }, 131 { { AudioNline }, 4 }, 132 { { AudioNmixerout }, 5 }, 133 { { AudioNmixerout AudioNmono }, 6 }, 134 { { Ac97Nphone }, 7 } } }; 135 136 /* 137 * Due to different values for each source that uses these structures, 138 * the ac97_query_devinfo function sets delta in mixer_devinfo_t using 139 * ac97_source_info.bits. 140 */ 141 static const struct audio_mixer_value 142 ac97_volume_stereo = { { AudioNvolume }, 2 }; 143 144 static const struct audio_mixer_value 145 ac97_volume_mono = { { AudioNvolume }, 1 }; 146 147 #define WRAP(a) &a, sizeof(a) 148 149 struct ac97_source_info { 150 const char *class; 151 const char *device; 152 const char *qualifier; 153 154 int type; 155 const void *info; 156 int info_size; 157 158 uint8_t reg; 159 uint16_t default_value; 160 uint8_t bits:3; 161 uint8_t ofs:4; 162 uint8_t mute:1; 163 uint8_t polarity:1; /* Does 0 == MAX or MIN */ 164 enum { 165 CHECK_NONE = 0, 166 CHECK_SURROUND, 167 CHECK_CENTER, 168 CHECK_LFE, 169 CHECK_HEADPHONES, 170 CHECK_TONE, 171 CHECK_MIC, 172 CHECK_LOUDNESS, 173 CHECK_3D, 174 CHECK_LINE1, 175 CHECK_LINE2, 176 CHECK_HANDSET 177 } req_feature; 178 179 int prev; 180 int next; 181 int mixer_class; 182 }; 183 184 static const struct ac97_source_info audio_source_info[] = { 185 { AudioCinputs, NULL, NULL, 186 AUDIO_MIXER_CLASS, }, 187 { AudioCoutputs, NULL, NULL, 188 AUDIO_MIXER_CLASS, }, 189 { AudioCrecord, NULL, NULL, 190 AUDIO_MIXER_CLASS, }, 191 /* Stereo master volume*/ 192 { AudioCoutputs, AudioNmaster, NULL, 193 AUDIO_MIXER_VALUE, WRAP(ac97_volume_stereo), 194 AC97_REG_MASTER_VOLUME, 0x8000, 5, 0, 1, 195 }, 196 /* Mono volume */ 197 { AudioCoutputs, AudioNmono, NULL, 198 AUDIO_MIXER_VALUE, WRAP(ac97_volume_mono), 199 AC97_REG_MASTER_VOLUME_MONO, 0x8000, 6, 0, 1, 200 }, 201 { AudioCoutputs, AudioNmono, AudioNsource, 202 AUDIO_MIXER_ENUM, WRAP(ac97_mono_select), 203 AC97_REG_GP, 0x0000, 1, 9, 0, 204 }, 205 /* Headphone volume */ 206 { AudioCoutputs, AudioNheadphone, NULL, 207 AUDIO_MIXER_VALUE, WRAP(ac97_volume_stereo), 208 AC97_REG_HEADPHONE_VOLUME, 0x8000, 6, 0, 1, 0, CHECK_HEADPHONES 209 }, 210 /* Surround volume - logic hard coded for mute */ 211 { AudioCoutputs, AudioNsurround, NULL, 212 AUDIO_MIXER_VALUE, WRAP(ac97_volume_stereo), 213 AC97_REG_SURR_MASTER, 0x8080, 5, 0, 1, 0, CHECK_SURROUND 214 }, 215 /* Center volume*/ 216 { AudioCoutputs, AudioNcenter, NULL, 217 AUDIO_MIXER_VALUE, WRAP(ac97_volume_mono), 218 AC97_REG_CENTER_LFE_MASTER, 0x8080, 5, 0, 0, 0, CHECK_CENTER 219 }, 220 { AudioCoutputs, AudioNcenter, AudioNmute, 221 AUDIO_MIXER_ENUM, WRAP(ac97_on_off), 222 AC97_REG_CENTER_LFE_MASTER, 0x8080, 1, 7, 0, 0, CHECK_CENTER 223 }, 224 /* LFE volume*/ 225 { AudioCoutputs, AudioNlfe, NULL, 226 AUDIO_MIXER_VALUE, WRAP(ac97_volume_mono), 227 AC97_REG_CENTER_LFE_MASTER, 0x8080, 5, 8, 0, 0, CHECK_LFE 228 }, 229 { AudioCoutputs, AudioNlfe, AudioNmute, 230 AUDIO_MIXER_ENUM, WRAP(ac97_on_off), 231 AC97_REG_CENTER_LFE_MASTER, 0x8080, 1, 15, 0, 0, CHECK_LFE 232 }, 233 /* Tone - bass */ 234 { AudioCoutputs, AudioNbass, NULL, 235 AUDIO_MIXER_VALUE, WRAP(ac97_volume_mono), 236 AC97_REG_MASTER_TONE, 0x0f0f, 4, 8, 0, 0, CHECK_TONE 237 }, 238 /* Tone - treble */ 239 { AudioCoutputs, AudioNtreble, NULL, 240 AUDIO_MIXER_VALUE, WRAP(ac97_volume_mono), 241 AC97_REG_MASTER_TONE, 0x0f0f, 4, 0, 0, 0, CHECK_TONE 242 }, 243 /* PC Beep Volume */ 244 { AudioCinputs, AudioNspeaker, NULL, 245 AUDIO_MIXER_VALUE, WRAP(ac97_volume_mono), 246 AC97_REG_PCBEEP_VOLUME, 0x0000, 4, 1, 1, 247 }, 248 249 /* Phone */ 250 { AudioCinputs, Ac97Nphone, NULL, 251 AUDIO_MIXER_VALUE, WRAP(ac97_volume_mono), 252 AC97_REG_PHONE_VOLUME, 0x8008, 5, 0, 1, 253 }, 254 /* Mic Volume */ 255 { AudioCinputs, AudioNmicrophone, NULL, 256 AUDIO_MIXER_VALUE, WRAP(ac97_volume_mono), 257 AC97_REG_MIC_VOLUME, 0x8008, 5, 0, 1, 258 }, 259 { AudioCinputs, AudioNmicrophone, AudioNpreamp, 260 AUDIO_MIXER_ENUM, WRAP(ac97_on_off), 261 AC97_REG_MIC_VOLUME, 0x8008, 1, 6, 0, 262 }, 263 { AudioCinputs, AudioNmicrophone, AudioNsource, 264 AUDIO_MIXER_ENUM, WRAP(ac97_mic_select), 265 AC97_REG_GP, 0x0000, 1, 8, 0, 266 }, 267 /* Line in Volume */ 268 { AudioCinputs, AudioNline, NULL, 269 AUDIO_MIXER_VALUE, WRAP(ac97_volume_stereo), 270 AC97_REG_LINEIN_VOLUME, 0x8808, 5, 0, 1, 271 }, 272 /* CD Volume */ 273 { AudioCinputs, AudioNcd, NULL, 274 AUDIO_MIXER_VALUE, WRAP(ac97_volume_stereo), 275 AC97_REG_CD_VOLUME, 0x8808, 5, 0, 1, 276 }, 277 /* Video Volume */ 278 { AudioCinputs, AudioNvideo, NULL, 279 AUDIO_MIXER_VALUE, WRAP(ac97_volume_stereo), 280 AC97_REG_VIDEO_VOLUME, 0x8808, 5, 0, 1, 281 }, 282 /* AUX volume */ 283 { AudioCinputs, AudioNaux, NULL, 284 AUDIO_MIXER_VALUE, WRAP(ac97_volume_stereo), 285 AC97_REG_AUX_VOLUME, 0x8808, 5, 0, 1, 286 }, 287 /* PCM out volume */ 288 { AudioCinputs, AudioNdac, NULL, 289 AUDIO_MIXER_VALUE, WRAP(ac97_volume_stereo), 290 AC97_REG_PCMOUT_VOLUME, 0x8808, 5, 0, 1, 291 }, 292 /* Record Source - some logic for this is hard coded - see below */ 293 { AudioCrecord, AudioNsource, NULL, 294 AUDIO_MIXER_ENUM, WRAP(ac97_source), 295 AC97_REG_RECORD_SELECT, 0x0000, 3, 0, 0, 296 }, 297 /* Record Gain */ 298 { AudioCrecord, AudioNvolume, NULL, 299 AUDIO_MIXER_VALUE, WRAP(ac97_volume_stereo), 300 AC97_REG_RECORD_GAIN, 0x8000, 4, 0, 1, 1, 301 }, 302 /* Record Gain mic */ 303 { AudioCrecord, AudioNmicrophone, NULL, 304 AUDIO_MIXER_VALUE, WRAP(ac97_volume_mono), 305 AC97_REG_RECORD_GAIN_MIC, 0x8000, 4, 0, 1, 1, CHECK_MIC 306 }, 307 /* */ 308 { AudioCoutputs, AudioNloudness, NULL, 309 AUDIO_MIXER_ENUM, WRAP(ac97_on_off), 310 AC97_REG_GP, 0x0000, 1, 12, 0, 0, CHECK_LOUDNESS 311 }, 312 { AudioCoutputs, AudioNspatial, NULL, 313 AUDIO_MIXER_ENUM, WRAP(ac97_on_off), 314 AC97_REG_GP, 0x0000, 1, 13, 0, 1, CHECK_3D 315 }, 316 { AudioCoutputs, AudioNspatial, "center", 317 AUDIO_MIXER_VALUE, WRAP(ac97_volume_mono), 318 AC97_REG_3D_CONTROL, 0x0000, 4, 8, 0, 1, CHECK_3D 319 }, 320 { AudioCoutputs, AudioNspatial, "depth", 321 AUDIO_MIXER_VALUE, WRAP(ac97_volume_mono), 322 AC97_REG_3D_CONTROL, 0x0000, 4, 0, 0, 1, CHECK_3D 323 }, 324 325 /* Missing features: Simulated Stereo, POP, Loopback mode */ 326 }; 327 328 static const struct ac97_source_info modem_source_info[] = { 329 /* Classes */ 330 { AudioCinputs, NULL, NULL, 331 AUDIO_MIXER_CLASS, }, 332 { AudioCoutputs, NULL, NULL, 333 AUDIO_MIXER_CLASS, }, 334 { AudioCinputs, Ac97Nline1, NULL, 335 AUDIO_MIXER_VALUE, WRAP(ac97_volume_mono), 336 AC97_REG_LINE1_LEVEL, 0x8080, 4, 0, 0, 1, CHECK_LINE1 337 }, 338 { AudioCoutputs, Ac97Nline1, NULL, 339 AUDIO_MIXER_VALUE, WRAP(ac97_volume_mono), 340 AC97_REG_LINE1_LEVEL, 0x8080, 4, 8, 0, 1, CHECK_LINE1 341 }, 342 { AudioCinputs, Ac97Nline1, AudioNmute, 343 AUDIO_MIXER_ENUM, WRAP(ac97_on_off), 344 AC97_REG_LINE1_LEVEL, 0x8080, 1, 7, 0, 0, CHECK_LINE1 345 }, 346 { AudioCoutputs, Ac97Nline1, AudioNmute, 347 AUDIO_MIXER_ENUM, WRAP(ac97_on_off), 348 AC97_REG_LINE1_LEVEL, 0x8080, 1, 15, 0, 0, CHECK_LINE1 349 }, 350 }; 351 352 #define AUDIO_SOURCE_INFO_SIZE \ 353 (sizeof(audio_source_info)/sizeof(audio_source_info[0])) 354 #define MODEM_SOURCE_INFO_SIZE \ 355 (sizeof(modem_source_info)/sizeof(modem_source_info[0])) 356 #define SOURCE_INFO_SIZE(as) ((as)->type == AC97_CODEC_TYPE_MODEM ? \ 357 MODEM_SOURCE_INFO_SIZE : AUDIO_SOURCE_INFO_SIZE) 358 359 /* 360 * Check out http://developer.intel.com/pc-supp/platform/ac97/ for 361 * information on AC-97 362 */ 363 364 struct ac97_softc { 365 /* ac97_codec_if must be at the first of ac97_softc. */ 366 struct ac97_codec_if codec_if; 367 368 struct ac97_host_if *host_if; 369 370 #define AUDIO_MAX_SOURCES (2 * AUDIO_SOURCE_INFO_SIZE) 371 #define MODEM_MAX_SOURCES (2 * MODEM_SOURCE_INFO_SIZE) 372 struct ac97_source_info audio_source_info[AUDIO_MAX_SOURCES]; 373 struct ac97_source_info modem_source_info[MODEM_MAX_SOURCES]; 374 struct ac97_source_info *source_info; 375 int num_source_info; 376 377 enum ac97_host_flags host_flags; 378 unsigned int ac97_clock; /* usually 48000 */ 379 #define AC97_STANDARD_CLOCK 48000U 380 uint16_t power_all; 381 uint16_t power_reg; /* -> AC97_REG_POWER */ 382 uint16_t caps; /* -> AC97_REG_RESET */ 383 uint16_t ext_id; /* -> AC97_REG_EXT_AUDIO_ID */ 384 uint16_t ext_mid; /* -> AC97_REG_EXT_MODEM_ID */ 385 uint16_t shadow_reg[128]; 386 387 int type; 388 389 /* sysctl */ 390 struct sysctllog *log; 391 int offhook_line1_mib; 392 int offhook_line2_mib; 393 int offhook_line1; 394 int offhook_line2; 395 }; 396 397 static struct ac97_codec_if_vtbl ac97civ = { 398 ac97_mixer_get_port, 399 ac97_mixer_set_port, 400 ac97_query_devinfo, 401 ac97_get_portnum_by_name, 402 ac97_restore_shadow, 403 ac97_get_extcaps, 404 ac97_set_rate, 405 ac97_set_clock, 406 ac97_detach, 407 }; 408 409 static const struct ac97_codecid { 410 uint32_t id; 411 uint32_t mask; 412 const char *name; 413 void (*init)(struct ac97_softc *); 414 } ac97codecid[] = { 415 /* 416 * Analog Devices SoundMAX 417 * http://www.soundmax.com/products/information/codecs.html 418 * http://www.analog.com/productSelection/pdf/AD1881A_0.pdf 419 * http://www.analog.com/productSelection/pdf/AD1885_0.pdf 420 * http://www.analog.com/UploadedFiles/Data_Sheets/206585810AD1980_0.pdf 421 * http://www.analog.com/productSelection/pdf/AD1981A_0.pdf 422 * http://www.analog.com/productSelection/pdf/AD1981B_0.pdf 423 * http://www.analog.com/UploadedFiles/Data_Sheets/180644528AD1985_0.pdf 424 */ 425 { AC97_CODEC_ID('A', 'D', 'S', 3), 426 0xffffffff, "Analog Devices AD1819B" }, 427 { AC97_CODEC_ID('A', 'D', 'S', 0x40), 428 0xffffffff, "Analog Devices AD1881" }, 429 { AC97_CODEC_ID('A', 'D', 'S', 0x48), 430 0xffffffff, "Analog Devices AD1881A" }, 431 { AC97_CODEC_ID('A', 'D', 'S', 0x60), 432 0xffffffff, "Analog Devices AD1885" }, 433 { AC97_CODEC_ID('A', 'D', 'S', 0x61), 434 0xffffffff, "Analog Devices AD1886" }, 435 { AC97_CODEC_ID('A', 'D', 'S', 0x63), 436 0xffffffff, "Analog Devices AD1886A" }, 437 { AC97_CODEC_ID('A', 'D', 'S', 0x68), 438 0xffffffff, "Analog Devices AD1888", ac97_ad198x_init }, 439 { AC97_CODEC_ID('A', 'D', 'S', 0x70), 440 0xffffffff, "Analog Devices AD1980", ac97_ad198x_init }, 441 { AC97_CODEC_ID('A', 'D', 'S', 0x72), 442 0xffffffff, "Analog Devices AD1981A" }, 443 { AC97_CODEC_ID('A', 'D', 'S', 0x74), 444 0xffffffff, "Analog Devices AD1981B" }, 445 { AC97_CODEC_ID('A', 'D', 'S', 0x75), 446 0xffffffff, "Analog Devices AD1985", ac97_ad198x_init }, 447 { AC97_CODEC_ID('A', 'D', 'S', 0), 448 AC97_VENDOR_ID_MASK, "Analog Devices unknown" }, 449 450 /* 451 * Datasheets: 452 * http://www.asahi-kasei.co.jp/akm/japanese/product/ak4543/ek4543.pdf 453 * http://www.asahi-kasei.co.jp/akm/japanese/product/ak4544a/ek4544a.pdf 454 * http://www.asahi-kasei.co.jp/akm/japanese/product/ak4545/ak4545_f00e.pdf 455 */ 456 { AC97_CODEC_ID('A', 'K', 'M', 0), 457 0xffffffff, "Asahi Kasei AK4540" }, 458 { AC97_CODEC_ID('A', 'K', 'M', 1), 459 0xffffffff, "Asahi Kasei AK4542" }, 460 { AC97_CODEC_ID('A', 'K', 'M', 2), 461 0xffffffff, "Asahi Kasei AK4541/AK4543" }, 462 { AC97_CODEC_ID('A', 'K', 'M', 5), 463 0xffffffff, "Asahi Kasei AK4544" }, 464 { AC97_CODEC_ID('A', 'K', 'M', 6), 465 0xffffffff, "Asahi Kasei AK4544A" }, 466 { AC97_CODEC_ID('A', 'K', 'M', 7), 467 0xffffffff, "Asahi Kasei AK4545" }, 468 { AC97_CODEC_ID('A', 'K', 'M', 0), 469 AC97_VENDOR_ID_MASK, "Asahi Kasei unknown" }, 470 471 /* 472 * Realtek & Avance Logic 473 * http://www.realtek.com.tw/downloads/downloads1-3.aspx?lineid=5&famid=All&series=All&Spec=True 474 * 475 * ALC650 and ALC658 support VRA, but it supports only 8000, 11025, 476 * 12000, 16000, 22050, 24000, 32000, 44100, and 48000 Hz. 477 */ 478 { AC97_CODEC_ID('A', 'L', 'C', 0x00), 479 0xfffffff0, "Realtek RL5306" }, 480 { AC97_CODEC_ID('A', 'L', 'C', 0x10), 481 0xfffffff0, "Realtek RL5382" }, 482 { AC97_CODEC_ID('A', 'L', 'C', 0x20), 483 0xfffffff0, "Realtek RL5383/RL5522/ALC100" }, 484 { AC97_CODEC_ID('A', 'L', 'G', 0x10), 485 0xffffffff, "Avance Logic ALC200/ALC201" }, 486 { AC97_CODEC_ID('A', 'L', 'G', 0x20), 487 0xfffffff0, "Avance Logic ALC650", ac97_alc650_init }, 488 { AC97_CODEC_ID('A', 'L', 'G', 0x30), 489 0xffffffff, "Avance Logic ALC101" }, 490 { AC97_CODEC_ID('A', 'L', 'G', 0x40), 491 0xffffffff, "Avance Logic ALC202" }, 492 { AC97_CODEC_ID('A', 'L', 'G', 0x50), 493 0xffffffff, "Avance Logic ALC250" }, 494 { AC97_CODEC_ID('A', 'L', 'G', 0x60), 495 0xfffffff0, "Avance Logic ALC655" }, 496 { AC97_CODEC_ID('A', 'L', 'G', 0x80), 497 0xfffffff0, "Avance Logic ALC658" }, 498 { AC97_CODEC_ID('A', 'L', 'G', 0x90), 499 0xfffffff0, "Avance Logic ALC850" }, 500 { AC97_CODEC_ID('A', 'L', 'C', 0), 501 AC97_VENDOR_ID_MASK, "Realtek unknown" }, 502 { AC97_CODEC_ID('A', 'L', 'G', 0), 503 AC97_VENDOR_ID_MASK, "Avance Logic unknown" }, 504 505 /** 506 * C-Media Electronics Inc. 507 * http://www.cmedia.com.tw/doc/CMI9739%206CH%20Audio%20Codec%20SPEC_Ver12.pdf 508 */ 509 { AC97_CODEC_ID('C', 'M', 'I', 0x61), 510 0xffffffff, "C-Media CMI9739" }, 511 { AC97_CODEC_ID('C', 'M', 'I', 0), 512 AC97_VENDOR_ID_MASK, "C-Media unknown" }, 513 514 /* Cirrus Logic, Crystal series: 515 * 'C' 'R' 'Y' 0x0[0-7] - CS4297 516 * 0x1[0-7] - CS4297A 517 * 0x2[0-7] - CS4298 518 * 0x2[8-f] - CS4294 519 * 0x3[0-7] - CS4299 520 * 0x4[8-f] - CS4201 521 * 0x5[8-f] - CS4205 522 * 0x6[0-7] - CS4291 523 * 0x7[0-7] - CS4202 524 * Datasheets: 525 * http://www.cirrus.com/pubs/cs4297A-5.pdf?DocumentID=593 526 * http://www.cirrus.com/pubs/cs4294.pdf?DocumentID=32 527 * http://www.cirrus.com/pubs/cs4299-5.pdf?DocumentID=594 528 * http://www.cirrus.com/pubs/cs4201-2.pdf?DocumentID=492 529 * http://www.cirrus.com/pubs/cs4205-2.pdf?DocumentID=492 530 * http://www.cirrus.com/pubs/cs4202-1.pdf?DocumentID=852 531 */ 532 { AC97_CODEC_ID('C', 'R', 'Y', 0x00), 533 0xfffffff8, "Crystal CS4297", }, 534 { AC97_CODEC_ID('C', 'R', 'Y', 0x10), 535 0xfffffff8, "Crystal CS4297A", }, 536 { AC97_CODEC_ID('C', 'R', 'Y', 0x20), 537 0xfffffff8, "Crystal CS4298", }, 538 { AC97_CODEC_ID('C', 'R', 'Y', 0x28), 539 0xfffffff8, "Crystal CS4294", }, 540 { AC97_CODEC_ID('C', 'R', 'Y', 0x30), 541 0xfffffff8, "Crystal CS4299", }, 542 { AC97_CODEC_ID('C', 'R', 'Y', 0x48), 543 0xfffffff8, "Crystal CS4201", }, 544 { AC97_CODEC_ID('C', 'R', 'Y', 0x58), 545 0xfffffff8, "Crystal CS4205", }, 546 { AC97_CODEC_ID('C', 'R', 'Y', 0x60), 547 0xfffffff8, "Crystal CS4291", }, 548 { AC97_CODEC_ID('C', 'R', 'Y', 0x70), 549 0xfffffff8, "Crystal CS4202", }, 550 { AC97_CODEC_ID('C', 'R', 'Y', 0), 551 AC97_VENDOR_ID_MASK, "Cirrus Logic unknown", }, 552 553 { 0x45838308, 0xffffffff, "ESS Technology ES1921", }, 554 { 0x45838300, AC97_VENDOR_ID_MASK, "ESS Technology unknown", }, 555 556 { AC97_CODEC_ID('H', 'R', 'S', 0), 557 0xffffffff, "Intersil HMP9701", }, 558 { AC97_CODEC_ID('H', 'R', 'S', 0), 559 AC97_VENDOR_ID_MASK, "Intersil unknown", }, 560 561 /* 562 * IC Ensemble (VIA) 563 * http://www.viatech.com/en/datasheet/DS1616.pdf 564 */ 565 { AC97_CODEC_ID('I', 'C', 'E', 0x01), 566 0xffffffff, "ICEnsemble ICE1230/VT1611", }, 567 { AC97_CODEC_ID('I', 'C', 'E', 0x11), 568 0xffffffff, "ICEnsemble ICE1232/VT1611A", }, 569 { AC97_CODEC_ID('I', 'C', 'E', 0x14), 570 0xffffffff, "ICEnsemble ICE1232A", }, 571 { AC97_CODEC_ID('I', 'C', 'E', 0x51), 572 0xffffffff, "VIA Technologies VT1616", ac97_vt1616_init }, 573 { AC97_CODEC_ID('I', 'C', 'E', 0x52), 574 0xffffffff, "VIA Technologies VT1616i", ac97_vt1616_init }, 575 { AC97_CODEC_ID('I', 'C', 'E', 0), 576 AC97_VENDOR_ID_MASK, "ICEnsemble/VIA unknown", }, 577 578 { AC97_CODEC_ID('N', 'S', 'C', 0), 579 0xffffffff, "National Semiconductor LM454[03568]", }, 580 { AC97_CODEC_ID('N', 'S', 'C', 49), 581 0xffffffff, "National Semiconductor LM4549", }, 582 { AC97_CODEC_ID('N', 'S', 'C', 0), 583 AC97_VENDOR_ID_MASK, "National Semiconductor unknown", }, 584 585 { AC97_CODEC_ID('P', 'S', 'C', 4), 586 0xffffffff, "Philips Semiconductor UCB1400", }, 587 { AC97_CODEC_ID('P', 'S', 'C', 0), 588 AC97_VENDOR_ID_MASK, "Philips Semiconductor unknown", }, 589 590 { AC97_CODEC_ID('S', 'I', 'L', 34), 591 0xffffffff, "Silicon Laboratory Si3036", }, 592 { AC97_CODEC_ID('S', 'I', 'L', 35), 593 0xffffffff, "Silicon Laboratory Si3038", }, 594 { AC97_CODEC_ID('S', 'I', 'L', 0), 595 AC97_VENDOR_ID_MASK, "Silicon Laboratory unknown", }, 596 597 { AC97_CODEC_ID('T', 'R', 'A', 2), 598 0xffffffff, "TriTech TR28022", }, 599 { AC97_CODEC_ID('T', 'R', 'A', 3), 600 0xffffffff, "TriTech TR28023", }, 601 { AC97_CODEC_ID('T', 'R', 'A', 6), 602 0xffffffff, "TriTech TR28026", }, 603 { AC97_CODEC_ID('T', 'R', 'A', 8), 604 0xffffffff, "TriTech TR28028", }, 605 { AC97_CODEC_ID('T', 'R', 'A', 35), 606 0xffffffff, "TriTech TR28602", }, 607 { AC97_CODEC_ID('T', 'R', 'A', 0), 608 AC97_VENDOR_ID_MASK, "TriTech unknown", }, 609 610 { AC97_CODEC_ID('T', 'X', 'N', 0x20), 611 0xffffffff, "Texas Instruments TLC320AD9xC", }, 612 { AC97_CODEC_ID('T', 'X', 'N', 0), 613 AC97_VENDOR_ID_MASK, "Texas Instruments unknown", }, 614 615 /* 616 * VIA 617 * http://www.viatech.com/en/multimedia/audio.jsp 618 */ 619 { AC97_CODEC_ID('V', 'I', 'A', 0x61), 620 0xffffffff, "VIA Technologies VT1612A", }, 621 { AC97_CODEC_ID('V', 'I', 'A', 0), 622 AC97_VENDOR_ID_MASK, "VIA Technologies unknown", }, 623 624 { AC97_CODEC_ID('W', 'E', 'C', 1), 625 0xffffffff, "Winbond W83971D", }, 626 { AC97_CODEC_ID('W', 'E', 'C', 0), 627 AC97_VENDOR_ID_MASK, "Winbond unknown", }, 628 629 /* 630 * http://www.wolfsonmicro.com/product_list.asp?cid=64 631 * http://www.wolfsonmicro.com/download.asp/did.56/WM9701A.pdf - 00 632 * http://www.wolfsonmicro.com/download.asp/did.57/WM9703.pdf - 03 633 * http://www.wolfsonmicro.com/download.asp/did.58/WM9704M.pdf - 04 634 * http://www.wolfsonmicro.com/download.asp/did.59/WM9704Q.pdf - 04 635 * http://www.wolfsonmicro.com/download.asp/did.184/WM9705_Rev34.pdf - 05 636 * http://www.wolfsonmicro.com/download.asp/did.60/WM9707.pdf - 03 637 * http://www.wolfsonmicro.com/download.asp/did.136/WM9708.pdf - 03 638 * http://www.wolfsonmicro.com/download.asp/did.243/WM9710.pdf - 05 639 */ 640 { AC97_CODEC_ID('W', 'M', 'L', 0), 641 0xffffffff, "Wolfson WM9701A", }, 642 { AC97_CODEC_ID('W', 'M', 'L', 3), 643 0xffffffff, "Wolfson WM9703/WM9707/WM9708", }, 644 { AC97_CODEC_ID('W', 'M', 'L', 4), 645 0xffffffff, "Wolfson WM9704", }, 646 { AC97_CODEC_ID('W', 'M', 'L', 5), 647 0xffffffff, "Wolfson WM9705/WM9710", }, 648 { AC97_CODEC_ID('W', 'M', 'L', 0), 649 AC97_VENDOR_ID_MASK, "Wolfson unknown", }, 650 651 /* 652 * http://www.yamaha.co.jp/english/product/lsi/us/products/pcaudio.html 653 * Datasheets: 654 * http://www.yamaha.co.jp/english/product/lsi/us/products/pdf/4MF743A20.pdf 655 * http://www.yamaha.co.jp/english/product/lsi/us/products/pdf/4MF753A20.pdf 656 */ 657 { AC97_CODEC_ID('Y', 'M', 'H', 0), 658 0xffffffff, "Yamaha YMF743-S", }, 659 { AC97_CODEC_ID('Y', 'M', 'H', 3), 660 0xffffffff, "Yamaha YMF753-S", }, 661 { AC97_CODEC_ID('Y', 'M', 'H', 0), 662 AC97_VENDOR_ID_MASK, "Yamaha unknown", }, 663 664 /* 665 * http://www.sigmatel.com/products/technical_docs.htm 666 * and 667 * http://www.sigmatel.com/documents/c-major-brochure-9-0.pdf 668 */ 669 { 0x83847600, 0xffffffff, "SigmaTel STAC9700", }, 670 { 0x83847604, 0xffffffff, "SigmaTel STAC9701/3/4/5", }, 671 { 0x83847605, 0xffffffff, "SigmaTel STAC9704", }, 672 { 0x83847608, 0xffffffff, "SigmaTel STAC9708", }, 673 { 0x83847609, 0xffffffff, "SigmaTel STAC9721/23", }, 674 { 0x83847644, 0xffffffff, "SigmaTel STAC9744/45", }, 675 { 0x83847650, 0xffffffff, "SigmaTel STAC9750/51", }, 676 { 0x83847652, 0xffffffff, "SigmaTel STAC9752/53", }, 677 { 0x83847656, 0xffffffff, "SigmaTel STAC9756/57", }, 678 { 0x83847658, 0xffffffff, "SigmaTel STAC9758/59", }, 679 { 0x83847666, 0xffffffff, "SigmaTel STAC9766/67", }, 680 { 0x83847684, 0xffffffff, "SigmaTel STAC9783/84", }, 681 { 0x83847600, AC97_VENDOR_ID_MASK, "SigmaTel unknown", }, 682 683 /* Conexant AC'97 modems -- good luck finding datasheets! */ 684 { AC97_CODEC_ID('C', 'X', 'T', 33), 685 0xffffffff, "Conexant HSD11246", }, 686 { AC97_CODEC_ID('C', 'X', 'T', 34), 687 0xffffffff, "Conexant D480 MDC V.92 Modem", }, 688 { AC97_CODEC_ID('C', 'X', 'T', 48), 689 0xffffffff, "Conexant CXT48", }, 690 { AC97_CODEC_ID('C', 'X', 'T', 0), 691 AC97_VENDOR_ID_MASK, "Conexant unknown", }, 692 693 { 0, 694 0, NULL, } 695 }; 696 697 static const char * const ac97enhancement[] = { 698 "no 3D stereo", 699 "Analog Devices Phat Stereo", 700 "Creative", 701 "National Semi 3D", 702 "Yamaha Ymersion", 703 "BBE 3D", 704 "Crystal Semi 3D", 705 "Qsound QXpander", 706 "Spatializer 3D", 707 "SRS 3D", 708 "Platform Tech 3D", 709 "AKM 3D", 710 "Aureal", 711 "AZTECH 3D", 712 "Binaura 3D", 713 "ESS Technology", 714 "Harman International VMAx", 715 "Nvidea 3D", 716 "Philips Incredible Sound", 717 "Texas Instruments' 3D", 718 "VLSI Technology 3D", 719 "TriTech 3D", 720 "Realtek 3D", 721 "Samsung 3D", 722 "Wolfson Microelectronics 3D", 723 "Delta Integration 3D", 724 "SigmaTel 3D", 725 "KS Waves 3D", 726 "Rockwell 3D", 727 "Unknown 3D", 728 "Unknown 3D", 729 "Unknown 3D", 730 }; 731 732 static const char * const ac97feature[] = { 733 "dedicated mic channel", 734 "reserved", 735 "tone", 736 "simulated stereo", 737 "headphone", 738 "bass boost", 739 "18 bit DAC", 740 "20 bit DAC", 741 "18 bit ADC", 742 "20 bit ADC" 743 }; 744 745 746 /* #define AC97_DEBUG 10 */ 747 /* #define AC97_IO_DEBUG */ 748 749 #ifdef AUDIO_DEBUG 750 #define DPRINTF(x) if (ac97debug) printf x 751 #define DPRINTFN(n,x) if (ac97debug>(n)) printf x 752 #ifdef AC97_DEBUG 753 int ac97debug = AC97_DEBUG; 754 #else 755 int ac97debug = 0; 756 #endif 757 #else 758 #define DPRINTF(x) 759 #define DPRINTFN(n,x) 760 #endif 761 762 #ifdef AC97_IO_DEBUG 763 static const char *ac97_register_names[0x80 / 2] = { 764 "RESET", "MASTER_VOLUME", "HEADPHONE_VOLUME", "MASTER_VOLUME_MONO", 765 "MASTER_TONE", "PCBEEP_VOLUME", "PHONE_VOLUME", "MIC_VOLUME", 766 "LINEIN_VOLUME", "CD_VOLUME", "VIDEO_VOLUME", "AUX_VOLUME", 767 "PCMOUT_VOLUME", "RECORD_SELECT", "RECORD_GATIN", "RECORD_GAIN_MIC", 768 "GP", "3D_CONTROL", "AUDIO_INT", "POWER", 769 "EXT_AUDIO_ID", "EXT_AUDIO_CTRL", "PCM_FRONT_DAC_RATE", "PCM_SURR_DAC_RATE", 770 "PCM_LFE_DAC_RATE", "PCM_LR_ADC_RATE", "PCM_MIC_ADC_RATE", "CENTER_LFE_MASTER", 771 "SURR_MASTER", "SPDIF_CTRL", "EXT_MODEM_ID", "EXT_MODEM_CTRL", 772 "LINE1_RATE", "LINE2_RATE", "HANDSET_RATE", "LINE1_LEVEL", 773 "LINE2_LEVEL", "HANDSET_LEVEL", "GPIO_PIN_CONFIG", "GPIO_PIN_POLARITY", 774 "GPIO_PIN_STICKY", "GPIO_PIN_WAKEUP", "GPIO_PIN_STATUS", "MISC_MODEM_CTRL", 775 "0x58", "VENDOR-5A", "VENDOR-5C", "VENDOR-5E", 776 "0x60", "0x62", "0x64", "0x66", 777 "0x68", "0x6a", "0x6c", "0x6e", 778 "VENDOR-70", "VENDOR-72", "VENDOR-74", "VENDOR-76", 779 "VENDOR-78", "VENDOR-7A", "VENDOR_ID1", "VENDOR_ID2" 780 }; 781 #endif 782 783 /* 784 * XXX Some cards have an inverted AC97_POWER_EAMP bit. 785 * These cards will produce no sound unless AC97_HOST_INVERTED_EAMP is set. 786 */ 787 788 #define POWER_EAMP_ON(as) ((as->host_flags & AC97_HOST_INVERTED_EAMP) \ 789 ? AC97_POWER_EAMP : 0) 790 #define POWER_EAMP_OFF(as) ((as->host_flags & AC97_HOST_INVERTED_EAMP) \ 791 ? 0 : AC97_POWER_EAMP) 792 793 static void 794 ac97_read(struct ac97_softc *as, uint8_t reg, uint16_t *val) 795 { 796 if (as->host_flags & AC97_HOST_DONT_READ && 797 (reg != AC97_REG_VENDOR_ID1 && reg != AC97_REG_VENDOR_ID2 && 798 reg != AC97_REG_RESET)) { 799 *val = as->shadow_reg[reg >> 1]; 800 return; 801 } 802 803 if (as->host_if->read(as->host_if->arg, reg, val)) { 804 *val = as->shadow_reg[reg >> 1]; 805 } 806 } 807 808 static int 809 ac97_write(struct ac97_softc *as, uint8_t reg, uint16_t val) 810 { 811 #ifndef AC97_IO_DEBUG 812 as->shadow_reg[reg >> 1] = val; 813 return as->host_if->write(as->host_if->arg, reg, val); 814 #else 815 int ret; 816 uint16_t actual; 817 818 as->shadow_reg[reg >> 1] = val; 819 ret = as->host_if->write(as->host_if->arg, reg, val); 820 as->host_if->read(as->host_if->arg, reg, &actual); 821 if (val != actual && reg < 0x80) { 822 printf("ac97_write: reg=%s, written=0x%04x, read=0x%04x\n", 823 ac97_register_names[reg / 2], val, actual); 824 } 825 return ret; 826 #endif 827 } 828 829 static void 830 ac97_setup_defaults(struct ac97_softc *as) 831 { 832 int idx; 833 const struct ac97_source_info *si; 834 835 memset(as->shadow_reg, 0, sizeof(as->shadow_reg)); 836 837 for (idx = 0; idx < AUDIO_SOURCE_INFO_SIZE; idx++) { 838 si = &audio_source_info[idx]; 839 ac97_write(as, si->reg, si->default_value); 840 } 841 for (idx = 0; idx < MODEM_SOURCE_INFO_SIZE; idx++) { 842 si = &modem_source_info[idx]; 843 ac97_write(as, si->reg, si->default_value); 844 } 845 } 846 847 static void 848 ac97_restore_shadow(struct ac97_codec_if *self) 849 { 850 struct ac97_softc *as; 851 const struct ac97_source_info *si; 852 int idx; 853 uint16_t val; 854 855 as = (struct ac97_softc *) self; 856 857 if (as->type == AC97_CODEC_TYPE_AUDIO) { 858 /* restore AC97_REG_POWER */ 859 ac97_write(as, AC97_REG_POWER, as->power_reg); 860 /* make sure chip is fully operational */ 861 for (idx = 50000; idx >= 0; idx--) { 862 ac97_read(as, AC97_REG_POWER, &val); 863 if ((val & as->power_all) == as->power_all) 864 break; 865 DELAY(10); 866 } 867 868 /* 869 * actually try changing a value! 870 * The default value of AC97_REG_MASTER_VOLUME is 0x8000. 871 */ 872 for (idx = 50000; idx >= 0; idx--) { 873 ac97_write(as, AC97_REG_MASTER_VOLUME, 0x1010); 874 ac97_read(as, AC97_REG_MASTER_VOLUME, &val); 875 if (val == 0x1010) 876 break; 877 DELAY(10); 878 } 879 } 880 881 for (idx = 0; idx < SOURCE_INFO_SIZE(as); idx++) { 882 if (as->type == AC97_CODEC_TYPE_MODEM) 883 si = &modem_source_info[idx]; 884 else 885 si = &audio_source_info[idx]; 886 /* don't "restore" to the reset reg! */ 887 if (si->reg != AC97_REG_RESET) 888 ac97_write(as, si->reg, as->shadow_reg[si->reg >> 1]); 889 } 890 891 if (as->ext_id & (AC97_EXT_AUDIO_VRA | AC97_EXT_AUDIO_DRA 892 | AC97_EXT_AUDIO_SPDIF | AC97_EXT_AUDIO_VRM 893 | AC97_EXT_AUDIO_CDAC | AC97_EXT_AUDIO_SDAC 894 | AC97_EXT_AUDIO_LDAC)) { 895 ac97_write(as, AC97_REG_EXT_AUDIO_CTRL, 896 as->shadow_reg[AC97_REG_EXT_AUDIO_CTRL >> 1]); 897 } 898 if (as->ext_mid & (AC97_EXT_MODEM_LINE1 | AC97_EXT_MODEM_LINE2 899 | AC97_EXT_MODEM_HANDSET | AC97_EXT_MODEM_CID1 900 | AC97_EXT_MODEM_CID2 | AC97_EXT_MODEM_ID0 901 | AC97_EXT_MODEM_ID1)) { 902 ac97_write(as, AC97_REG_EXT_MODEM_CTRL, 903 as->shadow_reg[AC97_REG_EXT_MODEM_CTRL >> 1]); 904 } 905 } 906 907 static int 908 ac97_str_equal(const char *a, const char *b) 909 { 910 return (a == b) || (a && b && (!strcmp(a, b))); 911 } 912 913 static int 914 ac97_check_capability(struct ac97_softc *as, int check) 915 { 916 switch (check) { 917 case CHECK_NONE: 918 return 1; 919 case CHECK_SURROUND: 920 return as->ext_id & AC97_EXT_AUDIO_SDAC; 921 case CHECK_CENTER: 922 return as->ext_id & AC97_EXT_AUDIO_CDAC; 923 case CHECK_LFE: 924 return as->ext_id & AC97_EXT_AUDIO_LDAC; 925 case CHECK_HEADPHONES: 926 return as->caps & AC97_CAPS_HEADPHONES; 927 case CHECK_TONE: 928 return as->caps & AC97_CAPS_TONECTRL; 929 case CHECK_MIC: 930 return as->caps & AC97_CAPS_MICIN; 931 case CHECK_LOUDNESS: 932 return as->caps & AC97_CAPS_LOUDNESS; 933 case CHECK_3D: 934 return AC97_CAPS_ENHANCEMENT(as->caps) != 0; 935 case CHECK_LINE1: 936 return as->ext_mid & AC97_EXT_MODEM_LINE1; 937 case CHECK_LINE2: 938 return as->ext_mid & AC97_EXT_MODEM_LINE2; 939 case CHECK_HANDSET: 940 return as->ext_mid & AC97_EXT_MODEM_HANDSET; 941 default: 942 printf("%s: internal error: feature=%d\n", __func__, check); 943 return 0; 944 } 945 } 946 947 static void 948 ac97_setup_source_info(struct ac97_softc *as) 949 { 950 int idx, ouridx; 951 struct ac97_source_info *si, *si2; 952 953 for (idx = 0, ouridx = 0; idx < SOURCE_INFO_SIZE(as); idx++) { 954 si = &as->source_info[ouridx]; 955 if (as->type == AC97_CODEC_TYPE_MODEM) { 956 if (!ac97_check_capability(as, 957 modem_source_info[idx].req_feature)) 958 continue; 959 memcpy(si, &modem_source_info[idx], sizeof(*si)); 960 } else { 961 if (!ac97_check_capability(as, 962 audio_source_info[idx].req_feature)) 963 continue; 964 memcpy(si, &audio_source_info[idx], sizeof(*si)); 965 } 966 967 switch (si->type) { 968 case AUDIO_MIXER_CLASS: 969 si->mixer_class = ouridx; 970 ouridx++; 971 break; 972 case AUDIO_MIXER_VALUE: 973 /* Todo - Test to see if it works */ 974 ouridx++; 975 976 /* Add an entry for mute, if necessary */ 977 if (si->mute) { 978 si = &as->source_info[ouridx]; 979 if (as->type == AC97_CODEC_TYPE_MODEM) 980 memcpy(si, &modem_source_info[idx], 981 sizeof(*si)); 982 else 983 memcpy(si, &audio_source_info[idx], 984 sizeof(*si)); 985 si->qualifier = AudioNmute; 986 si->type = AUDIO_MIXER_ENUM; 987 si->info = &ac97_on_off; 988 si->info_size = sizeof(ac97_on_off); 989 si->bits = 1; 990 si->ofs = 15; 991 si->mute = 0; 992 si->polarity = 0; 993 ouridx++; 994 } 995 break; 996 case AUDIO_MIXER_ENUM: 997 /* Todo - Test to see if it works */ 998 ouridx++; 999 break; 1000 default: 1001 aprint_error ("ac97: shouldn't get here\n"); 1002 break; 1003 } 1004 } 1005 1006 as->num_source_info = ouridx; 1007 1008 for (idx = 0; idx < as->num_source_info; idx++) { 1009 int idx2, previdx; 1010 1011 si = &as->source_info[idx]; 1012 1013 /* Find mixer class */ 1014 for (idx2 = 0; idx2 < as->num_source_info; idx2++) { 1015 si2 = &as->source_info[idx2]; 1016 1017 if (si2->type == AUDIO_MIXER_CLASS && 1018 ac97_str_equal(si->class, 1019 si2->class)) { 1020 si->mixer_class = idx2; 1021 } 1022 } 1023 1024 1025 /* Setup prev and next pointers */ 1026 if (si->prev != 0) 1027 continue; 1028 1029 if (si->qualifier) 1030 continue; 1031 1032 si->prev = AUDIO_MIXER_LAST; 1033 previdx = idx; 1034 1035 for (idx2 = 0; idx2 < as->num_source_info; idx2++) { 1036 if (idx2 == idx) 1037 continue; 1038 1039 si2 = &as->source_info[idx2]; 1040 1041 if (!si2->prev && 1042 ac97_str_equal(si->class, si2->class) && 1043 ac97_str_equal(si->device, si2->device)) { 1044 as->source_info[previdx].next = idx2; 1045 as->source_info[idx2].prev = previdx; 1046 1047 previdx = idx2; 1048 } 1049 } 1050 1051 as->source_info[previdx].next = AUDIO_MIXER_LAST; 1052 } 1053 } 1054 1055 /* backward compatibility */ 1056 int 1057 ac97_attach(struct ac97_host_if *host_if, struct device *sc_dev) 1058 { 1059 return ac97_attach_type(host_if, sc_dev, AC97_CODEC_TYPE_AUDIO); 1060 } 1061 1062 int 1063 ac97_attach_type(struct ac97_host_if *host_if, struct device *sc_dev, int type) 1064 { 1065 struct ac97_softc *as; 1066 int error, i, j; 1067 uint32_t id; 1068 uint16_t id1, id2; 1069 uint16_t extstat, rate; 1070 uint16_t val; 1071 mixer_ctrl_t ctl; 1072 void (*initfunc)(struct ac97_softc *); 1073 #define FLAGBUFLEN 140 1074 char flagbuf[FLAGBUFLEN]; 1075 1076 initfunc = NULL; 1077 as = malloc(sizeof(struct ac97_softc), M_DEVBUF, M_WAITOK|M_ZERO); 1078 1079 if (as == NULL) 1080 return ENOMEM; 1081 1082 as->codec_if.vtbl = &ac97civ; 1083 as->host_if = host_if; 1084 as->type = type; 1085 1086 if ((error = host_if->attach(host_if->arg, &as->codec_if))) { 1087 free(as, M_DEVBUF); 1088 return error; 1089 } 1090 1091 if (host_if->reset != NULL) { 1092 if ((error = host_if->reset(host_if->arg))) { 1093 free(as, M_DEVBUF); 1094 return error; 1095 } 1096 } 1097 1098 if (host_if->flags) 1099 as->host_flags = host_if->flags(host_if->arg); 1100 1101 /* 1102 * Assume codec has all four power bits. 1103 * XXXSCW: what to do for modems? 1104 */ 1105 as->power_all = AC97_POWER_REF | AC97_POWER_ANL | AC97_POWER_DAC | 1106 AC97_POWER_ADC; 1107 if (as->type == AC97_CODEC_TYPE_AUDIO) { 1108 host_if->write(host_if->arg, AC97_REG_RESET, 0); 1109 1110 /* 1111 * Power-up everything except the analogue mixer. 1112 * If this codec doesn't support analogue mixer power-down, 1113 * AC97_POWER_MIXER will read back as zero. 1114 */ 1115 host_if->write(host_if->arg, AC97_REG_POWER, AC97_POWER_MIXER); 1116 ac97_read(as, AC97_REG_POWER, &val); 1117 if ((val & AC97_POWER_MIXER) == 0) { 1118 /* Codec doesn't support analogue mixer power-down */ 1119 as->power_all &= ~AC97_POWER_ANL; 1120 } 1121 host_if->write(host_if->arg, AC97_REG_POWER, POWER_EAMP_ON(as)); 1122 1123 for (i = 500000; i >= 0; i--) { 1124 ac97_read(as, AC97_REG_POWER, &val); 1125 if ((val & as->power_all) == as->power_all) 1126 break; 1127 DELAY(1); 1128 } 1129 1130 /* save AC97_REG_POWER so that we can restore it later */ 1131 ac97_read(as, AC97_REG_POWER, &as->power_reg); 1132 } else if (as->type == AC97_CODEC_TYPE_MODEM) { 1133 host_if->write(host_if->arg, AC97_REG_EXT_MODEM_ID, 0); 1134 } 1135 1136 ac97_setup_defaults(as); 1137 if (as->type == AC97_CODEC_TYPE_AUDIO) 1138 ac97_read(as, AC97_REG_RESET, &as->caps); 1139 ac97_read(as, AC97_REG_VENDOR_ID1, &id1); 1140 ac97_read(as, AC97_REG_VENDOR_ID2, &id2); 1141 1142 id = (id1 << 16) | id2; 1143 aprint_normal("%s: ac97: ", sc_dev->dv_xname); 1144 1145 for (i = 0; ; i++) { 1146 if (ac97codecid[i].id == 0) { 1147 char pnp[4]; 1148 1149 AC97_GET_CODEC_ID(id, pnp); 1150 #define ISASCII(c) ((c) >= ' ' && (c) < 0x7f) 1151 if (ISASCII(pnp[0]) && ISASCII(pnp[1]) && 1152 ISASCII(pnp[2])) 1153 aprint_normal("%c%c%c%d", 1154 pnp[0], pnp[1], pnp[2], pnp[3]); 1155 else 1156 aprint_normal("unknown (0x%08x)", id); 1157 break; 1158 } 1159 if (ac97codecid[i].id == (id & ac97codecid[i].mask)) { 1160 aprint_normal("%s", ac97codecid[i].name); 1161 if (ac97codecid[i].mask == AC97_VENDOR_ID_MASK) { 1162 aprint_normal(" (0x%08x)", id); 1163 } 1164 initfunc = ac97codecid[i].init; 1165 break; 1166 } 1167 } 1168 aprint_normal(" codec; "); 1169 for (i = j = 0; i < 10; i++) { 1170 if (as->caps & (1 << i)) { 1171 aprint_normal("%s%s", j ? ", " : "", ac97feature[i]); 1172 j++; 1173 } 1174 } 1175 aprint_normal("%s%s\n", j ? ", " : "", 1176 ac97enhancement[AC97_CAPS_ENHANCEMENT(as->caps)]); 1177 1178 as->ac97_clock = AC97_STANDARD_CLOCK; 1179 1180 if (as->type == AC97_CODEC_TYPE_AUDIO) { 1181 ac97_read(as, AC97_REG_EXT_AUDIO_ID, &as->ext_id); 1182 if (as->ext_id != 0) { 1183 /* Print capabilities */ 1184 bitmask_snprintf(as->ext_id, 1185 "\20\20SECONDARY10\17SECONDARY01" 1186 "\14AC97_23\13AC97_22\12AMAP\11LDAC\10SDAC" 1187 "\7CDAC\4VRM\3SPDIF\2DRA\1VRA", 1188 flagbuf, FLAGBUFLEN); 1189 aprint_normal("%s: ac97: ext id %s\n", sc_dev->dv_xname, 1190 flagbuf); 1191 1192 /* Print unusual settings */ 1193 if (as->ext_id & AC97_EXT_AUDIO_DSA_MASK) { 1194 aprint_normal("%s: ac97: Slot assignment: ", 1195 sc_dev->dv_xname); 1196 switch (as->ext_id & AC97_EXT_AUDIO_DSA_MASK) { 1197 case AC97_EXT_AUDIO_DSA01: 1198 aprint_normal("7&8, 6&9, 10&11.\n"); 1199 break; 1200 case AC97_EXT_AUDIO_DSA10: 1201 aprint_normal("6&9, 10&11, 3&4.\n"); 1202 break; 1203 case AC97_EXT_AUDIO_DSA11: 1204 aprint_normal("10&11, 3&4, 7&8.\n"); 1205 break; 1206 } 1207 } 1208 if (as->host_flags & AC97_HOST_INVERTED_EAMP) { 1209 aprint_normal("%s: ac97: using inverted " 1210 "AC97_POWER_EAMP bit\n", 1211 sc_dev->dv_xname); 1212 } 1213 1214 /* Enable and disable features */ 1215 ac97_read(as, AC97_REG_EXT_AUDIO_CTRL, &extstat); 1216 extstat &= ~AC97_EXT_AUDIO_DRA; 1217 if (as->ext_id & AC97_EXT_AUDIO_LDAC) 1218 extstat |= AC97_EXT_AUDIO_LDAC; 1219 if (as->ext_id & AC97_EXT_AUDIO_SDAC) 1220 extstat |= AC97_EXT_AUDIO_SDAC; 1221 if (as->ext_id & AC97_EXT_AUDIO_CDAC) 1222 extstat |= AC97_EXT_AUDIO_CDAC; 1223 if (as->ext_id & AC97_EXT_AUDIO_VRM) 1224 extstat |= AC97_EXT_AUDIO_VRM; 1225 if (as->ext_id & AC97_EXT_AUDIO_SPDIF) { 1226 /* Output the same data as DAC to SPDIF output */ 1227 extstat &= ~AC97_EXT_AUDIO_SPSA_MASK; 1228 extstat |= AC97_EXT_AUDIO_SPSA34; 1229 } 1230 if (as->ext_id & AC97_EXT_AUDIO_VRA) 1231 extstat |= AC97_EXT_AUDIO_VRA; 1232 ac97_write(as, AC97_REG_EXT_AUDIO_CTRL, extstat); 1233 if (as->ext_id & AC97_EXT_AUDIO_VRA) { 1234 /* VRA should be enabled. */ 1235 /* so it claims to do variable rate, let's make sure */ 1236 ac97_write(as, AC97_REG_PCM_FRONT_DAC_RATE, 1237 44100); 1238 ac97_read(as, AC97_REG_PCM_FRONT_DAC_RATE, 1239 &rate); 1240 if (rate != 44100) { 1241 /* We can't believe ext_id */ 1242 as->ext_id = 0; 1243 aprint_normal( 1244 "%s: Ignore these capabilities.\n", 1245 sc_dev->dv_xname); 1246 } 1247 /* restore the default value */ 1248 ac97_write(as, AC97_REG_PCM_FRONT_DAC_RATE, 1249 AC97_SINGLE_RATE); 1250 } 1251 } 1252 } else if (as->type == AC97_CODEC_TYPE_MODEM) { 1253 const struct sysctlnode *node; 1254 const struct sysctlnode *node_line1; 1255 const struct sysctlnode *node_line2; 1256 uint16_t xrate = 8000; 1257 uint16_t xval, reg; 1258 int err; 1259 1260 ac97_read(as, AC97_REG_EXT_MODEM_ID, &as->ext_mid); 1261 if (as->ext_mid == 0 || as->ext_mid == 0xffff) { 1262 aprint_normal("%s: no modem codec found\n", 1263 sc_dev->dv_xname); 1264 return ENXIO; 1265 } 1266 as->type = AC97_CODEC_TYPE_MODEM; 1267 1268 /* Print capabilities */ 1269 bitmask_snprintf(as->ext_mid, 1270 "\20\5CID2\4CID1\3HANDSET\2LINE2\1LINE1", 1271 flagbuf, FLAGBUFLEN); 1272 aprint_normal("%s: ac97: ext mid %s", sc_dev->dv_xname, 1273 flagbuf); 1274 aprint_normal(", %s codec\n", 1275 (as->ext_mid & 0xc000) == 0 ? 1276 "primary" : "secondary"); 1277 1278 /* Setup modem and sysctls */ 1279 err = sysctl_createv(&as->log, 0, NULL, NULL, 0, CTLTYPE_NODE, 1280 "hw", NULL, NULL, 0, NULL, 0, CTL_HW, 1281 CTL_EOL); 1282 if (err != 0) 1283 goto setup_modem; 1284 err = sysctl_createv(&as->log, 0, NULL, &node, 0, 1285 CTLTYPE_NODE, sc_dev->dv_xname, NULL, 1286 NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, 1287 CTL_EOL); 1288 if (err != 0) 1289 goto setup_modem; 1290 setup_modem: 1291 /* reset */ 1292 ac97_write(as, AC97_REG_EXT_MODEM_ID, 1); 1293 1294 /* program rates */ 1295 xval = 0xff00 & ~AC97_EXT_MODEM_CTRL_PRA; 1296 if (as->ext_mid & AC97_EXT_MODEM_LINE1) { 1297 ac97_write(as, AC97_REG_LINE1_RATE, xrate); 1298 xval &= ~(AC97_EXT_MODEM_CTRL_PRC | 1299 AC97_EXT_MODEM_CTRL_PRD); 1300 } 1301 if (as->ext_mid & AC97_EXT_MODEM_LINE2) { 1302 ac97_write(as, AC97_REG_LINE2_RATE, xrate); 1303 xval &= ~(AC97_EXT_MODEM_CTRL_PRE | 1304 AC97_EXT_MODEM_CTRL_PRF); 1305 } 1306 if (as->ext_mid & AC97_EXT_MODEM_HANDSET) { 1307 ac97_write(as, AC97_REG_HANDSET_RATE, xrate); 1308 xval &= ~(AC97_EXT_MODEM_CTRL_PRG | 1309 AC97_EXT_MODEM_CTRL_PRH); 1310 } 1311 1312 /* power-up everything */ 1313 ac97_write(as, AC97_REG_EXT_MODEM_CTRL, 0); 1314 for (i = 5000; i >= 0; i--) { 1315 ac97_read(as, AC97_REG_EXT_MODEM_CTRL, ®); 1316 if ((reg & /*XXXval*/0xf) == /*XXXval*/0xf) 1317 break; 1318 DELAY(1); 1319 } 1320 if (i <= 0) { 1321 printf("%s: codec not responding, status=0x%x\n", 1322 sc_dev->dv_xname, reg); 1323 return ENXIO; 1324 } 1325 1326 /* setup sysctls */ 1327 if (as->ext_mid & AC97_EXT_MODEM_LINE1) { 1328 ac97_read(as, AC97_REG_GPIO_CFG, ®); 1329 reg &= ~AC97_GPIO_LINE1_OH; 1330 ac97_write(as, AC97_REG_GPIO_CFG, reg); 1331 ac97_read(as, AC97_REG_GPIO_POLARITY, ®); 1332 reg &= ~AC97_GPIO_LINE1_OH; 1333 ac97_write(as, AC97_REG_GPIO_POLARITY, reg); 1334 1335 err = sysctl_createv(&as->log, 0, NULL, &node_line1, 1336 CTLFLAG_READWRITE, CTLTYPE_INT, 1337 "line1", 1338 SYSCTL_DESCR("off-hook line1"), 1339 ac97_sysctl_verify, 0, as, 0, 1340 CTL_HW, node->sysctl_num, 1341 CTL_CREATE, CTL_EOL); 1342 if (err != 0) 1343 goto sysctl_err; 1344 as->offhook_line1_mib = node_line1->sysctl_num; 1345 } 1346 if (as->ext_mid & AC97_EXT_MODEM_LINE2) { 1347 ac97_read(as, AC97_REG_GPIO_CFG, ®); 1348 reg &= ~AC97_GPIO_LINE2_OH; 1349 ac97_write(as, AC97_REG_GPIO_CFG, reg); 1350 ac97_read(as, AC97_REG_GPIO_POLARITY, ®); 1351 reg &= ~AC97_GPIO_LINE2_OH; 1352 ac97_write(as, AC97_REG_GPIO_POLARITY, reg); 1353 1354 err = sysctl_createv(&as->log, 0, NULL, &node_line2, 1355 CTLFLAG_READWRITE, CTLTYPE_INT, 1356 "line2", 1357 SYSCTL_DESCR("off-hook line2"), 1358 ac97_sysctl_verify, 0, as, 0, 1359 CTL_HW, node->sysctl_num, 1360 CTL_CREATE, CTL_EOL); 1361 if (err != 0) 1362 goto sysctl_err; 1363 as->offhook_line2_mib = node_line2->sysctl_num; 1364 } 1365 sysctl_err: 1366 1367 ac97_write(as, AC97_REG_GPIO_STICKY, 0xffff); 1368 ac97_write(as, AC97_REG_GPIO_WAKEUP, 0x0); 1369 ac97_write(as, AC97_REG_MISC_AFE, 0x0); 1370 } 1371 1372 as->source_info = (as->type == AC97_CODEC_TYPE_MODEM ? 1373 as->modem_source_info : as->audio_source_info); 1374 ac97_setup_source_info(as); 1375 1376 memset(&ctl, 0, sizeof(ctl)); 1377 /* disable mutes */ 1378 for (i = 0; i < 11; i++) { 1379 static struct { 1380 const char *class, *device; 1381 } d[11] = { 1382 { AudioCoutputs, AudioNmaster}, 1383 { AudioCoutputs, AudioNheadphone}, 1384 { AudioCoutputs, AudioNsurround}, 1385 { AudioCoutputs, AudioNcenter}, 1386 { AudioCoutputs, AudioNlfe}, 1387 { AudioCinputs, AudioNdac}, 1388 { AudioCinputs, AudioNcd}, 1389 { AudioCinputs, AudioNline}, 1390 { AudioCinputs, AudioNaux}, 1391 { AudioCinputs, AudioNvideo}, 1392 { AudioCrecord, AudioNvolume}, 1393 }; 1394 1395 ctl.type = AUDIO_MIXER_ENUM; 1396 ctl.un.ord = 0; 1397 1398 ctl.dev = ac97_get_portnum_by_name(&as->codec_if, 1399 d[i].class, d[i].device, AudioNmute); 1400 ac97_mixer_set_port(&as->codec_if, &ctl); 1401 } 1402 ctl.type = AUDIO_MIXER_ENUM; 1403 ctl.un.ord = 0; 1404 ctl.dev = ac97_get_portnum_by_name(&as->codec_if, AudioCrecord, 1405 AudioNsource, NULL); 1406 ac97_mixer_set_port(&as->codec_if, &ctl); 1407 1408 /* set a reasonable default volume */ 1409 ctl.type = AUDIO_MIXER_VALUE; 1410 ctl.un.value.num_channels = 2; 1411 ctl.un.value.level[AUDIO_MIXER_LEVEL_LEFT] = \ 1412 ctl.un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = 127; 1413 ctl.dev = ac97_get_portnum_by_name(&as->codec_if, AudioCoutputs, 1414 AudioNmaster, NULL); 1415 ac97_mixer_set_port(&as->codec_if, &ctl); 1416 ctl.dev = ac97_get_portnum_by_name(&as->codec_if, AudioCoutputs, 1417 AudioNsurround, NULL); 1418 ac97_mixer_set_port(&as->codec_if, &ctl); 1419 ctl.un.value.num_channels = 1; 1420 ctl.dev = ac97_get_portnum_by_name(&as->codec_if, AudioCoutputs, 1421 AudioNcenter, NULL); 1422 ac97_mixer_set_port(&as->codec_if, &ctl); 1423 ctl.dev = ac97_get_portnum_by_name(&as->codec_if, AudioCoutputs, 1424 AudioNlfe, NULL); 1425 ac97_mixer_set_port(&as->codec_if, &ctl); 1426 1427 if (initfunc != NULL) 1428 initfunc(as); 1429 1430 /* restore AC97_REG_POWER */ 1431 if (as->type == AC97_CODEC_TYPE_AUDIO) 1432 ac97_write(as, AC97_REG_POWER, as->power_reg); 1433 1434 return 0; 1435 } 1436 1437 static void 1438 ac97_detach(struct ac97_codec_if *codec_if) 1439 { 1440 struct ac97_softc *as; 1441 1442 as = (struct ac97_softc *)codec_if; 1443 ac97_write(as, AC97_REG_POWER, AC97_POWER_IN | AC97_POWER_OUT 1444 | AC97_POWER_MIXER | AC97_POWER_MIXER_VREF 1445 | AC97_POWER_ACLINK | AC97_POWER_CLK | AC97_POWER_AUX 1446 | POWER_EAMP_OFF(as)); 1447 free(as, M_DEVBUF); 1448 } 1449 1450 static int 1451 ac97_query_devinfo(struct ac97_codec_if *codec_if, mixer_devinfo_t *dip) 1452 { 1453 struct ac97_softc *as; 1454 struct ac97_source_info *si; 1455 const char *name; 1456 1457 as = (struct ac97_softc *)codec_if; 1458 if (dip->index < as->num_source_info) { 1459 si = &as->source_info[dip->index]; 1460 dip->type = si->type; 1461 dip->mixer_class = si->mixer_class; 1462 dip->prev = si->prev; 1463 dip->next = si->next; 1464 1465 if (si->qualifier) 1466 name = si->qualifier; 1467 else if (si->device) 1468 name = si->device; 1469 else if (si->class) 1470 name = si->class; 1471 else 1472 name = 0; 1473 1474 if (name) 1475 strcpy(dip->label.name, name); 1476 1477 memcpy(&dip->un, si->info, si->info_size); 1478 1479 /* Set the delta for volume sources */ 1480 if (dip->type == AUDIO_MIXER_VALUE) 1481 dip->un.v.delta = 1 << (8 - si->bits); 1482 1483 return 0; 1484 } 1485 1486 return ENXIO; 1487 } 1488 1489 static int 1490 ac97_mixer_set_port(struct ac97_codec_if *codec_if, mixer_ctrl_t *cp) 1491 { 1492 struct ac97_softc *as; 1493 struct ac97_source_info *si; 1494 uint16_t mask; 1495 uint16_t val, newval; 1496 int error; 1497 1498 as = (struct ac97_softc *)codec_if; 1499 si = &as->source_info[cp->dev]; 1500 if (cp->dev < 0 || cp->dev >= as->num_source_info) 1501 return EINVAL; 1502 1503 if (cp->type != si->type) 1504 return EINVAL; 1505 1506 ac97_read(as, si->reg, &val); 1507 1508 DPRINTFN(5, ("read(%x) = %x\n", si->reg, val)); 1509 1510 mask = (1 << si->bits) - 1; 1511 1512 switch (cp->type) { 1513 case AUDIO_MIXER_ENUM: 1514 if (cp->un.ord > mask || cp->un.ord < 0) 1515 return EINVAL; 1516 1517 newval = (cp->un.ord << si->ofs); 1518 if (si->reg == AC97_REG_RECORD_SELECT) { 1519 newval |= (newval << (8 + si->ofs)); 1520 mask |= (mask << 8); 1521 mask = mask << si->ofs; 1522 } else if (si->reg == AC97_REG_SURR_MASTER) { 1523 newval = cp->un.ord ? 0x8080 : 0x0000; 1524 mask = 0x8080; 1525 } else 1526 mask = mask << si->ofs; 1527 break; 1528 case AUDIO_MIXER_VALUE: 1529 { 1530 const struct audio_mixer_value *value = si->info; 1531 uint16_t l, r, ol, or; 1532 int deltal, deltar; 1533 1534 if ((cp->un.value.num_channels <= 0) || 1535 (cp->un.value.num_channels > value->num_channels)) 1536 return EINVAL; 1537 1538 if (cp->un.value.num_channels == 1) { 1539 l = r = cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]; 1540 } else { 1541 if (!(as->host_flags & AC97_HOST_SWAPPED_CHANNELS)) { 1542 l = cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT]; 1543 r = cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT]; 1544 } else { /* left/right is reversed here */ 1545 r = cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT]; 1546 l = cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT]; 1547 } 1548 1549 } 1550 1551 if (!si->polarity) { 1552 l = 255 - l; 1553 r = 255 - r; 1554 } 1555 1556 ol = (val >> (8+si->ofs)) & mask; 1557 or = (val >> si->ofs) & mask; 1558 1559 deltal = (ol << (8 - si->bits)) - l; 1560 deltar = (or << (8 - si->bits)) - r; 1561 1562 l = l >> (8 - si->bits); 1563 r = r >> (8 - si->bits); 1564 1565 if (deltal && ol == l) 1566 l += (deltal > 0) ? (l ? -1 : 0) : (l < mask ? 1 : 0); 1567 if (deltar && or == r) 1568 r += (deltar > 0) ? (r ? -1 : 0) : (r < mask ? 1 : 0); 1569 1570 newval = ((r & mask) << si->ofs); 1571 if (value->num_channels == 2) { 1572 newval = newval | ((l & mask) << (si->ofs+8)); 1573 mask |= (mask << 8); 1574 } 1575 mask = mask << si->ofs; 1576 break; 1577 } 1578 default: 1579 return EINVAL; 1580 } 1581 1582 error = ac97_write(as, si->reg, (val & ~mask) | newval); 1583 if (error) 1584 return error; 1585 1586 return 0; 1587 } 1588 1589 static int 1590 ac97_get_portnum_by_name(struct ac97_codec_if *codec_if, const char *class, 1591 const char *device, const char *qualifier) 1592 { 1593 struct ac97_softc *as; 1594 int idx; 1595 1596 as = (struct ac97_softc *)codec_if; 1597 for (idx = 0; idx < as->num_source_info; idx++) { 1598 struct ac97_source_info *si = &as->source_info[idx]; 1599 if (ac97_str_equal(class, si->class) && 1600 ac97_str_equal(device, si->device) && 1601 ac97_str_equal(qualifier, si->qualifier)) 1602 return idx; 1603 } 1604 1605 return -1; 1606 } 1607 1608 static int 1609 ac97_mixer_get_port(struct ac97_codec_if *codec_if, mixer_ctrl_t *cp) 1610 { 1611 struct ac97_softc *as; 1612 struct ac97_source_info *si; 1613 uint16_t mask; 1614 uint16_t val; 1615 1616 as = (struct ac97_softc *)codec_if; 1617 si = &as->source_info[cp->dev]; 1618 if (cp->dev < 0 || cp->dev >= as->num_source_info) 1619 return EINVAL; 1620 1621 if (cp->type != si->type) 1622 return EINVAL; 1623 1624 ac97_read(as, si->reg, &val); 1625 1626 DPRINTFN(5, ("read(%x) = %x\n", si->reg, val)); 1627 1628 mask = (1 << si->bits) - 1; 1629 1630 switch (cp->type) { 1631 case AUDIO_MIXER_ENUM: 1632 cp->un.ord = (val >> si->ofs) & mask; 1633 DPRINTFN(4, ("AUDIO_MIXER_ENUM: %x %d %x %d\n", 1634 val, si->ofs, mask, cp->un.ord)); 1635 break; 1636 case AUDIO_MIXER_VALUE: 1637 { 1638 const struct audio_mixer_value *value = si->info; 1639 uint16_t l, r; 1640 1641 if ((cp->un.value.num_channels <= 0) || 1642 (cp->un.value.num_channels > value->num_channels)) 1643 return EINVAL; 1644 1645 if (value->num_channels == 1) { 1646 l = r = (val >> si->ofs) & mask; 1647 } else { 1648 if (!(as->host_flags & AC97_HOST_SWAPPED_CHANNELS)) { 1649 l = (val >> (si->ofs + 8)) & mask; 1650 r = (val >> si->ofs) & mask; 1651 } else { /* host has reversed channels */ 1652 r = (val >> (si->ofs + 8)) & mask; 1653 l = (val >> si->ofs) & mask; 1654 } 1655 } 1656 1657 l = (l << (8 - si->bits)); 1658 r = (r << (8 - si->bits)); 1659 if (!si->polarity) { 1660 l = 255 - l; 1661 r = 255 - r; 1662 } 1663 1664 /* The EAP driver averages l and r for stereo 1665 channels that are requested in MONO mode. Does this 1666 make sense? */ 1667 if (cp->un.value.num_channels == 1) { 1668 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = l; 1669 } else if (cp->un.value.num_channels == 2) { 1670 cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = l; 1671 cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = r; 1672 } 1673 1674 break; 1675 } 1676 default: 1677 return EINVAL; 1678 } 1679 1680 return 0; 1681 } 1682 1683 1684 static int 1685 ac97_set_rate(struct ac97_codec_if *codec_if, int target, u_int *rate) 1686 { 1687 struct ac97_softc *as; 1688 u_int value; 1689 uint16_t ext_stat; 1690 uint16_t actual; 1691 uint16_t power; 1692 uint16_t power_bit; 1693 1694 as = (struct ac97_softc *)codec_if; 1695 if (target == AC97_REG_PCM_MIC_ADC_RATE) { 1696 if (!(as->ext_id & AC97_EXT_AUDIO_VRM)) { 1697 *rate = AC97_SINGLE_RATE; 1698 return 0; 1699 } 1700 } else { 1701 if (!(as->ext_id & AC97_EXT_AUDIO_VRA)) { 1702 *rate = AC97_SINGLE_RATE; 1703 return 0; 1704 } 1705 } 1706 value = *rate * AC97_STANDARD_CLOCK / as->ac97_clock; 1707 ext_stat = 0; 1708 /* 1709 * PCM_FRONT_DAC_RATE/PCM_SURR_DAC_RATE/PCM_LFE_DAC_RATE 1710 * Check VRA, DRA 1711 * PCM_LR_ADC_RATE 1712 * Check VRA 1713 * PCM_MIC_ADC_RATE 1714 * Check VRM 1715 */ 1716 switch (target) { 1717 case AC97_REG_PCM_FRONT_DAC_RATE: 1718 case AC97_REG_PCM_SURR_DAC_RATE: 1719 case AC97_REG_PCM_LFE_DAC_RATE: 1720 power_bit = AC97_POWER_OUT; 1721 if (!(as->ext_id & AC97_EXT_AUDIO_VRA)) { 1722 *rate = AC97_SINGLE_RATE; 1723 return 0; 1724 } 1725 if (as->ext_id & AC97_EXT_AUDIO_DRA) { 1726 ac97_read(as, AC97_REG_EXT_AUDIO_CTRL, &ext_stat); 1727 if (value > 0x1ffff) { 1728 return EINVAL; 1729 } else if (value > 0xffff) { 1730 /* Enable DRA */ 1731 ext_stat |= AC97_EXT_AUDIO_DRA; 1732 ac97_write(as, AC97_REG_EXT_AUDIO_CTRL, ext_stat); 1733 value /= 2; 1734 } else { 1735 /* Disable DRA */ 1736 ext_stat &= ~AC97_EXT_AUDIO_DRA; 1737 ac97_write(as, AC97_REG_EXT_AUDIO_CTRL, ext_stat); 1738 } 1739 } else { 1740 if (value > 0xffff) 1741 return EINVAL; 1742 } 1743 break; 1744 case AC97_REG_PCM_LR_ADC_RATE: 1745 power_bit = AC97_POWER_IN; 1746 if (!(as->ext_id & AC97_EXT_AUDIO_VRA)) { 1747 *rate = AC97_SINGLE_RATE; 1748 return 0; 1749 } 1750 if (value > 0xffff) 1751 return EINVAL; 1752 break; 1753 case AC97_REG_PCM_MIC_ADC_RATE: 1754 power_bit = AC97_POWER_IN; 1755 if (!(as->ext_id & AC97_EXT_AUDIO_VRM)) { 1756 *rate = AC97_SINGLE_RATE; 1757 return 0; 1758 } 1759 if (value > 0xffff) 1760 return EINVAL; 1761 break; 1762 default: 1763 printf("%s: Unknown register: 0x%x\n", __func__, target); 1764 return EINVAL; 1765 } 1766 1767 ac97_read(as, AC97_REG_POWER, &power); 1768 ac97_write(as, AC97_REG_POWER, power | power_bit); 1769 1770 ac97_write(as, target, (uint16_t)value); 1771 ac97_read(as, target, &actual); 1772 actual = (uint32_t)actual * as->ac97_clock / AC97_STANDARD_CLOCK; 1773 1774 ac97_write(as, AC97_REG_POWER, power); 1775 if (ext_stat & AC97_EXT_AUDIO_DRA) { 1776 *rate = actual * 2; 1777 } else { 1778 *rate = actual; 1779 } 1780 return 0; 1781 } 1782 1783 static void 1784 ac97_set_clock(struct ac97_codec_if *codec_if, unsigned int clock) 1785 { 1786 struct ac97_softc *as; 1787 1788 as = (struct ac97_softc *)codec_if; 1789 as->ac97_clock = clock; 1790 } 1791 1792 static uint16_t 1793 ac97_get_extcaps(struct ac97_codec_if *codec_if) 1794 { 1795 struct ac97_softc *as; 1796 1797 as = (struct ac97_softc *)codec_if; 1798 return as->ext_id; 1799 } 1800 1801 static int 1802 ac97_add_port(struct ac97_softc *as, const struct ac97_source_info *src) 1803 { 1804 struct ac97_source_info *si; 1805 int ouridx, idx; 1806 1807 if ((as->type == AC97_CODEC_TYPE_AUDIO && 1808 as->num_source_info >= AUDIO_MAX_SOURCES) || 1809 (as->type == AC97_CODEC_TYPE_MODEM && 1810 as->num_source_info >= MODEM_MAX_SOURCES)) { 1811 printf("%s: internal error: increase MAX_SOURCES in %s\n", 1812 __func__, __FILE__); 1813 return -1; 1814 } 1815 if (!ac97_check_capability(as, src->req_feature)) 1816 return -1; 1817 ouridx = as->num_source_info; 1818 si = &as->source_info[ouridx]; 1819 memcpy(si, src, sizeof(*si)); 1820 1821 switch (si->type) { 1822 case AUDIO_MIXER_CLASS: 1823 case AUDIO_MIXER_VALUE: 1824 printf("%s: adding class/value is not supported yet.\n", 1825 __func__); 1826 return -1; 1827 case AUDIO_MIXER_ENUM: 1828 break; 1829 default: 1830 printf("%s: unknown type: %d\n", __func__, si->type); 1831 return -1; 1832 } 1833 as->num_source_info++; 1834 1835 si->mixer_class = ac97_get_portnum_by_name(&as->codec_if, si->class, 1836 NULL, NULL); 1837 /* Find the root of the device */ 1838 idx = ac97_get_portnum_by_name(&as->codec_if, si->class, 1839 si->device, NULL); 1840 /* Find the last item */ 1841 while (as->source_info[idx].next != AUDIO_MIXER_LAST) 1842 idx = as->source_info[idx].next; 1843 /* Append */ 1844 as->source_info[idx].next = ouridx; 1845 si->prev = idx; 1846 si->next = AUDIO_MIXER_LAST; 1847 1848 return 0; 1849 } 1850 1851 /** 1852 * Codec-dependent initialization 1853 */ 1854 1855 #define AD1980_REG_MISC 0x76 1856 #define AD1980_MISC_MBG0 0x0001 /* 0 1888/1980/1981 /1985 */ 1857 #define AD1980_MISC_MBG1 0x0002 /* 1 1888/1980/1981 /1985 */ 1858 #define AD1980_MISC_VREFD 0x0004 /* 2 1888/1980/1981 /1985 */ 1859 #define AD1980_MISC_VREFH 0x0008 /* 3 1888/1980/1981 /1985 */ 1860 #define AD1980_MISC_SRU 0x0010 /* 4 1888/1980 /1985 */ 1861 #define AD1980_MISC_LOSEL 0x0020 /* 5 1888/1980/1981 /1985 */ 1862 #define AD1980_MISC_2CMIC 0x0040 /* 6 1980/1981B/1985 */ 1863 #define AD1980_MISC_SPRD 0x0080 /* 7 1888/1980 /1985 */ 1864 #define AD1980_MISC_DMIX0 0x0100 /* 8 1888/1980 /1985 */ 1865 #define AD1980_MISC_DMIX1 0x0200 /* 9 1888/1980 /1985 */ 1866 #define AD1980_MISC_HPSEL 0x0400 /*10 1888/1980 /1985 */ 1867 #define AD1980_MISC_CLDIS 0x0800 /*11 1888/1980 /1985 */ 1868 #define AD1980_MISC_LODIS 0x1000 /*12 1888/1980/1981 /1985 */ 1869 #define AD1980_MISC_MSPLT 0x2000 /*13 1888/1980/1981 /1985 */ 1870 #define AD1980_MISC_AC97NC 0x4000 /*14 1888/1980 /1985 */ 1871 #define AD1980_MISC_DACZ 0x8000 /*15 1888/1980/1981 /1985 */ 1872 #define AD1981_REG_MISC 0x76 1873 #define AD1981_MISC_MADST 0x0010 /* 4 */ 1874 #define AD1981A_MISC_MADPD 0x0040 /* 6 */ 1875 #define AD1981B_MISC_MADPD 0x0080 /* 7 */ 1876 #define AD1981_MISC_FMXE 0x0200 /* 9 */ 1877 #define AD1981_MISC_DAM 0x0800 /*11 */ 1878 static void 1879 ac97_ad198x_init(struct ac97_softc *as) 1880 { 1881 int i; 1882 uint16_t misc; 1883 1884 ac97_read(as, AD1980_REG_MISC, &misc); 1885 ac97_write(as, AD1980_REG_MISC, 1886 misc | AD1980_MISC_LOSEL | AD1980_MISC_HPSEL); 1887 1888 for (i = 0; i < as->num_source_info; i++) { 1889 if (as->source_info[i].type != AUDIO_MIXER_VALUE) 1890 continue; 1891 1892 if (as->source_info[i].reg == AC97_REG_MASTER_VOLUME) 1893 as->source_info[i].reg = AC97_REG_SURR_MASTER; 1894 else if (as->source_info[i].reg == AC97_REG_SURR_MASTER) 1895 as->source_info[i].reg = AC97_REG_MASTER_VOLUME; 1896 } 1897 } 1898 1899 #define ALC650_REG_MULTI_CHANNEL_CONTROL 0x6a 1900 #define ALC650_MCC_SLOT_MODIFY_MASK 0xc000 1901 #define ALC650_MCC_FRONTDAC_FROM_SPDIFIN 0x2000 /* 13 */ 1902 #define ALC650_MCC_SPDIFOUT_FROM_ADC 0x1000 /* 12 */ 1903 #define ALC650_MCC_PCM_FROM_SPDIFIN 0x0800 /* 11 */ 1904 #define ALC650_MCC_MIC_OR_CENTERLFE 0x0400 /* 10 */ 1905 #define ALC650_MCC_LINEIN_OR_SURROUND 0x0200 /* 9 */ 1906 #define ALC650_MCC_INDEPENDENT_MASTER_L 0x0080 /* 7 */ 1907 #define ALC650_MCC_INDEPENDENT_MASTER_R 0x0040 /* 6 */ 1908 #define ALC650_MCC_ANALOG_TO_CENTERLFE 0x0020 /* 5 */ 1909 #define ALC650_MCC_ANALOG_TO_SURROUND 0x0010 /* 4 */ 1910 #define ALC650_MCC_EXCHANGE_CENTERLFE 0x0008 /* 3 */ 1911 #define ALC650_MCC_CENTERLFE_DOWNMIX 0x0004 /* 2 */ 1912 #define ALC650_MCC_SURROUND_DOWNMIX 0x0002 /* 1 */ 1913 #define ALC650_MCC_LINEOUT_TO_SURROUND 0x0001 /* 0 */ 1914 static void 1915 ac97_alc650_init(struct ac97_softc *as) 1916 { 1917 static const struct ac97_source_info sources[6] = { 1918 { AudioCoutputs, AudioNsurround, "lineinjack", 1919 AUDIO_MIXER_ENUM, WRAP(ac97_on_off), 1920 ALC650_REG_MULTI_CHANNEL_CONTROL, 1921 0x0000, 1, 9, 0, 0, CHECK_SURROUND }, 1922 { AudioCoutputs, AudioNsurround, "mixtofront", 1923 AUDIO_MIXER_ENUM, WRAP(ac97_on_off), 1924 ALC650_REG_MULTI_CHANNEL_CONTROL, 1925 0x0000, 1, 1, 0, 0, CHECK_SURROUND }, 1926 { AudioCoutputs, AudioNcenter, "micjack", 1927 AUDIO_MIXER_ENUM, WRAP(ac97_on_off), 1928 ALC650_REG_MULTI_CHANNEL_CONTROL, 1929 0x0000, 1, 10, 0, 0, CHECK_CENTER }, 1930 { AudioCoutputs, AudioNlfe, "micjack", 1931 AUDIO_MIXER_ENUM, WRAP(ac97_on_off), 1932 ALC650_REG_MULTI_CHANNEL_CONTROL, 1933 0x0000, 1, 10, 0, 0, CHECK_LFE }, 1934 { AudioCoutputs, AudioNcenter, "mixtofront", 1935 AUDIO_MIXER_ENUM, WRAP(ac97_on_off), 1936 ALC650_REG_MULTI_CHANNEL_CONTROL, 1937 0x0000, 1, 2, 0, 0, CHECK_CENTER }, 1938 { AudioCoutputs, AudioNlfe, "mixtofront", 1939 AUDIO_MIXER_ENUM, WRAP(ac97_on_off), 1940 ALC650_REG_MULTI_CHANNEL_CONTROL, 1941 0x0000, 1, 2, 0, 0, CHECK_LFE }, 1942 }; 1943 1944 ac97_add_port(as, &sources[0]); 1945 ac97_add_port(as, &sources[1]); 1946 ac97_add_port(as, &sources[2]); 1947 ac97_add_port(as, &sources[3]); 1948 ac97_add_port(as, &sources[4]); 1949 ac97_add_port(as, &sources[5]); 1950 } 1951 1952 #define VT1616_REG_IO_CONTROL 0x5a 1953 #define VT1616_IC_LVL (1 << 15) 1954 #define VT1616_IC_LFECENTER_TO_FRONT (1 << 12) 1955 #define VT1616_IC_SURROUND_TO_FRONT (1 << 11) 1956 #define VT1616_IC_BPDC (1 << 10) 1957 #define VT1616_IC_DC (1 << 9) 1958 #define VT1616_IC_IB_MASK 0x000c 1959 static void 1960 ac97_vt1616_init(struct ac97_softc *as) 1961 { 1962 static const struct ac97_source_info sources[3] = { 1963 { AudioCoutputs, AudioNsurround, "mixtofront", 1964 AUDIO_MIXER_ENUM, WRAP(ac97_on_off), 1965 VT1616_REG_IO_CONTROL, 1966 0x0000, 1, 11, 0, 0, CHECK_SURROUND }, 1967 { AudioCoutputs, AudioNcenter, "mixtofront", 1968 AUDIO_MIXER_ENUM, WRAP(ac97_on_off), 1969 VT1616_REG_IO_CONTROL, 1970 0x0000, 1, 12, 0, 0, CHECK_CENTER }, 1971 { AudioCoutputs, AudioNlfe, "mixtofront", 1972 AUDIO_MIXER_ENUM, WRAP(ac97_on_off), 1973 VT1616_REG_IO_CONTROL, 1974 0x0000, 1, 12, 0, 0, CHECK_LFE }, 1975 }; 1976 1977 ac97_add_port(as, &sources[0]); 1978 ac97_add_port(as, &sources[1]); 1979 ac97_add_port(as, &sources[2]); 1980 } 1981 1982 static int 1983 ac97_modem_offhook_set(struct ac97_softc *as, int line, int newval) 1984 { 1985 uint16_t val; 1986 1987 val = as->shadow_reg[AC97_REG_GPIO_STATUS >> 1]; 1988 switch (newval) { 1989 case 0: 1990 val &= ~line; 1991 break; 1992 case 1: 1993 val |= line; 1994 break; 1995 } 1996 ac97_write(as, AC97_REG_GPIO_STATUS, val); 1997 1998 return 0; 1999 } 2000 2001 static int 2002 ac97_sysctl_verify(SYSCTLFN_ARGS) 2003 { 2004 int error, tmp; 2005 struct sysctlnode node; 2006 struct ac97_softc *as; 2007 2008 node = *rnode; 2009 as = rnode->sysctl_data; 2010 if (node.sysctl_num == as->offhook_line1_mib) { 2011 tmp = as->offhook_line1; 2012 node.sysctl_data = &tmp; 2013 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 2014 if (error || newp == NULL) 2015 return error; 2016 2017 if (tmp < 0 || tmp > 1) 2018 return EINVAL; 2019 2020 as->offhook_line1 = tmp; 2021 ac97_modem_offhook_set(as, AC97_GPIO_LINE1_OH, tmp); 2022 } else if (node.sysctl_num == as->offhook_line2_mib) { 2023 tmp = as->offhook_line2; 2024 node.sysctl_data = &tmp; 2025 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 2026 if (error || newp == NULL) 2027 return error; 2028 2029 if (tmp < 0 || tmp > 1) 2030 return EINVAL; 2031 2032 as->offhook_line2 = tmp; 2033 ac97_modem_offhook_set(as, AC97_GPIO_LINE2_OH, tmp); 2034 } 2035 2036 return 0; 2037 } 2038