1 /* $OpenBSD: gus.c,v 1.50 2022/03/21 19:22:40 miod Exp $ */ 2 /* $NetBSD: gus.c,v 1.51 1998/01/25 23:48:06 mycroft Exp $ */ 3 4 /*- 5 * Copyright (c) 1996 The NetBSD Foundation, Inc. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to The NetBSD Foundation 9 * by Ken Hornstein and John Kohl. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 /* 34 * 35 * TODO: 36 * . figure out why mixer activity while sound is playing causes problems 37 * (phantom interrupts?) 38 * . figure out a better deinterleave strategy that avoids sucking up 39 * CPU, memory and cache bandwidth. (Maybe a special encoding? 40 * Maybe use the double-speed sampling/hardware deinterleave trick 41 * from the GUS SDK?) A 486/33 isn't quite fast enough to keep 42 * up with 44.1kHz 16-bit stereo output without some drop-outs. 43 * . use CS4231 for 16-bit sampling, for a-law and mu-law playback. 44 * . actually test full-duplex sampling(recording) and playback. 45 */ 46 47 /* 48 * Gravis UltraSound driver 49 * 50 * For more detailed information, see the GUS developers' kit 51 * available on the net at: 52 * 53 * http://www.gravis.com/Public/sdk/GUSDK222.ZIP 54 * 55 * See ultrawrd.doc inside--it's MS Word (ick), but it's the bible 56 * 57 */ 58 59 /* 60 * The GUS Max has a slightly strange set of connections between the CS4231 61 * and the GF1 and the DMA interconnects. It's set up so that the CS4231 can 62 * be playing while the GF1 is loading patches from the system. 63 * 64 * Here's a recreation of the DMA interconnect diagram: 65 * 66 * GF1 67 * +---------+ digital 68 * | | record ASIC 69 * | |--------------+ 70 * | | | +--------+ 71 * | | play (dram) | +----+ | | 72 * | |--------------(------|-\ | | +-+ | 73 * +---------+ | | >-|----|---|C|--|------ dma chan 1 74 * | +---|-/ | | +-+ | 75 * | | +----+ | | | 76 * | | +----+ | | | 77 * +---------+ +-+ +--(---|-\ | | | | 78 * | | play |8| | | >-|----|----+---|------ dma chan 2 79 * | ---C----|--------|/|------(---|-/ | | | 80 * | ^ |record |1| | +----+ | | 81 * | | | /----|6|------+ +--------+ 82 * | ---+----|--/ +-+ 83 * +---------+ 84 * CS4231 8-to-16 bit bus conversion, if needed 85 * 86 * 87 * "C" is an optional combiner. 88 * 89 */ 90 91 #include <sys/param.h> 92 #include <sys/systm.h> 93 #include <sys/errno.h> 94 #include <sys/ioctl.h> 95 #include <sys/syslog.h> 96 #include <sys/device.h> 97 #include <sys/buf.h> 98 #include <sys/fcntl.h> 99 #include <sys/malloc.h> 100 #include <sys/kernel.h> 101 #include <sys/timeout.h> 102 103 #include <machine/cpu.h> 104 #include <machine/intr.h> 105 #include <machine/bus.h> 106 #include <machine/cpufunc.h> 107 #include <sys/audioio.h> 108 #include <dev/audio_if.h> 109 110 #include <dev/isa/isavar.h> 111 #include <dev/isa/isadmavar.h> 112 113 #include <dev/ic/ics2101reg.h> 114 #include <dev/ic/cs4231reg.h> 115 #include <dev/ic/ad1848reg.h> 116 #include <dev/isa/ics2101var.h> 117 #include <dev/isa/ad1848var.h> 118 #include <dev/isa/cs4231var.h> 119 #include "gusreg.h" 120 #include "gusvar.h" 121 122 #ifdef AUDIO_DEBUG 123 #define GUSPLAYDEBUG /*XXX*/ 124 #define DPRINTF(x) if (gusdebug) printf x 125 #define DMAPRINTF(x) if (gusdmadebug) printf x 126 int gusdebug = 0; 127 int gusdmadebug = 0; 128 #else 129 #define DPRINTF(x) 130 #define DMAPRINTF(x) 131 #endif 132 int gus_dostereo = 1; 133 134 #define NDMARECS 2048 135 #ifdef GUSPLAYDEBUG 136 int gusstats = 0; 137 138 struct dma_record dmarecords[NDMARECS]; 139 140 int dmarecord_index = 0; 141 #endif 142 143 struct cfdriver gus_cd = { 144 NULL, "gus", DV_DULL 145 }; 146 147 /* 148 * A mapping from IRQ/DRQ values to the values used in the GUS's internal 149 * registers. A zero means that the referenced IRQ/DRQ is invalid 150 */ 151 const int gus_irq_map[] = { 152 IRQUNK, IRQUNK, 1, 3, IRQUNK, 2, IRQUNK, 4, IRQUNK, 1, IRQUNK, 5, 6, 153 IRQUNK, IRQUNK, 7 154 }; 155 const int gus_drq_map[] = { 156 DRQUNK, 1, DRQUNK, 2, DRQUNK, 3, 4, 5 157 }; 158 159 /* 160 * A list of valid base addresses for the GUS 161 */ 162 163 const int gus_base_addrs[] = { 164 0x210, 0x220, 0x230, 0x240, 0x250, 0x260 165 }; 166 const int gus_addrs = sizeof(gus_base_addrs) / sizeof(gus_base_addrs[0]); 167 168 /* 169 * Maximum frequency values of the GUS based on the number of currently active 170 * voices. Since the GUS samples a voice every 1.6 us, the maximum frequency 171 * is dependent on the number of active voices. Yes, it is pretty weird. 172 */ 173 174 static const int gus_max_frequency[] = { 175 44100, /* 14 voices */ 176 41160, /* 15 voices */ 177 38587, /* 16 voices */ 178 36317, /* 17 voices */ 179 34300, /* 18 voices */ 180 32494, /* 19 voices */ 181 30870, /* 20 voices */ 182 29400, /* 21 voices */ 183 28063, /* 22 voices */ 184 26843, /* 23 voices */ 185 25725, /* 24 voices */ 186 24696, /* 25 voices */ 187 23746, /* 26 voices */ 188 22866, /* 27 voices */ 189 22050, /* 28 voices */ 190 21289, /* 29 voices */ 191 20580, /* 30 voices */ 192 19916, /* 31 voices */ 193 19293 /* 32 voices */ 194 }; 195 /* 196 * A mapping of linear volume levels to the logarithmic volume values used 197 * by the GF1 chip on the GUS. From GUS SDK vol1.c. 198 */ 199 200 static const unsigned short gus_log_volumes[512] = { 201 0x0000, 202 0x0700, 0x07ff, 0x0880, 0x08ff, 0x0940, 0x0980, 0x09c0, 0x09ff, 0x0a20, 203 0x0a40, 0x0a60, 0x0a80, 0x0aa0, 0x0ac0, 0x0ae0, 0x0aff, 0x0b10, 0x0b20, 204 0x0b30, 0x0b40, 0x0b50, 0x0b60, 0x0b70, 0x0b80, 0x0b90, 0x0ba0, 0x0bb0, 205 0x0bc0, 0x0bd0, 0x0be0, 0x0bf0, 0x0bff, 0x0c08, 0x0c10, 0x0c18, 0x0c20, 206 0x0c28, 0x0c30, 0x0c38, 0x0c40, 0x0c48, 0x0c50, 0x0c58, 0x0c60, 0x0c68, 207 0x0c70, 0x0c78, 0x0c80, 0x0c88, 0x0c90, 0x0c98, 0x0ca0, 0x0ca8, 0x0cb0, 208 0x0cb8, 0x0cc0, 0x0cc8, 0x0cd0, 0x0cd8, 0x0ce0, 0x0ce8, 0x0cf0, 0x0cf8, 209 0x0cff, 0x0d04, 0x0d08, 0x0d0c, 0x0d10, 0x0d14, 0x0d18, 0x0d1c, 0x0d20, 210 0x0d24, 0x0d28, 0x0d2c, 0x0d30, 0x0d34, 0x0d38, 0x0d3c, 0x0d40, 0x0d44, 211 0x0d48, 0x0d4c, 0x0d50, 0x0d54, 0x0d58, 0x0d5c, 0x0d60, 0x0d64, 0x0d68, 212 0x0d6c, 0x0d70, 0x0d74, 0x0d78, 0x0d7c, 0x0d80, 0x0d84, 0x0d88, 0x0d8c, 213 0x0d90, 0x0d94, 0x0d98, 0x0d9c, 0x0da0, 0x0da4, 0x0da8, 0x0dac, 0x0db0, 214 0x0db4, 0x0db8, 0x0dbc, 0x0dc0, 0x0dc4, 0x0dc8, 0x0dcc, 0x0dd0, 0x0dd4, 215 0x0dd8, 0x0ddc, 0x0de0, 0x0de4, 0x0de8, 0x0dec, 0x0df0, 0x0df4, 0x0df8, 216 0x0dfc, 0x0dff, 0x0e02, 0x0e04, 0x0e06, 0x0e08, 0x0e0a, 0x0e0c, 0x0e0e, 217 0x0e10, 0x0e12, 0x0e14, 0x0e16, 0x0e18, 0x0e1a, 0x0e1c, 0x0e1e, 0x0e20, 218 0x0e22, 0x0e24, 0x0e26, 0x0e28, 0x0e2a, 0x0e2c, 0x0e2e, 0x0e30, 0x0e32, 219 0x0e34, 0x0e36, 0x0e38, 0x0e3a, 0x0e3c, 0x0e3e, 0x0e40, 0x0e42, 0x0e44, 220 0x0e46, 0x0e48, 0x0e4a, 0x0e4c, 0x0e4e, 0x0e50, 0x0e52, 0x0e54, 0x0e56, 221 0x0e58, 0x0e5a, 0x0e5c, 0x0e5e, 0x0e60, 0x0e62, 0x0e64, 0x0e66, 0x0e68, 222 0x0e6a, 0x0e6c, 0x0e6e, 0x0e70, 0x0e72, 0x0e74, 0x0e76, 0x0e78, 0x0e7a, 223 0x0e7c, 0x0e7e, 0x0e80, 0x0e82, 0x0e84, 0x0e86, 0x0e88, 0x0e8a, 0x0e8c, 224 0x0e8e, 0x0e90, 0x0e92, 0x0e94, 0x0e96, 0x0e98, 0x0e9a, 0x0e9c, 0x0e9e, 225 0x0ea0, 0x0ea2, 0x0ea4, 0x0ea6, 0x0ea8, 0x0eaa, 0x0eac, 0x0eae, 0x0eb0, 226 0x0eb2, 0x0eb4, 0x0eb6, 0x0eb8, 0x0eba, 0x0ebc, 0x0ebe, 0x0ec0, 0x0ec2, 227 0x0ec4, 0x0ec6, 0x0ec8, 0x0eca, 0x0ecc, 0x0ece, 0x0ed0, 0x0ed2, 0x0ed4, 228 0x0ed6, 0x0ed8, 0x0eda, 0x0edc, 0x0ede, 0x0ee0, 0x0ee2, 0x0ee4, 0x0ee6, 229 0x0ee8, 0x0eea, 0x0eec, 0x0eee, 0x0ef0, 0x0ef2, 0x0ef4, 0x0ef6, 0x0ef8, 230 0x0efa, 0x0efc, 0x0efe, 0x0eff, 0x0f01, 0x0f02, 0x0f03, 0x0f04, 0x0f05, 231 0x0f06, 0x0f07, 0x0f08, 0x0f09, 0x0f0a, 0x0f0b, 0x0f0c, 0x0f0d, 0x0f0e, 232 0x0f0f, 0x0f10, 0x0f11, 0x0f12, 0x0f13, 0x0f14, 0x0f15, 0x0f16, 0x0f17, 233 0x0f18, 0x0f19, 0x0f1a, 0x0f1b, 0x0f1c, 0x0f1d, 0x0f1e, 0x0f1f, 0x0f20, 234 0x0f21, 0x0f22, 0x0f23, 0x0f24, 0x0f25, 0x0f26, 0x0f27, 0x0f28, 0x0f29, 235 0x0f2a, 0x0f2b, 0x0f2c, 0x0f2d, 0x0f2e, 0x0f2f, 0x0f30, 0x0f31, 0x0f32, 236 0x0f33, 0x0f34, 0x0f35, 0x0f36, 0x0f37, 0x0f38, 0x0f39, 0x0f3a, 0x0f3b, 237 0x0f3c, 0x0f3d, 0x0f3e, 0x0f3f, 0x0f40, 0x0f41, 0x0f42, 0x0f43, 0x0f44, 238 0x0f45, 0x0f46, 0x0f47, 0x0f48, 0x0f49, 0x0f4a, 0x0f4b, 0x0f4c, 0x0f4d, 239 0x0f4e, 0x0f4f, 0x0f50, 0x0f51, 0x0f52, 0x0f53, 0x0f54, 0x0f55, 0x0f56, 240 0x0f57, 0x0f58, 0x0f59, 0x0f5a, 0x0f5b, 0x0f5c, 0x0f5d, 0x0f5e, 0x0f5f, 241 0x0f60, 0x0f61, 0x0f62, 0x0f63, 0x0f64, 0x0f65, 0x0f66, 0x0f67, 0x0f68, 242 0x0f69, 0x0f6a, 0x0f6b, 0x0f6c, 0x0f6d, 0x0f6e, 0x0f6f, 0x0f70, 0x0f71, 243 0x0f72, 0x0f73, 0x0f74, 0x0f75, 0x0f76, 0x0f77, 0x0f78, 0x0f79, 0x0f7a, 244 0x0f7b, 0x0f7c, 0x0f7d, 0x0f7e, 0x0f7f, 0x0f80, 0x0f81, 0x0f82, 0x0f83, 245 0x0f84, 0x0f85, 0x0f86, 0x0f87, 0x0f88, 0x0f89, 0x0f8a, 0x0f8b, 0x0f8c, 246 0x0f8d, 0x0f8e, 0x0f8f, 0x0f90, 0x0f91, 0x0f92, 0x0f93, 0x0f94, 0x0f95, 247 0x0f96, 0x0f97, 0x0f98, 0x0f99, 0x0f9a, 0x0f9b, 0x0f9c, 0x0f9d, 0x0f9e, 248 0x0f9f, 0x0fa0, 0x0fa1, 0x0fa2, 0x0fa3, 0x0fa4, 0x0fa5, 0x0fa6, 0x0fa7, 249 0x0fa8, 0x0fa9, 0x0faa, 0x0fab, 0x0fac, 0x0fad, 0x0fae, 0x0faf, 0x0fb0, 250 0x0fb1, 0x0fb2, 0x0fb3, 0x0fb4, 0x0fb5, 0x0fb6, 0x0fb7, 0x0fb8, 0x0fb9, 251 0x0fba, 0x0fbb, 0x0fbc, 0x0fbd, 0x0fbe, 0x0fbf, 0x0fc0, 0x0fc1, 0x0fc2, 252 0x0fc3, 0x0fc4, 0x0fc5, 0x0fc6, 0x0fc7, 0x0fc8, 0x0fc9, 0x0fca, 0x0fcb, 253 0x0fcc, 0x0fcd, 0x0fce, 0x0fcf, 0x0fd0, 0x0fd1, 0x0fd2, 0x0fd3, 0x0fd4, 254 0x0fd5, 0x0fd6, 0x0fd7, 0x0fd8, 0x0fd9, 0x0fda, 0x0fdb, 0x0fdc, 0x0fdd, 255 0x0fde, 0x0fdf, 0x0fe0, 0x0fe1, 0x0fe2, 0x0fe3, 0x0fe4, 0x0fe5, 0x0fe6, 256 0x0fe7, 0x0fe8, 0x0fe9, 0x0fea, 0x0feb, 0x0fec, 0x0fed, 0x0fee, 0x0fef, 257 0x0ff0, 0x0ff1, 0x0ff2, 0x0ff3, 0x0ff4, 0x0ff5, 0x0ff6, 0x0ff7, 0x0ff8, 258 0x0ff9, 0x0ffa, 0x0ffb, 0x0ffc, 0x0ffd, 0x0ffe, 0x0fff}; 259 260 /* 261 * Interface to higher level audio driver 262 */ 263 const struct audio_hw_if gus_hw_if = { 264 gusopen, 265 gusclose, 266 gus_set_params, 267 268 gus_round_blocksize, 269 270 gus_commit_settings, 271 272 NULL, 273 NULL, 274 275 gus_dma_output, 276 gus_dma_input, 277 gus_halt_out_dma, 278 gus_halt_in_dma, 279 gus_speaker_ctl, 280 281 NULL, 282 gus_mixer_set_port, 283 gus_mixer_get_port, 284 gus_mixer_query_devinfo, 285 gus_malloc, 286 gus_free, 287 gus_round, 288 gus_get_props, 289 290 NULL, 291 NULL 292 }; 293 294 const static struct audio_hw_if gusmax_hw_if = { 295 gusmaxopen, 296 gusmax_close, 297 gusmax_set_params, 298 299 gusmax_round_blocksize, 300 301 gusmax_commit_settings, 302 303 NULL, 304 NULL, 305 306 gusmax_dma_output, 307 gusmax_dma_input, 308 gusmax_halt_out_dma, 309 gusmax_halt_in_dma, 310 311 gusmax_speaker_ctl, 312 313 NULL, 314 gusmax_mixer_set_port, 315 gusmax_mixer_get_port, 316 gusmax_mixer_query_devinfo, 317 ad1848_malloc, 318 ad1848_free, 319 ad1848_round, 320 gusmax_get_props, 321 322 NULL, 323 NULL 324 }; 325 326 int 327 gusopen(void *addr, int flags) 328 { 329 struct gus_softc *sc = addr; 330 331 DPRINTF(("gusopen() called\n")); 332 333 if (sc->sc_flags & GUS_OPEN) 334 return EBUSY; 335 336 /* 337 * Some initialization 338 */ 339 340 sc->sc_flags |= GUS_OPEN; 341 sc->sc_dmabuf = 0; 342 sc->sc_playbuf = -1; 343 sc->sc_bufcnt = 0; 344 sc->sc_voc[GUS_VOICE_LEFT].start_addr = GUS_MEM_OFFSET - 1; 345 sc->sc_voc[GUS_VOICE_LEFT].current_addr = GUS_MEM_OFFSET; 346 347 if (HAS_CODEC(sc)) { 348 ad1848_open(&sc->sc_codec, flags); 349 sc->sc_codec.mute[AD1848_AUX1_CHANNEL] = 0; 350 ad1848_mute_channel(&sc->sc_codec, AD1848_AUX1_CHANNEL, 0); /* turn on DAC output */ 351 if (flags & FREAD) { 352 sc->sc_codec.mute[AD1848_MONO_CHANNEL] = 0; 353 ad1848_mute_channel(&sc->sc_codec, AD1848_MONO_CHANNEL, 0); 354 } 355 } else if (flags & FREAD) { 356 /* enable/unmute the microphone */ 357 if (HAS_MIXER(sc)) { 358 gusics_mic_mute(&sc->sc_mixer, 0); 359 } else 360 gus_mic_ctl(sc, SPKR_ON); 361 } 362 if (sc->sc_nbufs == 0) 363 gus_round_blocksize(sc, GUS_BUFFER_MULTIPLE); /* default blksiz */ 364 return 0; 365 } 366 367 int 368 gusmaxopen(void *addr, int flags) 369 { 370 struct ad1848_softc *ac = addr; 371 return gusopen(ac->parent, flags); 372 } 373 374 void 375 gus_deinterleave(struct gus_softc *sc, void *buf, int size) 376 { 377 /* deinterleave the stereo data. We can use sc->sc_deintr_buf 378 for scratch space. */ 379 int i; 380 381 if (size > sc->sc_blocksize) { 382 printf("gus: deinterleave %d > %d\n", size, sc->sc_blocksize); 383 return; 384 } else if (size < sc->sc_blocksize) { 385 DPRINTF(("gus: deinterleave %d < %d\n", size, sc->sc_blocksize)); 386 } 387 388 /* 389 * size is in bytes. 390 */ 391 if (sc->sc_precision == 16) { 392 u_short *dei = sc->sc_deintr_buf; 393 u_short *sbuf = buf; 394 size >>= 1; /* bytecnt to shortcnt */ 395 /* copy 2nd of each pair of samples to the staging area, while 396 compacting the 1st of each pair into the original area. */ 397 for (i = 0; i < size/2-1; i++) { 398 dei[i] = sbuf[i*2+1]; 399 sbuf[i+1] = sbuf[i*2+2]; 400 } 401 /* 402 * this has copied one less sample than half of the 403 * buffer. The first sample of the 1st stream was 404 * already in place and didn't need copying. 405 * Therefore, we've moved all of the 1st stream's 406 * samples into place. We have one sample from 2nd 407 * stream in the last slot of original area, not 408 * copied to the staging area (But we don't need to!). 409 * Copy the remainder of the original stream into place. 410 */ 411 bcopy(dei, &sbuf[size/2], i * sizeof(short)); 412 } else { 413 u_char *dei = sc->sc_deintr_buf; 414 u_char *sbuf = buf; 415 for (i = 0; i < size/2-1; i++) { 416 dei[i] = sbuf[i*2+1]; 417 sbuf[i+1] = sbuf[i*2+2]; 418 } 419 bcopy(dei, &sbuf[size/2], i); 420 } 421 } 422 423 /* 424 * Actually output a buffer to the DSP chip 425 */ 426 427 int 428 gusmax_dma_output(void *addr, void *buf, int size, void (*intr)(void *), 429 void *arg) 430 { 431 struct ad1848_softc *ac = addr; 432 return gus_dma_output(ac->parent, buf, size, intr, arg); 433 } 434 435 /* 436 * called at splaudio() from interrupt handler. 437 */ 438 void 439 stereo_dmaintr(void *arg) 440 { 441 struct gus_softc *sc = arg; 442 struct stereo_dma_intr *sa = &sc->sc_stereo; 443 444 DMAPRINTF(("stereo_dmaintr")); 445 446 /* 447 * Put other half in its place, then call the real interrupt routine :) 448 */ 449 450 sc->sc_dmaoutintr = sa->intr; 451 sc->sc_outarg = sa->arg; 452 453 #ifdef GUSPLAYDEBUG 454 if (gusstats) { 455 microtime(&dmarecords[dmarecord_index].tv); 456 dmarecords[dmarecord_index].gusaddr = sa->dmabuf; 457 dmarecords[dmarecord_index].bsdaddr = sa->buffer; 458 dmarecords[dmarecord_index].count = sa->size; 459 dmarecords[dmarecord_index].channel = 1; 460 dmarecords[dmarecord_index++].direction = 1; 461 dmarecord_index = dmarecord_index % NDMARECS; 462 } 463 #endif 464 465 gusdmaout(sc, sa->flags, sa->dmabuf, (caddr_t) sa->buffer, sa->size); 466 467 sa->flags = 0; 468 sa->dmabuf = 0; 469 sa->buffer = 0; 470 sa->size = 0; 471 sa->intr = 0; 472 sa->arg = 0; 473 } 474 475 /* 476 * Start up DMA output to the card. 477 * Called at splaudio(), either from intr handler or from 478 * generic audio code. 479 */ 480 int 481 gus_dma_output(void *addr, void *buf, int size, void (*intr)(void *), void *arg) 482 { 483 struct gus_softc *sc = addr; 484 u_char *buffer = buf; 485 u_long boarddma; 486 int flags; 487 488 DMAPRINTF(("gus_dma_output %d @ %p\n", size, buf)); 489 if (size != sc->sc_blocksize) { 490 DPRINTF(("gus_dma_output reqsize %d not sc_blocksize %d\n", 491 size, sc->sc_blocksize)); 492 return EINVAL; 493 } 494 495 flags = GUSMASK_DMA_WRITE; 496 if (sc->sc_precision == 16) 497 flags |= GUSMASK_DMA_DATA_SIZE; 498 if (sc->sc_encoding == AUDIO_ENCODING_ULAW || 499 sc->sc_encoding == AUDIO_ENCODING_ALAW || 500 sc->sc_encoding == AUDIO_ENCODING_ULINEAR_BE || 501 sc->sc_encoding == AUDIO_ENCODING_ULINEAR_LE) 502 flags |= GUSMASK_DMA_INVBIT; 503 504 if (sc->sc_channels == 2) { 505 if (sc->sc_precision == 16) { 506 if (size & 3) { 507 DPRINTF(("gus_dma_output: unpaired 16bit samples")); 508 size &= 3; 509 } 510 } else if (size & 1) { 511 DPRINTF(("gus_dma_output: unpaired samples")); 512 size &= 1; 513 } 514 if (size == 0) { 515 return 0; 516 } 517 518 gus_deinterleave(sc, (void *)buffer, size); 519 520 size >>= 1; 521 522 boarddma = size * sc->sc_dmabuf + GUS_MEM_OFFSET; 523 524 sc->sc_stereo.intr = intr; 525 sc->sc_stereo.arg = arg; 526 sc->sc_stereo.size = size; 527 sc->sc_stereo.dmabuf = boarddma + GUS_LEFT_RIGHT_OFFSET; 528 sc->sc_stereo.buffer = buffer + size; 529 sc->sc_stereo.flags = flags; 530 if (gus_dostereo) { 531 intr = stereo_dmaintr; 532 arg = sc; 533 } 534 } else 535 boarddma = size * sc->sc_dmabuf + GUS_MEM_OFFSET; 536 537 538 sc->sc_flags |= GUS_LOCKED; 539 sc->sc_dmaoutintr = intr; 540 sc->sc_outarg = arg; 541 542 #ifdef GUSPLAYDEBUG 543 if (gusstats) { 544 microtime(&dmarecords[dmarecord_index].tv); 545 dmarecords[dmarecord_index].gusaddr = boarddma; 546 dmarecords[dmarecord_index].bsdaddr = buffer; 547 dmarecords[dmarecord_index].count = size; 548 dmarecords[dmarecord_index].channel = 0; 549 dmarecords[dmarecord_index++].direction = 1; 550 dmarecord_index = dmarecord_index % NDMARECS; 551 } 552 #endif 553 554 gusdmaout(sc, flags, boarddma, (caddr_t) buffer, size); 555 return 0; 556 } 557 558 void 559 gusmax_close(void *addr) 560 { 561 struct ad1848_softc *ac = addr; 562 struct gus_softc *sc = ac->parent; 563 #if 0 564 ac->mute[AD1848_AUX1_CHANNEL] = MUTE_ALL; 565 ad1848_mute_channel(ac, MUTE_ALL); /* turn off DAC output */ 566 #endif 567 ad1848_close(ac); 568 gusclose(sc); 569 } 570 571 /* 572 * Close out device stuff. Called at splaudio() from generic audio layer. 573 */ 574 void 575 gusclose(void *addr) 576 { 577 struct gus_softc *sc = addr; 578 579 DPRINTF(("gus_close: sc=%p\n", sc)); 580 581 /* if (sc->sc_flags & GUS_DMAOUT_ACTIVE) */ { 582 gus_halt_out_dma(sc); 583 } 584 /* if (sc->sc_flags & GUS_DMAIN_ACTIVE) */ { 585 gus_halt_in_dma(sc); 586 } 587 sc->sc_flags &= ~(GUS_OPEN|GUS_LOCKED|GUS_DMAOUT_ACTIVE|GUS_DMAIN_ACTIVE); 588 589 if (sc->sc_deintr_buf) { 590 free(sc->sc_deintr_buf, M_DEVBUF, 0); 591 sc->sc_deintr_buf = NULL; 592 } 593 /* turn off speaker, etc. */ 594 595 /* make sure the voices shut up: */ 596 gus_stop_voice(sc, GUS_VOICE_LEFT, 1); 597 gus_stop_voice(sc, GUS_VOICE_RIGHT, 0); 598 } 599 600 /* 601 * Service interrupts. Farm them off to helper routines if we are using the 602 * GUS for simple playback/record 603 */ 604 605 #ifdef AUDIO_DEBUG 606 int gusintrcnt; 607 int gusdmaintrcnt; 608 int gusvocintrcnt; 609 #endif 610 611 int 612 gusintr(void *arg) 613 { 614 struct gus_softc *sc = arg; 615 bus_space_tag_t iot = sc->sc_iot; 616 bus_space_handle_t ioh1 = sc->sc_ioh1; 617 bus_space_handle_t ioh2 = sc->sc_ioh2; 618 unsigned char intr; 619 620 int retval = 0; 621 622 DPRINTF(("gusintr\n")); 623 #ifdef AUDIO_DEBUG 624 gusintrcnt++; 625 #endif 626 if (HAS_CODEC(sc)) 627 retval = ad1848_intr(&sc->sc_codec); 628 mtx_enter(&audio_lock); 629 if ((intr = bus_space_read_1(iot, ioh1, GUS_IRQ_STATUS)) & GUSMASK_IRQ_DMATC) { 630 DMAPRINTF(("gusintr dma flags=%x\n", sc->sc_flags)); 631 #ifdef AUDIO_DEBUG 632 gusdmaintrcnt++; 633 #endif 634 retval += gus_dmaout_intr(sc); 635 if (sc->sc_flags & GUS_DMAIN_ACTIVE) { 636 SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL); 637 intr = bus_space_read_1(iot, ioh2, GUS_DATA_HIGH); 638 if (intr & GUSMASK_SAMPLE_DMATC) { 639 retval += gus_dmain_intr(sc); 640 } 641 } 642 } 643 if (intr & (GUSMASK_IRQ_VOICE | GUSMASK_IRQ_VOLUME)) { 644 DMAPRINTF(("gusintr voice flags=%x\n", sc->sc_flags)); 645 #ifdef AUDIO_DEBUG 646 gusvocintrcnt++; 647 #endif 648 retval += gus_voice_intr(sc); 649 } 650 if (retval) { 651 mtx_leave(&audio_lock); 652 return 1; 653 } 654 mtx_leave(&audio_lock); 655 return retval; 656 } 657 658 int gus_bufcnt[GUS_MEM_FOR_BUFFERS / GUS_BUFFER_MULTIPLE]; 659 int gus_restart; /* how many restarts? */ 660 int gus_stops; /* how many times did voice stop? */ 661 int gus_falsestops; /* stopped but not done? */ 662 int gus_continues; 663 664 struct playcont { 665 struct timeval tv; 666 u_int playbuf; 667 u_int dmabuf; 668 u_char bufcnt; 669 u_char vaction; 670 u_char voccntl; 671 u_char volcntl; 672 u_long curaddr; 673 u_long endaddr; 674 } playstats[NDMARECS]; 675 676 int playcntr; 677 678 void 679 gus_dmaout_timeout(void *arg) 680 { 681 struct gus_softc *sc = arg; 682 bus_space_tag_t iot = sc->sc_iot; 683 bus_space_handle_t ioh2 = sc->sc_ioh2; 684 685 printf("%s: dmaout timeout\n", sc->sc_dev.dv_xname); 686 /* 687 * Stop any DMA. 688 */ 689 690 mtx_enter(&audio_lock); 691 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL); 692 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0); 693 694 #if 0 695 /* XXX we will dmadone below? */ 696 isa_dmaabort(sc->sc_dev.dv_parent, sc->sc_drq); 697 #endif 698 699 gus_dmaout_dointr(sc); 700 mtx_leave(&audio_lock); 701 } 702 703 704 /* 705 * Service DMA interrupts. This routine will only get called if we're doing 706 * a DMA transfer for playback/record requests from the audio layer. 707 */ 708 709 int 710 gus_dmaout_intr(struct gus_softc *sc) 711 { 712 bus_space_tag_t iot = sc->sc_iot; 713 bus_space_handle_t ioh2 = sc->sc_ioh2; 714 715 /* 716 * If we got a DMA transfer complete from the GUS DRAM, then deal 717 * with it. 718 */ 719 720 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL); 721 if (bus_space_read_1(iot, ioh2, GUS_DATA_HIGH) & GUSMASK_DMA_IRQPEND) { 722 timeout_del(&sc->sc_dma_tmo); 723 gus_dmaout_dointr(sc); 724 return 1; 725 } 726 return 0; 727 } 728 729 void 730 gus_dmaout_dointr(struct gus_softc *sc) 731 { 732 bus_space_tag_t iot = sc->sc_iot; 733 bus_space_handle_t ioh2 = sc->sc_ioh2; 734 735 /* sc->sc_dmaoutcnt - 1 because DMA controller counts from zero?. */ 736 isa_dmadone(sc->sc_dev.dv_parent, sc->sc_drq); 737 sc->sc_flags &= ~GUS_DMAOUT_ACTIVE; /* pending DMA is done */ 738 DMAPRINTF(("gus_dmaout_dointr %d @ %p\n", sc->sc_dmaoutcnt, 739 sc->sc_dmaoutaddr)); 740 741 /* 742 * to prevent clicking, we need to copy last sample 743 * from last buffer to scratch area just before beginning of 744 * buffer. However, if we're doing formats that are converted by 745 * the card during the DMA process, we need to pick up the converted 746 * byte rather than the one we have in memory. 747 */ 748 if (sc->sc_dmabuf == sc->sc_nbufs - 1) { 749 int i; 750 switch (sc->sc_encoding) { 751 case AUDIO_ENCODING_SLINEAR_LE: 752 case AUDIO_ENCODING_SLINEAR_BE: 753 if (sc->sc_precision == 8) 754 goto byte; 755 /* we have the native format */ 756 for (i = 1; i <= 2; i++) 757 guspoke(iot, ioh2, sc->sc_gusaddr - 758 (sc->sc_nbufs - 1) * sc->sc_chanblocksize - i, 759 sc->sc_dmaoutaddr[sc->sc_dmaoutcnt-i]); 760 break; 761 case AUDIO_ENCODING_ULINEAR_LE: 762 case AUDIO_ENCODING_ULINEAR_BE: 763 guspoke(iot, ioh2, sc->sc_gusaddr - 764 (sc->sc_nbufs - 1) * sc->sc_chanblocksize - 2, 765 guspeek(iot, ioh2, 766 sc->sc_gusaddr + sc->sc_chanblocksize - 2)); 767 case AUDIO_ENCODING_ALAW: 768 case AUDIO_ENCODING_ULAW: 769 byte: 770 /* we need to fetch the translated byte, then stuff it. */ 771 guspoke(iot, ioh2, sc->sc_gusaddr - 772 (sc->sc_nbufs - 1) * sc->sc_chanblocksize - 1, 773 guspeek(iot, ioh2, 774 sc->sc_gusaddr + sc->sc_chanblocksize - 1)); 775 break; 776 } 777 } 778 /* 779 * If this is the first half of stereo, "ignore" this one 780 * and copy out the second half. 781 */ 782 if (sc->sc_dmaoutintr == stereo_dmaintr) { 783 (*sc->sc_dmaoutintr)(sc->sc_outarg); 784 return; 785 } 786 /* 787 * If the voice is stopped, then start it. Reset the loop 788 * and roll bits. Call the audio layer routine, since if 789 * we're starting a stopped voice, that means that the next 790 * buffer can be filled 791 */ 792 793 sc->sc_flags &= ~GUS_LOCKED; 794 if (sc->sc_voc[GUS_VOICE_LEFT].voccntl & 795 GUSMASK_VOICE_STOPPED) { 796 if (sc->sc_flags & GUS_PLAYING) { 797 printf("%s: playing yet stopped?\n", sc->sc_dev.dv_xname); 798 } 799 sc->sc_bufcnt++; /* another yet to be played */ 800 gus_start_playing(sc, sc->sc_dmabuf); 801 gus_restart++; 802 } else { 803 /* 804 * set the sound action based on which buffer we 805 * just transferred. If we just transferred buffer 0 806 * we want the sound to loop when it gets to the nth 807 * buffer; if we just transferred 808 * any other buffer, we want the sound to roll over 809 * at least one more time. The voice interrupt 810 * handlers will take care of accounting & 811 * setting control bits if it's not caught up to us 812 * yet. 813 */ 814 if (++sc->sc_bufcnt == 2) { 815 /* 816 * XXX 817 * If we're too slow in reaction here, 818 * the voice could be just approaching the 819 * end of its run. It should be set to stop, 820 * so these adjustments might not DTRT. 821 */ 822 if (sc->sc_dmabuf == 0 && 823 sc->sc_playbuf == sc->sc_nbufs - 1) { 824 /* player is just at the last buf, we're at the 825 first. Turn on looping, turn off rolling. */ 826 sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_LOOP_ENABLE; 827 sc->sc_voc[GUS_VOICE_LEFT].volcntl &= ~GUSMASK_VOICE_ROLL; 828 playstats[playcntr].vaction = 3; 829 } else { 830 /* player is at previous buf: 831 turn on rolling, turn off looping */ 832 sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~GUSMASK_LOOP_ENABLE; 833 sc->sc_voc[GUS_VOICE_LEFT].volcntl |= GUSMASK_VOICE_ROLL; 834 playstats[playcntr].vaction = 4; 835 } 836 #ifdef GUSPLAYDEBUG 837 if (gusstats) { 838 microtime(&playstats[playcntr].tv); 839 playstats[playcntr].endaddr = sc->sc_voc[GUS_VOICE_LEFT].end_addr; 840 playstats[playcntr].voccntl = sc->sc_voc[GUS_VOICE_LEFT].voccntl; 841 playstats[playcntr].volcntl = sc->sc_voc[GUS_VOICE_LEFT].volcntl; 842 playstats[playcntr].playbuf = sc->sc_playbuf; 843 playstats[playcntr].dmabuf = sc->sc_dmabuf; 844 playstats[playcntr].bufcnt = sc->sc_bufcnt; 845 playstats[playcntr++].curaddr = gus_get_curaddr(sc, GUS_VOICE_LEFT); 846 playcntr = playcntr % NDMARECS; 847 } 848 #endif 849 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, GUS_VOICE_LEFT); 850 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL); 851 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_LEFT].voccntl); 852 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL); 853 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_LEFT].volcntl); 854 } 855 } 856 gus_bufcnt[sc->sc_bufcnt-1]++; 857 /* 858 * flip to the next DMA buffer 859 */ 860 861 sc->sc_dmabuf = (sc->sc_dmabuf + 1) % sc->sc_nbufs; 862 /* 863 * See comments below about DMA admission control strategy. 864 * We can call the upper level here if we have an 865 * idle buffer (not currently playing) to DMA into. 866 */ 867 if (sc->sc_dmaoutintr && sc->sc_bufcnt < sc->sc_nbufs) { 868 /* clean out to prevent double calls */ 869 void (*pfunc)(void *) = sc->sc_dmaoutintr; 870 void *arg = sc->sc_outarg; 871 872 sc->sc_outarg = 0; 873 sc->sc_dmaoutintr = 0; 874 (*pfunc)(arg); 875 } 876 } 877 878 /* 879 * Service voice interrupts 880 */ 881 882 int 883 gus_voice_intr(struct gus_softc *sc) 884 { 885 bus_space_tag_t iot = sc->sc_iot; 886 bus_space_handle_t ioh2 = sc->sc_ioh2; 887 int ignore = 0, voice, rval = 0; 888 unsigned char intr, status; 889 890 /* 891 * The point of this may not be obvious at first. A voice can 892 * interrupt more than once; according to the GUS SDK we are supposed 893 * to ignore multiple interrupts for the same voice. 894 */ 895 896 while(1) { 897 SELECT_GUS_REG(iot, ioh2, GUSREG_IRQ_STATUS); 898 intr = bus_space_read_1(iot, ioh2, GUS_DATA_HIGH); 899 900 if ((intr & (GUSMASK_WIRQ_VOLUME | GUSMASK_WIRQ_VOICE)) 901 == (GUSMASK_WIRQ_VOLUME | GUSMASK_WIRQ_VOICE)) 902 /* 903 * No more interrupts, time to return 904 */ 905 return rval; 906 907 if ((intr & GUSMASK_WIRQ_VOICE) == 0) { 908 909 /* 910 * We've got a voice interrupt. Ignore previous 911 * interrupts by the same voice. 912 */ 913 914 rval = 1; 915 voice = intr & GUSMASK_WIRQ_VOICEMASK; 916 917 if ((1 << voice) & ignore) 918 break; 919 920 ignore |= 1 << voice; 921 922 /* 923 * If the voice is stopped, then force it to stop 924 * (this stops it from continuously generating IRQs) 925 */ 926 927 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL+0x80); 928 status = bus_space_read_1(iot, ioh2, GUS_DATA_HIGH); 929 if (status & GUSMASK_VOICE_STOPPED) { 930 if (voice != GUS_VOICE_LEFT) { 931 DMAPRINTF(("%s: spurious voice %d stop?\n", 932 sc->sc_dev.dv_xname, voice)); 933 gus_stop_voice(sc, voice, 0); 934 continue; 935 } 936 gus_stop_voice(sc, voice, 1); 937 /* also kill right voice */ 938 gus_stop_voice(sc, GUS_VOICE_RIGHT, 0); 939 sc->sc_bufcnt--; /* it finished a buffer */ 940 if (sc->sc_bufcnt > 0) { 941 /* 942 * probably a race to get here: the voice 943 * stopped while the DMA code was just trying to 944 * get the next buffer in place. 945 * Start the voice again. 946 */ 947 printf("%s: stopped voice not drained? (%x)\n", 948 sc->sc_dev.dv_xname, sc->sc_bufcnt); 949 gus_falsestops++; 950 951 sc->sc_playbuf = (sc->sc_playbuf + 1) % sc->sc_nbufs; 952 gus_start_playing(sc, sc->sc_playbuf); 953 } else if (sc->sc_bufcnt < 0) { 954 panic("%s: negative bufcnt in stopped voice", 955 sc->sc_dev.dv_xname); 956 } else { 957 sc->sc_playbuf = -1; /* none are active */ 958 gus_stops++; 959 } 960 /* fall through to callback and admit another 961 buffer.... */ 962 } else if (sc->sc_bufcnt != 0) { 963 /* 964 * This should always be taken if the voice 965 * is not stopped. 966 */ 967 gus_continues++; 968 if (gus_continue_playing(sc, voice)) { 969 /* 970 * we shouldn't have continued--active DMA 971 * is in the way in the ring, for 972 * some as-yet undebugged reason. 973 */ 974 gus_stop_voice(sc, GUS_VOICE_LEFT, 1); 975 /* also kill right voice */ 976 gus_stop_voice(sc, GUS_VOICE_RIGHT, 0); 977 sc->sc_playbuf = -1; 978 gus_stops++; 979 } 980 } 981 /* 982 * call the upper level to send on down another 983 * block. We do admission rate control as follows: 984 * 985 * When starting up output (in the first N 986 * blocks), call the upper layer after the DMA is 987 * complete (see above in gus_dmaout_intr()). 988 * 989 * When output is already in progress and we have 990 * no more GUS buffers to use for DMA, the DMA 991 * output routines do not call the upper layer. 992 * Instead, we call the DMA completion routine 993 * here, after the voice interrupts indicating 994 * that it's finished with a buffer. 995 * 996 * However, don't call anything here if the DMA 997 * output flag is set, (which shouldn't happen) 998 * because we'll squish somebody else's DMA if 999 * that's the case. When DMA is done, it will 1000 * call back if there is a spare buffer. 1001 */ 1002 if (sc->sc_dmaoutintr && !(sc->sc_flags & GUS_LOCKED)) { 1003 if (sc->sc_dmaoutintr == stereo_dmaintr) 1004 printf("gusdmaout botch?\n"); 1005 else { 1006 /* clean out to avoid double calls */ 1007 void (*pfunc)(void *) = sc->sc_dmaoutintr; 1008 void *arg = sc->sc_outarg; 1009 1010 sc->sc_outarg = 0; 1011 sc->sc_dmaoutintr = 0; 1012 (*pfunc)(arg); 1013 } 1014 } 1015 } 1016 1017 /* 1018 * Ignore other interrupts for now 1019 */ 1020 } 1021 return 0; 1022 } 1023 1024 void 1025 gus_start_playing(struct gus_softc *sc, int bufno) 1026 { 1027 bus_space_tag_t iot = sc->sc_iot; 1028 bus_space_handle_t ioh2 = sc->sc_ioh2; 1029 /* 1030 * Start the voices playing, with buffer BUFNO. 1031 */ 1032 1033 /* 1034 * Loop or roll if we have buffers ready. 1035 */ 1036 1037 if (sc->sc_bufcnt == 1) { 1038 sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~(GUSMASK_LOOP_ENABLE); 1039 sc->sc_voc[GUS_VOICE_LEFT].volcntl &= ~(GUSMASK_VOICE_ROLL); 1040 } else { 1041 if (bufno == sc->sc_nbufs - 1) { 1042 sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_LOOP_ENABLE; 1043 sc->sc_voc[GUS_VOICE_LEFT].volcntl &= ~(GUSMASK_VOICE_ROLL); 1044 } else { 1045 sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~GUSMASK_LOOP_ENABLE; 1046 sc->sc_voc[GUS_VOICE_LEFT].volcntl |= GUSMASK_VOICE_ROLL; 1047 } 1048 } 1049 1050 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, GUS_VOICE_LEFT); 1051 1052 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL); 1053 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_LEFT].voccntl); 1054 1055 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL); 1056 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_LEFT].volcntl); 1057 1058 sc->sc_voc[GUS_VOICE_LEFT].current_addr = 1059 GUS_MEM_OFFSET + sc->sc_chanblocksize * bufno; 1060 sc->sc_voc[GUS_VOICE_LEFT].end_addr = 1061 sc->sc_voc[GUS_VOICE_LEFT].current_addr + sc->sc_chanblocksize - 1; 1062 sc->sc_voc[GUS_VOICE_RIGHT].current_addr = 1063 sc->sc_voc[GUS_VOICE_LEFT].current_addr + 1064 (gus_dostereo && sc->sc_channels == 2 ? GUS_LEFT_RIGHT_OFFSET : 0); 1065 /* 1066 * set up right channel to just loop forever, no interrupts, 1067 * starting at the buffer we just filled. We'll feed it data 1068 * at the same time as left channel. 1069 */ 1070 sc->sc_voc[GUS_VOICE_RIGHT].voccntl |= GUSMASK_LOOP_ENABLE; 1071 sc->sc_voc[GUS_VOICE_RIGHT].volcntl &= ~(GUSMASK_VOICE_ROLL); 1072 1073 #ifdef GUSPLAYDEBUG 1074 if (gusstats) { 1075 microtime(&playstats[playcntr].tv); 1076 playstats[playcntr].curaddr = sc->sc_voc[GUS_VOICE_LEFT].current_addr; 1077 1078 playstats[playcntr].voccntl = sc->sc_voc[GUS_VOICE_LEFT].voccntl; 1079 playstats[playcntr].volcntl = sc->sc_voc[GUS_VOICE_LEFT].volcntl; 1080 playstats[playcntr].endaddr = sc->sc_voc[GUS_VOICE_LEFT].end_addr; 1081 playstats[playcntr].playbuf = bufno; 1082 playstats[playcntr].dmabuf = sc->sc_dmabuf; 1083 playstats[playcntr].bufcnt = sc->sc_bufcnt; 1084 playstats[playcntr++].vaction = 5; 1085 playcntr = playcntr % NDMARECS; 1086 } 1087 #endif 1088 1089 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, GUS_VOICE_RIGHT); 1090 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL); 1091 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_RIGHT].voccntl); 1092 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL); 1093 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_RIGHT].volcntl); 1094 1095 gus_start_voice(sc, GUS_VOICE_RIGHT, 0); 1096 gus_start_voice(sc, GUS_VOICE_LEFT, 1); 1097 if (sc->sc_playbuf == -1) 1098 /* mark start of playing */ 1099 sc->sc_playbuf = bufno; 1100 } 1101 1102 int 1103 gus_continue_playing(struct gus_softc *sc, int voice) 1104 { 1105 bus_space_tag_t iot = sc->sc_iot; 1106 bus_space_handle_t ioh2 = sc->sc_ioh2; 1107 1108 /* 1109 * stop this voice from interrupting while we work. 1110 */ 1111 1112 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL); 1113 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl & ~(GUSMASK_VOICE_IRQ)); 1114 1115 /* 1116 * update playbuf to point to the buffer the hardware just started 1117 * playing 1118 */ 1119 sc->sc_playbuf = (sc->sc_playbuf + 1) % sc->sc_nbufs; 1120 1121 /* 1122 * account for buffer just finished 1123 */ 1124 if (--sc->sc_bufcnt == 0) { 1125 DPRINTF(("gus: bufcnt 0 on continuing voice?\n")); 1126 } 1127 if (sc->sc_playbuf == sc->sc_dmabuf && (sc->sc_flags & GUS_LOCKED)) { 1128 printf("%s: continue into active dmabuf?\n", sc->sc_dev.dv_xname); 1129 return 1; 1130 } 1131 1132 /* 1133 * Select the end of the buffer based on the currently active 1134 * buffer, [plus extra contiguous buffers (if ready)]. 1135 */ 1136 1137 /* 1138 * set endpoint at end of buffer we just started playing. 1139 * 1140 * The total gets -1 because end addrs are one less than you might 1141 * think (the end_addr is the address of the last sample to play) 1142 */ 1143 gus_set_endaddr(sc, voice, GUS_MEM_OFFSET + 1144 sc->sc_chanblocksize * (sc->sc_playbuf + 1) - 1); 1145 1146 if (sc->sc_bufcnt < 2) { 1147 /* 1148 * Clear out the loop and roll flags, and rotate the currently 1149 * playing buffer. That way, if we don't manage to get more 1150 * data before this buffer finishes, we'll just stop. 1151 */ 1152 sc->sc_voc[voice].voccntl &= ~GUSMASK_LOOP_ENABLE; 1153 sc->sc_voc[voice].volcntl &= ~GUSMASK_VOICE_ROLL; 1154 playstats[playcntr].vaction = 0; 1155 } else { 1156 /* 1157 * We have some buffers to play. set LOOP if we're on the 1158 * last buffer in the ring, otherwise set ROLL. 1159 */ 1160 if (sc->sc_playbuf == sc->sc_nbufs - 1) { 1161 sc->sc_voc[voice].voccntl |= GUSMASK_LOOP_ENABLE; 1162 sc->sc_voc[voice].volcntl &= ~GUSMASK_VOICE_ROLL; 1163 playstats[playcntr].vaction = 1; 1164 } else { 1165 sc->sc_voc[voice].voccntl &= ~GUSMASK_LOOP_ENABLE; 1166 sc->sc_voc[voice].volcntl |= GUSMASK_VOICE_ROLL; 1167 playstats[playcntr].vaction = 2; 1168 } 1169 } 1170 #ifdef GUSPLAYDEBUG 1171 if (gusstats) { 1172 microtime(&playstats[playcntr].tv); 1173 playstats[playcntr].curaddr = gus_get_curaddr(sc, voice); 1174 1175 playstats[playcntr].voccntl = sc->sc_voc[voice].voccntl; 1176 playstats[playcntr].volcntl = sc->sc_voc[voice].volcntl; 1177 playstats[playcntr].endaddr = sc->sc_voc[voice].end_addr; 1178 playstats[playcntr].playbuf = sc->sc_playbuf; 1179 playstats[playcntr].dmabuf = sc->sc_dmabuf; 1180 playstats[playcntr++].bufcnt = sc->sc_bufcnt; 1181 playcntr = playcntr % NDMARECS; 1182 } 1183 #endif 1184 1185 /* 1186 * (re-)set voice parameters. This will reenable interrupts from this 1187 * voice. 1188 */ 1189 1190 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL); 1191 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl); 1192 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL); 1193 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].volcntl); 1194 return 0; 1195 } 1196 1197 /* 1198 * Send/receive data into GUS's DRAM using DMA. Called at splaudio() 1199 */ 1200 1201 void 1202 gusdmaout(struct gus_softc *sc, int flags, u_long gusaddr, caddr_t buffaddr, 1203 int length) 1204 { 1205 unsigned char c = (unsigned char) flags; 1206 bus_space_tag_t iot = sc->sc_iot; 1207 bus_space_handle_t ioh2 = sc->sc_ioh2; 1208 1209 DMAPRINTF(("gusdmaout flags=%x scflags=%x\n", flags, sc->sc_flags)); 1210 1211 sc->sc_gusaddr = gusaddr; 1212 1213 /* 1214 * If we're using a 16 bit DMA channel, we have to jump through some 1215 * extra hoops; this includes translating the DRAM address a bit 1216 */ 1217 1218 if (sc->sc_drq >= 4) { 1219 c |= GUSMASK_DMA_WIDTH; 1220 gusaddr = convert_to_16bit(gusaddr); 1221 } 1222 1223 /* 1224 * Add flag bits that we always set - fast DMA, enable IRQ 1225 */ 1226 1227 c |= GUSMASK_DMA_ENABLE | GUSMASK_DMA_R0 | GUSMASK_DMA_IRQ; 1228 1229 /* 1230 * Make sure the GUS _isn't_ setup for DMA 1231 */ 1232 1233 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL); 1234 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0); 1235 1236 /* 1237 * Tell the PC DMA controller to start doing DMA 1238 */ 1239 1240 sc->sc_dmaoutaddr = (u_char *) buffaddr; 1241 sc->sc_dmaoutcnt = length; 1242 isa_dmastart(sc->sc_dev.dv_parent, sc->sc_drq, buffaddr, length, 1243 NULL, DMAMODE_WRITE, BUS_DMA_NOWAIT); 1244 1245 /* 1246 * Set up DMA address - use the upper 16 bits ONLY 1247 */ 1248 1249 sc->sc_flags |= GUS_DMAOUT_ACTIVE; 1250 1251 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_START); 1252 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, (int) (gusaddr >> 4)); 1253 1254 /* 1255 * Tell the GUS to start doing DMA 1256 */ 1257 1258 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL); 1259 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, c); 1260 1261 /* 1262 * XXX If we don't finish in one second, give up... 1263 */ 1264 timeout_add_sec(&sc->sc_dma_tmo, 1); 1265 } 1266 1267 /* 1268 * Start a voice playing on the GUS. Called from interrupt handler at 1269 * splaudio(). 1270 */ 1271 1272 void 1273 gus_start_voice(struct gus_softc *sc, int voice, int intrs) 1274 { 1275 bus_space_tag_t iot = sc->sc_iot; 1276 bus_space_handle_t ioh2 = sc->sc_ioh2; 1277 u_long start; 1278 u_long current; 1279 u_long end; 1280 1281 /* 1282 * Pick all the values for the voice out of the gus_voice struct 1283 * and use those to program the voice 1284 */ 1285 1286 start = sc->sc_voc[voice].start_addr; 1287 current = sc->sc_voc[voice].current_addr; 1288 end = sc->sc_voc[voice].end_addr; 1289 1290 /* 1291 * If we're using 16 bit data, mangle the addresses a bit 1292 */ 1293 1294 if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16) { 1295 /* -1 on start so that we get onto sample boundary--other 1296 code always sets it for 1-byte rollover protection */ 1297 start = convert_to_16bit(start-1); 1298 current = convert_to_16bit(current); 1299 end = convert_to_16bit(end); 1300 } 1301 1302 /* 1303 * Select the voice we want to use, and program the data addresses 1304 */ 1305 1306 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice); 1307 1308 SELECT_GUS_REG(iot, ioh2, GUSREG_START_ADDR_HIGH); 1309 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(start)); 1310 SELECT_GUS_REG(iot, ioh2, GUSREG_START_ADDR_LOW); 1311 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(start)); 1312 1313 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH); 1314 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(current)); 1315 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW); 1316 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(current)); 1317 1318 SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_HIGH); 1319 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(end)); 1320 SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_LOW); 1321 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(end)); 1322 1323 /* 1324 * (maybe) enable interrupts, disable voice stopping 1325 */ 1326 1327 if (intrs) { 1328 sc->sc_flags |= GUS_PLAYING; /* playing is about to start */ 1329 sc->sc_voc[voice].voccntl |= GUSMASK_VOICE_IRQ; 1330 DMAPRINTF(("gus voice playing=%x\n", sc->sc_flags)); 1331 } else 1332 sc->sc_voc[voice].voccntl &= ~GUSMASK_VOICE_IRQ; 1333 sc->sc_voc[voice].voccntl &= ~(GUSMASK_VOICE_STOPPED | 1334 GUSMASK_STOP_VOICE); 1335 1336 /* 1337 * Tell the GUS about it. Note that we're doing volume ramping here 1338 * from 0 up to the set volume to help reduce clicks. 1339 */ 1340 1341 SELECT_GUS_REG(iot, ioh2, GUSREG_START_VOLUME); 1342 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00); 1343 SELECT_GUS_REG(iot, ioh2, GUSREG_END_VOLUME); 1344 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].current_volume >> 4); 1345 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME); 1346 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x00); 1347 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_RATE); 1348 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 63); 1349 1350 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL); 1351 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl); 1352 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL); 1353 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00); 1354 delay(50); 1355 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL); 1356 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl); 1357 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL); 1358 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00); 1359 1360 } 1361 1362 /* 1363 * Stop a given voice. Called at splaudio(). 1364 */ 1365 1366 void 1367 gus_stop_voice(struct gus_softc *sc, int voice, int intrs_too) 1368 { 1369 bus_space_tag_t iot = sc->sc_iot; 1370 bus_space_handle_t ioh2 = sc->sc_ioh2; 1371 1372 sc->sc_voc[voice].voccntl |= GUSMASK_VOICE_STOPPED | 1373 GUSMASK_STOP_VOICE; 1374 if (intrs_too) { 1375 sc->sc_voc[voice].voccntl &= ~(GUSMASK_VOICE_IRQ); 1376 /* no more DMA to do */ 1377 sc->sc_flags &= ~GUS_PLAYING; 1378 } 1379 DMAPRINTF(("gusintr voice notplaying=%x\n", sc->sc_flags)); 1380 1381 guspoke(iot, ioh2, 0L, 0); 1382 1383 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice); 1384 1385 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME); 1386 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000); 1387 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL); 1388 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl); 1389 delay(100); 1390 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME); 1391 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000); 1392 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL); 1393 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl); 1394 1395 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH); 1396 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000); 1397 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW); 1398 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000); 1399 1400 } 1401 1402 1403 /* 1404 * Set the volume of a given voice. Called at splaudio(). 1405 */ 1406 void 1407 gus_set_volume(struct gus_softc *sc, int voice, int volume) 1408 { 1409 bus_space_tag_t iot = sc->sc_iot; 1410 bus_space_handle_t ioh2 = sc->sc_ioh2; 1411 unsigned int gusvol; 1412 1413 gusvol = gus_log_volumes[volume < 512 ? volume : 511]; 1414 1415 sc->sc_voc[voice].current_volume = gusvol; 1416 1417 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice); 1418 1419 SELECT_GUS_REG(iot, ioh2, GUSREG_START_VOLUME); 1420 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (unsigned char) (gusvol >> 4)); 1421 1422 SELECT_GUS_REG(iot, ioh2, GUSREG_END_VOLUME); 1423 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (unsigned char) (gusvol >> 4)); 1424 1425 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME); 1426 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, gusvol << 4); 1427 delay(500); 1428 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, gusvol << 4); 1429 1430 } 1431 1432 /* 1433 * Interface to the audio layer. 1434 */ 1435 1436 int 1437 gusmax_set_params(void *addr, int setmode, int usemode, struct audio_params *p, 1438 struct audio_params *r) 1439 { 1440 struct ad1848_softc *ac = addr; 1441 struct gus_softc *sc = ac->parent; 1442 int error; 1443 1444 error = ad1848_set_params(ac, setmode, usemode, p, r); 1445 if (error) 1446 return error; 1447 error = gus_set_params(sc, setmode, usemode, p, r); 1448 return error; 1449 } 1450 1451 int 1452 gus_set_params(void *addr, int setmode, int usemode, struct audio_params *p, 1453 struct audio_params *r) 1454 { 1455 struct gus_softc *sc = addr; 1456 1457 switch (p->encoding) { 1458 case AUDIO_ENCODING_SLINEAR_LE: 1459 case AUDIO_ENCODING_ULINEAR_LE: 1460 break; 1461 default: 1462 return (EINVAL); 1463 } 1464 1465 /* XXX: why?! this is called with interrupts disabled */ 1466 mtx_enter(&audio_lock); 1467 1468 if (p->precision == 8) { 1469 sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~GUSMASK_DATA_SIZE16; 1470 sc->sc_voc[GUS_VOICE_RIGHT].voccntl &= ~GUSMASK_DATA_SIZE16; 1471 } else { 1472 sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_DATA_SIZE16; 1473 sc->sc_voc[GUS_VOICE_RIGHT].voccntl |= GUSMASK_DATA_SIZE16; 1474 } 1475 1476 sc->sc_encoding = p->encoding; 1477 sc->sc_precision = p->precision; 1478 sc->sc_channels = p->channels; 1479 1480 mtx_leave(&audio_lock); 1481 1482 if (p->sample_rate > gus_max_frequency[sc->sc_voices - GUS_MIN_VOICES]) 1483 p->sample_rate = gus_max_frequency[sc->sc_voices - GUS_MIN_VOICES]; 1484 if (setmode & AUMODE_RECORD) 1485 sc->sc_irate = p->sample_rate; 1486 if (setmode & AUMODE_PLAY) 1487 sc->sc_orate = p->sample_rate; 1488 1489 p->bps = AUDIO_BPS(p->precision); 1490 r->bps = AUDIO_BPS(r->precision); 1491 p->msb = r->msb = 1; 1492 1493 return 0; 1494 } 1495 1496 /* 1497 * Interface to the audio layer - set the blocksize to the correct number 1498 * of units 1499 */ 1500 1501 int 1502 gusmax_round_blocksize(void *addr, int blocksize) 1503 { 1504 struct ad1848_softc *ac = addr; 1505 struct gus_softc *sc = ac->parent; 1506 1507 /* blocksize = ad1848_round_blocksize(ac, blocksize);*/ 1508 return gus_round_blocksize(sc, blocksize); 1509 } 1510 1511 int 1512 gus_round_blocksize(void *addr, int blocksize) 1513 { 1514 struct gus_softc *sc = addr; 1515 1516 DPRINTF(("gus_round_blocksize called\n")); 1517 1518 if ((sc->sc_encoding == AUDIO_ENCODING_ULAW || 1519 sc->sc_encoding == AUDIO_ENCODING_ALAW) && blocksize > 32768) 1520 blocksize = 32768; 1521 else if (blocksize > 65536) 1522 blocksize = 65536; 1523 1524 if ((blocksize % GUS_BUFFER_MULTIPLE) != 0) 1525 blocksize = (blocksize / GUS_BUFFER_MULTIPLE + 1) * 1526 GUS_BUFFER_MULTIPLE; 1527 1528 /* set up temporary buffer to hold the deinterleave, if necessary 1529 for stereo output */ 1530 if (sc->sc_deintr_buf) { 1531 free(sc->sc_deintr_buf, M_DEVBUF, 0); 1532 sc->sc_deintr_buf = NULL; 1533 } 1534 sc->sc_deintr_buf = malloc(blocksize/2, M_DEVBUF, M_WAITOK); 1535 1536 sc->sc_blocksize = blocksize; 1537 /* multi-buffering not quite working yet. */ 1538 sc->sc_nbufs = /*GUS_MEM_FOR_BUFFERS / blocksize*/ 2; 1539 1540 gus_set_chan_addrs(sc); 1541 1542 return blocksize; 1543 } 1544 1545 int 1546 gus_get_out_gain(caddr_t addr) 1547 { 1548 struct gus_softc *sc = (struct gus_softc *) addr; 1549 1550 DPRINTF(("gus_get_out_gain called\n")); 1551 return sc->sc_ogain / 2; 1552 } 1553 1554 inline void 1555 gus_set_voices(struct gus_softc *sc, int voices) 1556 { 1557 bus_space_tag_t iot = sc->sc_iot; 1558 bus_space_handle_t ioh2 = sc->sc_ioh2; 1559 /* 1560 * Select the active number of voices 1561 */ 1562 1563 SELECT_GUS_REG(iot, ioh2, GUSREG_ACTIVE_VOICES); 1564 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (voices-1) | 0xc0); 1565 1566 sc->sc_voices = voices; 1567 } 1568 1569 /* 1570 * Actually set the settings of various values on the card 1571 */ 1572 1573 int 1574 gusmax_commit_settings(void *addr) 1575 { 1576 struct ad1848_softc *ac = addr; 1577 struct gus_softc *sc = ac->parent; 1578 int error; 1579 1580 error = ad1848_commit_settings(ac); 1581 if (error) 1582 return error; 1583 return gus_commit_settings(sc); 1584 } 1585 1586 /* 1587 * Commit the settings. Called at normal IPL. 1588 */ 1589 int 1590 gus_commit_settings(void *addr) 1591 { 1592 struct gus_softc *sc = addr; 1593 1594 DPRINTF(("gus_commit_settings called (gain = %d)\n",sc->sc_ogain)); 1595 1596 1597 /* XXX: why?! this is called with interrupts disabled */ 1598 mtx_enter(&audio_lock); 1599 1600 gus_set_recrate(sc, sc->sc_irate); 1601 gus_set_volume(sc, GUS_VOICE_LEFT, sc->sc_ogain); 1602 gus_set_volume(sc, GUS_VOICE_RIGHT, sc->sc_ogain); 1603 gus_set_samprate(sc, GUS_VOICE_LEFT, sc->sc_orate); 1604 gus_set_samprate(sc, GUS_VOICE_RIGHT, sc->sc_orate); 1605 mtx_leave(&audio_lock); 1606 gus_set_chan_addrs(sc); 1607 1608 return 0; 1609 } 1610 1611 void 1612 gus_set_chan_addrs(struct gus_softc *sc) 1613 { 1614 /* 1615 * We use sc_nbufs * blocksize bytes of storage in the on-board GUS 1616 * ram. 1617 * For mono, each of the sc_nbufs buffers is DMA'd to in one chunk, 1618 * and both left & right channels play the same buffer. 1619 * 1620 * For stereo, each channel gets a contiguous half of the memory, 1621 * and each has sc_nbufs buffers of size blocksize/2. 1622 * Stereo data are deinterleaved in main memory before the DMA out 1623 * routines are called to queue the output. 1624 * 1625 * The blocksize per channel is kept in sc_chanblocksize. 1626 */ 1627 if (sc->sc_channels == 2) 1628 sc->sc_chanblocksize = sc->sc_blocksize/2; 1629 else 1630 sc->sc_chanblocksize = sc->sc_blocksize; 1631 1632 sc->sc_voc[GUS_VOICE_LEFT].start_addr = GUS_MEM_OFFSET - 1; 1633 sc->sc_voc[GUS_VOICE_RIGHT].start_addr = 1634 (gus_dostereo && sc->sc_channels == 2 ? GUS_LEFT_RIGHT_OFFSET : 0) 1635 + GUS_MEM_OFFSET - 1; 1636 sc->sc_voc[GUS_VOICE_RIGHT].current_addr = 1637 sc->sc_voc[GUS_VOICE_RIGHT].start_addr + 1; 1638 sc->sc_voc[GUS_VOICE_RIGHT].end_addr = 1639 sc->sc_voc[GUS_VOICE_RIGHT].start_addr + 1640 sc->sc_nbufs * sc->sc_chanblocksize; 1641 1642 } 1643 1644 /* 1645 * Set the sample rate of the given voice. Called at splaudio(). 1646 */ 1647 1648 void 1649 gus_set_samprate(struct gus_softc *sc, int voice, int freq) 1650 { 1651 bus_space_tag_t iot = sc->sc_iot; 1652 bus_space_handle_t ioh2 = sc->sc_ioh2; 1653 unsigned int fc; 1654 u_long temp, f = (u_long) freq; 1655 1656 /* 1657 * calculate fc based on the number of active voices; 1658 * we need to use longs to preserve enough bits 1659 */ 1660 1661 temp = (u_long) gus_max_frequency[sc->sc_voices-GUS_MIN_VOICES]; 1662 1663 fc = (unsigned int)(((f << 9L) + (temp >> 1L)) / temp); 1664 1665 fc <<= 1; 1666 1667 1668 /* 1669 * Program the voice frequency, and set it in the voice data record 1670 */ 1671 1672 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice); 1673 SELECT_GUS_REG(iot, ioh2, GUSREG_FREQ_CONTROL); 1674 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, fc); 1675 1676 sc->sc_voc[voice].rate = freq; 1677 1678 } 1679 1680 /* 1681 * Set the sample rate of the recording frequency. Formula is from the GUS 1682 * SDK. Called at splaudio(). 1683 */ 1684 1685 void 1686 gus_set_recrate(struct gus_softc *sc, u_long rate) 1687 { 1688 bus_space_tag_t iot = sc->sc_iot; 1689 bus_space_handle_t ioh2 = sc->sc_ioh2; 1690 u_char realrate; 1691 DPRINTF(("gus_set_recrate %lu\n", rate)); 1692 1693 #if 0 1694 realrate = 9878400/(16*(rate+2)); /* formula from GUS docs */ 1695 #endif 1696 realrate = (9878400 >> 4)/rate - 2; /* formula from code, sigh. */ 1697 1698 SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_FREQ); 1699 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, realrate); 1700 } 1701 1702 /* 1703 * Interface to the audio layer - turn the output on or off. Note that some 1704 * of these bits are flipped in the register 1705 */ 1706 1707 int 1708 gusmax_speaker_ctl(void *addr, int newstate) 1709 { 1710 struct ad1848_softc *sc = addr; 1711 return gus_speaker_ctl(sc->parent, newstate); 1712 } 1713 1714 int 1715 gus_speaker_ctl(void *addr, int newstate) 1716 { 1717 struct gus_softc *sc = (struct gus_softc *) addr; 1718 bus_space_tag_t iot = sc->sc_iot; 1719 bus_space_handle_t ioh1 = sc->sc_ioh1; 1720 1721 /* Line out bit is flipped: 0 enables, 1 disables */ 1722 if ((newstate == SPKR_ON) && 1723 (sc->sc_mixcontrol & GUSMASK_LINE_OUT)) { 1724 sc->sc_mixcontrol &= ~GUSMASK_LINE_OUT; 1725 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol); 1726 } 1727 if ((newstate == SPKR_OFF) && 1728 (sc->sc_mixcontrol & GUSMASK_LINE_OUT) == 0) { 1729 sc->sc_mixcontrol |= GUSMASK_LINE_OUT; 1730 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol); 1731 } 1732 1733 return 0; 1734 } 1735 1736 int 1737 gus_linein_ctl(void *addr, int newstate) 1738 { 1739 struct gus_softc *sc = (struct gus_softc *) addr; 1740 bus_space_tag_t iot = sc->sc_iot; 1741 bus_space_handle_t ioh1 = sc->sc_ioh1; 1742 1743 /* Line in bit is flipped: 0 enables, 1 disables */ 1744 if ((newstate == SPKR_ON) && 1745 (sc->sc_mixcontrol & GUSMASK_LINE_IN)) { 1746 sc->sc_mixcontrol &= ~GUSMASK_LINE_IN; 1747 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol); 1748 } 1749 if ((newstate == SPKR_OFF) && 1750 (sc->sc_mixcontrol & GUSMASK_LINE_IN) == 0) { 1751 sc->sc_mixcontrol |= GUSMASK_LINE_IN; 1752 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol); 1753 } 1754 1755 return 0; 1756 } 1757 1758 int 1759 gus_mic_ctl(void *addr, int newstate) 1760 { 1761 struct gus_softc *sc = (struct gus_softc *) addr; 1762 bus_space_tag_t iot = sc->sc_iot; 1763 bus_space_handle_t ioh1 = sc->sc_ioh1; 1764 1765 /* Mic bit is normal: 1 enables, 0 disables */ 1766 if ((newstate == SPKR_ON) && 1767 (sc->sc_mixcontrol & GUSMASK_MIC_IN) == 0) { 1768 sc->sc_mixcontrol |= GUSMASK_MIC_IN; 1769 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol); 1770 } 1771 if ((newstate == SPKR_OFF) && 1772 (sc->sc_mixcontrol & GUSMASK_MIC_IN)) { 1773 sc->sc_mixcontrol &= ~GUSMASK_MIC_IN; 1774 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol); 1775 } 1776 1777 return 0; 1778 } 1779 1780 /* 1781 * Set the end address of a give voice. Called at splaudio(). 1782 */ 1783 1784 void 1785 gus_set_endaddr(struct gus_softc *sc, int voice, u_long addr) 1786 { 1787 bus_space_tag_t iot = sc->sc_iot; 1788 bus_space_handle_t ioh2 = sc->sc_ioh2; 1789 1790 sc->sc_voc[voice].end_addr = addr; 1791 1792 if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16) 1793 addr = convert_to_16bit(addr); 1794 1795 SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_HIGH); 1796 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(addr)); 1797 SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_LOW); 1798 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(addr)); 1799 1800 } 1801 1802 #ifdef GUSPLAYDEBUG 1803 /* 1804 * Set current address. Called at splaudio(). 1805 */ 1806 void 1807 gus_set_curaddr(struct gus_softc *sc, int voice, u_long addr) 1808 { 1809 bus_space_tag_t iot = sc->sc_iot; 1810 bus_space_handle_t ioh2 = sc->sc_ioh2; 1811 1812 sc->sc_voc[voice].current_addr = addr; 1813 1814 if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16) 1815 addr = convert_to_16bit(addr); 1816 1817 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice); 1818 1819 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH); 1820 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(addr)); 1821 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW); 1822 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(addr)); 1823 1824 } 1825 1826 /* 1827 * Get current GUS playback address. Called at splaudio(). 1828 */ 1829 u_long 1830 gus_get_curaddr(struct gus_softc *sc, int voice) 1831 { 1832 bus_space_tag_t iot = sc->sc_iot; 1833 bus_space_handle_t ioh2 = sc->sc_ioh2; 1834 u_long addr; 1835 1836 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice); 1837 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH|GUSREG_READ); 1838 addr = (bus_space_read_2(iot, ioh2, GUS_DATA_LOW) & 0x1fff) << 7; 1839 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW|GUSREG_READ); 1840 addr |= (bus_space_read_2(iot, ioh2, GUS_DATA_LOW) >> 9L) & 0x7f; 1841 1842 if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16) 1843 addr = (addr & 0xc0000) | ((addr & 0x1ffff) << 1); /* undo 16-bit change */ 1844 DPRINTF(("gus voice %d curaddr %ld end_addr %ld\n", 1845 voice, addr, sc->sc_voc[voice].end_addr)); 1846 /* XXX sanity check the address? */ 1847 1848 return(addr); 1849 } 1850 #endif 1851 1852 /* 1853 * Convert an address value to a "16 bit" value - why this is necessary I 1854 * have NO idea 1855 */ 1856 1857 u_long 1858 convert_to_16bit(u_long address) 1859 { 1860 u_long old_address; 1861 1862 old_address = address; 1863 address >>= 1; 1864 address &= 0x0001ffffL; 1865 address |= (old_address & 0x000c0000L); 1866 1867 return (address); 1868 } 1869 1870 /* 1871 * Write a value into the GUS's DRAM 1872 */ 1873 1874 void 1875 guspoke(bus_space_tag_t iot, bus_space_handle_t ioh2, long address, 1876 unsigned char value) 1877 { 1878 1879 /* 1880 * Select the DRAM address 1881 */ 1882 1883 SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_LOW); 1884 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, (unsigned int) (address & 0xffff)); 1885 SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_HIGH); 1886 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (unsigned char) ((address >> 16) & 0xff)); 1887 1888 /* 1889 * Actually write the data 1890 */ 1891 1892 bus_space_write_1(iot, ioh2, GUS_DRAM_DATA, value); 1893 } 1894 1895 /* 1896 * Read a value from the GUS's DRAM 1897 */ 1898 1899 unsigned char 1900 guspeek(bus_space_tag_t iot, bus_space_handle_t ioh2, u_long address) 1901 { 1902 1903 /* 1904 * Select the DRAM address 1905 */ 1906 1907 SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_LOW); 1908 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, (unsigned int) (address & 0xffff)); 1909 SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_HIGH); 1910 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (unsigned char) ((address >> 16) & 0xff)); 1911 1912 /* 1913 * Read in the data from the board 1914 */ 1915 1916 return (unsigned char) bus_space_read_1(iot, ioh2, GUS_DRAM_DATA); 1917 } 1918 1919 /* 1920 * Reset the Gravis UltraSound card, completely 1921 */ 1922 1923 void 1924 gusreset(struct gus_softc *sc, int voices) 1925 { 1926 bus_space_tag_t iot = sc->sc_iot; 1927 bus_space_handle_t ioh1 = sc->sc_ioh1; 1928 bus_space_handle_t ioh2 = sc->sc_ioh2; 1929 bus_space_handle_t ioh4 = sc->sc_ioh4; 1930 int i; 1931 1932 mtx_enter(&audio_lock); 1933 1934 /* 1935 * Reset the GF1 chip 1936 */ 1937 1938 SELECT_GUS_REG(iot, ioh2, GUSREG_RESET); 1939 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00); 1940 1941 delay(500); 1942 1943 /* 1944 * Release reset 1945 */ 1946 1947 SELECT_GUS_REG(iot, ioh2, GUSREG_RESET); 1948 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, GUSMASK_MASTER_RESET); 1949 1950 delay(500); 1951 1952 /* 1953 * Reset MIDI port as well, if applicable 1954 */ 1955 1956 if (ioh4 != (bus_space_handle_t)NULL) { 1957 bus_space_write_1(iot, ioh4, GUS_MIDI_CONTROL, MIDI_RESET); 1958 1959 delay(500); 1960 1961 bus_space_write_1(iot, ioh4, GUS_MIDI_CONTROL, 0x00); 1962 } 1963 1964 /* 1965 * Clear interrupts 1966 */ 1967 1968 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL); 1969 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00); 1970 SELECT_GUS_REG(iot, ioh2, GUSREG_TIMER_CONTROL); 1971 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00); 1972 SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL); 1973 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00); 1974 1975 gus_set_voices(sc, voices); 1976 1977 bus_space_read_1(iot, ioh1, GUS_IRQ_STATUS); 1978 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL); 1979 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH); 1980 SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL); 1981 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH); 1982 SELECT_GUS_REG(iot, ioh2, GUSREG_IRQ_STATUS); 1983 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH); 1984 1985 /* 1986 * Reset voice specific information 1987 */ 1988 1989 for(i = 0; i < voices; i++) { 1990 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) i); 1991 1992 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL); 1993 1994 sc->sc_voc[i].voccntl = GUSMASK_VOICE_STOPPED | 1995 GUSMASK_STOP_VOICE; 1996 1997 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[i].voccntl); 1998 1999 sc->sc_voc[i].volcntl = GUSMASK_VOLUME_STOPPED | 2000 GUSMASK_STOP_VOLUME; 2001 2002 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL); 2003 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[i].volcntl); 2004 2005 delay(100); 2006 2007 gus_set_samprate(sc, i, 8000); 2008 SELECT_GUS_REG(iot, ioh2, GUSREG_START_ADDR_HIGH); 2009 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000); 2010 SELECT_GUS_REG(iot, ioh2, GUSREG_START_ADDR_LOW); 2011 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000); 2012 SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_HIGH); 2013 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000); 2014 SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_LOW); 2015 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000); 2016 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_RATE); 2017 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x01); 2018 SELECT_GUS_REG(iot, ioh2, GUSREG_START_VOLUME); 2019 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x10); 2020 SELECT_GUS_REG(iot, ioh2, GUSREG_END_VOLUME); 2021 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0xe0); 2022 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME); 2023 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000); 2024 2025 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH); 2026 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000); 2027 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW); 2028 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000); 2029 SELECT_GUS_REG(iot, ioh2, GUSREG_PAN_POS); 2030 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x07); 2031 } 2032 2033 /* 2034 * Clear out any pending IRQs 2035 */ 2036 2037 bus_space_read_1(iot, ioh1, GUS_IRQ_STATUS); 2038 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL); 2039 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH); 2040 SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL); 2041 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH); 2042 SELECT_GUS_REG(iot, ioh2, GUSREG_IRQ_STATUS); 2043 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH); 2044 2045 SELECT_GUS_REG(iot, ioh2, GUSREG_RESET); 2046 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, GUSMASK_MASTER_RESET | GUSMASK_DAC_ENABLE | 2047 GUSMASK_IRQ_ENABLE); 2048 2049 mtx_leave(&audio_lock); 2050 } 2051 2052 2053 int 2054 gus_init_cs4231(struct gus_softc *sc) 2055 { 2056 bus_space_tag_t iot = sc->sc_iot; 2057 bus_space_handle_t ioh1 = sc->sc_ioh1; 2058 int port = sc->sc_iobase; 2059 u_char ctrl; 2060 2061 ctrl = (port & 0xf0) >> 4; /* set port address middle nibble */ 2062 /* 2063 * The codec is a bit weird--swapped dma channels. 2064 */ 2065 ctrl |= GUS_MAX_CODEC_ENABLE; 2066 if (sc->sc_drq >= 4) 2067 ctrl |= GUS_MAX_RECCHAN16; 2068 if (sc->sc_recdrq >= 4) 2069 ctrl |= GUS_MAX_PLAYCHAN16; 2070 2071 bus_space_write_1(iot, ioh1, GUS_MAX_CTRL, ctrl); 2072 2073 sc->sc_codec.sc_iot = sc->sc_iot; 2074 sc->sc_codec.sc_iobase = port+GUS_MAX_CODEC_BASE; 2075 2076 if (ad1848_mapprobe(&sc->sc_codec, sc->sc_codec.sc_iobase) == 0) { 2077 sc->sc_flags &= ~GUS_CODEC_INSTALLED; 2078 return (0); 2079 } else { 2080 struct ad1848_volume vol = {AUDIO_MAX_GAIN, AUDIO_MAX_GAIN}; 2081 sc->sc_flags |= GUS_CODEC_INSTALLED; 2082 sc->sc_codec.parent = sc; 2083 sc->sc_codec.sc_drq = sc->sc_recdrq; 2084 sc->sc_codec.sc_recdrq = sc->sc_drq; 2085 /* enable line in and mic in the GUS mixer; the codec chip 2086 will do the real mixing for them. */ 2087 sc->sc_mixcontrol &= ~GUSMASK_LINE_IN; /* 0 enables. */ 2088 sc->sc_mixcontrol |= GUSMASK_MIC_IN; /* 1 enables. */ 2089 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol); 2090 2091 ad1848_attach(&sc->sc_codec); 2092 /* turn on pre-MUX microphone gain. */ 2093 ad1848_set_mic_gain(&sc->sc_codec, &vol); 2094 2095 return (1); 2096 } 2097 } 2098 2099 /* 2100 * stubs (XXX) 2101 */ 2102 2103 int 2104 gus_set_in_gain(caddr_t addr, u_int gain, u_char balance) 2105 { 2106 DPRINTF(("gus_set_in_gain called\n")); 2107 return 0; 2108 } 2109 2110 int 2111 gus_get_in_gain(caddr_t addr) 2112 { 2113 DPRINTF(("gus_get_in_gain called\n")); 2114 return 0; 2115 } 2116 2117 int 2118 gusmax_dma_input(void *addr, void *buf, int size, void (*callback)(void *), 2119 void *arg) 2120 { 2121 struct ad1848_softc *sc = addr; 2122 return gus_dma_input(sc->parent, buf, size, callback, arg); 2123 } 2124 2125 /* 2126 * Start sampling the input source into the requested DMA buffer. 2127 * Called at splaudio(), either from top-half or from interrupt handler. 2128 */ 2129 int 2130 gus_dma_input(void *addr, void *buf, int size, void (*callback)(void *), 2131 void *arg) 2132 { 2133 struct gus_softc *sc = addr; 2134 bus_space_tag_t iot = sc->sc_iot; 2135 bus_space_handle_t ioh2 = sc->sc_ioh2; 2136 u_char dmac; 2137 DMAPRINTF(("gus_dma_input called\n")); 2138 2139 /* 2140 * Sample SIZE bytes of data from the card, into buffer at BUF. 2141 */ 2142 if (sc->sc_precision == 16) { 2143 return EINVAL; /* XXX */ 2144 } 2145 2146 /* set DMA modes */ 2147 dmac = GUSMASK_SAMPLE_IRQ|GUSMASK_SAMPLE_START; 2148 if (sc->sc_recdrq >= 4) 2149 dmac |= GUSMASK_SAMPLE_DATA16; 2150 if (sc->sc_encoding == AUDIO_ENCODING_ULAW || 2151 sc->sc_encoding == AUDIO_ENCODING_ALAW || 2152 sc->sc_encoding == AUDIO_ENCODING_ULINEAR_LE || 2153 sc->sc_encoding == AUDIO_ENCODING_ULINEAR_BE) 2154 dmac |= GUSMASK_SAMPLE_INVBIT; 2155 if (sc->sc_channels == 2) 2156 dmac |= GUSMASK_SAMPLE_STEREO; 2157 isa_dmastart(sc->sc_dev.dv_parent, sc->sc_recdrq, buf, size, 2158 NULL, DMAMODE_READ, BUS_DMA_NOWAIT); 2159 2160 DMAPRINTF(("gus_dma_input isadma_started\n")); 2161 sc->sc_flags |= GUS_DMAIN_ACTIVE; 2162 sc->sc_dmainintr = callback; 2163 sc->sc_inarg = arg; 2164 sc->sc_dmaincnt = size; 2165 sc->sc_dmainaddr = buf; 2166 2167 SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL); 2168 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, dmac); /* Go! */ 2169 2170 2171 DMAPRINTF(("gus_dma_input returning\n")); 2172 return 0; 2173 } 2174 2175 int 2176 gus_dmain_intr(struct gus_softc *sc) 2177 { 2178 void (*callback)(void *); 2179 void *arg; 2180 2181 DMAPRINTF(("gus_dmain_intr called\n")); 2182 if (sc->sc_dmainintr) { 2183 isa_dmadone(sc->sc_dev.dv_parent, sc->sc_recdrq); 2184 callback = sc->sc_dmainintr; 2185 arg = sc->sc_inarg; 2186 2187 sc->sc_dmainaddr = 0; 2188 sc->sc_dmaincnt = 0; 2189 sc->sc_dmainintr = 0; 2190 sc->sc_inarg = 0; 2191 2192 sc->sc_flags &= ~GUS_DMAIN_ACTIVE; 2193 DMAPRINTF(("calling dmain_intr callback %p(%p)\n", callback, arg)); 2194 (*callback)(arg); 2195 return 1; 2196 } else { 2197 DMAPRINTF(("gus_dmain_intr false?\n")); 2198 return 0; /* XXX ??? */ 2199 } 2200 } 2201 2202 int 2203 gusmax_halt_out_dma(void *addr) 2204 { 2205 struct ad1848_softc *sc = addr; 2206 return gus_halt_out_dma(sc->parent); 2207 } 2208 2209 2210 int 2211 gusmax_halt_in_dma(void *addr) 2212 { 2213 struct ad1848_softc *sc = addr; 2214 return gus_halt_in_dma(sc->parent); 2215 } 2216 2217 /* 2218 * Stop any DMA output. Called at splaudio(). 2219 */ 2220 int 2221 gus_halt_out_dma(void *addr) 2222 { 2223 struct gus_softc *sc = addr; 2224 bus_space_tag_t iot = sc->sc_iot; 2225 bus_space_handle_t ioh2 = sc->sc_ioh2; 2226 2227 mtx_enter(&audio_lock); 2228 DMAPRINTF(("gus_halt_out_dma called\n")); 2229 /* 2230 * Make sure the GUS _isn't_ setup for DMA 2231 */ 2232 2233 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL); 2234 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0); 2235 2236 timeout_del(&sc->sc_dma_tmo); 2237 isa_dmaabort(sc->sc_dev.dv_parent, sc->sc_drq); 2238 sc->sc_flags &= ~(GUS_DMAOUT_ACTIVE|GUS_LOCKED); 2239 sc->sc_dmaoutintr = 0; 2240 sc->sc_outarg = 0; 2241 sc->sc_dmaoutaddr = 0; 2242 sc->sc_dmaoutcnt = 0; 2243 sc->sc_dmabuf = 0; 2244 sc->sc_bufcnt = 0; 2245 sc->sc_playbuf = -1; 2246 /* also stop playing */ 2247 gus_stop_voice(sc, GUS_VOICE_LEFT, 1); 2248 gus_stop_voice(sc, GUS_VOICE_RIGHT, 0); 2249 mtx_leave(&audio_lock); 2250 return 0; 2251 } 2252 2253 /* 2254 * Stop any DMA output. Called at splaudio(). 2255 */ 2256 int 2257 gus_halt_in_dma(void *addr) 2258 { 2259 struct gus_softc *sc = addr; 2260 bus_space_tag_t iot = sc->sc_iot; 2261 bus_space_handle_t ioh2 = sc->sc_ioh2; 2262 2263 mtx_enter(&audio_lock); 2264 DMAPRINTF(("gus_halt_in_dma called\n")); 2265 2266 /* 2267 * Make sure the GUS _isn't_ setup for DMA 2268 */ 2269 2270 SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL); 2271 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 2272 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH) & ~(GUSMASK_SAMPLE_START|GUSMASK_SAMPLE_IRQ)); 2273 2274 isa_dmaabort(sc->sc_dev.dv_parent, sc->sc_recdrq); 2275 sc->sc_flags &= ~GUS_DMAIN_ACTIVE; 2276 sc->sc_dmainintr = 0; 2277 sc->sc_inarg = 0; 2278 sc->sc_dmainaddr = 0; 2279 sc->sc_dmaincnt = 0; 2280 mtx_leave(&audio_lock); 2281 return 0; 2282 } 2283 2284 2285 ad1848_devmap_t gusmapping[] = { 2286 {GUSMAX_DAC_LVL, AD1848_KIND_LVL, AD1848_AUX1_CHANNEL}, 2287 {GUSMAX_LINE_IN_LVL, AD1848_KIND_LVL, AD1848_LINE_CHANNEL}, 2288 {GUSMAX_MONO_LVL, AD1848_KIND_LVL, AD1848_MONO_CHANNEL}, 2289 {GUSMAX_CD_LVL, AD1848_KIND_LVL, AD1848_AUX2_CHANNEL}, 2290 {GUSMAX_MONITOR_LVL, AD1848_KIND_LVL, AD1848_MONITOR_CHANNEL}, 2291 {GUSMAX_OUT_LVL, AD1848_KIND_LVL, AD1848_DAC_CHANNEL}, 2292 {GUSMAX_DAC_MUTE, AD1848_KIND_MUTE, AD1848_AUX1_CHANNEL}, 2293 {GUSMAX_LINE_IN_MUTE, AD1848_KIND_MUTE, AD1848_LINE_CHANNEL}, 2294 {GUSMAX_MONO_MUTE, AD1848_KIND_MUTE, AD1848_MONO_CHANNEL}, 2295 {GUSMAX_CD_MUTE, AD1848_KIND_MUTE, AD1848_AUX2_CHANNEL}, 2296 {GUSMAX_MONITOR_MUTE, AD1848_KIND_MUTE, AD1848_MONITOR_CHANNEL}, 2297 {GUSMAX_REC_LVL, AD1848_KIND_RECORDGAIN, -1}, 2298 {GUSMAX_RECORD_SOURCE, AD1848_KIND_RECORDSOURCE, -1} 2299 }; 2300 2301 int nummap = sizeof(gusmapping) / sizeof(gusmapping[0]); 2302 2303 int 2304 gusmax_mixer_get_port(void *addr, mixer_ctrl_t *cp) 2305 { 2306 struct ad1848_softc *ac = addr; 2307 struct gus_softc *sc = ac->parent; 2308 struct ad1848_volume vol; 2309 int error = ad1848_mixer_get_port(ac, gusmapping, nummap, cp); 2310 2311 if (error != ENXIO) 2312 return (error); 2313 2314 error = EINVAL; 2315 2316 switch (cp->dev) { 2317 case GUSMAX_SPEAKER_LVL: /* fake speaker for mute naming */ 2318 if (cp->type == AUDIO_MIXER_VALUE) { 2319 if (sc->sc_mixcontrol & GUSMASK_LINE_OUT) 2320 vol.left = vol.right = AUDIO_MAX_GAIN; 2321 else 2322 vol.left = vol.right = AUDIO_MIN_GAIN; 2323 error = 0; 2324 ad1848_from_vol(cp, &vol); 2325 } 2326 break; 2327 2328 case GUSMAX_SPEAKER_MUTE: 2329 if (cp->type == AUDIO_MIXER_ENUM) { 2330 cp->un.ord = sc->sc_mixcontrol & GUSMASK_LINE_OUT ? 1 : 0; 2331 error = 0; 2332 } 2333 break; 2334 default: 2335 error = ENXIO; 2336 break; 2337 } 2338 2339 return(error); 2340 } 2341 2342 int 2343 gus_mixer_get_port(void *addr, mixer_ctrl_t *cp) 2344 { 2345 struct gus_softc *sc = addr; 2346 struct ics2101_softc *ic = &sc->sc_mixer; 2347 struct ad1848_volume vol; 2348 int error = EINVAL; 2349 2350 DPRINTF(("gus_mixer_get_port: dev=%d type=%d\n", cp->dev, cp->type)); 2351 2352 if (!HAS_MIXER(sc) && cp->dev > GUSICS_MASTER_MUTE) 2353 return ENXIO; 2354 2355 switch (cp->dev) { 2356 2357 case GUSICS_MIC_IN_MUTE: /* Microphone */ 2358 if (cp->type == AUDIO_MIXER_ENUM) { 2359 if (HAS_MIXER(sc)) 2360 cp->un.ord = ic->sc_mute[GUSMIX_CHAN_MIC][ICSMIX_LEFT]; 2361 else 2362 cp->un.ord = 2363 sc->sc_mixcontrol & GUSMASK_MIC_IN ? 0 : 1; 2364 error = 0; 2365 } 2366 break; 2367 2368 case GUSICS_LINE_IN_MUTE: 2369 if (cp->type == AUDIO_MIXER_ENUM) { 2370 if (HAS_MIXER(sc)) 2371 cp->un.ord = ic->sc_mute[GUSMIX_CHAN_LINE][ICSMIX_LEFT]; 2372 else 2373 cp->un.ord = 2374 sc->sc_mixcontrol & GUSMASK_LINE_IN ? 1 : 0; 2375 error = 0; 2376 } 2377 break; 2378 2379 case GUSICS_MASTER_MUTE: 2380 if (cp->type == AUDIO_MIXER_ENUM) { 2381 if (HAS_MIXER(sc)) 2382 cp->un.ord = ic->sc_mute[GUSMIX_CHAN_MASTER][ICSMIX_LEFT]; 2383 else 2384 cp->un.ord = 2385 sc->sc_mixcontrol & GUSMASK_LINE_OUT ? 1 : 0; 2386 error = 0; 2387 } 2388 break; 2389 2390 case GUSICS_DAC_MUTE: 2391 if (cp->type == AUDIO_MIXER_ENUM) { 2392 cp->un.ord = ic->sc_mute[GUSMIX_CHAN_DAC][ICSMIX_LEFT]; 2393 error = 0; 2394 } 2395 break; 2396 2397 case GUSICS_CD_MUTE: 2398 if (cp->type == AUDIO_MIXER_ENUM) { 2399 cp->un.ord = ic->sc_mute[GUSMIX_CHAN_CD][ICSMIX_LEFT]; 2400 error = 0; 2401 } 2402 break; 2403 2404 case GUSICS_MASTER_LVL: 2405 if (cp->type == AUDIO_MIXER_VALUE) { 2406 vol.left = ic->sc_setting[GUSMIX_CHAN_MASTER][ICSMIX_LEFT]; 2407 vol.right = ic->sc_setting[GUSMIX_CHAN_MASTER][ICSMIX_RIGHT]; 2408 if (ad1848_from_vol(cp, &vol)) 2409 error = 0; 2410 } 2411 break; 2412 2413 case GUSICS_MIC_IN_LVL: /* Microphone */ 2414 if (cp->type == AUDIO_MIXER_VALUE) { 2415 vol.left = ic->sc_setting[GUSMIX_CHAN_MIC][ICSMIX_LEFT]; 2416 vol.right = ic->sc_setting[GUSMIX_CHAN_MIC][ICSMIX_RIGHT]; 2417 if (ad1848_from_vol(cp, &vol)) 2418 error = 0; 2419 } 2420 break; 2421 2422 case GUSICS_LINE_IN_LVL: /* line in */ 2423 if (cp->type == AUDIO_MIXER_VALUE) { 2424 vol.left = ic->sc_setting[GUSMIX_CHAN_LINE][ICSMIX_LEFT]; 2425 vol.right = ic->sc_setting[GUSMIX_CHAN_LINE][ICSMIX_RIGHT]; 2426 if (ad1848_from_vol(cp, &vol)) 2427 error = 0; 2428 } 2429 break; 2430 2431 2432 case GUSICS_CD_LVL: 2433 if (cp->type == AUDIO_MIXER_VALUE) { 2434 vol.left = ic->sc_setting[GUSMIX_CHAN_CD][ICSMIX_LEFT]; 2435 vol.right = ic->sc_setting[GUSMIX_CHAN_CD][ICSMIX_RIGHT]; 2436 if (ad1848_from_vol(cp, &vol)) 2437 error = 0; 2438 } 2439 break; 2440 2441 case GUSICS_DAC_LVL: /* dac out */ 2442 if (cp->type == AUDIO_MIXER_VALUE) { 2443 vol.left = ic->sc_setting[GUSMIX_CHAN_DAC][ICSMIX_LEFT]; 2444 vol.right = ic->sc_setting[GUSMIX_CHAN_DAC][ICSMIX_RIGHT]; 2445 if (ad1848_from_vol(cp, &vol)) 2446 error = 0; 2447 } 2448 break; 2449 2450 2451 case GUSICS_RECORD_SOURCE: 2452 if (cp->type == AUDIO_MIXER_ENUM) { 2453 /* Can't set anything else useful, sigh. */ 2454 cp->un.ord = 0; 2455 } 2456 break; 2457 2458 default: 2459 return ENXIO; 2460 /*NOTREACHED*/ 2461 } 2462 return error; 2463 } 2464 2465 void 2466 gusics_master_mute(struct ics2101_softc *ic, int mute) 2467 { 2468 ics2101_mix_mute(ic, GUSMIX_CHAN_MASTER, ICSMIX_LEFT, mute); 2469 ics2101_mix_mute(ic, GUSMIX_CHAN_MASTER, ICSMIX_RIGHT, mute); 2470 } 2471 2472 void 2473 gusics_mic_mute(struct ics2101_softc *ic, int mute) 2474 { 2475 ics2101_mix_mute(ic, GUSMIX_CHAN_MIC, ICSMIX_LEFT, mute); 2476 ics2101_mix_mute(ic, GUSMIX_CHAN_MIC, ICSMIX_RIGHT, mute); 2477 } 2478 2479 void 2480 gusics_linein_mute(struct ics2101_softc *ic, int mute) 2481 { 2482 ics2101_mix_mute(ic, GUSMIX_CHAN_LINE, ICSMIX_LEFT, mute); 2483 ics2101_mix_mute(ic, GUSMIX_CHAN_LINE, ICSMIX_RIGHT, mute); 2484 } 2485 2486 void 2487 gusics_cd_mute(struct ics2101_softc *ic, int mute) 2488 { 2489 ics2101_mix_mute(ic, GUSMIX_CHAN_CD, ICSMIX_LEFT, mute); 2490 ics2101_mix_mute(ic, GUSMIX_CHAN_CD, ICSMIX_RIGHT, mute); 2491 } 2492 2493 void 2494 gusics_dac_mute(struct ics2101_softc *ic, int mute) 2495 { 2496 ics2101_mix_mute(ic, GUSMIX_CHAN_DAC, ICSMIX_LEFT, mute); 2497 ics2101_mix_mute(ic, GUSMIX_CHAN_DAC, ICSMIX_RIGHT, mute); 2498 } 2499 2500 int 2501 gusmax_mixer_set_port(void *addr, mixer_ctrl_t *cp) 2502 { 2503 struct ad1848_softc *ac = addr; 2504 struct gus_softc *sc = ac->parent; 2505 struct ad1848_volume vol; 2506 int error = ad1848_mixer_set_port(ac, gusmapping, nummap, cp); 2507 2508 if (error != ENXIO) 2509 return (error); 2510 2511 DPRINTF(("gusmax_mixer_set_port: dev=%d type=%d\n", cp->dev, cp->type)); 2512 2513 switch (cp->dev) { 2514 case GUSMAX_SPEAKER_LVL: 2515 if (cp->type == AUDIO_MIXER_VALUE && 2516 cp->un.value.num_channels == 1) { 2517 if (ad1848_to_vol(cp, &vol)) { 2518 gus_speaker_ctl(sc, vol.left > AUDIO_MIN_GAIN ? 2519 SPKR_ON : SPKR_OFF); 2520 error = 0; 2521 } 2522 } 2523 break; 2524 2525 case GUSMAX_SPEAKER_MUTE: 2526 if (cp->type == AUDIO_MIXER_ENUM) { 2527 gus_speaker_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON); 2528 error = 0; 2529 } 2530 break; 2531 2532 default: 2533 return ENXIO; 2534 /*NOTREACHED*/ 2535 } 2536 return error; 2537 } 2538 2539 int 2540 gus_mixer_set_port(void *addr, mixer_ctrl_t *cp) 2541 { 2542 struct gus_softc *sc = addr; 2543 struct ics2101_softc *ic = &sc->sc_mixer; 2544 struct ad1848_volume vol; 2545 int error = EINVAL; 2546 2547 DPRINTF(("gus_mixer_set_port: dev=%d type=%d\n", cp->dev, cp->type)); 2548 2549 if (!HAS_MIXER(sc) && cp->dev > GUSICS_MASTER_MUTE) 2550 return ENXIO; 2551 2552 switch (cp->dev) { 2553 2554 case GUSICS_MIC_IN_MUTE: /* Microphone */ 2555 if (cp->type == AUDIO_MIXER_ENUM) { 2556 DPRINTF(("mic mute %d\n", cp->un.ord)); 2557 if (HAS_MIXER(sc)) { 2558 gusics_mic_mute(ic, cp->un.ord); 2559 } 2560 gus_mic_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON); 2561 error = 0; 2562 } 2563 break; 2564 2565 case GUSICS_LINE_IN_MUTE: 2566 if (cp->type == AUDIO_MIXER_ENUM) { 2567 DPRINTF(("linein mute %d\n", cp->un.ord)); 2568 if (HAS_MIXER(sc)) { 2569 gusics_linein_mute(ic, cp->un.ord); 2570 } 2571 gus_linein_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON); 2572 error = 0; 2573 } 2574 break; 2575 2576 case GUSICS_MASTER_MUTE: 2577 if (cp->type == AUDIO_MIXER_ENUM) { 2578 DPRINTF(("master mute %d\n", cp->un.ord)); 2579 if (HAS_MIXER(sc)) { 2580 gusics_master_mute(ic, cp->un.ord); 2581 } 2582 gus_speaker_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON); 2583 error = 0; 2584 } 2585 break; 2586 2587 case GUSICS_DAC_MUTE: 2588 if (cp->type == AUDIO_MIXER_ENUM) { 2589 gusics_dac_mute(ic, cp->un.ord); 2590 error = 0; 2591 } 2592 break; 2593 2594 case GUSICS_CD_MUTE: 2595 if (cp->type == AUDIO_MIXER_ENUM) { 2596 gusics_cd_mute(ic, cp->un.ord); 2597 error = 0; 2598 } 2599 break; 2600 2601 case GUSICS_MASTER_LVL: 2602 if (cp->type == AUDIO_MIXER_VALUE) { 2603 if (ad1848_to_vol(cp, &vol)) { 2604 ics2101_mix_attenuate(ic, 2605 GUSMIX_CHAN_MASTER, 2606 ICSMIX_LEFT, 2607 vol.left); 2608 ics2101_mix_attenuate(ic, 2609 GUSMIX_CHAN_MASTER, 2610 ICSMIX_RIGHT, 2611 vol.right); 2612 error = 0; 2613 } 2614 } 2615 break; 2616 2617 case GUSICS_MIC_IN_LVL: /* Microphone */ 2618 if (cp->type == AUDIO_MIXER_VALUE) { 2619 if (ad1848_to_vol(cp, &vol)) { 2620 ics2101_mix_attenuate(ic, 2621 GUSMIX_CHAN_MIC, 2622 ICSMIX_LEFT, 2623 vol.left); 2624 ics2101_mix_attenuate(ic, 2625 GUSMIX_CHAN_MIC, 2626 ICSMIX_RIGHT, 2627 vol.right); 2628 error = 0; 2629 } 2630 } 2631 break; 2632 2633 case GUSICS_LINE_IN_LVL: /* line in */ 2634 if (cp->type == AUDIO_MIXER_VALUE) { 2635 if (ad1848_to_vol(cp, &vol)) { 2636 ics2101_mix_attenuate(ic, 2637 GUSMIX_CHAN_LINE, 2638 ICSMIX_LEFT, 2639 vol.left); 2640 ics2101_mix_attenuate(ic, 2641 GUSMIX_CHAN_LINE, 2642 ICSMIX_RIGHT, 2643 vol.right); 2644 error = 0; 2645 } 2646 } 2647 break; 2648 2649 2650 case GUSICS_CD_LVL: 2651 if (cp->type == AUDIO_MIXER_VALUE) { 2652 if (ad1848_to_vol(cp, &vol)) { 2653 ics2101_mix_attenuate(ic, 2654 GUSMIX_CHAN_CD, 2655 ICSMIX_LEFT, 2656 vol.left); 2657 ics2101_mix_attenuate(ic, 2658 GUSMIX_CHAN_CD, 2659 ICSMIX_RIGHT, 2660 vol.right); 2661 error = 0; 2662 } 2663 } 2664 break; 2665 2666 case GUSICS_DAC_LVL: /* dac out */ 2667 if (cp->type == AUDIO_MIXER_VALUE) { 2668 if (ad1848_to_vol(cp, &vol)) { 2669 ics2101_mix_attenuate(ic, 2670 GUSMIX_CHAN_DAC, 2671 ICSMIX_LEFT, 2672 vol.left); 2673 ics2101_mix_attenuate(ic, 2674 GUSMIX_CHAN_DAC, 2675 ICSMIX_RIGHT, 2676 vol.right); 2677 error = 0; 2678 } 2679 } 2680 break; 2681 2682 2683 case GUSICS_RECORD_SOURCE: 2684 if (cp->type == AUDIO_MIXER_ENUM && cp->un.ord == 0) { 2685 /* Can't set anything else useful, sigh. */ 2686 error = 0; 2687 } 2688 break; 2689 2690 default: 2691 return ENXIO; 2692 /*NOTREACHED*/ 2693 } 2694 return error; 2695 } 2696 2697 int 2698 gus_get_props(void *addr) 2699 { 2700 struct gus_softc *sc = addr; 2701 return AUDIO_PROP_MMAP | 2702 (sc->sc_recdrq == sc->sc_drq ? 0 : AUDIO_PROP_FULLDUPLEX); 2703 } 2704 2705 int 2706 gusmax_get_props(void *addr) 2707 { 2708 struct ad1848_softc *ac = addr; 2709 return gus_get_props(ac->parent); 2710 } 2711 2712 int 2713 gusmax_mixer_query_devinfo(void *addr, mixer_devinfo_t *dip) 2714 { 2715 DPRINTF(("gusmax_query_devinfo: index=%d\n", dip->index)); 2716 2717 switch(dip->index) { 2718 #if 0 2719 case GUSMAX_MIC_IN_LVL: /* Microphone */ 2720 dip->type = AUDIO_MIXER_VALUE; 2721 dip->mixer_class = GUSMAX_INPUT_CLASS; 2722 dip->prev = AUDIO_MIXER_LAST; 2723 dip->next = GUSMAX_MIC_IN_MUTE; 2724 strlcpy(dip->label.name, AudioNmicrophone, sizeof dip->label.name); 2725 dip->un.v.num_channels = 2; 2726 strlcpy(dip->un.v.units.name, AudioNvolume, 2727 sizeof dip->un.v.units.name); 2728 break; 2729 #endif 2730 2731 case GUSMAX_MONO_LVL: /* mono/microphone mixer */ 2732 dip->type = AUDIO_MIXER_VALUE; 2733 dip->mixer_class = GUSMAX_INPUT_CLASS; 2734 dip->prev = AUDIO_MIXER_LAST; 2735 dip->next = GUSMAX_MONO_MUTE; 2736 strlcpy(dip->label.name, AudioNmicrophone, sizeof dip->label.name); 2737 dip->un.v.num_channels = 1; 2738 strlcpy(dip->un.v.units.name, AudioNvolume, 2739 sizeof dip->un.v.units.name); 2740 break; 2741 2742 case GUSMAX_DAC_LVL: /* dacout */ 2743 dip->type = AUDIO_MIXER_VALUE; 2744 dip->mixer_class = GUSMAX_INPUT_CLASS; 2745 dip->prev = AUDIO_MIXER_LAST; 2746 dip->next = GUSMAX_DAC_MUTE; 2747 strlcpy(dip->label.name, AudioNdac, sizeof dip->label.name); 2748 dip->un.v.num_channels = 2; 2749 strlcpy(dip->un.v.units.name, AudioNvolume, 2750 sizeof dip->un.v.units.name); 2751 break; 2752 2753 case GUSMAX_LINE_IN_LVL: /* line */ 2754 dip->type = AUDIO_MIXER_VALUE; 2755 dip->mixer_class = GUSMAX_INPUT_CLASS; 2756 dip->prev = AUDIO_MIXER_LAST; 2757 dip->next = GUSMAX_LINE_IN_MUTE; 2758 strlcpy(dip->label.name, AudioNline, sizeof dip->label.name); 2759 dip->un.v.num_channels = 2; 2760 strlcpy(dip->un.v.units.name, AudioNvolume, 2761 sizeof dip->un.v.units.name); 2762 break; 2763 2764 case GUSMAX_CD_LVL: /* cd */ 2765 dip->type = AUDIO_MIXER_VALUE; 2766 dip->mixer_class = GUSMAX_INPUT_CLASS; 2767 dip->prev = AUDIO_MIXER_LAST; 2768 dip->next = GUSMAX_CD_MUTE; 2769 strlcpy(dip->label.name, AudioNcd, sizeof dip->label.name); 2770 dip->un.v.num_channels = 2; 2771 strlcpy(dip->un.v.units.name, AudioNvolume, 2772 sizeof dip->un.v.units.name); 2773 break; 2774 2775 2776 case GUSMAX_MONITOR_LVL: /* monitor level */ 2777 dip->type = AUDIO_MIXER_VALUE; 2778 dip->mixer_class = GUSMAX_MONITOR_CLASS; 2779 dip->next = GUSMAX_MONITOR_MUTE; 2780 dip->prev = AUDIO_MIXER_LAST; 2781 strlcpy(dip->label.name, AudioNmonitor, sizeof dip->label.name); 2782 dip->un.v.num_channels = 1; 2783 strlcpy(dip->un.v.units.name, AudioNvolume, 2784 sizeof dip->un.v.units.name); 2785 break; 2786 2787 case GUSMAX_OUT_LVL: /* cs4231 output volume: not useful? */ 2788 dip->type = AUDIO_MIXER_VALUE; 2789 dip->mixer_class = GUSMAX_MONITOR_CLASS; 2790 dip->prev = dip->next = AUDIO_MIXER_LAST; 2791 strlcpy(dip->label.name, AudioNoutput, sizeof dip->label.name); 2792 dip->un.v.num_channels = 2; 2793 strlcpy(dip->un.v.units.name, AudioNvolume, 2794 sizeof dip->un.v.units.name); 2795 break; 2796 2797 case GUSMAX_SPEAKER_LVL: /* fake speaker volume */ 2798 dip->type = AUDIO_MIXER_VALUE; 2799 dip->mixer_class = GUSMAX_MONITOR_CLASS; 2800 dip->prev = AUDIO_MIXER_LAST; 2801 dip->next = GUSMAX_SPEAKER_MUTE; 2802 strlcpy(dip->label.name, AudioNmaster, sizeof dip->label.name); 2803 dip->un.v.num_channels = 2; 2804 strlcpy(dip->un.v.units.name, AudioNvolume, 2805 sizeof dip->un.v.units.name); 2806 break; 2807 2808 case GUSMAX_LINE_IN_MUTE: 2809 dip->mixer_class = GUSMAX_INPUT_CLASS; 2810 dip->type = AUDIO_MIXER_ENUM; 2811 dip->prev = GUSMAX_LINE_IN_LVL; 2812 dip->next = AUDIO_MIXER_LAST; 2813 goto mute; 2814 2815 case GUSMAX_DAC_MUTE: 2816 dip->mixer_class = GUSMAX_INPUT_CLASS; 2817 dip->type = AUDIO_MIXER_ENUM; 2818 dip->prev = GUSMAX_DAC_LVL; 2819 dip->next = AUDIO_MIXER_LAST; 2820 goto mute; 2821 2822 case GUSMAX_CD_MUTE: 2823 dip->mixer_class = GUSMAX_INPUT_CLASS; 2824 dip->type = AUDIO_MIXER_ENUM; 2825 dip->prev = GUSMAX_CD_LVL; 2826 dip->next = AUDIO_MIXER_LAST; 2827 goto mute; 2828 2829 case GUSMAX_MONO_MUTE: 2830 dip->mixer_class = GUSMAX_INPUT_CLASS; 2831 dip->type = AUDIO_MIXER_ENUM; 2832 dip->prev = GUSMAX_MONO_LVL; 2833 dip->next = AUDIO_MIXER_LAST; 2834 goto mute; 2835 2836 case GUSMAX_MONITOR_MUTE: 2837 dip->mixer_class = GUSMAX_OUTPUT_CLASS; 2838 dip->type = AUDIO_MIXER_ENUM; 2839 dip->prev = GUSMAX_MONITOR_LVL; 2840 dip->next = AUDIO_MIXER_LAST; 2841 goto mute; 2842 2843 case GUSMAX_SPEAKER_MUTE: 2844 dip->mixer_class = GUSMAX_OUTPUT_CLASS; 2845 dip->type = AUDIO_MIXER_ENUM; 2846 dip->prev = GUSMAX_SPEAKER_LVL; 2847 dip->next = AUDIO_MIXER_LAST; 2848 mute: 2849 strlcpy(dip->label.name, AudioNmute, sizeof dip->label.name); 2850 dip->un.e.num_mem = 2; 2851 strlcpy(dip->un.e.member[0].label.name, AudioNoff, 2852 sizeof dip->un.e.member[0].label.name); 2853 dip->un.e.member[0].ord = 0; 2854 strlcpy(dip->un.e.member[1].label.name, AudioNon, 2855 sizeof dip->un.e.member[1].label.name); 2856 dip->un.e.member[1].ord = 1; 2857 break; 2858 2859 case GUSMAX_REC_LVL: /* record level */ 2860 dip->type = AUDIO_MIXER_VALUE; 2861 dip->mixer_class = GUSMAX_RECORD_CLASS; 2862 dip->prev = AUDIO_MIXER_LAST; 2863 dip->next = GUSMAX_RECORD_SOURCE; 2864 strlcpy(dip->label.name, AudioNrecord, sizeof dip->label.name); 2865 dip->un.v.num_channels = 2; 2866 strlcpy(dip->un.v.units.name, AudioNvolume, sizeof dip->un.v.units.name); 2867 break; 2868 2869 case GUSMAX_RECORD_SOURCE: 2870 dip->mixer_class = GUSMAX_RECORD_CLASS; 2871 dip->type = AUDIO_MIXER_ENUM; 2872 dip->prev = GUSMAX_REC_LVL; 2873 dip->next = AUDIO_MIXER_LAST; 2874 strlcpy(dip->label.name, AudioNsource, sizeof dip->label.name); 2875 dip->un.e.num_mem = 4; 2876 strlcpy(dip->un.e.member[0].label.name, AudioNoutput, 2877 sizeof dip->un.e.member[0].label.name); 2878 dip->un.e.member[0].ord = DAC_IN_PORT; 2879 strlcpy(dip->un.e.member[1].label.name, AudioNmicrophone, 2880 sizeof dip->un.e.member[1].label.name); 2881 dip->un.e.member[1].ord = MIC_IN_PORT; 2882 strlcpy(dip->un.e.member[2].label.name, AudioNdac, 2883 sizeof dip->un.e.member[2].label.name); 2884 dip->un.e.member[2].ord = AUX1_IN_PORT; 2885 strlcpy(dip->un.e.member[3].label.name, AudioNline, 2886 sizeof dip->un.e.member[3].label.name); 2887 dip->un.e.member[3].ord = LINE_IN_PORT; 2888 break; 2889 2890 case GUSMAX_INPUT_CLASS: /* input class descriptor */ 2891 dip->type = AUDIO_MIXER_CLASS; 2892 dip->mixer_class = GUSMAX_INPUT_CLASS; 2893 dip->next = dip->prev = AUDIO_MIXER_LAST; 2894 strlcpy(dip->label.name, AudioCinputs, sizeof dip->label.name); 2895 break; 2896 2897 case GUSMAX_OUTPUT_CLASS: /* output class descriptor */ 2898 dip->type = AUDIO_MIXER_CLASS; 2899 dip->mixer_class = GUSMAX_OUTPUT_CLASS; 2900 dip->next = dip->prev = AUDIO_MIXER_LAST; 2901 strlcpy(dip->label.name, AudioCoutputs, sizeof dip->label.name); 2902 break; 2903 2904 case GUSMAX_MONITOR_CLASS: /* monitor class descriptor */ 2905 dip->type = AUDIO_MIXER_CLASS; 2906 dip->mixer_class = GUSMAX_MONITOR_CLASS; 2907 dip->next = dip->prev = AUDIO_MIXER_LAST; 2908 strlcpy(dip->label.name, AudioCmonitor, sizeof dip->label.name); 2909 break; 2910 2911 case GUSMAX_RECORD_CLASS: /* record source class */ 2912 dip->type = AUDIO_MIXER_CLASS; 2913 dip->mixer_class = GUSMAX_RECORD_CLASS; 2914 dip->next = dip->prev = AUDIO_MIXER_LAST; 2915 strlcpy(dip->label.name, AudioCrecord, sizeof dip->label.name); 2916 break; 2917 2918 default: 2919 return ENXIO; 2920 /*NOTREACHED*/ 2921 } 2922 DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name)); 2923 return 0; 2924 } 2925 2926 int 2927 gus_mixer_query_devinfo(void *addr, mixer_devinfo_t *dip) 2928 { 2929 struct gus_softc *sc = addr; 2930 2931 DPRINTF(("gusmax_query_devinfo: index=%d\n", dip->index)); 2932 2933 if (!HAS_MIXER(sc) && dip->index > GUSICS_MASTER_MUTE) 2934 return ENXIO; 2935 2936 switch(dip->index) { 2937 2938 case GUSICS_MIC_IN_LVL: /* Microphone */ 2939 dip->type = AUDIO_MIXER_VALUE; 2940 dip->mixer_class = GUSICS_INPUT_CLASS; 2941 dip->prev = AUDIO_MIXER_LAST; 2942 dip->next = GUSICS_MIC_IN_MUTE; 2943 strlcpy(dip->label.name, AudioNmicrophone, 2944 sizeof dip->label.name); 2945 dip->un.v.num_channels = 2; 2946 strlcpy(dip->un.v.units.name, AudioNvolume, 2947 sizeof dip->un.v.units.name); 2948 break; 2949 2950 case GUSICS_LINE_IN_LVL: /* line */ 2951 dip->type = AUDIO_MIXER_VALUE; 2952 dip->mixer_class = GUSICS_INPUT_CLASS; 2953 dip->prev = AUDIO_MIXER_LAST; 2954 dip->next = GUSICS_LINE_IN_MUTE; 2955 strlcpy(dip->label.name, AudioNline, sizeof dip->label.name); 2956 dip->un.v.num_channels = 2; 2957 strlcpy(dip->un.v.units.name, AudioNvolume, 2958 sizeof dip->un.v.units.name); 2959 break; 2960 2961 case GUSICS_CD_LVL: /* cd */ 2962 dip->type = AUDIO_MIXER_VALUE; 2963 dip->mixer_class = GUSICS_INPUT_CLASS; 2964 dip->prev = AUDIO_MIXER_LAST; 2965 dip->next = GUSICS_CD_MUTE; 2966 strlcpy(dip->label.name, AudioNcd, sizeof dip->label.name); 2967 dip->un.v.num_channels = 2; 2968 strlcpy(dip->un.v.units.name, AudioNvolume, 2969 sizeof dip->un.v.units.name); 2970 break; 2971 2972 case GUSICS_DAC_LVL: /* dacout */ 2973 dip->type = AUDIO_MIXER_VALUE; 2974 dip->mixer_class = GUSICS_INPUT_CLASS; 2975 dip->prev = AUDIO_MIXER_LAST; 2976 dip->next = GUSICS_DAC_MUTE; 2977 strlcpy(dip->label.name, AudioNdac, sizeof dip->label.name); 2978 dip->un.v.num_channels = 2; 2979 strlcpy(dip->un.v.units.name, AudioNvolume, 2980 sizeof dip->un.v.units.name); 2981 break; 2982 2983 case GUSICS_MASTER_LVL: /* master output */ 2984 dip->type = AUDIO_MIXER_VALUE; 2985 dip->mixer_class = GUSICS_OUTPUT_CLASS; 2986 dip->prev = AUDIO_MIXER_LAST; 2987 dip->next = GUSICS_MASTER_MUTE; 2988 strlcpy(dip->label.name, AudioNmaster, sizeof dip->label.name); 2989 dip->un.v.num_channels = 2; 2990 strlcpy(dip->un.v.units.name, AudioNvolume, 2991 sizeof dip->un.v.units.name); 2992 break; 2993 2994 2995 case GUSICS_LINE_IN_MUTE: 2996 dip->mixer_class = GUSICS_INPUT_CLASS; 2997 dip->type = AUDIO_MIXER_ENUM; 2998 dip->prev = GUSICS_LINE_IN_LVL; 2999 dip->next = AUDIO_MIXER_LAST; 3000 goto mute; 3001 3002 case GUSICS_DAC_MUTE: 3003 dip->mixer_class = GUSICS_INPUT_CLASS; 3004 dip->type = AUDIO_MIXER_ENUM; 3005 dip->prev = GUSICS_DAC_LVL; 3006 dip->next = AUDIO_MIXER_LAST; 3007 goto mute; 3008 3009 case GUSICS_CD_MUTE: 3010 dip->mixer_class = GUSICS_INPUT_CLASS; 3011 dip->type = AUDIO_MIXER_ENUM; 3012 dip->prev = GUSICS_CD_LVL; 3013 dip->next = AUDIO_MIXER_LAST; 3014 goto mute; 3015 3016 case GUSICS_MIC_IN_MUTE: 3017 dip->mixer_class = GUSICS_INPUT_CLASS; 3018 dip->type = AUDIO_MIXER_ENUM; 3019 dip->prev = GUSICS_MIC_IN_LVL; 3020 dip->next = AUDIO_MIXER_LAST; 3021 goto mute; 3022 3023 case GUSICS_MASTER_MUTE: 3024 dip->mixer_class = GUSICS_OUTPUT_CLASS; 3025 dip->type = AUDIO_MIXER_ENUM; 3026 dip->prev = GUSICS_MASTER_LVL; 3027 dip->next = AUDIO_MIXER_LAST; 3028 mute: 3029 strlcpy(dip->label.name, AudioNmute, sizeof dip->label.name); 3030 dip->un.e.num_mem = 2; 3031 strlcpy(dip->un.e.member[0].label.name, AudioNoff, 3032 sizeof dip->un.e.member[0].label.name); 3033 dip->un.e.member[0].ord = 0; 3034 strlcpy(dip->un.e.member[1].label.name, AudioNon, 3035 sizeof dip->un.e.member[1].label.name); 3036 dip->un.e.member[1].ord = 1; 3037 break; 3038 3039 case GUSICS_RECORD_SOURCE: 3040 dip->mixer_class = GUSICS_RECORD_CLASS; 3041 dip->type = AUDIO_MIXER_ENUM; 3042 dip->prev = dip->next = AUDIO_MIXER_LAST; 3043 strlcpy(dip->label.name, AudioNsource, sizeof dip->label.name); 3044 dip->un.e.num_mem = 1; 3045 strlcpy(dip->un.e.member[0].label.name, AudioNoutput, 3046 sizeof dip->un.e.member[0].label.name); 3047 dip->un.e.member[0].ord = GUSICS_MASTER_LVL; 3048 break; 3049 3050 case GUSICS_INPUT_CLASS: 3051 dip->type = AUDIO_MIXER_CLASS; 3052 dip->mixer_class = GUSICS_INPUT_CLASS; 3053 dip->next = dip->prev = AUDIO_MIXER_LAST; 3054 strlcpy(dip->label.name, AudioCinputs, sizeof dip->label.name); 3055 break; 3056 3057 case GUSICS_OUTPUT_CLASS: 3058 dip->type = AUDIO_MIXER_CLASS; 3059 dip->mixer_class = GUSICS_OUTPUT_CLASS; 3060 dip->next = dip->prev = AUDIO_MIXER_LAST; 3061 strlcpy(dip->label.name, AudioCoutputs, sizeof dip->label.name); 3062 break; 3063 3064 case GUSICS_RECORD_CLASS: 3065 dip->type = AUDIO_MIXER_CLASS; 3066 dip->mixer_class = GUSICS_RECORD_CLASS; 3067 dip->next = dip->prev = AUDIO_MIXER_LAST; 3068 strlcpy(dip->label.name, AudioCrecord, sizeof dip->label.name); 3069 break; 3070 3071 default: 3072 return ENXIO; 3073 /*NOTREACHED*/ 3074 } 3075 DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name)); 3076 return 0; 3077 } 3078 3079 void * 3080 gus_malloc(void *addr, int direction, size_t size, int pool, int flags) 3081 { 3082 struct gus_softc *sc = addr; 3083 int drq; 3084 3085 if (direction == AUMODE_PLAY) 3086 drq = sc->sc_drq; 3087 else 3088 drq = sc->sc_recdrq; 3089 3090 return isa_malloc(sc->sc_isa, drq, size, pool, flags); 3091 } 3092 3093 void 3094 gus_free(void *addr, void *ptr, int pool) 3095 { 3096 isa_free(ptr, pool); 3097 } 3098 3099 size_t 3100 gus_round(void *addr, int direction, size_t size) 3101 { 3102 if (size > MAX_ISADMA) 3103 size = MAX_ISADMA; 3104 return size; 3105 } 3106 3107 /* 3108 * Setup the ICS mixer in "transparent" mode: reset everything to a sensible 3109 * level. Levels as suggested by GUS SDK code. 3110 */ 3111 3112 void 3113 gus_init_ics2101(struct gus_softc *sc) 3114 { 3115 struct ics2101_softc *ic = &sc->sc_mixer; 3116 sc->sc_mixer.sc_iot = sc->sc_iot; 3117 sc->sc_mixer.sc_selio = GUS_MIXER_SELECT; 3118 sc->sc_mixer.sc_selio_ioh = sc->sc_ioh3; 3119 sc->sc_mixer.sc_dataio = GUS_MIXER_DATA; 3120 sc->sc_mixer.sc_dataio_ioh = sc->sc_ioh2; 3121 sc->sc_mixer.sc_flags = (sc->sc_revision == 5) ? ICS_FLIP : 0; 3122 3123 ics2101_mix_attenuate(ic, 3124 GUSMIX_CHAN_MIC, 3125 ICSMIX_LEFT, 3126 ICSMIX_MIN_ATTN); 3127 ics2101_mix_attenuate(ic, 3128 GUSMIX_CHAN_MIC, 3129 ICSMIX_RIGHT, 3130 ICSMIX_MIN_ATTN); 3131 /* 3132 * Start with microphone muted by the mixer... 3133 */ 3134 gusics_mic_mute(ic, 1); 3135 3136 /* ... and enabled by the GUS master mix control */ 3137 gus_mic_ctl(sc, SPKR_ON); 3138 3139 ics2101_mix_attenuate(ic, 3140 GUSMIX_CHAN_LINE, 3141 ICSMIX_LEFT, 3142 ICSMIX_MIN_ATTN); 3143 ics2101_mix_attenuate(ic, 3144 GUSMIX_CHAN_LINE, 3145 ICSMIX_RIGHT, 3146 ICSMIX_MIN_ATTN); 3147 3148 ics2101_mix_attenuate(ic, 3149 GUSMIX_CHAN_CD, 3150 ICSMIX_LEFT, 3151 ICSMIX_MIN_ATTN); 3152 ics2101_mix_attenuate(ic, 3153 GUSMIX_CHAN_CD, 3154 ICSMIX_RIGHT, 3155 ICSMIX_MIN_ATTN); 3156 3157 ics2101_mix_attenuate(ic, 3158 GUSMIX_CHAN_DAC, 3159 ICSMIX_LEFT, 3160 ICSMIX_MIN_ATTN); 3161 ics2101_mix_attenuate(ic, 3162 GUSMIX_CHAN_DAC, 3163 ICSMIX_RIGHT, 3164 ICSMIX_MIN_ATTN); 3165 3166 ics2101_mix_attenuate(ic, 3167 ICSMIX_CHAN_4, 3168 ICSMIX_LEFT, 3169 ICSMIX_MAX_ATTN); 3170 ics2101_mix_attenuate(ic, 3171 ICSMIX_CHAN_4, 3172 ICSMIX_RIGHT, 3173 ICSMIX_MAX_ATTN); 3174 3175 ics2101_mix_attenuate(ic, 3176 GUSMIX_CHAN_MASTER, 3177 ICSMIX_LEFT, 3178 ICSMIX_MIN_ATTN); 3179 ics2101_mix_attenuate(ic, 3180 GUSMIX_CHAN_MASTER, 3181 ICSMIX_RIGHT, 3182 ICSMIX_MIN_ATTN); 3183 /* unmute other stuff: */ 3184 gusics_cd_mute(ic, 0); 3185 gusics_dac_mute(ic, 0); 3186 gusics_linein_mute(ic, 0); 3187 return; 3188 } 3189 3190 3191 3192 void 3193 gus_subattach(struct gus_softc *sc, struct isa_attach_args *ia) 3194 { 3195 int i; 3196 bus_space_tag_t iot; 3197 unsigned char c,d,m; 3198 u_long s; 3199 3200 iot = sc->sc_iot; 3201 3202 /* 3203 * Figure out our board rev, and see if we need to initialize the 3204 * mixer 3205 */ 3206 3207 c = bus_space_read_1(iot, sc->sc_ioh3, GUS_BOARD_REV); 3208 if (c != 0xff) 3209 sc->sc_revision = c; 3210 else 3211 sc->sc_revision = 0; 3212 3213 SELECT_GUS_REG(iot, sc->sc_ioh2, GUSREG_RESET); 3214 bus_space_write_1(iot, sc->sc_ioh2, GUS_DATA_HIGH, 0x00); 3215 3216 gusreset(sc, GUS_MAX_VOICES); /* initialize all voices */ 3217 gusreset(sc, GUS_MIN_VOICES); /* then set to just the ones we use */ 3218 3219 /* 3220 * Setup the IRQ and DRQ lines in software, using values from 3221 * config file 3222 */ 3223 3224 m = GUSMASK_LINE_IN|GUSMASK_LINE_OUT; /* disable all */ 3225 3226 c = ((unsigned char) gus_irq_map[ia->ia_irq]) | GUSMASK_BOTH_RQ; 3227 3228 if (sc->sc_recdrq == sc->sc_drq) 3229 d = (unsigned char) (gus_drq_map[sc->sc_drq] | 3230 GUSMASK_BOTH_RQ); 3231 else 3232 d = (unsigned char) (gus_drq_map[sc->sc_drq] | 3233 gus_drq_map[sc->sc_recdrq] << 3); 3234 3235 /* 3236 * Program the IRQ and DMA channels on the GUS. Note that we hardwire 3237 * the GUS to only use one IRQ channel, but we give the user the 3238 * option of using two DMA channels (the other one given by the drq2 3239 * option in the config file). Two DMA channels are needed for full- 3240 * duplex operation. 3241 * 3242 * The order of these operations is very magical. 3243 */ 3244 3245 s = intr_disable(); /* XXX needed? */ 3246 3247 bus_space_write_1(iot, sc->sc_ioh1, GUS_REG_CONTROL, GUS_REG_IRQCTL); 3248 bus_space_write_1(iot, sc->sc_ioh1, GUS_MIX_CONTROL, m); 3249 bus_space_write_1(iot, sc->sc_ioh1, GUS_IRQCTL_CONTROL, 0x00); 3250 bus_space_write_1(iot, sc->sc_ioh1, 0x0f, 0x00); 3251 3252 bus_space_write_1(iot, sc->sc_ioh1, GUS_MIX_CONTROL, m); 3253 3254 /* magic reset? */ 3255 bus_space_write_1(iot, sc->sc_ioh1, GUS_DMA_CONTROL, d | 0x80); 3256 3257 bus_space_write_1(iot, sc->sc_ioh1, GUS_MIX_CONTROL, 3258 m | GUSMASK_CONTROL_SEL); 3259 bus_space_write_1(iot, sc->sc_ioh1, GUS_IRQ_CONTROL, c); 3260 3261 bus_space_write_1(iot, sc->sc_ioh1, GUS_MIX_CONTROL, m); 3262 bus_space_write_1(iot, sc->sc_ioh1, GUS_DMA_CONTROL, d); 3263 3264 bus_space_write_1(iot, sc->sc_ioh1, GUS_MIX_CONTROL, 3265 m | GUSMASK_CONTROL_SEL); 3266 bus_space_write_1(iot, sc->sc_ioh1, GUS_IRQ_CONTROL, c); 3267 3268 bus_space_write_1(iot, sc->sc_ioh2, GUS_VOICE_SELECT, 0x00); 3269 3270 /* enable line in, line out. leave mic disabled. */ 3271 bus_space_write_1(iot, sc->sc_ioh1, GUS_MIX_CONTROL, 3272 (m | GUSMASK_LATCHES) & ~(GUSMASK_LINE_OUT|GUSMASK_LINE_IN)); 3273 bus_space_write_1(iot, sc->sc_ioh2, GUS_VOICE_SELECT, 0x00); 3274 3275 intr_restore(s); 3276 3277 sc->sc_mixcontrol = 3278 (m | GUSMASK_LATCHES) & ~(GUSMASK_LINE_OUT|GUSMASK_LINE_IN); 3279 3280 sc->sc_codec.sc_isa = sc->sc_isa; 3281 3282 if (sc->sc_revision >= 5 && sc->sc_revision <= 9) { 3283 sc->sc_flags |= GUS_MIXER_INSTALLED; 3284 gus_init_ics2101(sc); 3285 } 3286 if (sc->sc_revision < 10 || !gus_init_cs4231(sc)) { 3287 /* Not using the CS4231, so create our DMA maps. */ 3288 if (sc->sc_drq != -1) { 3289 if (isa_dmamap_create(sc->sc_isa, sc->sc_drq, 3290 MAX_ISADMA, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) { 3291 printf("%s: can't create map for drq %d\n", 3292 sc->sc_dev.dv_xname, sc->sc_drq); 3293 return; 3294 } 3295 } 3296 if (sc->sc_recdrq != -1 && sc->sc_recdrq != sc->sc_drq) { 3297 if (isa_dmamap_create(sc->sc_isa, sc->sc_recdrq, 3298 MAX_ISADMA, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) { 3299 printf("%s: can't create map for drq %d\n", 3300 sc->sc_dev.dv_xname, sc->sc_recdrq); 3301 return; 3302 } 3303 } 3304 } 3305 3306 timeout_set(&sc->sc_dma_tmo, gus_dmaout_timeout, sc); 3307 3308 SELECT_GUS_REG(iot, sc->sc_ioh2, GUSREG_RESET); 3309 /* 3310 * Check to see how much memory we have on this card; see if any 3311 * "mirroring" occurs. We're assuming at least 256K already exists 3312 * on the card; otherwise the initial probe would have failed 3313 */ 3314 3315 guspoke(iot, sc->sc_ioh2, 0L, 0x00); 3316 for(i = 1; i < 1024; i++) { 3317 u_long loc; 3318 3319 /* 3320 * See if we've run into mirroring yet 3321 */ 3322 3323 if (guspeek(iot, sc->sc_ioh2, 0L) != 0) 3324 break; 3325 3326 loc = i << 10; 3327 3328 guspoke(iot, sc->sc_ioh2, loc, 0xaa); 3329 if (guspeek(iot, sc->sc_ioh2, loc) != 0xaa) 3330 break; 3331 } 3332 3333 sc->sc_dsize = i; 3334 /* 3335 * The "official" (3.x) version number cannot easily be obtained. 3336 * The revision register does not correspond to the minor number 3337 * of the board version. Simply use the revision register as 3338 * identification. 3339 */ 3340 printf(": ver %d", sc->sc_revision); 3341 if (sc->sc_revision >= 10) 3342 printf(", MAX"); 3343 else { 3344 if (HAS_MIXER(sc)) 3345 printf(", ICS2101 mixer"); 3346 if (HAS_CODEC(sc)) 3347 printf(", %s codec/mixer", sc->sc_codec.chip_name); 3348 } 3349 printf(", %dKB DRAM, ", sc->sc_dsize); 3350 if (sc->sc_recdrq == sc->sc_drq) { 3351 printf("half-duplex"); 3352 } else { 3353 printf("full-duplex, record drq %d", sc->sc_recdrq); 3354 } 3355 3356 printf("\n"); 3357 3358 /* 3359 * Setup a default interrupt handler 3360 */ 3361 3362 sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq, 3363 IST_EDGE, IPL_AUDIO | IPL_MPSAFE, 3364 gusintr, sc /* sc->sc_gusdsp */, sc->sc_dev.dv_xname); 3365 3366 /* 3367 * Set some default values 3368 * XXX others start with 8kHz mono mulaw 3369 */ 3370 3371 sc->sc_irate = sc->sc_orate = 44100; 3372 sc->sc_encoding = AUDIO_ENCODING_SLINEAR_LE; 3373 sc->sc_precision = 16; 3374 sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_DATA_SIZE16; 3375 sc->sc_voc[GUS_VOICE_RIGHT].voccntl |= GUSMASK_DATA_SIZE16; 3376 sc->sc_channels = 1; 3377 sc->sc_ogain = 340; 3378 gus_commit_settings(sc); 3379 3380 /* 3381 * We always put the left channel full left & right channel 3382 * full right. 3383 * For mono playback, we set up both voices playing the same buffer. 3384 */ 3385 bus_space_write_1(iot, sc->sc_ioh2, GUS_VOICE_SELECT, 3386 (u_char)GUS_VOICE_LEFT); 3387 SELECT_GUS_REG(iot, sc->sc_ioh2, GUSREG_PAN_POS); 3388 bus_space_write_1(iot, sc->sc_ioh2, GUS_DATA_HIGH, GUS_PAN_FULL_LEFT); 3389 3390 bus_space_write_1(iot, sc->sc_ioh2, GUS_VOICE_SELECT, 3391 (u_char)GUS_VOICE_RIGHT); 3392 SELECT_GUS_REG(iot, sc->sc_ioh2, GUSREG_PAN_POS); 3393 bus_space_write_1(iot, sc->sc_ioh2, GUS_DATA_HIGH, GUS_PAN_FULL_RIGHT); 3394 3395 /* 3396 * Attach to the generic audio layer 3397 */ 3398 3399 if (HAS_CODEC(sc)) { 3400 audio_attach_mi(&gusmax_hw_if, (void *)&sc->sc_codec, NULL, 3401 &sc->sc_dev); 3402 } else { 3403 audio_attach_mi(&gus_hw_if, (void *)sc, NULL, &sc->sc_dev); 3404 } 3405 } 3406 3407 /* 3408 * Test to see if a particular I/O base is valid for the GUS. Return true 3409 * if it is. 3410 */ 3411 3412 int 3413 gus_test_iobase (bus_space_tag_t iot, int iobase) 3414 { 3415 bus_space_handle_t ioh1, ioh2, ioh3, ioh4; 3416 u_char s1, s2; 3417 int rv = 0; 3418 3419 /* Map i/o space */ 3420 if (bus_space_map(iot, iobase, GUS_NPORT1, 0, &ioh1)) 3421 return 0; 3422 if (bus_space_map(iot, iobase+GUS_IOH2_OFFSET, GUS_NPORT2, 0, &ioh2)) 3423 goto bad1; 3424 3425 /* XXX Maybe we shouldn't fail on mapping this, but just assume 3426 * the card is of revision 0? */ 3427 if (bus_space_map(iot, iobase+GUS_IOH3_OFFSET, GUS_NPORT3, 0, &ioh3)) 3428 goto bad2; 3429 3430 if (bus_space_map(iot, iobase+GUS_IOH4_OFFSET, GUS_NPORT4, 0, &ioh4)) 3431 goto bad3; 3432 3433 /* 3434 * Reset GUS to an initial state before we do anything. 3435 */ 3436 3437 mtx_enter(&audio_lock); 3438 delay(500); 3439 3440 SELECT_GUS_REG(iot, ioh2, GUSREG_RESET); 3441 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00); 3442 3443 delay(500); 3444 3445 SELECT_GUS_REG(iot, ioh2, GUSREG_RESET); 3446 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, GUSMASK_MASTER_RESET); 3447 3448 delay(500); 3449 3450 mtx_leave(&audio_lock); 3451 3452 /* 3453 * See if we can write to the board's memory 3454 */ 3455 3456 s1 = guspeek(iot, ioh2, 0L); 3457 s2 = guspeek(iot, ioh2, 1L); 3458 3459 guspoke(iot, ioh2, 0L, 0xaa); 3460 guspoke(iot, ioh2, 1L, 0x55); 3461 3462 if (guspeek(iot, ioh2, 0L) != 0xaa) 3463 goto bad; 3464 3465 guspoke(iot, ioh2, 0L, s1); 3466 guspoke(iot, ioh2, 1L, s2); 3467 3468 rv = 1; 3469 3470 bad: 3471 bus_space_unmap(iot, ioh4, GUS_NPORT4); 3472 bad3: 3473 bus_space_unmap(iot, ioh3, GUS_NPORT3); 3474 bad2: 3475 bus_space_unmap(iot, ioh2, GUS_NPORT2); 3476 bad1: 3477 bus_space_unmap(iot, ioh1, GUS_NPORT1); 3478 return rv; 3479 } 3480