1 1.34 andvar /* $NetBSD: ad1848.c,v 1.34 2024/02/09 22:08:34 andvar Exp $ */ 2 1.1 pk 3 1.5 mycroft /*- 4 1.31 jmcneill * Copyright (c) 1999, 2008 The NetBSD Foundation, Inc. 5 1.5 mycroft * All rights reserved. 6 1.5 mycroft * 7 1.5 mycroft * This code is derived from software contributed to The NetBSD Foundation 8 1.5 mycroft * by Ken Hornstein and John Kohl. 9 1.5 mycroft * 10 1.5 mycroft * Redistribution and use in source and binary forms, with or without 11 1.5 mycroft * modification, are permitted provided that the following conditions 12 1.5 mycroft * are met: 13 1.5 mycroft * 1. Redistributions of source code must retain the above copyright 14 1.5 mycroft * notice, this list of conditions and the following disclaimer. 15 1.5 mycroft * 2. Redistributions in binary form must reproduce the above copyright 16 1.5 mycroft * notice, this list of conditions and the following disclaimer in the 17 1.5 mycroft * documentation and/or other materials provided with the distribution. 18 1.5 mycroft * 19 1.5 mycroft * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 1.5 mycroft * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 1.5 mycroft * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 1.5 mycroft * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 1.5 mycroft * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.5 mycroft * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.5 mycroft * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.5 mycroft * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.5 mycroft * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.5 mycroft * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.5 mycroft * POSSIBILITY OF SUCH DAMAGE. 30 1.5 mycroft */ 31 1.1 pk /* 32 1.1 pk * Copyright (c) 1994 John Brezak 33 1.1 pk * Copyright (c) 1991-1993 Regents of the University of California. 34 1.1 pk * All rights reserved. 35 1.1 pk * 36 1.1 pk * Redistribution and use in source and binary forms, with or without 37 1.1 pk * modification, are permitted provided that the following conditions 38 1.1 pk * are met: 39 1.1 pk * 1. Redistributions of source code must retain the above copyright 40 1.1 pk * notice, this list of conditions and the following disclaimer. 41 1.1 pk * 2. Redistributions in binary form must reproduce the above copyright 42 1.1 pk * notice, this list of conditions and the following disclaimer in the 43 1.1 pk * documentation and/or other materials provided with the distribution. 44 1.1 pk * 3. All advertising materials mentioning features or use of this software 45 1.1 pk * must display the following acknowledgement: 46 1.1 pk * This product includes software developed by the Computer Systems 47 1.1 pk * Engineering Group at Lawrence Berkeley Laboratory. 48 1.1 pk * 4. Neither the name of the University nor of the Laboratory may be used 49 1.1 pk * to endorse or promote products derived from this software without 50 1.1 pk * specific prior written permission. 51 1.1 pk * 52 1.1 pk * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 53 1.1 pk * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 54 1.1 pk * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 55 1.1 pk * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 56 1.1 pk * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 57 1.1 pk * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 58 1.1 pk * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 59 1.1 pk * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 60 1.1 pk * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 61 1.1 pk * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 62 1.1 pk * SUCH DAMAGE. 63 1.1 pk * 64 1.1 pk */ 65 1.1 pk 66 1.1 pk /* 67 1.1 pk * Copyright by Hannu Savolainen 1994 68 1.1 pk * 69 1.1 pk * Redistribution and use in source and binary forms, with or without 70 1.1 pk * modification, are permitted provided that the following conditions are 71 1.1 pk * met: 1. Redistributions of source code must retain the above copyright 72 1.1 pk * notice, this list of conditions and the following disclaimer. 2. 73 1.1 pk * Redistributions in binary form must reproduce the above copyright notice, 74 1.1 pk * this list of conditions and the following disclaimer in the documentation 75 1.1 pk * and/or other materials provided with the distribution. 76 1.1 pk * 77 1.1 pk * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY 78 1.1 pk * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 79 1.1 pk * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 80 1.1 pk * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 81 1.1 pk * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 82 1.1 pk * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 83 1.1 pk * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 84 1.1 pk * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 85 1.1 pk * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 86 1.1 pk * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 87 1.1 pk * SUCH DAMAGE. 88 1.1 pk * 89 1.1 pk */ 90 1.1 pk /* 91 1.1 pk * Portions of this code are from the VOXware support for the ad1848 92 1.1 pk * by Hannu Savolainen <hannu (at) voxware.pp.fi> 93 1.1 pk * 94 1.31 jmcneill * Portions also ripped from the SoundBlaster driver for NetBSD. 95 1.1 pk */ 96 1.12 lukem 97 1.12 lukem #include <sys/cdefs.h> 98 1.34 andvar __KERNEL_RCSID(0, "$NetBSD: ad1848.c,v 1.34 2024/02/09 22:08:34 andvar Exp $"); 99 1.1 pk 100 1.1 pk #include <sys/param.h> 101 1.1 pk #include <sys/systm.h> 102 1.1 pk #include <sys/errno.h> 103 1.1 pk #include <sys/ioctl.h> 104 1.1 pk #include <sys/device.h> 105 1.7 itohy #include <sys/fcntl.h> 106 1.1 pk /*#include <sys/syslog.h>*/ 107 1.1 pk /*#include <sys/proc.h>*/ 108 1.1 pk 109 1.26 ad #include <sys/cpu.h> 110 1.26 ad #include <sys/bus.h> 111 1.1 pk 112 1.1 pk #include <sys/audioio.h> 113 1.32 isaki #include <dev/audio/audio_if.h> 114 1.1 pk 115 1.1 pk #include <dev/ic/ad1848reg.h> 116 1.1 pk #include <dev/ic/cs4231reg.h> 117 1.6 rh #include <dev/ic/cs4237reg.h> 118 1.1 pk #include <dev/ic/ad1848var.h> 119 1.1 pk #if 0 120 1.1 pk #include <dev/isa/cs4231var.h> 121 1.1 pk #endif 122 1.1 pk 123 1.11 itohy /* 124 1.11 itohy * AD1845 on some machines don't match the AD1845 doc 125 1.11 itohy * and defining AD1845_HACK to 1 works around the problems. 126 1.11 itohy * options AD1845_HACK=0 should work if you have ``correct'' one. 127 1.11 itohy */ 128 1.11 itohy #ifndef AD1845_HACK 129 1.11 itohy #define AD1845_HACK 1 /* weird mixer, can't play slinear_be */ 130 1.11 itohy #endif 131 1.11 itohy 132 1.1 pk #ifdef AUDIO_DEBUG 133 1.1 pk #define DPRINTF(x) if (ad1848debug) printf x 134 1.2 pk int ad1848debug = 0; 135 1.28 garbled void ad1848_dump_regs(struct ad1848_softc *); 136 1.1 pk #else 137 1.1 pk #define DPRINTF(x) 138 1.1 pk #endif 139 1.1 pk 140 1.32 isaki /* The HW supports more frequencies but I chose several major ones. */ 141 1.32 isaki static const struct audio_format ad1848_formats[] = { 142 1.32 isaki { 143 1.32 isaki .mode = AUMODE_PLAY | AUMODE_RECORD, 144 1.32 isaki .encoding = AUDIO_ENCODING_SLINEAR_LE, 145 1.32 isaki .validbits = 16, 146 1.32 isaki .precision = 16, 147 1.32 isaki .channels = 2, 148 1.32 isaki .channel_mask = AUFMT_STEREO, 149 1.32 isaki .frequency_type = 6, 150 1.32 isaki .frequency = { 8000, 11025, 16000, 22050, 44100, 48000 }, 151 1.32 isaki }, 152 1.32 isaki }; 153 1.32 isaki #define AD1848_NFORMATS __arraycount(ad1848_formats) 154 1.32 isaki 155 1.1 pk /* 156 1.1 pk * Initial values for the indirect registers of CS4248/AD1848. 157 1.1 pk */ 158 1.10 jdolecek static const int ad1848_init_values[] = { 159 1.1 pk GAIN_12|INPUT_MIC_GAIN_ENABLE, /* Left Input Control */ 160 1.1 pk GAIN_12|INPUT_MIC_GAIN_ENABLE, /* Right Input Control */ 161 1.1 pk ATTEN_12, /* Left Aux #1 Input Control */ 162 1.1 pk ATTEN_12, /* Right Aux #1 Input Control */ 163 1.1 pk ATTEN_12, /* Left Aux #2 Input Control */ 164 1.1 pk ATTEN_12, /* Right Aux #2 Input Control */ 165 1.1 pk /* bits 5-0 are attenuation select */ 166 1.1 pk ATTEN_12, /* Left DAC output Control */ 167 1.1 pk ATTEN_12, /* Right DAC output Control */ 168 1.1 pk CLOCK_XTAL1|FMT_PCM8, /* Clock and Data Format */ 169 1.1 pk SINGLE_DMA|AUTO_CAL_ENABLE, /* Interface Config */ 170 1.1 pk INTERRUPT_ENABLE, /* Pin control */ 171 1.1 pk 0x00, /* Test and Init */ 172 1.1 pk MODE2, /* Misc control */ 173 1.1 pk ATTEN_0<<2, /* Digital Mix Control */ 174 1.1 pk 0, /* Upper base Count */ 175 1.1 pk 0, /* Lower base Count */ 176 1.1 pk 177 1.1 pk /* These are for CS4231 &c. only (additional registers): */ 178 1.1 pk 0, /* Alt feature 1 */ 179 1.1 pk 0, /* Alt feature 2 */ 180 1.1 pk ATTEN_12, /* Left line in */ 181 1.1 pk ATTEN_12, /* Right line in */ 182 1.1 pk 0, /* Timer low */ 183 1.1 pk 0, /* Timer high */ 184 1.1 pk 0, /* unused */ 185 1.1 pk 0, /* unused */ 186 1.1 pk 0, /* IRQ status */ 187 1.1 pk 0, /* unused */ 188 1.1 pk /* Mono input (a.k.a speaker) (mic) Control */ 189 1.1 pk MONO_INPUT_MUTE|ATTEN_6, /* mute speaker by default */ 190 1.1 pk 0, /* unused */ 191 1.1 pk 0, /* record format */ 192 1.1 pk 0, /* Crystal Clock Select */ 193 1.1 pk 0, /* upper record count */ 194 1.1 pk 0 /* lower record count */ 195 1.1 pk }; 196 1.1 pk 197 1.1 pk 198 1.1 pk int 199 1.18 thorpej ad1848_to_vol(mixer_ctrl_t *cp, struct ad1848_volume *vol) 200 1.1 pk { 201 1.20 kent 202 1.1 pk if (cp->un.value.num_channels == 1) { 203 1.1 pk vol->left = 204 1.1 pk vol->right = cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]; 205 1.20 kent return 1; 206 1.1 pk } 207 1.1 pk else if (cp->un.value.num_channels == 2) { 208 1.1 pk vol->left = cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT]; 209 1.1 pk vol->right = cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT]; 210 1.20 kent return 1; 211 1.1 pk } 212 1.20 kent return 0; 213 1.1 pk } 214 1.1 pk 215 1.1 pk int 216 1.18 thorpej ad1848_from_vol(mixer_ctrl_t *cp, struct ad1848_volume *vol) 217 1.1 pk { 218 1.20 kent 219 1.1 pk if (cp->un.value.num_channels == 1) { 220 1.1 pk cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = vol->left; 221 1.20 kent return 1; 222 1.1 pk } 223 1.1 pk else if (cp->un.value.num_channels == 2) { 224 1.1 pk cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = vol->left; 225 1.1 pk cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = vol->right; 226 1.20 kent return 1; 227 1.1 pk } 228 1.20 kent return 0; 229 1.1 pk } 230 1.1 pk 231 1.1 pk 232 1.30 plunky int 233 1.18 thorpej ad_read(struct ad1848_softc *sc, int reg) 234 1.1 pk { 235 1.1 pk int x; 236 1.1 pk 237 1.1 pk ADWRITE(sc, AD1848_IADDR, (reg & 0xff) | sc->MCE_bit); 238 1.1 pk x = ADREAD(sc, AD1848_IDATA); 239 1.1 pk /* printf("(%02x<-%02x) ", reg|sc->MCE_bit, x); */ 240 1.1 pk return x; 241 1.1 pk } 242 1.1 pk 243 1.30 plunky void 244 1.18 thorpej ad_write(struct ad1848_softc *sc, int reg, int data) 245 1.1 pk { 246 1.20 kent 247 1.1 pk ADWRITE(sc, AD1848_IADDR, (reg & 0xff) | sc->MCE_bit); 248 1.1 pk ADWRITE(sc, AD1848_IDATA, data & 0xff); 249 1.1 pk /* printf("(%02x->%02x) ", reg|sc->MCE_bit, data); */ 250 1.1 pk } 251 1.1 pk 252 1.6 rh /* 253 1.6 rh * extended registers (mode 3) require an additional level of 254 1.6 rh * indirection through CS_XREG (I23). 255 1.6 rh */ 256 1.6 rh 257 1.30 plunky int 258 1.18 thorpej ad_xread(struct ad1848_softc *sc, int reg) 259 1.6 rh { 260 1.6 rh int x; 261 1.6 rh 262 1.6 rh ADWRITE(sc, AD1848_IADDR, CS_XREG | sc->MCE_bit); 263 1.6 rh ADWRITE(sc, AD1848_IDATA, (reg | ALT_F3_XRAE) & 0xff); 264 1.6 rh x = ADREAD(sc, AD1848_IDATA); 265 1.6 rh 266 1.6 rh return x; 267 1.6 rh } 268 1.6 rh 269 1.30 plunky void 270 1.18 thorpej ad_xwrite(struct ad1848_softc *sc, int reg, int val) 271 1.6 rh { 272 1.20 kent 273 1.6 rh ADWRITE(sc, AD1848_IADDR, CS_XREG | sc->MCE_bit); 274 1.6 rh ADWRITE(sc, AD1848_IDATA, (reg | ALT_F3_XRAE) & 0xff); 275 1.6 rh ADWRITE(sc, AD1848_IDATA, val & 0xff); 276 1.6 rh } 277 1.6 rh 278 1.1 pk static void 279 1.18 thorpej ad_set_MCE(struct ad1848_softc *sc, int state) 280 1.1 pk { 281 1.20 kent 282 1.1 pk if (state) 283 1.1 pk sc->MCE_bit = MODE_CHANGE_ENABLE; 284 1.1 pk else 285 1.1 pk sc->MCE_bit = 0; 286 1.1 pk ADWRITE(sc, AD1848_IADDR, sc->MCE_bit); 287 1.1 pk } 288 1.1 pk 289 1.1 pk static void 290 1.18 thorpej wait_for_calibration(struct ad1848_softc *sc) 291 1.1 pk { 292 1.1 pk int timeout; 293 1.1 pk 294 1.1 pk DPRINTF(("ad1848: Auto calibration started.\n")); 295 1.1 pk /* 296 1.1 pk * Wait until the auto calibration process has finished. 297 1.1 pk * 298 1.1 pk * 1) Wait until the chip becomes ready (reads don't return 0x80). 299 1.1 pk * 2) Wait until the ACI bit of I11 gets on and then off. 300 1.1 pk * Because newer chips are fast we may never see the ACI 301 1.1 pk * bit go on. Just delay a little instead. 302 1.1 pk */ 303 1.1 pk timeout = 10000; 304 1.1 pk while (timeout > 0 && ADREAD(sc, AD1848_IADDR) == SP_IN_INIT) { 305 1.1 pk delay(10); 306 1.1 pk timeout--; 307 1.1 pk } 308 1.23 christos if (timeout <= 0) { 309 1.1 pk DPRINTF(("ad1848: Auto calibration timed out(1).\n")); 310 1.23 christos } 311 1.1 pk 312 1.1 pk /* Set register addr */ 313 1.1 pk ADWRITE(sc, AD1848_IADDR, SP_TEST_AND_INIT); 314 1.1 pk /* Wait for address to appear when read back. */ 315 1.1 pk timeout = 100000; 316 1.1 pk while (timeout > 0 && 317 1.1 pk (ADREAD(sc, AD1848_IADDR)&SP_IADDR_MASK) != SP_TEST_AND_INIT) { 318 1.1 pk delay(10); 319 1.1 pk timeout--; 320 1.1 pk } 321 1.23 christos if (timeout <= 0) { 322 1.1 pk DPRINTF(("ad1848: Auto calibration timed out(1.5).\n")); 323 1.23 christos } 324 1.1 pk 325 1.1 pk if (!(ad_read(sc, SP_TEST_AND_INIT) & AUTO_CAL_IN_PROG)) { 326 1.1 pk if (sc->mode > 1) { 327 1.1 pk /* A new chip, just delay a little. */ 328 1.20 kent delay(100); /* XXX what should it be? */ 329 1.1 pk } else { 330 1.1 pk timeout = 10000; 331 1.1 pk while (timeout > 0 && 332 1.1 pk !(ad_read(sc, SP_TEST_AND_INIT) & 333 1.1 pk AUTO_CAL_IN_PROG)) { 334 1.1 pk delay(10); 335 1.1 pk timeout--; 336 1.1 pk } 337 1.23 christos if (timeout <= 0) { 338 1.1 pk DPRINTF(("ad1848: Auto calibration timed out(2).\n")); 339 1.23 christos } 340 1.1 pk } 341 1.1 pk } 342 1.1 pk 343 1.1 pk timeout = 10000; 344 1.1 pk while (timeout > 0 && 345 1.1 pk ad_read(sc, SP_TEST_AND_INIT) & AUTO_CAL_IN_PROG) { 346 1.1 pk delay(10); 347 1.1 pk timeout--; 348 1.1 pk } 349 1.23 christos if (timeout <= 0) { 350 1.1 pk DPRINTF(("ad1848: Auto calibration timed out(3).\n")); 351 1.23 christos } 352 1.1 pk } 353 1.1 pk 354 1.1 pk #ifdef AUDIO_DEBUG 355 1.1 pk void 356 1.18 thorpej ad1848_dump_regs(struct ad1848_softc *sc) 357 1.1 pk { 358 1.1 pk int i; 359 1.1 pk u_char r; 360 1.1 pk 361 1.1 pk printf("ad1848 status=%02x", ADREAD(sc, AD1848_STATUS)); 362 1.1 pk printf(" regs: "); 363 1.1 pk for (i = 0; i < 16; i++) { 364 1.1 pk r = ad_read(sc, i); 365 1.1 pk printf("%02x ", r); 366 1.1 pk } 367 1.6 rh if (sc->mode >= 2) { 368 1.1 pk for (i = 16; i < 32; i++) { 369 1.1 pk r = ad_read(sc, i); 370 1.1 pk printf("%02x ", r); 371 1.1 pk } 372 1.1 pk } 373 1.1 pk printf("\n"); 374 1.1 pk } 375 1.18 thorpej #endif /* AUDIO_DEBUG */ 376 1.1 pk 377 1.1 pk 378 1.1 pk /* 379 1.1 pk * Attach hardware to driver, attach hardware driver to audio 380 1.1 pk * pseudo-device driver . 381 1.1 pk */ 382 1.1 pk void 383 1.18 thorpej ad1848_attach(struct ad1848_softc *sc) 384 1.1 pk { 385 1.1 pk static struct ad1848_volume vol_mid = {220, 220}; 386 1.1 pk static struct ad1848_volume vol_0 = {0, 0}; 387 1.20 kent int i; 388 1.1 pk int timeout; 389 1.1 pk 390 1.1 pk /* Initialize the ad1848... */ 391 1.1 pk for (i = 0; i < 0x10; i++) { 392 1.1 pk ad_write(sc, i, ad1848_init_values[i]); 393 1.1 pk timeout = 100000; 394 1.7 itohy while (timeout > 0 && ADREAD(sc, AD1848_IADDR) & SP_IN_INIT) 395 1.1 pk timeout--; 396 1.1 pk } 397 1.1 pk /* ...and additional CS4231 stuff too */ 398 1.6 rh if (sc->mode >= 2) { 399 1.1 pk ad_write(sc, SP_INTERFACE_CONFIG, 0); /* disable SINGLE_DMA */ 400 1.1 pk for (i = 0x10; i < 0x20; i++) 401 1.1 pk if (ad1848_init_values[i] != 0) { 402 1.1 pk ad_write(sc, i, ad1848_init_values[i]); 403 1.1 pk timeout = 100000; 404 1.1 pk while (timeout > 0 && 405 1.7 itohy ADREAD(sc, AD1848_IADDR) & SP_IN_INIT) 406 1.1 pk timeout--; 407 1.1 pk } 408 1.1 pk } 409 1.1 pk ad1848_reset(sc); 410 1.1 pk 411 1.1 pk /* Set default gains */ 412 1.1 pk ad1848_set_rec_gain(sc, &vol_mid); 413 1.1 pk ad1848_set_channel_gain(sc, AD1848_DAC_CHANNEL, &vol_mid); 414 1.1 pk ad1848_set_channel_gain(sc, AD1848_MONITOR_CHANNEL, &vol_0); 415 1.1 pk ad1848_set_channel_gain(sc, AD1848_AUX1_CHANNEL, &vol_mid); /* CD volume */ 416 1.7 itohy sc->mute[AD1848_MONITOR_CHANNEL] = MUTE_ALL; 417 1.11 itohy if (sc->mode >= 2 418 1.11 itohy #if AD1845_HACK 419 1.11 itohy && sc->is_ad1845 == 0 420 1.11 itohy #endif 421 1.11 itohy ) { 422 1.1 pk ad1848_set_channel_gain(sc, AD1848_AUX2_CHANNEL, &vol_mid); /* CD volume */ 423 1.1 pk ad1848_set_channel_gain(sc, AD1848_LINE_CHANNEL, &vol_mid); 424 1.1 pk ad1848_set_channel_gain(sc, AD1848_MONO_CHANNEL, &vol_0); 425 1.1 pk sc->mute[AD1848_MONO_CHANNEL] = MUTE_ALL; 426 1.1 pk } else 427 1.1 pk ad1848_set_channel_gain(sc, AD1848_AUX2_CHANNEL, &vol_0); 428 1.1 pk 429 1.1 pk /* Set default port */ 430 1.1 pk ad1848_set_rec_port(sc, MIC_IN_PORT); 431 1.1 pk 432 1.1 pk printf(": %s", sc->chip_name); 433 1.1 pk } 434 1.1 pk 435 1.1 pk /* 436 1.1 pk * Various routines to interface to higher level audio driver 437 1.1 pk */ 438 1.18 thorpej static const struct ad1848_mixerinfo { 439 1.1 pk int left_reg; 440 1.1 pk int right_reg; 441 1.1 pk int atten_bits; 442 1.1 pk int atten_mask; 443 1.1 pk } mixer_channel_info[] = 444 1.1 pk { 445 1.1 pk { SP_LEFT_AUX2_CONTROL, SP_RIGHT_AUX2_CONTROL, AUX_INPUT_ATTEN_BITS, 446 1.1 pk AUX_INPUT_ATTEN_MASK }, 447 1.1 pk { SP_LEFT_AUX1_CONTROL, SP_RIGHT_AUX1_CONTROL, AUX_INPUT_ATTEN_BITS, 448 1.1 pk AUX_INPUT_ATTEN_MASK }, 449 1.1 pk { SP_LEFT_OUTPUT_CONTROL, SP_RIGHT_OUTPUT_CONTROL, 450 1.1 pk OUTPUT_ATTEN_BITS, OUTPUT_ATTEN_MASK }, 451 1.1 pk { CS_LEFT_LINE_CONTROL, CS_RIGHT_LINE_CONTROL, LINE_INPUT_ATTEN_BITS, 452 1.1 pk LINE_INPUT_ATTEN_MASK }, 453 1.1 pk { CS_MONO_IO_CONTROL, 0, MONO_INPUT_ATTEN_BITS, MONO_INPUT_ATTEN_MASK }, 454 1.15 martin { CS_MONO_IO_CONTROL, 0, 0, 0 }, 455 1.1 pk { SP_DIGITAL_MIX, 0, OUTPUT_ATTEN_BITS, MIX_ATTEN_MASK } 456 1.1 pk }; 457 1.1 pk 458 1.1 pk /* 459 1.1 pk * This function doesn't set the mute flags but does use them. 460 1.1 pk * The mute flags reflect the mutes that have been applied by the user. 461 1.34 andvar * However, the driver occasionally wants to mute devices (e.g. when changing 462 1.1 pk * sampling rate). These operations should not affect the mute flags. 463 1.1 pk */ 464 1.1 pk 465 1.1 pk void 466 1.18 thorpej ad1848_mute_channel(struct ad1848_softc *sc, int device, int mute) 467 1.1 pk { 468 1.1 pk u_char reg; 469 1.1 pk 470 1.1 pk reg = ad_read(sc, mixer_channel_info[device].left_reg); 471 1.1 pk 472 1.1 pk if (mute & MUTE_LEFT) { 473 1.7 itohy if (device == AD1848_MONITOR_CHANNEL) { 474 1.7 itohy if (sc->open_mode & FREAD) 475 1.7 itohy ad1848_mute_wave_output(sc, WAVE_UNMUTE1, 0); 476 1.1 pk ad_write(sc, mixer_channel_info[device].left_reg, 477 1.7 itohy reg & ~DIGITAL_MIX1_ENABLE); 478 1.15 martin } else if (device == AD1848_OUT_CHANNEL) 479 1.15 martin ad_write(sc, mixer_channel_info[device].left_reg, 480 1.15 martin reg | MONO_OUTPUT_MUTE); 481 1.15 martin else 482 1.1 pk ad_write(sc, mixer_channel_info[device].left_reg, 483 1.1 pk reg | 0x80); 484 1.1 pk } else if (!(sc->mute[device] & MUTE_LEFT)) { 485 1.7 itohy if (device == AD1848_MONITOR_CHANNEL) { 486 1.1 pk ad_write(sc, mixer_channel_info[device].left_reg, 487 1.7 itohy reg | DIGITAL_MIX1_ENABLE); 488 1.7 itohy if (sc->open_mode & FREAD) 489 1.7 itohy ad1848_mute_wave_output(sc, WAVE_UNMUTE1, 1); 490 1.15 martin } else if (device == AD1848_OUT_CHANNEL) 491 1.15 martin ad_write(sc, mixer_channel_info[device].left_reg, 492 1.15 martin reg & ~MONO_OUTPUT_MUTE); 493 1.15 martin else 494 1.1 pk ad_write(sc, mixer_channel_info[device].left_reg, 495 1.1 pk reg & ~0x80); 496 1.1 pk } 497 1.1 pk 498 1.1 pk if (!mixer_channel_info[device].right_reg) 499 1.1 pk return; 500 1.1 pk 501 1.1 pk reg = ad_read(sc, mixer_channel_info[device].right_reg); 502 1.1 pk 503 1.1 pk if (mute & MUTE_RIGHT) { 504 1.1 pk ad_write(sc, mixer_channel_info[device].right_reg, reg | 0x80); 505 1.1 pk } else if (!(sc->mute[device] & MUTE_RIGHT)) { 506 1.1 pk ad_write(sc, mixer_channel_info[device].right_reg, reg &~0x80); 507 1.1 pk } 508 1.1 pk } 509 1.1 pk 510 1.1 pk int 511 1.18 thorpej ad1848_set_channel_gain(struct ad1848_softc *sc, int device, 512 1.18 thorpej struct ad1848_volume *gp) 513 1.1 pk { 514 1.20 kent const struct ad1848_mixerinfo *info; 515 1.1 pk u_char reg; 516 1.1 pk u_int atten; 517 1.1 pk 518 1.20 kent info = &mixer_channel_info[device]; 519 1.1 pk sc->gains[device] = *gp; 520 1.1 pk 521 1.7 itohy atten = (AUDIO_MAX_GAIN - gp->left) * (info->atten_bits + 1) / 522 1.7 itohy (AUDIO_MAX_GAIN + 1); 523 1.1 pk 524 1.1 pk reg = ad_read(sc, info->left_reg) & (info->atten_mask); 525 1.1 pk if (device == AD1848_MONITOR_CHANNEL) 526 1.1 pk reg |= ((atten & info->atten_bits) << 2); 527 1.1 pk else 528 1.1 pk reg |= ((atten & info->atten_bits)); 529 1.1 pk 530 1.1 pk ad_write(sc, info->left_reg, reg); 531 1.1 pk 532 1.1 pk if (!info->right_reg) 533 1.20 kent return 0; 534 1.1 pk 535 1.7 itohy atten = (AUDIO_MAX_GAIN - gp->right) * (info->atten_bits + 1) / 536 1.7 itohy (AUDIO_MAX_GAIN + 1); 537 1.1 pk reg = ad_read(sc, info->right_reg); 538 1.1 pk reg &= info->atten_mask; 539 1.1 pk ad_write(sc, info->right_reg, (atten & info->atten_bits) | reg); 540 1.1 pk 541 1.20 kent return 0; 542 1.1 pk } 543 1.1 pk 544 1.1 pk int 545 1.18 thorpej ad1848_get_device_gain(struct ad1848_softc *sc, int device, 546 1.18 thorpej struct ad1848_volume *gp) 547 1.1 pk { 548 1.20 kent 549 1.1 pk *gp = sc->gains[device]; 550 1.20 kent return 0; 551 1.1 pk } 552 1.1 pk 553 1.1 pk int 554 1.18 thorpej ad1848_get_rec_gain(struct ad1848_softc *sc, struct ad1848_volume *gp) 555 1.1 pk { 556 1.20 kent 557 1.1 pk *gp = sc->rec_gain; 558 1.20 kent return 0; 559 1.1 pk } 560 1.1 pk 561 1.1 pk int 562 1.18 thorpej ad1848_set_rec_gain(struct ad1848_softc *sc, struct ad1848_volume *gp) 563 1.1 pk { 564 1.1 pk u_char reg, gain; 565 1.1 pk 566 1.1 pk DPRINTF(("ad1848_set_rec_gain: %d:%d\n", gp->left, gp->right)); 567 1.1 pk 568 1.1 pk sc->rec_gain = *gp; 569 1.1 pk 570 1.7 itohy gain = (gp->left * (GAIN_22_5 + 1)) / (AUDIO_MAX_GAIN + 1); 571 1.1 pk reg = ad_read(sc, SP_LEFT_INPUT_CONTROL); 572 1.1 pk reg &= INPUT_GAIN_MASK; 573 1.1 pk ad_write(sc, SP_LEFT_INPUT_CONTROL, (gain & 0x0f) | reg); 574 1.1 pk 575 1.7 itohy gain = (gp->right * (GAIN_22_5 + 1)) / (AUDIO_MAX_GAIN + 1); 576 1.1 pk reg = ad_read(sc, SP_RIGHT_INPUT_CONTROL); 577 1.1 pk reg &= INPUT_GAIN_MASK; 578 1.1 pk ad_write(sc, SP_RIGHT_INPUT_CONTROL, (gain & 0x0f) | reg); 579 1.1 pk 580 1.20 kent return 0; 581 1.1 pk } 582 1.1 pk 583 1.1 pk void 584 1.18 thorpej ad1848_mute_wave_output(struct ad1848_softc *sc, int mute, int set) 585 1.1 pk { 586 1.7 itohy int m; 587 1.7 itohy 588 1.7 itohy DPRINTF(("ad1848_mute_wave_output: %d, %d\n", mute, set)); 589 1.1 pk 590 1.7 itohy if (mute == WAVE_MUTE2_INIT) { 591 1.7 itohy sc->wave_mute_status = 0; 592 1.7 itohy mute = WAVE_MUTE2; 593 1.1 pk } 594 1.7 itohy if (set) 595 1.7 itohy m = sc->wave_mute_status |= mute; 596 1.7 itohy else 597 1.7 itohy m = sc->wave_mute_status &= ~mute; 598 1.1 pk 599 1.7 itohy if (m & WAVE_MUTE0 || ((m & WAVE_UNMUTE1) == 0 && m & WAVE_MUTE2)) 600 1.7 itohy ad1848_mute_channel(sc, AD1848_DAC_CHANNEL, MUTE_ALL); 601 1.7 itohy else 602 1.7 itohy ad1848_mute_channel(sc, AD1848_DAC_CHANNEL, 603 1.7 itohy sc->mute[AD1848_DAC_CHANNEL]); 604 1.1 pk } 605 1.1 pk 606 1.1 pk int 607 1.18 thorpej ad1848_set_mic_gain(struct ad1848_softc *sc, struct ad1848_volume *gp) 608 1.1 pk { 609 1.1 pk u_char reg; 610 1.1 pk 611 1.1 pk DPRINTF(("cs4231_set_mic_gain: %d\n", gp->left)); 612 1.1 pk 613 1.1 pk if (gp->left > AUDIO_MAX_GAIN/2) { 614 1.1 pk sc->mic_gain_on = 1; 615 1.1 pk reg = ad_read(sc, SP_LEFT_INPUT_CONTROL); 616 1.1 pk ad_write(sc, SP_LEFT_INPUT_CONTROL, 617 1.1 pk reg | INPUT_MIC_GAIN_ENABLE); 618 1.1 pk } else { 619 1.1 pk sc->mic_gain_on = 0; 620 1.1 pk reg = ad_read(sc, SP_LEFT_INPUT_CONTROL); 621 1.1 pk ad_write(sc, SP_LEFT_INPUT_CONTROL, 622 1.1 pk reg & ~INPUT_MIC_GAIN_ENABLE); 623 1.1 pk } 624 1.1 pk 625 1.20 kent return 0; 626 1.1 pk } 627 1.1 pk 628 1.1 pk int 629 1.18 thorpej ad1848_get_mic_gain(struct ad1848_softc *sc, struct ad1848_volume *gp) 630 1.1 pk { 631 1.1 pk if (sc->mic_gain_on) 632 1.1 pk gp->left = gp->right = AUDIO_MAX_GAIN; 633 1.1 pk else 634 1.1 pk gp->left = gp->right = AUDIO_MIN_GAIN; 635 1.20 kent return 0; 636 1.1 pk } 637 1.1 pk 638 1.27 martin static const ad1848_devmap_t * 639 1.27 martin ad1848_mixer_find_dev(const ad1848_devmap_t *map, int cnt, mixer_ctrl_t *cp) 640 1.1 pk { 641 1.1 pk int i; 642 1.1 pk 643 1.1 pk for (i = 0; i < cnt; i++) { 644 1.1 pk if (map[i].id == cp->dev) { 645 1.1 pk return (&map[i]); 646 1.1 pk } 647 1.1 pk } 648 1.20 kent return 0; 649 1.1 pk } 650 1.1 pk 651 1.1 pk int 652 1.27 martin ad1848_mixer_get_port(struct ad1848_softc *ac, const struct ad1848_devmap *map, 653 1.18 thorpej int cnt, mixer_ctrl_t *cp) 654 1.1 pk { 655 1.27 martin const ad1848_devmap_t *entry; 656 1.1 pk struct ad1848_volume vol; 657 1.20 kent int error; 658 1.1 pk int dev; 659 1.1 pk 660 1.20 kent error = EINVAL; 661 1.1 pk if (!(entry = ad1848_mixer_find_dev(map, cnt, cp))) 662 1.20 kent return ENXIO; 663 1.1 pk 664 1.1 pk dev = entry->dev; 665 1.1 pk 666 1.1 pk switch (entry->kind) { 667 1.1 pk case AD1848_KIND_LVL: 668 1.1 pk if (cp->type != AUDIO_MIXER_VALUE) 669 1.1 pk break; 670 1.1 pk 671 1.1 pk if (dev < AD1848_AUX2_CHANNEL || 672 1.1 pk dev > AD1848_MONITOR_CHANNEL) 673 1.1 pk break; 674 1.1 pk 675 1.1 pk if (cp->un.value.num_channels != 1 && 676 1.1 pk mixer_channel_info[dev].right_reg == 0) 677 1.1 pk break; 678 1.1 pk 679 1.1 pk error = ad1848_get_device_gain(ac, dev, &vol); 680 1.1 pk if (!error) 681 1.1 pk ad1848_from_vol(cp, &vol); 682 1.1 pk 683 1.1 pk break; 684 1.1 pk 685 1.1 pk case AD1848_KIND_MUTE: 686 1.1 pk if (cp->type != AUDIO_MIXER_ENUM) break; 687 1.1 pk 688 1.1 pk cp->un.ord = ac->mute[dev] ? 1 : 0; 689 1.1 pk error = 0; 690 1.1 pk break; 691 1.1 pk 692 1.1 pk case AD1848_KIND_RECORDGAIN: 693 1.1 pk if (cp->type != AUDIO_MIXER_VALUE) break; 694 1.1 pk 695 1.1 pk error = ad1848_get_rec_gain(ac, &vol); 696 1.1 pk if (!error) 697 1.1 pk ad1848_from_vol(cp, &vol); 698 1.1 pk 699 1.1 pk break; 700 1.1 pk 701 1.1 pk case AD1848_KIND_MICGAIN: 702 1.1 pk if (cp->type != AUDIO_MIXER_VALUE) break; 703 1.1 pk 704 1.1 pk error = ad1848_get_mic_gain(ac, &vol); 705 1.1 pk if (!error) 706 1.1 pk ad1848_from_vol(cp, &vol); 707 1.1 pk 708 1.1 pk break; 709 1.1 pk 710 1.1 pk case AD1848_KIND_RECORDSOURCE: 711 1.1 pk if (cp->type != AUDIO_MIXER_ENUM) break; 712 1.1 pk cp->un.ord = ad1848_get_rec_port(ac); 713 1.1 pk error = 0; 714 1.1 pk break; 715 1.1 pk 716 1.1 pk default: 717 1.1 pk printf ("Invalid kind\n"); 718 1.1 pk break; 719 1.1 pk } 720 1.1 pk 721 1.20 kent return error; 722 1.1 pk } 723 1.1 pk 724 1.1 pk int 725 1.27 martin ad1848_mixer_set_port(struct ad1848_softc *ac, const struct ad1848_devmap *map, 726 1.18 thorpej int cnt, mixer_ctrl_t *cp) 727 1.1 pk { 728 1.27 martin const ad1848_devmap_t *entry; 729 1.1 pk struct ad1848_volume vol; 730 1.20 kent int error; 731 1.1 pk int dev; 732 1.1 pk 733 1.20 kent error = EINVAL; 734 1.1 pk if (!(entry = ad1848_mixer_find_dev(map, cnt, cp))) 735 1.20 kent return ENXIO; 736 1.1 pk 737 1.1 pk dev = entry->dev; 738 1.1 pk 739 1.1 pk switch (entry->kind) { 740 1.1 pk case AD1848_KIND_LVL: 741 1.1 pk if (cp->type != AUDIO_MIXER_VALUE) 742 1.1 pk break; 743 1.1 pk 744 1.1 pk if (dev < AD1848_AUX2_CHANNEL || 745 1.1 pk dev > AD1848_MONITOR_CHANNEL) 746 1.1 pk break; 747 1.1 pk 748 1.1 pk if (cp->un.value.num_channels != 1 && 749 1.1 pk mixer_channel_info[dev].right_reg == 0) 750 1.1 pk break; 751 1.1 pk 752 1.1 pk ad1848_to_vol(cp, &vol); 753 1.1 pk error = ad1848_set_channel_gain(ac, dev, &vol); 754 1.1 pk break; 755 1.1 pk 756 1.1 pk case AD1848_KIND_MUTE: 757 1.1 pk if (cp->type != AUDIO_MIXER_ENUM) break; 758 1.1 pk 759 1.1 pk ac->mute[dev] = (cp->un.ord ? MUTE_ALL : 0); 760 1.1 pk ad1848_mute_channel(ac, dev, ac->mute[dev]); 761 1.1 pk error = 0; 762 1.1 pk break; 763 1.1 pk 764 1.1 pk case AD1848_KIND_RECORDGAIN: 765 1.1 pk if (cp->type != AUDIO_MIXER_VALUE) break; 766 1.1 pk 767 1.1 pk ad1848_to_vol(cp, &vol); 768 1.1 pk error = ad1848_set_rec_gain(ac, &vol); 769 1.1 pk break; 770 1.1 pk 771 1.1 pk case AD1848_KIND_MICGAIN: 772 1.1 pk if (cp->type != AUDIO_MIXER_VALUE) break; 773 1.1 pk 774 1.1 pk ad1848_to_vol(cp, &vol); 775 1.1 pk error = ad1848_set_mic_gain(ac, &vol); 776 1.1 pk break; 777 1.1 pk 778 1.1 pk case AD1848_KIND_RECORDSOURCE: 779 1.1 pk if (cp->type != AUDIO_MIXER_ENUM) break; 780 1.1 pk 781 1.1 pk error = ad1848_set_rec_port(ac, cp->un.ord); 782 1.1 pk break; 783 1.1 pk 784 1.1 pk default: 785 1.1 pk printf ("Invalid kind\n"); 786 1.1 pk break; 787 1.1 pk } 788 1.1 pk 789 1.20 kent return error; 790 1.1 pk } 791 1.1 pk 792 1.1 pk int 793 1.32 isaki ad1848_query_format(void *addr, audio_format_query_t *afp) 794 1.1 pk { 795 1.1 pk 796 1.32 isaki return audio_query_format(ad1848_formats, AD1848_NFORMATS, afp); 797 1.1 pk } 798 1.1 pk 799 1.1 pk int 800 1.32 isaki ad1848_set_format(void *addr, int setmode, 801 1.32 isaki const audio_params_t *p, const audio_params_t *r, 802 1.32 isaki audio_filter_reg_t *pfil, audio_filter_reg_t *rfil) 803 1.1 pk { 804 1.20 kent struct ad1848_softc *sc; 805 1.32 isaki int rate; 806 1.32 isaki int error; 807 1.1 pk 808 1.32 isaki /* *p and *r are the identical because !AUDIO_PROP_INDEPENDENT. */ 809 1.32 isaki DPRINTF(("%s: %u %u %u %u\n", __func__, 810 1.32 isaki p->encoding, p->precision, p->channels, p->sample_rate)); 811 1.1 pk 812 1.20 kent sc = addr; 813 1.1 pk 814 1.32 isaki rate = p->sample_rate; 815 1.32 isaki error = ad1848_set_speed(sc, &rate); 816 1.1 pk if (error) 817 1.1 pk return error; 818 1.1 pk 819 1.32 isaki sc->format_bits = FMT_TWOS_COMP >> 5; 820 1.1 pk sc->channels = p->channels; 821 1.1 pk sc->precision = p->precision; 822 1.1 pk sc->need_commit = 1; 823 1.1 pk 824 1.32 isaki DPRINTF(("%s succeeded\n", __func__)); 825 1.20 kent return 0; 826 1.1 pk } 827 1.1 pk 828 1.1 pk int 829 1.18 thorpej ad1848_set_rec_port(struct ad1848_softc *sc, int port) 830 1.1 pk { 831 1.1 pk u_char inp, reg; 832 1.7 itohy 833 1.1 pk DPRINTF(("ad1848_set_rec_port: 0x%x\n", port)); 834 1.1 pk 835 1.1 pk if (port == MIC_IN_PORT) 836 1.1 pk inp = MIC_INPUT; 837 1.1 pk else if (port == LINE_IN_PORT) 838 1.1 pk inp = LINE_INPUT; 839 1.1 pk else if (port == DAC_IN_PORT) 840 1.1 pk inp = MIXED_DAC_INPUT; 841 1.6 rh else if (sc->mode >= 2 && port == AUX1_IN_PORT) 842 1.1 pk inp = AUX_INPUT; 843 1.1 pk else 844 1.20 kent return EINVAL; 845 1.1 pk 846 1.1 pk reg = ad_read(sc, SP_LEFT_INPUT_CONTROL); 847 1.1 pk reg &= INPUT_SOURCE_MASK; 848 1.1 pk ad_write(sc, SP_LEFT_INPUT_CONTROL, (inp|reg)); 849 1.1 pk 850 1.1 pk reg = ad_read(sc, SP_RIGHT_INPUT_CONTROL); 851 1.1 pk reg &= INPUT_SOURCE_MASK; 852 1.1 pk ad_write(sc, SP_RIGHT_INPUT_CONTROL, (inp|reg)); 853 1.1 pk 854 1.1 pk sc->rec_port = port; 855 1.1 pk 856 1.20 kent return 0; 857 1.1 pk } 858 1.1 pk 859 1.1 pk int 860 1.18 thorpej ad1848_get_rec_port(struct ad1848_softc *sc) 861 1.1 pk { 862 1.20 kent return sc->rec_port; 863 1.1 pk } 864 1.1 pk 865 1.1 pk int 866 1.18 thorpej ad1848_open(void *addr, int flags) 867 1.1 pk { 868 1.20 kent struct ad1848_softc *sc; 869 1.5 mycroft u_char reg; 870 1.1 pk 871 1.20 kent sc = addr; 872 1.1 pk DPRINTF(("ad1848_open: sc=%p\n", sc)); 873 1.1 pk 874 1.7 itohy sc->open_mode = flags; 875 1.7 itohy 876 1.1 pk /* Enable interrupts */ 877 1.1 pk DPRINTF(("ad1848_open: enable intrs\n")); 878 1.5 mycroft reg = ad_read(sc, SP_PIN_CONTROL); 879 1.5 mycroft ad_write(sc, SP_PIN_CONTROL, reg | INTERRUPT_ENABLE); 880 1.1 pk 881 1.7 itohy /* If recording && monitoring, the playback part is also used. */ 882 1.7 itohy if (flags & FREAD && sc->mute[AD1848_MONITOR_CHANNEL] == 0) 883 1.7 itohy ad1848_mute_wave_output(sc, WAVE_UNMUTE1, 1); 884 1.7 itohy 885 1.1 pk #ifdef AUDIO_DEBUG 886 1.1 pk if (ad1848debug) 887 1.1 pk ad1848_dump_regs(sc); 888 1.1 pk #endif 889 1.1 pk 890 1.1 pk return 0; 891 1.1 pk } 892 1.1 pk 893 1.1 pk void 894 1.18 thorpej ad1848_close(void *addr) 895 1.1 pk { 896 1.20 kent struct ad1848_softc *sc; 897 1.5 mycroft u_char reg; 898 1.1 pk 899 1.20 kent sc = addr; 900 1.7 itohy sc->open_mode = 0; 901 1.7 itohy 902 1.7 itohy ad1848_mute_wave_output(sc, WAVE_UNMUTE1, 0); 903 1.7 itohy 904 1.1 pk /* Disable interrupts */ 905 1.1 pk DPRINTF(("ad1848_close: disable intrs\n")); 906 1.5 mycroft reg = ad_read(sc, SP_PIN_CONTROL); 907 1.5 mycroft ad_write(sc, SP_PIN_CONTROL, reg & ~INTERRUPT_ENABLE); 908 1.1 pk 909 1.1 pk #ifdef AUDIO_DEBUG 910 1.1 pk if (ad1848debug) 911 1.1 pk ad1848_dump_regs(sc); 912 1.1 pk #endif 913 1.1 pk } 914 1.1 pk 915 1.1 pk /* 916 1.1 pk * Lower-level routines 917 1.1 pk */ 918 1.1 pk int 919 1.18 thorpej ad1848_commit_settings(void *addr) 920 1.1 pk { 921 1.20 kent struct ad1848_softc *sc; 922 1.1 pk int timeout; 923 1.1 pk u_char fs; 924 1.1 pk 925 1.20 kent sc = addr; 926 1.1 pk if (!sc->need_commit) 927 1.1 pk return 0; 928 1.1 pk 929 1.31 jmcneill mutex_spin_enter(&sc->sc_intr_lock); 930 1.1 pk 931 1.7 itohy ad1848_mute_wave_output(sc, WAVE_MUTE0, 1); 932 1.1 pk 933 1.1 pk ad_set_MCE(sc, 1); /* Enables changes to the format select reg */ 934 1.1 pk 935 1.1 pk fs = sc->speed_bits | (sc->format_bits << 5); 936 1.1 pk 937 1.1 pk if (sc->channels == 2) 938 1.1 pk fs |= FMT_STEREO; 939 1.14 itohy 940 1.14 itohy /* 941 1.14 itohy * OPL3-SA2 (YMF711) is sometimes busy here. 942 1.14 itohy * Wait until it becomes ready. 943 1.14 itohy */ 944 1.14 itohy for (timeout = 0; 945 1.14 itohy timeout < 1000 && ADREAD(sc, AD1848_IADDR) & SP_IN_INIT; timeout++) 946 1.14 itohy delay(10); 947 1.1 pk 948 1.1 pk ad_write(sc, SP_CLOCK_DATA_FORMAT, fs); 949 1.1 pk 950 1.1 pk /* 951 1.6 rh * If mode >= 2 (CS4231), set I28 also. 952 1.1 pk * It's the capture format register. 953 1.1 pk */ 954 1.6 rh if (sc->mode >= 2) { 955 1.1 pk /* 956 1.1 pk * Gravis Ultrasound MAX SDK sources says something about 957 1.1 pk * errata sheets, with the implication that these inb()s 958 1.1 pk * are necessary. 959 1.1 pk */ 960 1.1 pk (void)ADREAD(sc, AD1848_IDATA); 961 1.1 pk (void)ADREAD(sc, AD1848_IDATA); 962 1.16 wiz /* Write to I8 starts resynchronization. Wait for completion. */ 963 1.1 pk timeout = 100000; 964 1.1 pk while (timeout > 0 && ADREAD(sc, AD1848_IADDR) == SP_IN_INIT) 965 1.1 pk timeout--; 966 1.1 pk 967 1.1 pk ad_write(sc, CS_REC_FORMAT, fs); 968 1.1 pk (void)ADREAD(sc, AD1848_IDATA); 969 1.1 pk (void)ADREAD(sc, AD1848_IDATA); 970 1.1 pk /* Now wait for resync for capture side of the house */ 971 1.1 pk } 972 1.1 pk /* 973 1.16 wiz * Write to I8 starts resynchronization. Wait until it completes. 974 1.1 pk */ 975 1.1 pk timeout = 100000; 976 1.8 thorpej while (timeout > 0 && ADREAD(sc, AD1848_IADDR) == SP_IN_INIT) { 977 1.8 thorpej delay(10); 978 1.1 pk timeout--; 979 1.8 thorpej } 980 1.1 pk 981 1.1 pk if (ADREAD(sc, AD1848_IADDR) == SP_IN_INIT) 982 1.1 pk printf("ad1848_commit: Auto calibration timed out\n"); 983 1.1 pk 984 1.1 pk /* 985 1.1 pk * Starts the calibration process and 986 1.1 pk * enters playback mode after it. 987 1.1 pk */ 988 1.1 pk ad_set_MCE(sc, 0); 989 1.1 pk wait_for_calibration(sc); 990 1.1 pk 991 1.7 itohy ad1848_mute_wave_output(sc, WAVE_MUTE0, 0); 992 1.1 pk 993 1.31 jmcneill mutex_spin_exit(&sc->sc_intr_lock); 994 1.1 pk 995 1.1 pk sc->need_commit = 0; 996 1.31 jmcneill 997 1.1 pk return 0; 998 1.1 pk } 999 1.1 pk 1000 1.1 pk void 1001 1.18 thorpej ad1848_reset(struct ad1848_softc *sc) 1002 1.1 pk { 1003 1.1 pk u_char r; 1004 1.1 pk 1005 1.1 pk DPRINTF(("ad1848_reset\n")); 1006 1.1 pk 1007 1.1 pk /* Clear the PEN and CEN bits */ 1008 1.1 pk r = ad_read(sc, SP_INTERFACE_CONFIG); 1009 1.1 pk r &= ~(CAPTURE_ENABLE | PLAYBACK_ENABLE); 1010 1.1 pk ad_write(sc, SP_INTERFACE_CONFIG, r); 1011 1.1 pk 1012 1.6 rh if (sc->mode >= 2) { 1013 1.1 pk ADWRITE(sc, AD1848_IADDR, CS_IRQ_STATUS); 1014 1.1 pk ADWRITE(sc, AD1848_IDATA, 0); 1015 1.1 pk } 1016 1.1 pk /* Clear interrupt status */ 1017 1.1 pk ADWRITE(sc, AD1848_STATUS, 0); 1018 1.1 pk #ifdef AUDIO_DEBUG 1019 1.1 pk if (ad1848debug) 1020 1.1 pk ad1848_dump_regs(sc); 1021 1.1 pk #endif 1022 1.1 pk } 1023 1.1 pk 1024 1.1 pk int 1025 1.19 kent ad1848_set_speed(struct ad1848_softc *sc, u_int *argp) 1026 1.1 pk { 1027 1.1 pk /* 1028 1.1 pk * The sampling speed is encoded in the least significant nible of I8. 1029 1.17 tsutsui * The LSB selects the clock source (0=24.576 MHz, 1=16.9344 MHz) and 1030 1.1 pk * other three bits select the divisor (indirectly): 1031 1.1 pk * 1032 1.1 pk * The available speeds are in the following table. Keep the speeds in 1033 1.1 pk * the increasing order. 1034 1.1 pk */ 1035 1.1 pk typedef struct { 1036 1.1 pk int speed; 1037 1.1 pk u_char bits; 1038 1.1 pk } speed_struct; 1039 1.20 kent u_long arg; 1040 1.1 pk 1041 1.10 jdolecek static const speed_struct speed_table[] = { 1042 1.1 pk {5510, (0 << 1) | 1}, 1043 1.1 pk {5510, (0 << 1) | 1}, 1044 1.1 pk {6620, (7 << 1) | 1}, 1045 1.1 pk {8000, (0 << 1) | 0}, 1046 1.1 pk {9600, (7 << 1) | 0}, 1047 1.1 pk {11025, (1 << 1) | 1}, 1048 1.1 pk {16000, (1 << 1) | 0}, 1049 1.1 pk {18900, (2 << 1) | 1}, 1050 1.1 pk {22050, (3 << 1) | 1}, 1051 1.1 pk {27420, (2 << 1) | 0}, 1052 1.1 pk {32000, (3 << 1) | 0}, 1053 1.1 pk {33075, (6 << 1) | 1}, 1054 1.1 pk {37800, (4 << 1) | 1}, 1055 1.1 pk {44100, (5 << 1) | 1}, 1056 1.1 pk {48000, (6 << 1) | 0} 1057 1.1 pk }; 1058 1.1 pk 1059 1.20 kent int i, n, selected; 1060 1.1 pk 1061 1.20 kent arg = *argp; 1062 1.20 kent selected = -1; 1063 1.1 pk n = sizeof(speed_table) / sizeof(speed_struct); 1064 1.1 pk 1065 1.1 pk if (arg < speed_table[0].speed) 1066 1.1 pk selected = 0; 1067 1.1 pk if (arg > speed_table[n - 1].speed) 1068 1.1 pk selected = n - 1; 1069 1.1 pk 1070 1.1 pk for (i = 1 /*really*/ ; selected == -1 && i < n; i++) 1071 1.1 pk if (speed_table[i].speed == arg) 1072 1.1 pk selected = i; 1073 1.1 pk else if (speed_table[i].speed > arg) { 1074 1.1 pk int diff1, diff2; 1075 1.1 pk 1076 1.1 pk diff1 = arg - speed_table[i - 1].speed; 1077 1.1 pk diff2 = speed_table[i].speed - arg; 1078 1.1 pk 1079 1.1 pk if (diff1 < diff2) 1080 1.1 pk selected = i - 1; 1081 1.1 pk else 1082 1.1 pk selected = i; 1083 1.1 pk } 1084 1.1 pk 1085 1.1 pk if (selected == -1) { 1086 1.1 pk printf("ad1848: Can't find speed???\n"); 1087 1.1 pk selected = 3; 1088 1.1 pk } 1089 1.1 pk 1090 1.1 pk sc->speed_bits = speed_table[selected].bits; 1091 1.1 pk sc->need_commit = 1; 1092 1.1 pk *argp = speed_table[selected].speed; 1093 1.1 pk 1094 1.20 kent return 0; 1095 1.1 pk } 1096 1.1 pk 1097 1.1 pk /* 1098 1.1 pk * Halt I/O 1099 1.1 pk */ 1100 1.1 pk int 1101 1.18 thorpej ad1848_halt_output(void *addr) 1102 1.1 pk { 1103 1.20 kent struct ad1848_softc *sc; 1104 1.1 pk u_char reg; 1105 1.1 pk 1106 1.5 mycroft DPRINTF(("ad1848: ad1848_halt_output\n")); 1107 1.20 kent sc = addr; 1108 1.1 pk reg = ad_read(sc, SP_INTERFACE_CONFIG); 1109 1.5 mycroft ad_write(sc, SP_INTERFACE_CONFIG, reg & ~PLAYBACK_ENABLE); 1110 1.1 pk 1111 1.20 kent return 0; 1112 1.1 pk } 1113 1.1 pk 1114 1.1 pk int 1115 1.18 thorpej ad1848_halt_input(void *addr) 1116 1.1 pk { 1117 1.20 kent struct ad1848_softc *sc; 1118 1.1 pk u_char reg; 1119 1.1 pk 1120 1.5 mycroft DPRINTF(("ad1848: ad1848_halt_input\n")); 1121 1.20 kent sc = addr; 1122 1.1 pk reg = ad_read(sc, SP_INTERFACE_CONFIG); 1123 1.5 mycroft ad_write(sc, SP_INTERFACE_CONFIG, reg & ~CAPTURE_ENABLE); 1124 1.1 pk 1125 1.20 kent return 0; 1126 1.1 pk } 1127 1.31 jmcneill 1128 1.31 jmcneill void 1129 1.31 jmcneill ad1848_get_locks(void *addr, kmutex_t **intr, kmutex_t **thread) 1130 1.31 jmcneill { 1131 1.31 jmcneill struct ad1848_softc *sc; 1132 1.31 jmcneill 1133 1.31 jmcneill sc = addr; 1134 1.31 jmcneill *intr = &sc->sc_intr_lock; 1135 1.31 jmcneill *thread = &sc->sc_lock; 1136 1.31 jmcneill } 1137 1.31 jmcneill 1138 1.31 jmcneill void 1139 1.31 jmcneill ad1848_init_locks(struct ad1848_softc *sc, int ipl) 1140 1.31 jmcneill { 1141 1.31 jmcneill 1142 1.31 jmcneill mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE); 1143 1.31 jmcneill mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, ipl); 1144 1.31 jmcneill } 1145 1.31 jmcneill 1146 1.31 jmcneill void 1147 1.31 jmcneill ad1848_destroy_locks(struct ad1848_softc *sc) 1148 1.31 jmcneill { 1149 1.31 jmcneill 1150 1.31 jmcneill mutex_destroy(&sc->sc_lock); 1151 1.31 jmcneill mutex_destroy(&sc->sc_intr_lock); 1152 1.31 jmcneill } 1153