1 /* $OpenBSD: gus.c,v 1.43 2015/06/25 20:05:11 ratchov 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 struct audio_hw_if gus_hw_if = { 264 gusopen, 265 gusclose, 266 NULL, /* drain */ 267 268 gus_query_encoding, 269 270 gus_set_params, 271 272 gus_round_blocksize, 273 274 gus_commit_settings, 275 276 NULL, 277 NULL, 278 279 gus_dma_output, 280 gus_dma_input, 281 gus_halt_out_dma, 282 gus_halt_in_dma, 283 gus_speaker_ctl, 284 285 gus_getdev, 286 NULL, 287 gus_mixer_set_port, 288 gus_mixer_get_port, 289 gus_mixer_query_devinfo, 290 gus_malloc, 291 gus_free, 292 gus_round, 293 gus_mappage, 294 gus_get_props, 295 296 NULL, 297 NULL, 298 NULL 299 }; 300 301 static struct audio_hw_if gusmax_hw_if = { 302 gusmaxopen, 303 gusmax_close, 304 NULL, /* drain */ 305 306 gus_query_encoding, /* query encoding */ 307 308 gusmax_set_params, 309 310 gusmax_round_blocksize, 311 312 gusmax_commit_settings, 313 314 NULL, 315 NULL, 316 317 gusmax_dma_output, 318 gusmax_dma_input, 319 gusmax_halt_out_dma, 320 gusmax_halt_in_dma, 321 322 gusmax_speaker_ctl, 323 324 gus_getdev, 325 NULL, 326 gusmax_mixer_set_port, 327 gusmax_mixer_get_port, 328 gusmax_mixer_query_devinfo, 329 ad1848_malloc, 330 ad1848_free, 331 ad1848_round, 332 ad1848_mappage, 333 gusmax_get_props, 334 335 NULL, 336 NULL, 337 NULL 338 }; 339 340 /* 341 * Some info about the current audio device 342 */ 343 struct audio_device gus_device = { 344 "UltraSound", 345 "", 346 "gus", 347 }; 348 349 350 int 351 gusopen(void *addr, int flags) 352 { 353 struct gus_softc *sc = addr; 354 355 DPRINTF(("gusopen() called\n")); 356 357 if (sc->sc_flags & GUS_OPEN) 358 return EBUSY; 359 360 /* 361 * Some initialization 362 */ 363 364 sc->sc_flags |= GUS_OPEN; 365 sc->sc_dmabuf = 0; 366 sc->sc_playbuf = -1; 367 sc->sc_bufcnt = 0; 368 sc->sc_voc[GUS_VOICE_LEFT].start_addr = GUS_MEM_OFFSET - 1; 369 sc->sc_voc[GUS_VOICE_LEFT].current_addr = GUS_MEM_OFFSET; 370 371 if (HAS_CODEC(sc)) { 372 ad1848_open(&sc->sc_codec, flags); 373 sc->sc_codec.mute[AD1848_AUX1_CHANNEL] = 0; 374 ad1848_mute_channel(&sc->sc_codec, AD1848_AUX1_CHANNEL, 0); /* turn on DAC output */ 375 if (flags & FREAD) { 376 sc->sc_codec.mute[AD1848_MONO_CHANNEL] = 0; 377 ad1848_mute_channel(&sc->sc_codec, AD1848_MONO_CHANNEL, 0); 378 } 379 } else if (flags & FREAD) { 380 /* enable/unmute the microphone */ 381 if (HAS_MIXER(sc)) { 382 gusics_mic_mute(&sc->sc_mixer, 0); 383 } else 384 gus_mic_ctl(sc, SPKR_ON); 385 } 386 if (sc->sc_nbufs == 0) 387 gus_round_blocksize(sc, GUS_BUFFER_MULTIPLE); /* default blksiz */ 388 return 0; 389 } 390 391 int 392 gusmaxopen(void *addr, int flags) 393 { 394 struct ad1848_softc *ac = addr; 395 return gusopen(ac->parent, flags); 396 } 397 398 void 399 gus_deinterleave(struct gus_softc *sc, void *buf, int size) 400 { 401 /* deinterleave the stereo data. We can use sc->sc_deintr_buf 402 for scratch space. */ 403 int i; 404 405 if (size > sc->sc_blocksize) { 406 printf("gus: deinterleave %d > %d\n", size, sc->sc_blocksize); 407 return; 408 } else if (size < sc->sc_blocksize) { 409 DPRINTF(("gus: deinterleave %d < %d\n", size, sc->sc_blocksize)); 410 } 411 412 /* 413 * size is in bytes. 414 */ 415 if (sc->sc_precision == 16) { 416 u_short *dei = sc->sc_deintr_buf; 417 u_short *sbuf = buf; 418 size >>= 1; /* bytecnt to shortcnt */ 419 /* copy 2nd of each pair of samples to the staging area, while 420 compacting the 1st of each pair into the original area. */ 421 for (i = 0; i < size/2-1; i++) { 422 dei[i] = sbuf[i*2+1]; 423 sbuf[i+1] = sbuf[i*2+2]; 424 } 425 /* 426 * this has copied one less sample than half of the 427 * buffer. The first sample of the 1st stream was 428 * already in place and didn't need copying. 429 * Therefore, we've moved all of the 1st stream's 430 * samples into place. We have one sample from 2nd 431 * stream in the last slot of original area, not 432 * copied to the staging area (But we don't need to!). 433 * Copy the remainder of the original stream into place. 434 */ 435 bcopy(dei, &sbuf[size/2], i * sizeof(short)); 436 } else { 437 u_char *dei = sc->sc_deintr_buf; 438 u_char *sbuf = buf; 439 for (i = 0; i < size/2-1; i++) { 440 dei[i] = sbuf[i*2+1]; 441 sbuf[i+1] = sbuf[i*2+2]; 442 } 443 bcopy(dei, &sbuf[size/2], i); 444 } 445 } 446 447 /* 448 * Actually output a buffer to the DSP chip 449 */ 450 451 int 452 gusmax_dma_output(void *addr, void *buf, int size, void (*intr)(void *), 453 void *arg) 454 { 455 struct ad1848_softc *ac = addr; 456 return gus_dma_output(ac->parent, buf, size, intr, arg); 457 } 458 459 /* 460 * called at splaudio() from interrupt handler. 461 */ 462 void 463 stereo_dmaintr(void *arg) 464 { 465 struct gus_softc *sc = arg; 466 struct stereo_dma_intr *sa = &sc->sc_stereo; 467 468 DMAPRINTF(("stereo_dmaintr")); 469 470 /* 471 * Put other half in its place, then call the real interrupt routine :) 472 */ 473 474 sc->sc_dmaoutintr = sa->intr; 475 sc->sc_outarg = sa->arg; 476 477 #ifdef GUSPLAYDEBUG 478 if (gusstats) { 479 microtime(&dmarecords[dmarecord_index].tv); 480 dmarecords[dmarecord_index].gusaddr = sa->dmabuf; 481 dmarecords[dmarecord_index].bsdaddr = sa->buffer; 482 dmarecords[dmarecord_index].count = sa->size; 483 dmarecords[dmarecord_index].channel = 1; 484 dmarecords[dmarecord_index++].direction = 1; 485 dmarecord_index = dmarecord_index % NDMARECS; 486 } 487 #endif 488 489 gusdmaout(sc, sa->flags, sa->dmabuf, (caddr_t) sa->buffer, sa->size); 490 491 sa->flags = 0; 492 sa->dmabuf = 0; 493 sa->buffer = 0; 494 sa->size = 0; 495 sa->intr = 0; 496 sa->arg = 0; 497 } 498 499 /* 500 * Start up DMA output to the card. 501 * Called at splaudio(), either from intr handler or from 502 * generic audio code. 503 */ 504 int 505 gus_dma_output(void *addr, void *buf, int size, void (*intr)(void *), void *arg) 506 { 507 struct gus_softc *sc = addr; 508 u_char *buffer = buf; 509 u_long boarddma; 510 int flags; 511 512 DMAPRINTF(("gus_dma_output %d @ %p\n", size, buf)); 513 if (size != sc->sc_blocksize) { 514 DPRINTF(("gus_dma_output reqsize %d not sc_blocksize %d\n", 515 size, sc->sc_blocksize)); 516 return EINVAL; 517 } 518 519 flags = GUSMASK_DMA_WRITE; 520 if (sc->sc_precision == 16) 521 flags |= GUSMASK_DMA_DATA_SIZE; 522 if (sc->sc_encoding == AUDIO_ENCODING_ULAW || 523 sc->sc_encoding == AUDIO_ENCODING_ALAW || 524 sc->sc_encoding == AUDIO_ENCODING_ULINEAR_BE || 525 sc->sc_encoding == AUDIO_ENCODING_ULINEAR_LE) 526 flags |= GUSMASK_DMA_INVBIT; 527 528 if (sc->sc_channels == 2) { 529 if (sc->sc_precision == 16) { 530 if (size & 3) { 531 DPRINTF(("gus_dma_output: unpaired 16bit samples")); 532 size &= 3; 533 } 534 } else if (size & 1) { 535 DPRINTF(("gus_dma_output: unpaired samples")); 536 size &= 1; 537 } 538 if (size == 0) { 539 return 0; 540 } 541 542 gus_deinterleave(sc, (void *)buffer, size); 543 544 size >>= 1; 545 546 boarddma = size * sc->sc_dmabuf + GUS_MEM_OFFSET; 547 548 sc->sc_stereo.intr = intr; 549 sc->sc_stereo.arg = arg; 550 sc->sc_stereo.size = size; 551 sc->sc_stereo.dmabuf = boarddma + GUS_LEFT_RIGHT_OFFSET; 552 sc->sc_stereo.buffer = buffer + size; 553 sc->sc_stereo.flags = flags; 554 if (gus_dostereo) { 555 intr = stereo_dmaintr; 556 arg = sc; 557 } 558 } else 559 boarddma = size * sc->sc_dmabuf + GUS_MEM_OFFSET; 560 561 562 sc->sc_flags |= GUS_LOCKED; 563 sc->sc_dmaoutintr = intr; 564 sc->sc_outarg = arg; 565 566 #ifdef GUSPLAYDEBUG 567 if (gusstats) { 568 microtime(&dmarecords[dmarecord_index].tv); 569 dmarecords[dmarecord_index].gusaddr = boarddma; 570 dmarecords[dmarecord_index].bsdaddr = buffer; 571 dmarecords[dmarecord_index].count = size; 572 dmarecords[dmarecord_index].channel = 0; 573 dmarecords[dmarecord_index++].direction = 1; 574 dmarecord_index = dmarecord_index % NDMARECS; 575 } 576 #endif 577 578 gusdmaout(sc, flags, boarddma, (caddr_t) buffer, size); 579 return 0; 580 } 581 582 void 583 gusmax_close(void *addr) 584 { 585 struct ad1848_softc *ac = addr; 586 struct gus_softc *sc = ac->parent; 587 #if 0 588 ac->mute[AD1848_AUX1_CHANNEL] = MUTE_ALL; 589 ad1848_mute_channel(ac, MUTE_ALL); /* turn off DAC output */ 590 #endif 591 ad1848_close(ac); 592 gusclose(sc); 593 } 594 595 /* 596 * Close out device stuff. Called at splaudio() from generic audio layer. 597 */ 598 void 599 gusclose(void *addr) 600 { 601 struct gus_softc *sc = addr; 602 603 DPRINTF(("gus_close: sc=%p\n", sc)); 604 605 /* if (sc->sc_flags & GUS_DMAOUT_ACTIVE) */ { 606 gus_halt_out_dma(sc); 607 } 608 /* if (sc->sc_flags & GUS_DMAIN_ACTIVE) */ { 609 gus_halt_in_dma(sc); 610 } 611 sc->sc_flags &= ~(GUS_OPEN|GUS_LOCKED|GUS_DMAOUT_ACTIVE|GUS_DMAIN_ACTIVE); 612 613 if (sc->sc_deintr_buf) { 614 free(sc->sc_deintr_buf, M_DEVBUF, 0); 615 sc->sc_deintr_buf = NULL; 616 } 617 /* turn off speaker, etc. */ 618 619 /* make sure the voices shut up: */ 620 gus_stop_voice(sc, GUS_VOICE_LEFT, 1); 621 gus_stop_voice(sc, GUS_VOICE_RIGHT, 0); 622 } 623 624 /* 625 * Service interrupts. Farm them off to helper routines if we are using the 626 * GUS for simple playback/record 627 */ 628 629 #ifdef AUDIO_DEBUG 630 int gusintrcnt; 631 int gusdmaintrcnt; 632 int gusvocintrcnt; 633 #endif 634 635 int 636 gusintr(void *arg) 637 { 638 struct gus_softc *sc = arg; 639 bus_space_tag_t iot = sc->sc_iot; 640 bus_space_handle_t ioh1 = sc->sc_ioh1; 641 bus_space_handle_t ioh2 = sc->sc_ioh2; 642 unsigned char intr; 643 644 int retval = 0; 645 646 DPRINTF(("gusintr\n")); 647 #ifdef AUDIO_DEBUG 648 gusintrcnt++; 649 #endif 650 if (HAS_CODEC(sc)) 651 retval = ad1848_intr(&sc->sc_codec); 652 mtx_enter(&audio_lock); 653 if ((intr = bus_space_read_1(iot, ioh1, GUS_IRQ_STATUS)) & GUSMASK_IRQ_DMATC) { 654 DMAPRINTF(("gusintr dma flags=%x\n", sc->sc_flags)); 655 #ifdef AUDIO_DEBUG 656 gusdmaintrcnt++; 657 #endif 658 retval += gus_dmaout_intr(sc); 659 if (sc->sc_flags & GUS_DMAIN_ACTIVE) { 660 SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL); 661 intr = bus_space_read_1(iot, ioh2, GUS_DATA_HIGH); 662 if (intr & GUSMASK_SAMPLE_DMATC) { 663 retval += gus_dmain_intr(sc); 664 } 665 } 666 } 667 if (intr & (GUSMASK_IRQ_VOICE | GUSMASK_IRQ_VOLUME)) { 668 DMAPRINTF(("gusintr voice flags=%x\n", sc->sc_flags)); 669 #ifdef AUDIO_DEBUG 670 gusvocintrcnt++; 671 #endif 672 retval += gus_voice_intr(sc); 673 } 674 if (retval) { 675 mtx_leave(&audio_lock); 676 return 1; 677 } 678 mtx_leave(&audio_lock); 679 return retval; 680 } 681 682 int gus_bufcnt[GUS_MEM_FOR_BUFFERS / GUS_BUFFER_MULTIPLE]; 683 int gus_restart; /* how many restarts? */ 684 int gus_stops; /* how many times did voice stop? */ 685 int gus_falsestops; /* stopped but not done? */ 686 int gus_continues; 687 688 struct playcont { 689 struct timeval tv; 690 u_int playbuf; 691 u_int dmabuf; 692 u_char bufcnt; 693 u_char vaction; 694 u_char voccntl; 695 u_char volcntl; 696 u_long curaddr; 697 u_long endaddr; 698 } playstats[NDMARECS]; 699 700 int playcntr; 701 702 void 703 gus_dmaout_timeout(void *arg) 704 { 705 struct gus_softc *sc = arg; 706 bus_space_tag_t iot = sc->sc_iot; 707 bus_space_handle_t ioh2 = sc->sc_ioh2; 708 709 printf("%s: dmaout timeout\n", sc->sc_dev.dv_xname); 710 /* 711 * Stop any DMA. 712 */ 713 714 mtx_enter(&audio_lock); 715 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL); 716 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0); 717 718 #if 0 719 /* XXX we will dmadone below? */ 720 isa_dmaabort(sc->sc_dev.dv_parent, sc->sc_drq); 721 #endif 722 723 gus_dmaout_dointr(sc); 724 mtx_leave(&audio_lock); 725 } 726 727 728 /* 729 * Service DMA interrupts. This routine will only get called if we're doing 730 * a DMA transfer for playback/record requests from the audio layer. 731 */ 732 733 int 734 gus_dmaout_intr(struct gus_softc *sc) 735 { 736 bus_space_tag_t iot = sc->sc_iot; 737 bus_space_handle_t ioh2 = sc->sc_ioh2; 738 739 /* 740 * If we got a DMA transfer complete from the GUS DRAM, then deal 741 * with it. 742 */ 743 744 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL); 745 if (bus_space_read_1(iot, ioh2, GUS_DATA_HIGH) & GUSMASK_DMA_IRQPEND) { 746 timeout_del(&sc->sc_dma_tmo); 747 gus_dmaout_dointr(sc); 748 return 1; 749 } 750 return 0; 751 } 752 753 void 754 gus_dmaout_dointr(struct gus_softc *sc) 755 { 756 bus_space_tag_t iot = sc->sc_iot; 757 bus_space_handle_t ioh2 = sc->sc_ioh2; 758 759 /* sc->sc_dmaoutcnt - 1 because DMA controller counts from zero?. */ 760 isa_dmadone(sc->sc_dev.dv_parent, sc->sc_drq); 761 sc->sc_flags &= ~GUS_DMAOUT_ACTIVE; /* pending DMA is done */ 762 DMAPRINTF(("gus_dmaout_dointr %d @ %p\n", sc->sc_dmaoutcnt, 763 sc->sc_dmaoutaddr)); 764 765 /* 766 * to prevent clicking, we need to copy last sample 767 * from last buffer to scratch area just before beginning of 768 * buffer. However, if we're doing formats that are converted by 769 * the card during the DMA process, we need to pick up the converted 770 * byte rather than the one we have in memory. 771 */ 772 if (sc->sc_dmabuf == sc->sc_nbufs - 1) { 773 int i; 774 switch (sc->sc_encoding) { 775 case AUDIO_ENCODING_SLINEAR_LE: 776 case AUDIO_ENCODING_SLINEAR_BE: 777 if (sc->sc_precision == 8) 778 goto byte; 779 /* we have the native format */ 780 for (i = 1; i <= 2; i++) 781 guspoke(iot, ioh2, sc->sc_gusaddr - 782 (sc->sc_nbufs - 1) * sc->sc_chanblocksize - i, 783 sc->sc_dmaoutaddr[sc->sc_dmaoutcnt-i]); 784 break; 785 case AUDIO_ENCODING_ULINEAR_LE: 786 case AUDIO_ENCODING_ULINEAR_BE: 787 guspoke(iot, ioh2, sc->sc_gusaddr - 788 (sc->sc_nbufs - 1) * sc->sc_chanblocksize - 2, 789 guspeek(iot, ioh2, 790 sc->sc_gusaddr + sc->sc_chanblocksize - 2)); 791 case AUDIO_ENCODING_ALAW: 792 case AUDIO_ENCODING_ULAW: 793 byte: 794 /* we need to fetch the translated byte, then stuff it. */ 795 guspoke(iot, ioh2, sc->sc_gusaddr - 796 (sc->sc_nbufs - 1) * sc->sc_chanblocksize - 1, 797 guspeek(iot, ioh2, 798 sc->sc_gusaddr + sc->sc_chanblocksize - 1)); 799 break; 800 } 801 } 802 /* 803 * If this is the first half of stereo, "ignore" this one 804 * and copy out the second half. 805 */ 806 if (sc->sc_dmaoutintr == stereo_dmaintr) { 807 (*sc->sc_dmaoutintr)(sc->sc_outarg); 808 return; 809 } 810 /* 811 * If the voice is stopped, then start it. Reset the loop 812 * and roll bits. Call the audio layer routine, since if 813 * we're starting a stopped voice, that means that the next 814 * buffer can be filled 815 */ 816 817 sc->sc_flags &= ~GUS_LOCKED; 818 if (sc->sc_voc[GUS_VOICE_LEFT].voccntl & 819 GUSMASK_VOICE_STOPPED) { 820 if (sc->sc_flags & GUS_PLAYING) { 821 printf("%s: playing yet stopped?\n", sc->sc_dev.dv_xname); 822 } 823 sc->sc_bufcnt++; /* another yet to be played */ 824 gus_start_playing(sc, sc->sc_dmabuf); 825 gus_restart++; 826 } else { 827 /* 828 * set the sound action based on which buffer we 829 * just transferred. If we just transferred buffer 0 830 * we want the sound to loop when it gets to the nth 831 * buffer; if we just transferred 832 * any other buffer, we want the sound to roll over 833 * at least one more time. The voice interrupt 834 * handlers will take care of accounting & 835 * setting control bits if it's not caught up to us 836 * yet. 837 */ 838 if (++sc->sc_bufcnt == 2) { 839 /* 840 * XXX 841 * If we're too slow in reaction here, 842 * the voice could be just approaching the 843 * end of its run. It should be set to stop, 844 * so these adjustments might not DTRT. 845 */ 846 if (sc->sc_dmabuf == 0 && 847 sc->sc_playbuf == sc->sc_nbufs - 1) { 848 /* player is just at the last buf, we're at the 849 first. Turn on looping, turn off rolling. */ 850 sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_LOOP_ENABLE; 851 sc->sc_voc[GUS_VOICE_LEFT].volcntl &= ~GUSMASK_VOICE_ROLL; 852 playstats[playcntr].vaction = 3; 853 } else { 854 /* player is at previous buf: 855 turn on rolling, turn off looping */ 856 sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~GUSMASK_LOOP_ENABLE; 857 sc->sc_voc[GUS_VOICE_LEFT].volcntl |= GUSMASK_VOICE_ROLL; 858 playstats[playcntr].vaction = 4; 859 } 860 #ifdef GUSPLAYDEBUG 861 if (gusstats) { 862 microtime(&playstats[playcntr].tv); 863 playstats[playcntr].endaddr = sc->sc_voc[GUS_VOICE_LEFT].end_addr; 864 playstats[playcntr].voccntl = sc->sc_voc[GUS_VOICE_LEFT].voccntl; 865 playstats[playcntr].volcntl = sc->sc_voc[GUS_VOICE_LEFT].volcntl; 866 playstats[playcntr].playbuf = sc->sc_playbuf; 867 playstats[playcntr].dmabuf = sc->sc_dmabuf; 868 playstats[playcntr].bufcnt = sc->sc_bufcnt; 869 playstats[playcntr++].curaddr = gus_get_curaddr(sc, GUS_VOICE_LEFT); 870 playcntr = playcntr % NDMARECS; 871 } 872 #endif 873 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, GUS_VOICE_LEFT); 874 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL); 875 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_LEFT].voccntl); 876 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL); 877 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_LEFT].volcntl); 878 } 879 } 880 gus_bufcnt[sc->sc_bufcnt-1]++; 881 /* 882 * flip to the next DMA buffer 883 */ 884 885 sc->sc_dmabuf = ++sc->sc_dmabuf % sc->sc_nbufs; 886 /* 887 * See comments below about DMA admission control strategy. 888 * We can call the upper level here if we have an 889 * idle buffer (not currently playing) to DMA into. 890 */ 891 if (sc->sc_dmaoutintr && sc->sc_bufcnt < sc->sc_nbufs) { 892 /* clean out to prevent double calls */ 893 void (*pfunc)(void *) = sc->sc_dmaoutintr; 894 void *arg = sc->sc_outarg; 895 896 sc->sc_outarg = 0; 897 sc->sc_dmaoutintr = 0; 898 (*pfunc)(arg); 899 } 900 } 901 902 /* 903 * Service voice interrupts 904 */ 905 906 int 907 gus_voice_intr(struct gus_softc *sc) 908 { 909 bus_space_tag_t iot = sc->sc_iot; 910 bus_space_handle_t ioh2 = sc->sc_ioh2; 911 int ignore = 0, voice, rval = 0; 912 unsigned char intr, status; 913 914 /* 915 * The point of this may not be obvious at first. A voice can 916 * interrupt more than once; according to the GUS SDK we are supposed 917 * to ignore multiple interrupts for the same voice. 918 */ 919 920 while(1) { 921 SELECT_GUS_REG(iot, ioh2, GUSREG_IRQ_STATUS); 922 intr = bus_space_read_1(iot, ioh2, GUS_DATA_HIGH); 923 924 if ((intr & (GUSMASK_WIRQ_VOLUME | GUSMASK_WIRQ_VOICE)) 925 == (GUSMASK_WIRQ_VOLUME | GUSMASK_WIRQ_VOICE)) 926 /* 927 * No more interrupts, time to return 928 */ 929 return rval; 930 931 if ((intr & GUSMASK_WIRQ_VOICE) == 0) { 932 933 /* 934 * We've got a voice interrupt. Ignore previous 935 * interrupts by the same voice. 936 */ 937 938 rval = 1; 939 voice = intr & GUSMASK_WIRQ_VOICEMASK; 940 941 if ((1 << voice) & ignore) 942 break; 943 944 ignore |= 1 << voice; 945 946 /* 947 * If the voice is stopped, then force it to stop 948 * (this stops it from continuously generating IRQs) 949 */ 950 951 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL+0x80); 952 status = bus_space_read_1(iot, ioh2, GUS_DATA_HIGH); 953 if (status & GUSMASK_VOICE_STOPPED) { 954 if (voice != GUS_VOICE_LEFT) { 955 DMAPRINTF(("%s: spurious voice %d stop?\n", 956 sc->sc_dev.dv_xname, voice)); 957 gus_stop_voice(sc, voice, 0); 958 continue; 959 } 960 gus_stop_voice(sc, voice, 1); 961 /* also kill right voice */ 962 gus_stop_voice(sc, GUS_VOICE_RIGHT, 0); 963 sc->sc_bufcnt--; /* it finished a buffer */ 964 if (sc->sc_bufcnt > 0) { 965 /* 966 * probably a race to get here: the voice 967 * stopped while the DMA code was just trying to 968 * get the next buffer in place. 969 * Start the voice again. 970 */ 971 printf("%s: stopped voice not drained? (%x)\n", 972 sc->sc_dev.dv_xname, sc->sc_bufcnt); 973 gus_falsestops++; 974 975 sc->sc_playbuf = ++sc->sc_playbuf % sc->sc_nbufs; 976 gus_start_playing(sc, sc->sc_playbuf); 977 } else if (sc->sc_bufcnt < 0) { 978 panic("%s: negative bufcnt in stopped voice", 979 sc->sc_dev.dv_xname); 980 } else { 981 sc->sc_playbuf = -1; /* none are active */ 982 gus_stops++; 983 } 984 /* fall through to callback and admit another 985 buffer.... */ 986 } else if (sc->sc_bufcnt != 0) { 987 /* 988 * This should always be taken if the voice 989 * is not stopped. 990 */ 991 gus_continues++; 992 if (gus_continue_playing(sc, voice)) { 993 /* 994 * we shouldn't have continued--active DMA 995 * is in the way in the ring, for 996 * some as-yet undebugged reason. 997 */ 998 gus_stop_voice(sc, GUS_VOICE_LEFT, 1); 999 /* also kill right voice */ 1000 gus_stop_voice(sc, GUS_VOICE_RIGHT, 0); 1001 sc->sc_playbuf = -1; 1002 gus_stops++; 1003 } 1004 } 1005 /* 1006 * call the upper level to send on down another 1007 * block. We do admission rate control as follows: 1008 * 1009 * When starting up output (in the first N 1010 * blocks), call the upper layer after the DMA is 1011 * complete (see above in gus_dmaout_intr()). 1012 * 1013 * When output is already in progress and we have 1014 * no more GUS buffers to use for DMA, the DMA 1015 * output routines do not call the upper layer. 1016 * Instead, we call the DMA completion routine 1017 * here, after the voice interrupts indicating 1018 * that it's finished with a buffer. 1019 * 1020 * However, don't call anything here if the DMA 1021 * output flag is set, (which shouldn't happen) 1022 * because we'll squish somebody else's DMA if 1023 * that's the case. When DMA is done, it will 1024 * call back if there is a spare buffer. 1025 */ 1026 if (sc->sc_dmaoutintr && !(sc->sc_flags & GUS_LOCKED)) { 1027 if (sc->sc_dmaoutintr == stereo_dmaintr) 1028 printf("gusdmaout botch?\n"); 1029 else { 1030 /* clean out to avoid double calls */ 1031 void (*pfunc)(void *) = sc->sc_dmaoutintr; 1032 void *arg = sc->sc_outarg; 1033 1034 sc->sc_outarg = 0; 1035 sc->sc_dmaoutintr = 0; 1036 (*pfunc)(arg); 1037 } 1038 } 1039 } 1040 1041 /* 1042 * Ignore other interrupts for now 1043 */ 1044 } 1045 return 0; 1046 } 1047 1048 void 1049 gus_start_playing(struct gus_softc *sc, int bufno) 1050 { 1051 bus_space_tag_t iot = sc->sc_iot; 1052 bus_space_handle_t ioh2 = sc->sc_ioh2; 1053 /* 1054 * Start the voices playing, with buffer BUFNO. 1055 */ 1056 1057 /* 1058 * Loop or roll if we have buffers ready. 1059 */ 1060 1061 if (sc->sc_bufcnt == 1) { 1062 sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~(GUSMASK_LOOP_ENABLE); 1063 sc->sc_voc[GUS_VOICE_LEFT].volcntl &= ~(GUSMASK_VOICE_ROLL); 1064 } else { 1065 if (bufno == sc->sc_nbufs - 1) { 1066 sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_LOOP_ENABLE; 1067 sc->sc_voc[GUS_VOICE_LEFT].volcntl &= ~(GUSMASK_VOICE_ROLL); 1068 } else { 1069 sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~GUSMASK_LOOP_ENABLE; 1070 sc->sc_voc[GUS_VOICE_LEFT].volcntl |= GUSMASK_VOICE_ROLL; 1071 } 1072 } 1073 1074 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, GUS_VOICE_LEFT); 1075 1076 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL); 1077 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_LEFT].voccntl); 1078 1079 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL); 1080 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_LEFT].volcntl); 1081 1082 sc->sc_voc[GUS_VOICE_LEFT].current_addr = 1083 GUS_MEM_OFFSET + sc->sc_chanblocksize * bufno; 1084 sc->sc_voc[GUS_VOICE_LEFT].end_addr = 1085 sc->sc_voc[GUS_VOICE_LEFT].current_addr + sc->sc_chanblocksize - 1; 1086 sc->sc_voc[GUS_VOICE_RIGHT].current_addr = 1087 sc->sc_voc[GUS_VOICE_LEFT].current_addr + 1088 (gus_dostereo && sc->sc_channels == 2 ? GUS_LEFT_RIGHT_OFFSET : 0); 1089 /* 1090 * set up right channel to just loop forever, no interrupts, 1091 * starting at the buffer we just filled. We'll feed it data 1092 * at the same time as left channel. 1093 */ 1094 sc->sc_voc[GUS_VOICE_RIGHT].voccntl |= GUSMASK_LOOP_ENABLE; 1095 sc->sc_voc[GUS_VOICE_RIGHT].volcntl &= ~(GUSMASK_VOICE_ROLL); 1096 1097 #ifdef GUSPLAYDEBUG 1098 if (gusstats) { 1099 microtime(&playstats[playcntr].tv); 1100 playstats[playcntr].curaddr = sc->sc_voc[GUS_VOICE_LEFT].current_addr; 1101 1102 playstats[playcntr].voccntl = sc->sc_voc[GUS_VOICE_LEFT].voccntl; 1103 playstats[playcntr].volcntl = sc->sc_voc[GUS_VOICE_LEFT].volcntl; 1104 playstats[playcntr].endaddr = sc->sc_voc[GUS_VOICE_LEFT].end_addr; 1105 playstats[playcntr].playbuf = bufno; 1106 playstats[playcntr].dmabuf = sc->sc_dmabuf; 1107 playstats[playcntr].bufcnt = sc->sc_bufcnt; 1108 playstats[playcntr++].vaction = 5; 1109 playcntr = playcntr % NDMARECS; 1110 } 1111 #endif 1112 1113 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, GUS_VOICE_RIGHT); 1114 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL); 1115 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_RIGHT].voccntl); 1116 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL); 1117 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_RIGHT].volcntl); 1118 1119 gus_start_voice(sc, GUS_VOICE_RIGHT, 0); 1120 gus_start_voice(sc, GUS_VOICE_LEFT, 1); 1121 if (sc->sc_playbuf == -1) 1122 /* mark start of playing */ 1123 sc->sc_playbuf = bufno; 1124 } 1125 1126 int 1127 gus_continue_playing(struct gus_softc *sc, int voice) 1128 { 1129 bus_space_tag_t iot = sc->sc_iot; 1130 bus_space_handle_t ioh2 = sc->sc_ioh2; 1131 1132 /* 1133 * stop this voice from interrupting while we work. 1134 */ 1135 1136 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL); 1137 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl & ~(GUSMASK_VOICE_IRQ)); 1138 1139 /* 1140 * update playbuf to point to the buffer the hardware just started 1141 * playing 1142 */ 1143 sc->sc_playbuf = ++sc->sc_playbuf % sc->sc_nbufs; 1144 1145 /* 1146 * account for buffer just finished 1147 */ 1148 if (--sc->sc_bufcnt == 0) { 1149 DPRINTF(("gus: bufcnt 0 on continuing voice?\n")); 1150 } 1151 if (sc->sc_playbuf == sc->sc_dmabuf && (sc->sc_flags & GUS_LOCKED)) { 1152 printf("%s: continue into active dmabuf?\n", sc->sc_dev.dv_xname); 1153 return 1; 1154 } 1155 1156 /* 1157 * Select the end of the buffer based on the currently active 1158 * buffer, [plus extra contiguous buffers (if ready)]. 1159 */ 1160 1161 /* 1162 * set endpoint at end of buffer we just started playing. 1163 * 1164 * The total gets -1 because end addrs are one less than you might 1165 * think (the end_addr is the address of the last sample to play) 1166 */ 1167 gus_set_endaddr(sc, voice, GUS_MEM_OFFSET + 1168 sc->sc_chanblocksize * (sc->sc_playbuf + 1) - 1); 1169 1170 if (sc->sc_bufcnt < 2) { 1171 /* 1172 * Clear out the loop and roll flags, and rotate the currently 1173 * playing buffer. That way, if we don't manage to get more 1174 * data before this buffer finishes, we'll just stop. 1175 */ 1176 sc->sc_voc[voice].voccntl &= ~GUSMASK_LOOP_ENABLE; 1177 sc->sc_voc[voice].volcntl &= ~GUSMASK_VOICE_ROLL; 1178 playstats[playcntr].vaction = 0; 1179 } else { 1180 /* 1181 * We have some buffers to play. set LOOP if we're on the 1182 * last buffer in the ring, otherwise set ROLL. 1183 */ 1184 if (sc->sc_playbuf == sc->sc_nbufs - 1) { 1185 sc->sc_voc[voice].voccntl |= GUSMASK_LOOP_ENABLE; 1186 sc->sc_voc[voice].volcntl &= ~GUSMASK_VOICE_ROLL; 1187 playstats[playcntr].vaction = 1; 1188 } else { 1189 sc->sc_voc[voice].voccntl &= ~GUSMASK_LOOP_ENABLE; 1190 sc->sc_voc[voice].volcntl |= GUSMASK_VOICE_ROLL; 1191 playstats[playcntr].vaction = 2; 1192 } 1193 } 1194 #ifdef GUSPLAYDEBUG 1195 if (gusstats) { 1196 microtime(&playstats[playcntr].tv); 1197 playstats[playcntr].curaddr = gus_get_curaddr(sc, voice); 1198 1199 playstats[playcntr].voccntl = sc->sc_voc[voice].voccntl; 1200 playstats[playcntr].volcntl = sc->sc_voc[voice].volcntl; 1201 playstats[playcntr].endaddr = sc->sc_voc[voice].end_addr; 1202 playstats[playcntr].playbuf = sc->sc_playbuf; 1203 playstats[playcntr].dmabuf = sc->sc_dmabuf; 1204 playstats[playcntr++].bufcnt = sc->sc_bufcnt; 1205 playcntr = playcntr % NDMARECS; 1206 } 1207 #endif 1208 1209 /* 1210 * (re-)set voice parameters. This will reenable interrupts from this 1211 * voice. 1212 */ 1213 1214 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL); 1215 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl); 1216 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL); 1217 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].volcntl); 1218 return 0; 1219 } 1220 1221 /* 1222 * Send/receive data into GUS's DRAM using DMA. Called at splaudio() 1223 */ 1224 1225 void 1226 gusdmaout(struct gus_softc *sc, int flags, u_long gusaddr, caddr_t buffaddr, 1227 int length) 1228 { 1229 unsigned char c = (unsigned char) flags; 1230 bus_space_tag_t iot = sc->sc_iot; 1231 bus_space_handle_t ioh2 = sc->sc_ioh2; 1232 1233 DMAPRINTF(("gusdmaout flags=%x scflags=%x\n", flags, sc->sc_flags)); 1234 1235 sc->sc_gusaddr = gusaddr; 1236 1237 /* 1238 * If we're using a 16 bit DMA channel, we have to jump through some 1239 * extra hoops; this includes translating the DRAM address a bit 1240 */ 1241 1242 if (sc->sc_drq >= 4) { 1243 c |= GUSMASK_DMA_WIDTH; 1244 gusaddr = convert_to_16bit(gusaddr); 1245 } 1246 1247 /* 1248 * Add flag bits that we always set - fast DMA, enable IRQ 1249 */ 1250 1251 c |= GUSMASK_DMA_ENABLE | GUSMASK_DMA_R0 | GUSMASK_DMA_IRQ; 1252 1253 /* 1254 * Make sure the GUS _isn't_ setup for DMA 1255 */ 1256 1257 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL); 1258 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0); 1259 1260 /* 1261 * Tell the PC DMA controller to start doing DMA 1262 */ 1263 1264 sc->sc_dmaoutaddr = (u_char *) buffaddr; 1265 sc->sc_dmaoutcnt = length; 1266 isa_dmastart(sc->sc_dev.dv_parent, sc->sc_drq, buffaddr, length, 1267 NULL, DMAMODE_WRITE, BUS_DMA_NOWAIT); 1268 1269 /* 1270 * Set up DMA address - use the upper 16 bits ONLY 1271 */ 1272 1273 sc->sc_flags |= GUS_DMAOUT_ACTIVE; 1274 1275 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_START); 1276 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, (int) (gusaddr >> 4)); 1277 1278 /* 1279 * Tell the GUS to start doing DMA 1280 */ 1281 1282 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL); 1283 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, c); 1284 1285 /* 1286 * XXX If we don't finish in one second, give up... 1287 */ 1288 timeout_add_sec(&sc->sc_dma_tmo, 1); 1289 } 1290 1291 /* 1292 * Start a voice playing on the GUS. Called from interrupt handler at 1293 * splaudio(). 1294 */ 1295 1296 void 1297 gus_start_voice(struct gus_softc *sc, int voice, int intrs) 1298 { 1299 bus_space_tag_t iot = sc->sc_iot; 1300 bus_space_handle_t ioh2 = sc->sc_ioh2; 1301 u_long start; 1302 u_long current; 1303 u_long end; 1304 1305 /* 1306 * Pick all the values for the voice out of the gus_voice struct 1307 * and use those to program the voice 1308 */ 1309 1310 start = sc->sc_voc[voice].start_addr; 1311 current = sc->sc_voc[voice].current_addr; 1312 end = sc->sc_voc[voice].end_addr; 1313 1314 /* 1315 * If we're using 16 bit data, mangle the addresses a bit 1316 */ 1317 1318 if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16) { 1319 /* -1 on start so that we get onto sample boundary--other 1320 code always sets it for 1-byte rollover protection */ 1321 start = convert_to_16bit(start-1); 1322 current = convert_to_16bit(current); 1323 end = convert_to_16bit(end); 1324 } 1325 1326 /* 1327 * Select the voice we want to use, and program the data addresses 1328 */ 1329 1330 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice); 1331 1332 SELECT_GUS_REG(iot, ioh2, GUSREG_START_ADDR_HIGH); 1333 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(start)); 1334 SELECT_GUS_REG(iot, ioh2, GUSREG_START_ADDR_LOW); 1335 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(start)); 1336 1337 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH); 1338 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(current)); 1339 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW); 1340 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(current)); 1341 1342 SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_HIGH); 1343 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(end)); 1344 SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_LOW); 1345 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(end)); 1346 1347 /* 1348 * (maybe) enable interrupts, disable voice stopping 1349 */ 1350 1351 if (intrs) { 1352 sc->sc_flags |= GUS_PLAYING; /* playing is about to start */ 1353 sc->sc_voc[voice].voccntl |= GUSMASK_VOICE_IRQ; 1354 DMAPRINTF(("gus voice playing=%x\n", sc->sc_flags)); 1355 } else 1356 sc->sc_voc[voice].voccntl &= ~GUSMASK_VOICE_IRQ; 1357 sc->sc_voc[voice].voccntl &= ~(GUSMASK_VOICE_STOPPED | 1358 GUSMASK_STOP_VOICE); 1359 1360 /* 1361 * Tell the GUS about it. Note that we're doing volume ramping here 1362 * from 0 up to the set volume to help reduce clicks. 1363 */ 1364 1365 SELECT_GUS_REG(iot, ioh2, GUSREG_START_VOLUME); 1366 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00); 1367 SELECT_GUS_REG(iot, ioh2, GUSREG_END_VOLUME); 1368 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].current_volume >> 4); 1369 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME); 1370 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x00); 1371 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_RATE); 1372 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 63); 1373 1374 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL); 1375 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl); 1376 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL); 1377 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00); 1378 delay(50); 1379 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL); 1380 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl); 1381 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL); 1382 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00); 1383 1384 } 1385 1386 /* 1387 * Stop a given voice. Called at splaudio(). 1388 */ 1389 1390 void 1391 gus_stop_voice(struct gus_softc *sc, int voice, int intrs_too) 1392 { 1393 bus_space_tag_t iot = sc->sc_iot; 1394 bus_space_handle_t ioh2 = sc->sc_ioh2; 1395 1396 sc->sc_voc[voice].voccntl |= GUSMASK_VOICE_STOPPED | 1397 GUSMASK_STOP_VOICE; 1398 if (intrs_too) { 1399 sc->sc_voc[voice].voccntl &= ~(GUSMASK_VOICE_IRQ); 1400 /* no more DMA to do */ 1401 sc->sc_flags &= ~GUS_PLAYING; 1402 } 1403 DMAPRINTF(("gusintr voice notplaying=%x\n", sc->sc_flags)); 1404 1405 guspoke(iot, ioh2, 0L, 0); 1406 1407 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice); 1408 1409 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME); 1410 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000); 1411 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL); 1412 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl); 1413 delay(100); 1414 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME); 1415 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000); 1416 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL); 1417 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl); 1418 1419 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH); 1420 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000); 1421 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW); 1422 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000); 1423 1424 } 1425 1426 1427 /* 1428 * Set the volume of a given voice. Called at splaudio(). 1429 */ 1430 void 1431 gus_set_volume(struct gus_softc *sc, int voice, int volume) 1432 { 1433 bus_space_tag_t iot = sc->sc_iot; 1434 bus_space_handle_t ioh2 = sc->sc_ioh2; 1435 unsigned int gusvol; 1436 1437 gusvol = gus_log_volumes[volume < 512 ? volume : 511]; 1438 1439 sc->sc_voc[voice].current_volume = gusvol; 1440 1441 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice); 1442 1443 SELECT_GUS_REG(iot, ioh2, GUSREG_START_VOLUME); 1444 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (unsigned char) (gusvol >> 4)); 1445 1446 SELECT_GUS_REG(iot, ioh2, GUSREG_END_VOLUME); 1447 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (unsigned char) (gusvol >> 4)); 1448 1449 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME); 1450 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, gusvol << 4); 1451 delay(500); 1452 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, gusvol << 4); 1453 1454 } 1455 1456 /* 1457 * Interface to the audio layer. 1458 */ 1459 1460 int 1461 gusmax_set_params(void *addr, int setmode, int usemode, struct audio_params *p, 1462 struct audio_params *r) 1463 { 1464 struct ad1848_softc *ac = addr; 1465 struct gus_softc *sc = ac->parent; 1466 int error; 1467 1468 error = ad1848_set_params(ac, setmode, usemode, p, r); 1469 if (error) 1470 return error; 1471 error = gus_set_params(sc, setmode, usemode, p, r); 1472 return error; 1473 } 1474 1475 int 1476 gus_set_params(void *addr, int setmode, int usemode, struct audio_params *p, 1477 struct audio_params *r) 1478 { 1479 struct gus_softc *sc = addr; 1480 1481 switch (p->encoding) { 1482 case AUDIO_ENCODING_SLINEAR_LE: 1483 case AUDIO_ENCODING_ULINEAR_LE: 1484 break; 1485 default: 1486 return (EINVAL); 1487 } 1488 1489 /* XXX: why?! this is called with interrupts disabled */ 1490 mtx_enter(&audio_lock); 1491 1492 if (p->precision == 8) { 1493 sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~GUSMASK_DATA_SIZE16; 1494 sc->sc_voc[GUS_VOICE_RIGHT].voccntl &= ~GUSMASK_DATA_SIZE16; 1495 } else { 1496 sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_DATA_SIZE16; 1497 sc->sc_voc[GUS_VOICE_RIGHT].voccntl |= GUSMASK_DATA_SIZE16; 1498 } 1499 1500 sc->sc_encoding = p->encoding; 1501 sc->sc_precision = p->precision; 1502 sc->sc_channels = p->channels; 1503 1504 mtx_leave(&audio_lock); 1505 1506 if (p->sample_rate > gus_max_frequency[sc->sc_voices - GUS_MIN_VOICES]) 1507 p->sample_rate = gus_max_frequency[sc->sc_voices - GUS_MIN_VOICES]; 1508 if (setmode & AUMODE_RECORD) 1509 sc->sc_irate = p->sample_rate; 1510 if (setmode & AUMODE_PLAY) 1511 sc->sc_orate = p->sample_rate; 1512 1513 p->bps = AUDIO_BPS(p->precision); 1514 r->bps = AUDIO_BPS(r->precision); 1515 p->msb = r->msb = 1; 1516 1517 return 0; 1518 } 1519 1520 /* 1521 * Interface to the audio layer - set the blocksize to the correct number 1522 * of units 1523 */ 1524 1525 int 1526 gusmax_round_blocksize(void *addr, int blocksize) 1527 { 1528 struct ad1848_softc *ac = addr; 1529 struct gus_softc *sc = ac->parent; 1530 1531 /* blocksize = ad1848_round_blocksize(ac, blocksize);*/ 1532 return gus_round_blocksize(sc, blocksize); 1533 } 1534 1535 int 1536 gus_round_blocksize(addr, blocksize) 1537 void * addr; 1538 int blocksize; 1539 { 1540 struct gus_softc *sc = addr; 1541 1542 DPRINTF(("gus_round_blocksize called\n")); 1543 1544 if ((sc->sc_encoding == AUDIO_ENCODING_ULAW || 1545 sc->sc_encoding == AUDIO_ENCODING_ALAW) && blocksize > 32768) 1546 blocksize = 32768; 1547 else if (blocksize > 65536) 1548 blocksize = 65536; 1549 1550 if ((blocksize % GUS_BUFFER_MULTIPLE) != 0) 1551 blocksize = (blocksize / GUS_BUFFER_MULTIPLE + 1) * 1552 GUS_BUFFER_MULTIPLE; 1553 1554 /* set up temporary buffer to hold the deinterleave, if necessary 1555 for stereo output */ 1556 if (sc->sc_deintr_buf) { 1557 free(sc->sc_deintr_buf, M_DEVBUF, 0); 1558 sc->sc_deintr_buf = NULL; 1559 } 1560 sc->sc_deintr_buf = malloc(blocksize/2, M_DEVBUF, M_WAITOK); 1561 1562 sc->sc_blocksize = blocksize; 1563 /* multi-buffering not quite working yet. */ 1564 sc->sc_nbufs = /*GUS_MEM_FOR_BUFFERS / blocksize*/ 2; 1565 1566 gus_set_chan_addrs(sc); 1567 1568 return blocksize; 1569 } 1570 1571 int 1572 gus_get_out_gain(caddr_t addr) 1573 { 1574 struct gus_softc *sc = (struct gus_softc *) addr; 1575 1576 DPRINTF(("gus_get_out_gain called\n")); 1577 return sc->sc_ogain / 2; 1578 } 1579 1580 inline void 1581 gus_set_voices(struct gus_softc *sc, int voices) 1582 { 1583 bus_space_tag_t iot = sc->sc_iot; 1584 bus_space_handle_t ioh2 = sc->sc_ioh2; 1585 /* 1586 * Select the active number of voices 1587 */ 1588 1589 SELECT_GUS_REG(iot, ioh2, GUSREG_ACTIVE_VOICES); 1590 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (voices-1) | 0xc0); 1591 1592 sc->sc_voices = voices; 1593 } 1594 1595 /* 1596 * Actually set the settings of various values on the card 1597 */ 1598 1599 int 1600 gusmax_commit_settings(void *addr) 1601 { 1602 struct ad1848_softc *ac = addr; 1603 struct gus_softc *sc = ac->parent; 1604 int error; 1605 1606 error = ad1848_commit_settings(ac); 1607 if (error) 1608 return error; 1609 return gus_commit_settings(sc); 1610 } 1611 1612 /* 1613 * Commit the settings. Called at normal IPL. 1614 */ 1615 int 1616 gus_commit_settings(void *addr) 1617 { 1618 struct gus_softc *sc = addr; 1619 1620 DPRINTF(("gus_commit_settings called (gain = %d)\n",sc->sc_ogain)); 1621 1622 1623 /* XXX: why?! this is called with interrupts disabled */ 1624 mtx_enter(&audio_lock); 1625 1626 gus_set_recrate(sc, sc->sc_irate); 1627 gus_set_volume(sc, GUS_VOICE_LEFT, sc->sc_ogain); 1628 gus_set_volume(sc, GUS_VOICE_RIGHT, sc->sc_ogain); 1629 gus_set_samprate(sc, GUS_VOICE_LEFT, sc->sc_orate); 1630 gus_set_samprate(sc, GUS_VOICE_RIGHT, sc->sc_orate); 1631 mtx_leave(&audio_lock); 1632 gus_set_chan_addrs(sc); 1633 1634 return 0; 1635 } 1636 1637 void 1638 gus_set_chan_addrs(struct gus_softc *sc) 1639 { 1640 /* 1641 * We use sc_nbufs * blocksize bytes of storage in the on-board GUS 1642 * ram. 1643 * For mono, each of the sc_nbufs buffers is DMA'd to in one chunk, 1644 * and both left & right channels play the same buffer. 1645 * 1646 * For stereo, each channel gets a contiguous half of the memory, 1647 * and each has sc_nbufs buffers of size blocksize/2. 1648 * Stereo data are deinterleaved in main memory before the DMA out 1649 * routines are called to queue the output. 1650 * 1651 * The blocksize per channel is kept in sc_chanblocksize. 1652 */ 1653 if (sc->sc_channels == 2) 1654 sc->sc_chanblocksize = sc->sc_blocksize/2; 1655 else 1656 sc->sc_chanblocksize = sc->sc_blocksize; 1657 1658 sc->sc_voc[GUS_VOICE_LEFT].start_addr = GUS_MEM_OFFSET - 1; 1659 sc->sc_voc[GUS_VOICE_RIGHT].start_addr = 1660 (gus_dostereo && sc->sc_channels == 2 ? GUS_LEFT_RIGHT_OFFSET : 0) 1661 + GUS_MEM_OFFSET - 1; 1662 sc->sc_voc[GUS_VOICE_RIGHT].current_addr = 1663 sc->sc_voc[GUS_VOICE_RIGHT].start_addr + 1; 1664 sc->sc_voc[GUS_VOICE_RIGHT].end_addr = 1665 sc->sc_voc[GUS_VOICE_RIGHT].start_addr + 1666 sc->sc_nbufs * sc->sc_chanblocksize; 1667 1668 } 1669 1670 /* 1671 * Set the sample rate of the given voice. Called at splaudio(). 1672 */ 1673 1674 void 1675 gus_set_samprate(struct gus_softc *sc, int voice, int freq) 1676 { 1677 bus_space_tag_t iot = sc->sc_iot; 1678 bus_space_handle_t ioh2 = sc->sc_ioh2; 1679 unsigned int fc; 1680 u_long temp, f = (u_long) freq; 1681 1682 /* 1683 * calculate fc based on the number of active voices; 1684 * we need to use longs to preserve enough bits 1685 */ 1686 1687 temp = (u_long) gus_max_frequency[sc->sc_voices-GUS_MIN_VOICES]; 1688 1689 fc = (unsigned int)(((f << 9L) + (temp >> 1L)) / temp); 1690 1691 fc <<= 1; 1692 1693 1694 /* 1695 * Program the voice frequency, and set it in the voice data record 1696 */ 1697 1698 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice); 1699 SELECT_GUS_REG(iot, ioh2, GUSREG_FREQ_CONTROL); 1700 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, fc); 1701 1702 sc->sc_voc[voice].rate = freq; 1703 1704 } 1705 1706 /* 1707 * Set the sample rate of the recording frequency. Formula is from the GUS 1708 * SDK. Called at splaudio(). 1709 */ 1710 1711 void 1712 gus_set_recrate(struct gus_softc *sc, u_long rate) 1713 { 1714 bus_space_tag_t iot = sc->sc_iot; 1715 bus_space_handle_t ioh2 = sc->sc_ioh2; 1716 u_char realrate; 1717 DPRINTF(("gus_set_recrate %lu\n", rate)); 1718 1719 #if 0 1720 realrate = 9878400/(16*(rate+2)); /* formula from GUS docs */ 1721 #endif 1722 realrate = (9878400 >> 4)/rate - 2; /* formula from code, sigh. */ 1723 1724 SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_FREQ); 1725 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, realrate); 1726 } 1727 1728 /* 1729 * Interface to the audio layer - turn the output on or off. Note that some 1730 * of these bits are flipped in the register 1731 */ 1732 1733 int 1734 gusmax_speaker_ctl(void *addr, int newstate) 1735 { 1736 struct ad1848_softc *sc = addr; 1737 return gus_speaker_ctl(sc->parent, newstate); 1738 } 1739 1740 int 1741 gus_speaker_ctl(void *addr, int newstate) 1742 { 1743 struct gus_softc *sc = (struct gus_softc *) addr; 1744 bus_space_tag_t iot = sc->sc_iot; 1745 bus_space_handle_t ioh1 = sc->sc_ioh1; 1746 1747 /* Line out bit is flipped: 0 enables, 1 disables */ 1748 if ((newstate == SPKR_ON) && 1749 (sc->sc_mixcontrol & GUSMASK_LINE_OUT)) { 1750 sc->sc_mixcontrol &= ~GUSMASK_LINE_OUT; 1751 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol); 1752 } 1753 if ((newstate == SPKR_OFF) && 1754 (sc->sc_mixcontrol & GUSMASK_LINE_OUT) == 0) { 1755 sc->sc_mixcontrol |= GUSMASK_LINE_OUT; 1756 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol); 1757 } 1758 1759 return 0; 1760 } 1761 1762 int 1763 gus_linein_ctl(void *addr, int newstate) 1764 { 1765 struct gus_softc *sc = (struct gus_softc *) addr; 1766 bus_space_tag_t iot = sc->sc_iot; 1767 bus_space_handle_t ioh1 = sc->sc_ioh1; 1768 1769 /* Line in bit is flipped: 0 enables, 1 disables */ 1770 if ((newstate == SPKR_ON) && 1771 (sc->sc_mixcontrol & GUSMASK_LINE_IN)) { 1772 sc->sc_mixcontrol &= ~GUSMASK_LINE_IN; 1773 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol); 1774 } 1775 if ((newstate == SPKR_OFF) && 1776 (sc->sc_mixcontrol & GUSMASK_LINE_IN) == 0) { 1777 sc->sc_mixcontrol |= GUSMASK_LINE_IN; 1778 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol); 1779 } 1780 1781 return 0; 1782 } 1783 1784 int 1785 gus_mic_ctl(void *addr, int newstate) 1786 { 1787 struct gus_softc *sc = (struct gus_softc *) addr; 1788 bus_space_tag_t iot = sc->sc_iot; 1789 bus_space_handle_t ioh1 = sc->sc_ioh1; 1790 1791 /* Mic bit is normal: 1 enables, 0 disables */ 1792 if ((newstate == SPKR_ON) && 1793 (sc->sc_mixcontrol & GUSMASK_MIC_IN) == 0) { 1794 sc->sc_mixcontrol |= GUSMASK_MIC_IN; 1795 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol); 1796 } 1797 if ((newstate == SPKR_OFF) && 1798 (sc->sc_mixcontrol & GUSMASK_MIC_IN)) { 1799 sc->sc_mixcontrol &= ~GUSMASK_MIC_IN; 1800 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol); 1801 } 1802 1803 return 0; 1804 } 1805 1806 /* 1807 * Set the end address of a give voice. Called at splaudio(). 1808 */ 1809 1810 void 1811 gus_set_endaddr(struct gus_softc *sc, int voice, u_long addr) 1812 { 1813 bus_space_tag_t iot = sc->sc_iot; 1814 bus_space_handle_t ioh2 = sc->sc_ioh2; 1815 1816 sc->sc_voc[voice].end_addr = addr; 1817 1818 if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16) 1819 addr = convert_to_16bit(addr); 1820 1821 SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_HIGH); 1822 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(addr)); 1823 SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_LOW); 1824 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(addr)); 1825 1826 } 1827 1828 #ifdef GUSPLAYDEBUG 1829 /* 1830 * Set current address. Called at splaudio(). 1831 */ 1832 void 1833 gus_set_curaddr(struct gus_softc *sc, int voice, u_long addr) 1834 { 1835 bus_space_tag_t iot = sc->sc_iot; 1836 bus_space_handle_t ioh2 = sc->sc_ioh2; 1837 1838 sc->sc_voc[voice].current_addr = addr; 1839 1840 if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16) 1841 addr = convert_to_16bit(addr); 1842 1843 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice); 1844 1845 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH); 1846 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(addr)); 1847 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW); 1848 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(addr)); 1849 1850 } 1851 1852 /* 1853 * Get current GUS playback address. Called at splaudio(). 1854 */ 1855 u_long 1856 gus_get_curaddr(struct gus_softc *sc, int voice) 1857 { 1858 bus_space_tag_t iot = sc->sc_iot; 1859 bus_space_handle_t ioh2 = sc->sc_ioh2; 1860 u_long addr; 1861 1862 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice); 1863 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH|GUSREG_READ); 1864 addr = (bus_space_read_2(iot, ioh2, GUS_DATA_LOW) & 0x1fff) << 7; 1865 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW|GUSREG_READ); 1866 addr |= (bus_space_read_2(iot, ioh2, GUS_DATA_LOW) >> 9L) & 0x7f; 1867 1868 if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16) 1869 addr = (addr & 0xc0000) | ((addr & 0x1ffff) << 1); /* undo 16-bit change */ 1870 DPRINTF(("gus voice %d curaddr %ld end_addr %ld\n", 1871 voice, addr, sc->sc_voc[voice].end_addr)); 1872 /* XXX sanity check the address? */ 1873 1874 return(addr); 1875 } 1876 #endif 1877 1878 /* 1879 * Convert an address value to a "16 bit" value - why this is necessary I 1880 * have NO idea 1881 */ 1882 1883 u_long 1884 convert_to_16bit(u_long address) 1885 { 1886 u_long old_address; 1887 1888 old_address = address; 1889 address >>= 1; 1890 address &= 0x0001ffffL; 1891 address |= (old_address & 0x000c0000L); 1892 1893 return (address); 1894 } 1895 1896 /* 1897 * Write a value into the GUS's DRAM 1898 */ 1899 1900 void 1901 guspoke(bus_space_tag_t iot, bus_space_handle_t ioh2, long address, 1902 unsigned char value) 1903 { 1904 1905 /* 1906 * Select the DRAM address 1907 */ 1908 1909 SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_LOW); 1910 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, (unsigned int) (address & 0xffff)); 1911 SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_HIGH); 1912 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (unsigned char) ((address >> 16) & 0xff)); 1913 1914 /* 1915 * Actually write the data 1916 */ 1917 1918 bus_space_write_1(iot, ioh2, GUS_DRAM_DATA, value); 1919 } 1920 1921 /* 1922 * Read a value from the GUS's DRAM 1923 */ 1924 1925 unsigned char 1926 guspeek(bus_space_tag_t iot, bus_space_handle_t ioh2, u_long address) 1927 { 1928 1929 /* 1930 * Select the DRAM address 1931 */ 1932 1933 SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_LOW); 1934 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, (unsigned int) (address & 0xffff)); 1935 SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_HIGH); 1936 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (unsigned char) ((address >> 16) & 0xff)); 1937 1938 /* 1939 * Read in the data from the board 1940 */ 1941 1942 return (unsigned char) bus_space_read_1(iot, ioh2, GUS_DRAM_DATA); 1943 } 1944 1945 /* 1946 * Reset the Gravis UltraSound card, completely 1947 */ 1948 1949 void 1950 gusreset(struct gus_softc *sc, int voices) 1951 { 1952 bus_space_tag_t iot = sc->sc_iot; 1953 bus_space_handle_t ioh1 = sc->sc_ioh1; 1954 bus_space_handle_t ioh2 = sc->sc_ioh2; 1955 bus_space_handle_t ioh4 = sc->sc_ioh4; 1956 int i; 1957 1958 mtx_enter(&audio_lock); 1959 1960 /* 1961 * Reset the GF1 chip 1962 */ 1963 1964 SELECT_GUS_REG(iot, ioh2, GUSREG_RESET); 1965 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00); 1966 1967 delay(500); 1968 1969 /* 1970 * Release reset 1971 */ 1972 1973 SELECT_GUS_REG(iot, ioh2, GUSREG_RESET); 1974 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, GUSMASK_MASTER_RESET); 1975 1976 delay(500); 1977 1978 /* 1979 * Reset MIDI port as well, if applicable 1980 */ 1981 1982 if (ioh4 != (bus_space_handle_t)NULL) { 1983 bus_space_write_1(iot, ioh4, GUS_MIDI_CONTROL, MIDI_RESET); 1984 1985 delay(500); 1986 1987 bus_space_write_1(iot, ioh4, GUS_MIDI_CONTROL, 0x00); 1988 } 1989 1990 /* 1991 * Clear interrupts 1992 */ 1993 1994 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL); 1995 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00); 1996 SELECT_GUS_REG(iot, ioh2, GUSREG_TIMER_CONTROL); 1997 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00); 1998 SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL); 1999 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00); 2000 2001 gus_set_voices(sc, voices); 2002 2003 bus_space_read_1(iot, ioh1, GUS_IRQ_STATUS); 2004 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL); 2005 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH); 2006 SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL); 2007 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH); 2008 SELECT_GUS_REG(iot, ioh2, GUSREG_IRQ_STATUS); 2009 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH); 2010 2011 /* 2012 * Reset voice specific information 2013 */ 2014 2015 for(i = 0; i < voices; i++) { 2016 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) i); 2017 2018 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL); 2019 2020 sc->sc_voc[i].voccntl = GUSMASK_VOICE_STOPPED | 2021 GUSMASK_STOP_VOICE; 2022 2023 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[i].voccntl); 2024 2025 sc->sc_voc[i].volcntl = GUSMASK_VOLUME_STOPPED | 2026 GUSMASK_STOP_VOLUME; 2027 2028 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL); 2029 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[i].volcntl); 2030 2031 delay(100); 2032 2033 gus_set_samprate(sc, i, 8000); 2034 SELECT_GUS_REG(iot, ioh2, GUSREG_START_ADDR_HIGH); 2035 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000); 2036 SELECT_GUS_REG(iot, ioh2, GUSREG_START_ADDR_LOW); 2037 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000); 2038 SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_HIGH); 2039 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000); 2040 SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_LOW); 2041 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000); 2042 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_RATE); 2043 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x01); 2044 SELECT_GUS_REG(iot, ioh2, GUSREG_START_VOLUME); 2045 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x10); 2046 SELECT_GUS_REG(iot, ioh2, GUSREG_END_VOLUME); 2047 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0xe0); 2048 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME); 2049 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000); 2050 2051 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH); 2052 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000); 2053 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW); 2054 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000); 2055 SELECT_GUS_REG(iot, ioh2, GUSREG_PAN_POS); 2056 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x07); 2057 } 2058 2059 /* 2060 * Clear out any pending IRQs 2061 */ 2062 2063 bus_space_read_1(iot, ioh1, GUS_IRQ_STATUS); 2064 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL); 2065 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH); 2066 SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL); 2067 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH); 2068 SELECT_GUS_REG(iot, ioh2, GUSREG_IRQ_STATUS); 2069 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH); 2070 2071 SELECT_GUS_REG(iot, ioh2, GUSREG_RESET); 2072 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, GUSMASK_MASTER_RESET | GUSMASK_DAC_ENABLE | 2073 GUSMASK_IRQ_ENABLE); 2074 2075 mtx_leave(&audio_lock); 2076 } 2077 2078 2079 int 2080 gus_init_cs4231(struct gus_softc *sc) 2081 { 2082 bus_space_tag_t iot = sc->sc_iot; 2083 bus_space_handle_t ioh1 = sc->sc_ioh1; 2084 int port = sc->sc_iobase; 2085 u_char ctrl; 2086 2087 ctrl = (port & 0xf0) >> 4; /* set port address middle nibble */ 2088 /* 2089 * The codec is a bit weird--swapped dma channels. 2090 */ 2091 ctrl |= GUS_MAX_CODEC_ENABLE; 2092 if (sc->sc_drq >= 4) 2093 ctrl |= GUS_MAX_RECCHAN16; 2094 if (sc->sc_recdrq >= 4) 2095 ctrl |= GUS_MAX_PLAYCHAN16; 2096 2097 bus_space_write_1(iot, ioh1, GUS_MAX_CTRL, ctrl); 2098 2099 sc->sc_codec.sc_iot = sc->sc_iot; 2100 sc->sc_codec.sc_iobase = port+GUS_MAX_CODEC_BASE; 2101 2102 if (ad1848_mapprobe(&sc->sc_codec, sc->sc_codec.sc_iobase) == 0) { 2103 sc->sc_flags &= ~GUS_CODEC_INSTALLED; 2104 return (0); 2105 } else { 2106 struct ad1848_volume vol = {AUDIO_MAX_GAIN, AUDIO_MAX_GAIN}; 2107 sc->sc_flags |= GUS_CODEC_INSTALLED; 2108 sc->sc_codec.parent = sc; 2109 sc->sc_codec.sc_drq = sc->sc_recdrq; 2110 sc->sc_codec.sc_recdrq = sc->sc_drq; 2111 gus_hw_if = gusmax_hw_if; 2112 /* enable line in and mic in the GUS mixer; the codec chip 2113 will do the real mixing for them. */ 2114 sc->sc_mixcontrol &= ~GUSMASK_LINE_IN; /* 0 enables. */ 2115 sc->sc_mixcontrol |= GUSMASK_MIC_IN; /* 1 enables. */ 2116 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol); 2117 2118 ad1848_attach(&sc->sc_codec); 2119 /* turn on pre-MUX microphone gain. */ 2120 ad1848_set_mic_gain(&sc->sc_codec, &vol); 2121 2122 return (1); 2123 } 2124 } 2125 2126 2127 /* 2128 * Return info about the audio device, for the AUDIO_GETINFO ioctl 2129 */ 2130 2131 int 2132 gus_getdev(void *addr, struct audio_device *dev) 2133 { 2134 *dev = gus_device; 2135 return 0; 2136 } 2137 2138 /* 2139 * stubs (XXX) 2140 */ 2141 2142 int 2143 gus_set_in_gain(caddr_t addr, u_int gain, u_char balance) 2144 { 2145 DPRINTF(("gus_set_in_gain called\n")); 2146 return 0; 2147 } 2148 2149 int 2150 gus_get_in_gain(caddr_t addr) 2151 { 2152 DPRINTF(("gus_get_in_gain called\n")); 2153 return 0; 2154 } 2155 2156 int 2157 gusmax_dma_input(void *addr, void *buf, int size, void (*callback)(void *), 2158 void *arg) 2159 { 2160 struct ad1848_softc *sc = addr; 2161 return gus_dma_input(sc->parent, buf, size, callback, arg); 2162 } 2163 2164 /* 2165 * Start sampling the input source into the requested DMA buffer. 2166 * Called at splaudio(), either from top-half or from interrupt handler. 2167 */ 2168 int 2169 gus_dma_input(void *addr, void *buf, int size, void (*callback)(void *), 2170 void *arg) 2171 { 2172 struct gus_softc *sc = addr; 2173 bus_space_tag_t iot = sc->sc_iot; 2174 bus_space_handle_t ioh2 = sc->sc_ioh2; 2175 u_char dmac; 2176 DMAPRINTF(("gus_dma_input called\n")); 2177 2178 /* 2179 * Sample SIZE bytes of data from the card, into buffer at BUF. 2180 */ 2181 if (sc->sc_precision == 16) { 2182 return EINVAL; /* XXX */ 2183 } 2184 2185 /* set DMA modes */ 2186 dmac = GUSMASK_SAMPLE_IRQ|GUSMASK_SAMPLE_START; 2187 if (sc->sc_recdrq >= 4) 2188 dmac |= GUSMASK_SAMPLE_DATA16; 2189 if (sc->sc_encoding == AUDIO_ENCODING_ULAW || 2190 sc->sc_encoding == AUDIO_ENCODING_ALAW || 2191 sc->sc_encoding == AUDIO_ENCODING_ULINEAR_LE || 2192 sc->sc_encoding == AUDIO_ENCODING_ULINEAR_BE) 2193 dmac |= GUSMASK_SAMPLE_INVBIT; 2194 if (sc->sc_channels == 2) 2195 dmac |= GUSMASK_SAMPLE_STEREO; 2196 isa_dmastart(sc->sc_dev.dv_parent, sc->sc_recdrq, buf, size, 2197 NULL, DMAMODE_READ, BUS_DMA_NOWAIT); 2198 2199 DMAPRINTF(("gus_dma_input isadma_started\n")); 2200 sc->sc_flags |= GUS_DMAIN_ACTIVE; 2201 sc->sc_dmainintr = callback; 2202 sc->sc_inarg = arg; 2203 sc->sc_dmaincnt = size; 2204 sc->sc_dmainaddr = buf; 2205 2206 SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL); 2207 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, dmac); /* Go! */ 2208 2209 2210 DMAPRINTF(("gus_dma_input returning\n")); 2211 return 0; 2212 } 2213 2214 int 2215 gus_dmain_intr(struct gus_softc *sc) 2216 { 2217 void (*callback)(void *); 2218 void *arg; 2219 2220 DMAPRINTF(("gus_dmain_intr called\n")); 2221 if (sc->sc_dmainintr) { 2222 isa_dmadone(sc->sc_dev.dv_parent, sc->sc_recdrq); 2223 callback = sc->sc_dmainintr; 2224 arg = sc->sc_inarg; 2225 2226 sc->sc_dmainaddr = 0; 2227 sc->sc_dmaincnt = 0; 2228 sc->sc_dmainintr = 0; 2229 sc->sc_inarg = 0; 2230 2231 sc->sc_flags &= ~GUS_DMAIN_ACTIVE; 2232 DMAPRINTF(("calling dmain_intr callback %p(%p)\n", callback, arg)); 2233 (*callback)(arg); 2234 return 1; 2235 } else { 2236 DMAPRINTF(("gus_dmain_intr false?\n")); 2237 return 0; /* XXX ??? */ 2238 } 2239 } 2240 2241 int 2242 gusmax_halt_out_dma(void *addr) 2243 { 2244 struct ad1848_softc *sc = addr; 2245 return gus_halt_out_dma(sc->parent); 2246 } 2247 2248 2249 int 2250 gusmax_halt_in_dma(void *addr) 2251 { 2252 struct ad1848_softc *sc = addr; 2253 return gus_halt_in_dma(sc->parent); 2254 } 2255 2256 /* 2257 * Stop any DMA output. Called at splaudio(). 2258 */ 2259 int 2260 gus_halt_out_dma(void *addr) 2261 { 2262 struct gus_softc *sc = addr; 2263 bus_space_tag_t iot = sc->sc_iot; 2264 bus_space_handle_t ioh2 = sc->sc_ioh2; 2265 2266 mtx_enter(&audio_lock); 2267 DMAPRINTF(("gus_halt_out_dma called\n")); 2268 /* 2269 * Make sure the GUS _isn't_ setup for DMA 2270 */ 2271 2272 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL); 2273 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0); 2274 2275 timeout_del(&sc->sc_dma_tmo); 2276 isa_dmaabort(sc->sc_dev.dv_parent, sc->sc_drq); 2277 sc->sc_flags &= ~(GUS_DMAOUT_ACTIVE|GUS_LOCKED); 2278 sc->sc_dmaoutintr = 0; 2279 sc->sc_outarg = 0; 2280 sc->sc_dmaoutaddr = 0; 2281 sc->sc_dmaoutcnt = 0; 2282 sc->sc_dmabuf = 0; 2283 sc->sc_bufcnt = 0; 2284 sc->sc_playbuf = -1; 2285 /* also stop playing */ 2286 gus_stop_voice(sc, GUS_VOICE_LEFT, 1); 2287 gus_stop_voice(sc, GUS_VOICE_RIGHT, 0); 2288 mtx_leave(&audio_lock); 2289 return 0; 2290 } 2291 2292 /* 2293 * Stop any DMA output. Called at splaudio(). 2294 */ 2295 int 2296 gus_halt_in_dma(void *addr) 2297 { 2298 struct gus_softc *sc = addr; 2299 bus_space_tag_t iot = sc->sc_iot; 2300 bus_space_handle_t ioh2 = sc->sc_ioh2; 2301 2302 mtx_enter(&audio_lock); 2303 DMAPRINTF(("gus_halt_in_dma called\n")); 2304 2305 /* 2306 * Make sure the GUS _isn't_ setup for DMA 2307 */ 2308 2309 SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL); 2310 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 2311 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH) & ~(GUSMASK_SAMPLE_START|GUSMASK_SAMPLE_IRQ)); 2312 2313 isa_dmaabort(sc->sc_dev.dv_parent, sc->sc_recdrq); 2314 sc->sc_flags &= ~GUS_DMAIN_ACTIVE; 2315 sc->sc_dmainintr = 0; 2316 sc->sc_inarg = 0; 2317 sc->sc_dmainaddr = 0; 2318 sc->sc_dmaincnt = 0; 2319 mtx_leave(&audio_lock); 2320 return 0; 2321 } 2322 2323 2324 ad1848_devmap_t gusmapping[] = { 2325 {GUSMAX_DAC_LVL, AD1848_KIND_LVL, AD1848_AUX1_CHANNEL}, 2326 {GUSMAX_LINE_IN_LVL, AD1848_KIND_LVL, AD1848_LINE_CHANNEL}, 2327 {GUSMAX_MONO_LVL, AD1848_KIND_LVL, AD1848_MONO_CHANNEL}, 2328 {GUSMAX_CD_LVL, AD1848_KIND_LVL, AD1848_AUX2_CHANNEL}, 2329 {GUSMAX_MONITOR_LVL, AD1848_KIND_LVL, AD1848_MONITOR_CHANNEL}, 2330 {GUSMAX_OUT_LVL, AD1848_KIND_LVL, AD1848_DAC_CHANNEL}, 2331 {GUSMAX_DAC_MUTE, AD1848_KIND_MUTE, AD1848_AUX1_CHANNEL}, 2332 {GUSMAX_LINE_IN_MUTE, AD1848_KIND_MUTE, AD1848_LINE_CHANNEL}, 2333 {GUSMAX_MONO_MUTE, AD1848_KIND_MUTE, AD1848_MONO_CHANNEL}, 2334 {GUSMAX_CD_MUTE, AD1848_KIND_MUTE, AD1848_AUX2_CHANNEL}, 2335 {GUSMAX_MONITOR_MUTE, AD1848_KIND_MUTE, AD1848_MONITOR_CHANNEL}, 2336 {GUSMAX_REC_LVL, AD1848_KIND_RECORDGAIN, -1}, 2337 {GUSMAX_RECORD_SOURCE, AD1848_KIND_RECORDSOURCE, -1} 2338 }; 2339 2340 int nummap = sizeof(gusmapping) / sizeof(gusmapping[0]); 2341 2342 int 2343 gusmax_mixer_get_port(void *addr, mixer_ctrl_t *cp) 2344 { 2345 struct ad1848_softc *ac = addr; 2346 struct gus_softc *sc = ac->parent; 2347 struct ad1848_volume vol; 2348 int error = ad1848_mixer_get_port(ac, gusmapping, nummap, cp); 2349 2350 if (error != ENXIO) 2351 return (error); 2352 2353 error = EINVAL; 2354 2355 switch (cp->dev) { 2356 case GUSMAX_SPEAKER_LVL: /* fake speaker for mute naming */ 2357 if (cp->type == AUDIO_MIXER_VALUE) { 2358 if (sc->sc_mixcontrol & GUSMASK_LINE_OUT) 2359 vol.left = vol.right = AUDIO_MAX_GAIN; 2360 else 2361 vol.left = vol.right = AUDIO_MIN_GAIN; 2362 error = 0; 2363 ad1848_from_vol(cp, &vol); 2364 } 2365 break; 2366 2367 case GUSMAX_SPEAKER_MUTE: 2368 if (cp->type == AUDIO_MIXER_ENUM) { 2369 cp->un.ord = sc->sc_mixcontrol & GUSMASK_LINE_OUT ? 1 : 0; 2370 error = 0; 2371 } 2372 break; 2373 default: 2374 error = ENXIO; 2375 break; 2376 } 2377 2378 return(error); 2379 } 2380 2381 int 2382 gus_mixer_get_port(void *addr, mixer_ctrl_t *cp) 2383 { 2384 struct gus_softc *sc = addr; 2385 struct ics2101_softc *ic = &sc->sc_mixer; 2386 struct ad1848_volume vol; 2387 int error = EINVAL; 2388 2389 DPRINTF(("gus_mixer_get_port: dev=%d type=%d\n", cp->dev, cp->type)); 2390 2391 if (!HAS_MIXER(sc) && cp->dev > GUSICS_MASTER_MUTE) 2392 return ENXIO; 2393 2394 switch (cp->dev) { 2395 2396 case GUSICS_MIC_IN_MUTE: /* Microphone */ 2397 if (cp->type == AUDIO_MIXER_ENUM) { 2398 if (HAS_MIXER(sc)) 2399 cp->un.ord = ic->sc_mute[GUSMIX_CHAN_MIC][ICSMIX_LEFT]; 2400 else 2401 cp->un.ord = 2402 sc->sc_mixcontrol & GUSMASK_MIC_IN ? 0 : 1; 2403 error = 0; 2404 } 2405 break; 2406 2407 case GUSICS_LINE_IN_MUTE: 2408 if (cp->type == AUDIO_MIXER_ENUM) { 2409 if (HAS_MIXER(sc)) 2410 cp->un.ord = ic->sc_mute[GUSMIX_CHAN_LINE][ICSMIX_LEFT]; 2411 else 2412 cp->un.ord = 2413 sc->sc_mixcontrol & GUSMASK_LINE_IN ? 1 : 0; 2414 error = 0; 2415 } 2416 break; 2417 2418 case GUSICS_MASTER_MUTE: 2419 if (cp->type == AUDIO_MIXER_ENUM) { 2420 if (HAS_MIXER(sc)) 2421 cp->un.ord = ic->sc_mute[GUSMIX_CHAN_MASTER][ICSMIX_LEFT]; 2422 else 2423 cp->un.ord = 2424 sc->sc_mixcontrol & GUSMASK_LINE_OUT ? 1 : 0; 2425 error = 0; 2426 } 2427 break; 2428 2429 case GUSICS_DAC_MUTE: 2430 if (cp->type == AUDIO_MIXER_ENUM) { 2431 cp->un.ord = ic->sc_mute[GUSMIX_CHAN_DAC][ICSMIX_LEFT]; 2432 error = 0; 2433 } 2434 break; 2435 2436 case GUSICS_CD_MUTE: 2437 if (cp->type == AUDIO_MIXER_ENUM) { 2438 cp->un.ord = ic->sc_mute[GUSMIX_CHAN_CD][ICSMIX_LEFT]; 2439 error = 0; 2440 } 2441 break; 2442 2443 case GUSICS_MASTER_LVL: 2444 if (cp->type == AUDIO_MIXER_VALUE) { 2445 vol.left = ic->sc_setting[GUSMIX_CHAN_MASTER][ICSMIX_LEFT]; 2446 vol.right = ic->sc_setting[GUSMIX_CHAN_MASTER][ICSMIX_RIGHT]; 2447 if (ad1848_from_vol(cp, &vol)) 2448 error = 0; 2449 } 2450 break; 2451 2452 case GUSICS_MIC_IN_LVL: /* Microphone */ 2453 if (cp->type == AUDIO_MIXER_VALUE) { 2454 vol.left = ic->sc_setting[GUSMIX_CHAN_MIC][ICSMIX_LEFT]; 2455 vol.right = ic->sc_setting[GUSMIX_CHAN_MIC][ICSMIX_RIGHT]; 2456 if (ad1848_from_vol(cp, &vol)) 2457 error = 0; 2458 } 2459 break; 2460 2461 case GUSICS_LINE_IN_LVL: /* line in */ 2462 if (cp->type == AUDIO_MIXER_VALUE) { 2463 vol.left = ic->sc_setting[GUSMIX_CHAN_LINE][ICSMIX_LEFT]; 2464 vol.right = ic->sc_setting[GUSMIX_CHAN_LINE][ICSMIX_RIGHT]; 2465 if (ad1848_from_vol(cp, &vol)) 2466 error = 0; 2467 } 2468 break; 2469 2470 2471 case GUSICS_CD_LVL: 2472 if (cp->type == AUDIO_MIXER_VALUE) { 2473 vol.left = ic->sc_setting[GUSMIX_CHAN_CD][ICSMIX_LEFT]; 2474 vol.right = ic->sc_setting[GUSMIX_CHAN_CD][ICSMIX_RIGHT]; 2475 if (ad1848_from_vol(cp, &vol)) 2476 error = 0; 2477 } 2478 break; 2479 2480 case GUSICS_DAC_LVL: /* dac out */ 2481 if (cp->type == AUDIO_MIXER_VALUE) { 2482 vol.left = ic->sc_setting[GUSMIX_CHAN_DAC][ICSMIX_LEFT]; 2483 vol.right = ic->sc_setting[GUSMIX_CHAN_DAC][ICSMIX_RIGHT]; 2484 if (ad1848_from_vol(cp, &vol)) 2485 error = 0; 2486 } 2487 break; 2488 2489 2490 case GUSICS_RECORD_SOURCE: 2491 if (cp->type == AUDIO_MIXER_ENUM) { 2492 /* Can't set anything else useful, sigh. */ 2493 cp->un.ord = 0; 2494 } 2495 break; 2496 2497 default: 2498 return ENXIO; 2499 /*NOTREACHED*/ 2500 } 2501 return error; 2502 } 2503 2504 void 2505 gusics_master_mute(struct ics2101_softc *ic, int mute) 2506 { 2507 ics2101_mix_mute(ic, GUSMIX_CHAN_MASTER, ICSMIX_LEFT, mute); 2508 ics2101_mix_mute(ic, GUSMIX_CHAN_MASTER, ICSMIX_RIGHT, mute); 2509 } 2510 2511 void 2512 gusics_mic_mute(struct ics2101_softc *ic, int mute) 2513 { 2514 ics2101_mix_mute(ic, GUSMIX_CHAN_MIC, ICSMIX_LEFT, mute); 2515 ics2101_mix_mute(ic, GUSMIX_CHAN_MIC, ICSMIX_RIGHT, mute); 2516 } 2517 2518 void 2519 gusics_linein_mute(struct ics2101_softc *ic, int mute) 2520 { 2521 ics2101_mix_mute(ic, GUSMIX_CHAN_LINE, ICSMIX_LEFT, mute); 2522 ics2101_mix_mute(ic, GUSMIX_CHAN_LINE, ICSMIX_RIGHT, mute); 2523 } 2524 2525 void 2526 gusics_cd_mute(struct ics2101_softc *ic, int mute) 2527 { 2528 ics2101_mix_mute(ic, GUSMIX_CHAN_CD, ICSMIX_LEFT, mute); 2529 ics2101_mix_mute(ic, GUSMIX_CHAN_CD, ICSMIX_RIGHT, mute); 2530 } 2531 2532 void 2533 gusics_dac_mute(struct ics2101_softc *ic, int mute) 2534 { 2535 ics2101_mix_mute(ic, GUSMIX_CHAN_DAC, ICSMIX_LEFT, mute); 2536 ics2101_mix_mute(ic, GUSMIX_CHAN_DAC, ICSMIX_RIGHT, mute); 2537 } 2538 2539 int 2540 gusmax_mixer_set_port(void *addr, mixer_ctrl_t *cp) 2541 { 2542 struct ad1848_softc *ac = addr; 2543 struct gus_softc *sc = ac->parent; 2544 struct ad1848_volume vol; 2545 int error = ad1848_mixer_set_port(ac, gusmapping, nummap, cp); 2546 2547 if (error != ENXIO) 2548 return (error); 2549 2550 DPRINTF(("gusmax_mixer_set_port: dev=%d type=%d\n", cp->dev, cp->type)); 2551 2552 switch (cp->dev) { 2553 case GUSMAX_SPEAKER_LVL: 2554 if (cp->type == AUDIO_MIXER_VALUE && 2555 cp->un.value.num_channels == 1) { 2556 if (ad1848_to_vol(cp, &vol)) { 2557 gus_speaker_ctl(sc, vol.left > AUDIO_MIN_GAIN ? 2558 SPKR_ON : SPKR_OFF); 2559 error = 0; 2560 } 2561 } 2562 break; 2563 2564 case GUSMAX_SPEAKER_MUTE: 2565 if (cp->type == AUDIO_MIXER_ENUM) { 2566 gus_speaker_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON); 2567 error = 0; 2568 } 2569 break; 2570 2571 default: 2572 return ENXIO; 2573 /*NOTREACHED*/ 2574 } 2575 return error; 2576 } 2577 2578 int 2579 gus_mixer_set_port(void *addr, mixer_ctrl_t *cp) 2580 { 2581 struct gus_softc *sc = addr; 2582 struct ics2101_softc *ic = &sc->sc_mixer; 2583 struct ad1848_volume vol; 2584 int error = EINVAL; 2585 2586 DPRINTF(("gus_mixer_set_port: dev=%d type=%d\n", cp->dev, cp->type)); 2587 2588 if (!HAS_MIXER(sc) && cp->dev > GUSICS_MASTER_MUTE) 2589 return ENXIO; 2590 2591 switch (cp->dev) { 2592 2593 case GUSICS_MIC_IN_MUTE: /* Microphone */ 2594 if (cp->type == AUDIO_MIXER_ENUM) { 2595 DPRINTF(("mic mute %d\n", cp->un.ord)); 2596 if (HAS_MIXER(sc)) { 2597 gusics_mic_mute(ic, cp->un.ord); 2598 } 2599 gus_mic_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON); 2600 error = 0; 2601 } 2602 break; 2603 2604 case GUSICS_LINE_IN_MUTE: 2605 if (cp->type == AUDIO_MIXER_ENUM) { 2606 DPRINTF(("linein mute %d\n", cp->un.ord)); 2607 if (HAS_MIXER(sc)) { 2608 gusics_linein_mute(ic, cp->un.ord); 2609 } 2610 gus_linein_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON); 2611 error = 0; 2612 } 2613 break; 2614 2615 case GUSICS_MASTER_MUTE: 2616 if (cp->type == AUDIO_MIXER_ENUM) { 2617 DPRINTF(("master mute %d\n", cp->un.ord)); 2618 if (HAS_MIXER(sc)) { 2619 gusics_master_mute(ic, cp->un.ord); 2620 } 2621 gus_speaker_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON); 2622 error = 0; 2623 } 2624 break; 2625 2626 case GUSICS_DAC_MUTE: 2627 if (cp->type == AUDIO_MIXER_ENUM) { 2628 gusics_dac_mute(ic, cp->un.ord); 2629 error = 0; 2630 } 2631 break; 2632 2633 case GUSICS_CD_MUTE: 2634 if (cp->type == AUDIO_MIXER_ENUM) { 2635 gusics_cd_mute(ic, cp->un.ord); 2636 error = 0; 2637 } 2638 break; 2639 2640 case GUSICS_MASTER_LVL: 2641 if (cp->type == AUDIO_MIXER_VALUE) { 2642 if (ad1848_to_vol(cp, &vol)) { 2643 ics2101_mix_attenuate(ic, 2644 GUSMIX_CHAN_MASTER, 2645 ICSMIX_LEFT, 2646 vol.left); 2647 ics2101_mix_attenuate(ic, 2648 GUSMIX_CHAN_MASTER, 2649 ICSMIX_RIGHT, 2650 vol.right); 2651 error = 0; 2652 } 2653 } 2654 break; 2655 2656 case GUSICS_MIC_IN_LVL: /* Microphone */ 2657 if (cp->type == AUDIO_MIXER_VALUE) { 2658 if (ad1848_to_vol(cp, &vol)) { 2659 ics2101_mix_attenuate(ic, 2660 GUSMIX_CHAN_MIC, 2661 ICSMIX_LEFT, 2662 vol.left); 2663 ics2101_mix_attenuate(ic, 2664 GUSMIX_CHAN_MIC, 2665 ICSMIX_RIGHT, 2666 vol.right); 2667 error = 0; 2668 } 2669 } 2670 break; 2671 2672 case GUSICS_LINE_IN_LVL: /* line in */ 2673 if (cp->type == AUDIO_MIXER_VALUE) { 2674 if (ad1848_to_vol(cp, &vol)) { 2675 ics2101_mix_attenuate(ic, 2676 GUSMIX_CHAN_LINE, 2677 ICSMIX_LEFT, 2678 vol.left); 2679 ics2101_mix_attenuate(ic, 2680 GUSMIX_CHAN_LINE, 2681 ICSMIX_RIGHT, 2682 vol.right); 2683 error = 0; 2684 } 2685 } 2686 break; 2687 2688 2689 case GUSICS_CD_LVL: 2690 if (cp->type == AUDIO_MIXER_VALUE) { 2691 if (ad1848_to_vol(cp, &vol)) { 2692 ics2101_mix_attenuate(ic, 2693 GUSMIX_CHAN_CD, 2694 ICSMIX_LEFT, 2695 vol.left); 2696 ics2101_mix_attenuate(ic, 2697 GUSMIX_CHAN_CD, 2698 ICSMIX_RIGHT, 2699 vol.right); 2700 error = 0; 2701 } 2702 } 2703 break; 2704 2705 case GUSICS_DAC_LVL: /* dac out */ 2706 if (cp->type == AUDIO_MIXER_VALUE) { 2707 if (ad1848_to_vol(cp, &vol)) { 2708 ics2101_mix_attenuate(ic, 2709 GUSMIX_CHAN_DAC, 2710 ICSMIX_LEFT, 2711 vol.left); 2712 ics2101_mix_attenuate(ic, 2713 GUSMIX_CHAN_DAC, 2714 ICSMIX_RIGHT, 2715 vol.right); 2716 error = 0; 2717 } 2718 } 2719 break; 2720 2721 2722 case GUSICS_RECORD_SOURCE: 2723 if (cp->type == AUDIO_MIXER_ENUM && cp->un.ord == 0) { 2724 /* Can't set anything else useful, sigh. */ 2725 error = 0; 2726 } 2727 break; 2728 2729 default: 2730 return ENXIO; 2731 /*NOTREACHED*/ 2732 } 2733 return error; 2734 } 2735 2736 int 2737 gus_get_props(void *addr) 2738 { 2739 struct gus_softc *sc = addr; 2740 return AUDIO_PROP_MMAP | 2741 (sc->sc_recdrq == sc->sc_drq ? 0 : AUDIO_PROP_FULLDUPLEX); 2742 } 2743 2744 int 2745 gusmax_get_props(void *addr) 2746 { 2747 struct ad1848_softc *ac = addr; 2748 return gus_get_props(ac->parent); 2749 } 2750 2751 int 2752 gusmax_mixer_query_devinfo(void *addr, mixer_devinfo_t *dip) 2753 { 2754 DPRINTF(("gusmax_query_devinfo: index=%d\n", dip->index)); 2755 2756 switch(dip->index) { 2757 #if 0 2758 case GUSMAX_MIC_IN_LVL: /* Microphone */ 2759 dip->type = AUDIO_MIXER_VALUE; 2760 dip->mixer_class = GUSMAX_INPUT_CLASS; 2761 dip->prev = AUDIO_MIXER_LAST; 2762 dip->next = GUSMAX_MIC_IN_MUTE; 2763 strlcpy(dip->label.name, AudioNmicrophone, sizeof dip->label.name); 2764 dip->un.v.num_channels = 2; 2765 strlcpy(dip->un.v.units.name, AudioNvolume, 2766 sizeof dip->un.v.units.name); 2767 break; 2768 #endif 2769 2770 case GUSMAX_MONO_LVL: /* mono/microphone mixer */ 2771 dip->type = AUDIO_MIXER_VALUE; 2772 dip->mixer_class = GUSMAX_INPUT_CLASS; 2773 dip->prev = AUDIO_MIXER_LAST; 2774 dip->next = GUSMAX_MONO_MUTE; 2775 strlcpy(dip->label.name, AudioNmicrophone, sizeof dip->label.name); 2776 dip->un.v.num_channels = 1; 2777 strlcpy(dip->un.v.units.name, AudioNvolume, 2778 sizeof dip->un.v.units.name); 2779 break; 2780 2781 case GUSMAX_DAC_LVL: /* dacout */ 2782 dip->type = AUDIO_MIXER_VALUE; 2783 dip->mixer_class = GUSMAX_INPUT_CLASS; 2784 dip->prev = AUDIO_MIXER_LAST; 2785 dip->next = GUSMAX_DAC_MUTE; 2786 strlcpy(dip->label.name, AudioNdac, sizeof dip->label.name); 2787 dip->un.v.num_channels = 2; 2788 strlcpy(dip->un.v.units.name, AudioNvolume, 2789 sizeof dip->un.v.units.name); 2790 break; 2791 2792 case GUSMAX_LINE_IN_LVL: /* line */ 2793 dip->type = AUDIO_MIXER_VALUE; 2794 dip->mixer_class = GUSMAX_INPUT_CLASS; 2795 dip->prev = AUDIO_MIXER_LAST; 2796 dip->next = GUSMAX_LINE_IN_MUTE; 2797 strlcpy(dip->label.name, AudioNline, sizeof dip->label.name); 2798 dip->un.v.num_channels = 2; 2799 strlcpy(dip->un.v.units.name, AudioNvolume, 2800 sizeof dip->un.v.units.name); 2801 break; 2802 2803 case GUSMAX_CD_LVL: /* cd */ 2804 dip->type = AUDIO_MIXER_VALUE; 2805 dip->mixer_class = GUSMAX_INPUT_CLASS; 2806 dip->prev = AUDIO_MIXER_LAST; 2807 dip->next = GUSMAX_CD_MUTE; 2808 strlcpy(dip->label.name, AudioNcd, sizeof dip->label.name); 2809 dip->un.v.num_channels = 2; 2810 strlcpy(dip->un.v.units.name, AudioNvolume, 2811 sizeof dip->un.v.units.name); 2812 break; 2813 2814 2815 case GUSMAX_MONITOR_LVL: /* monitor level */ 2816 dip->type = AUDIO_MIXER_VALUE; 2817 dip->mixer_class = GUSMAX_MONITOR_CLASS; 2818 dip->next = GUSMAX_MONITOR_MUTE; 2819 dip->prev = AUDIO_MIXER_LAST; 2820 strlcpy(dip->label.name, AudioNmonitor, sizeof dip->label.name); 2821 dip->un.v.num_channels = 1; 2822 strlcpy(dip->un.v.units.name, AudioNvolume, 2823 sizeof dip->un.v.units.name); 2824 break; 2825 2826 case GUSMAX_OUT_LVL: /* cs4231 output volume: not useful? */ 2827 dip->type = AUDIO_MIXER_VALUE; 2828 dip->mixer_class = GUSMAX_MONITOR_CLASS; 2829 dip->prev = dip->next = AUDIO_MIXER_LAST; 2830 strlcpy(dip->label.name, AudioNoutput, sizeof dip->label.name); 2831 dip->un.v.num_channels = 2; 2832 strlcpy(dip->un.v.units.name, AudioNvolume, 2833 sizeof dip->un.v.units.name); 2834 break; 2835 2836 case GUSMAX_SPEAKER_LVL: /* fake speaker volume */ 2837 dip->type = AUDIO_MIXER_VALUE; 2838 dip->mixer_class = GUSMAX_MONITOR_CLASS; 2839 dip->prev = AUDIO_MIXER_LAST; 2840 dip->next = GUSMAX_SPEAKER_MUTE; 2841 strlcpy(dip->label.name, AudioNmaster, sizeof dip->label.name); 2842 dip->un.v.num_channels = 2; 2843 strlcpy(dip->un.v.units.name, AudioNvolume, 2844 sizeof dip->un.v.units.name); 2845 break; 2846 2847 case GUSMAX_LINE_IN_MUTE: 2848 dip->mixer_class = GUSMAX_INPUT_CLASS; 2849 dip->type = AUDIO_MIXER_ENUM; 2850 dip->prev = GUSMAX_LINE_IN_LVL; 2851 dip->next = AUDIO_MIXER_LAST; 2852 goto mute; 2853 2854 case GUSMAX_DAC_MUTE: 2855 dip->mixer_class = GUSMAX_INPUT_CLASS; 2856 dip->type = AUDIO_MIXER_ENUM; 2857 dip->prev = GUSMAX_DAC_LVL; 2858 dip->next = AUDIO_MIXER_LAST; 2859 goto mute; 2860 2861 case GUSMAX_CD_MUTE: 2862 dip->mixer_class = GUSMAX_INPUT_CLASS; 2863 dip->type = AUDIO_MIXER_ENUM; 2864 dip->prev = GUSMAX_CD_LVL; 2865 dip->next = AUDIO_MIXER_LAST; 2866 goto mute; 2867 2868 case GUSMAX_MONO_MUTE: 2869 dip->mixer_class = GUSMAX_INPUT_CLASS; 2870 dip->type = AUDIO_MIXER_ENUM; 2871 dip->prev = GUSMAX_MONO_LVL; 2872 dip->next = AUDIO_MIXER_LAST; 2873 goto mute; 2874 2875 case GUSMAX_MONITOR_MUTE: 2876 dip->mixer_class = GUSMAX_OUTPUT_CLASS; 2877 dip->type = AUDIO_MIXER_ENUM; 2878 dip->prev = GUSMAX_MONITOR_LVL; 2879 dip->next = AUDIO_MIXER_LAST; 2880 goto mute; 2881 2882 case GUSMAX_SPEAKER_MUTE: 2883 dip->mixer_class = GUSMAX_OUTPUT_CLASS; 2884 dip->type = AUDIO_MIXER_ENUM; 2885 dip->prev = GUSMAX_SPEAKER_LVL; 2886 dip->next = AUDIO_MIXER_LAST; 2887 mute: 2888 strlcpy(dip->label.name, AudioNmute, sizeof dip->label.name); 2889 dip->un.e.num_mem = 2; 2890 strlcpy(dip->un.e.member[0].label.name, AudioNoff, 2891 sizeof dip->un.e.member[0].label.name); 2892 dip->un.e.member[0].ord = 0; 2893 strlcpy(dip->un.e.member[1].label.name, AudioNon, 2894 sizeof dip->un.e.member[1].label.name); 2895 dip->un.e.member[1].ord = 1; 2896 break; 2897 2898 case GUSMAX_REC_LVL: /* record level */ 2899 dip->type = AUDIO_MIXER_VALUE; 2900 dip->mixer_class = GUSMAX_RECORD_CLASS; 2901 dip->prev = AUDIO_MIXER_LAST; 2902 dip->next = GUSMAX_RECORD_SOURCE; 2903 strlcpy(dip->label.name, AudioNrecord, sizeof dip->label.name); 2904 dip->un.v.num_channels = 2; 2905 strlcpy(dip->un.v.units.name, AudioNvolume, sizeof dip->un.v.units.name); 2906 break; 2907 2908 case GUSMAX_RECORD_SOURCE: 2909 dip->mixer_class = GUSMAX_RECORD_CLASS; 2910 dip->type = AUDIO_MIXER_ENUM; 2911 dip->prev = GUSMAX_REC_LVL; 2912 dip->next = AUDIO_MIXER_LAST; 2913 strlcpy(dip->label.name, AudioNsource, sizeof dip->label.name); 2914 dip->un.e.num_mem = 4; 2915 strlcpy(dip->un.e.member[0].label.name, AudioNoutput, 2916 sizeof dip->un.e.member[0].label.name); 2917 dip->un.e.member[0].ord = DAC_IN_PORT; 2918 strlcpy(dip->un.e.member[1].label.name, AudioNmicrophone, 2919 sizeof dip->un.e.member[1].label.name); 2920 dip->un.e.member[1].ord = MIC_IN_PORT; 2921 strlcpy(dip->un.e.member[2].label.name, AudioNdac, 2922 sizeof dip->un.e.member[2].label.name); 2923 dip->un.e.member[2].ord = AUX1_IN_PORT; 2924 strlcpy(dip->un.e.member[3].label.name, AudioNline, 2925 sizeof dip->un.e.member[3].label.name); 2926 dip->un.e.member[3].ord = LINE_IN_PORT; 2927 break; 2928 2929 case GUSMAX_INPUT_CLASS: /* input class descriptor */ 2930 dip->type = AUDIO_MIXER_CLASS; 2931 dip->mixer_class = GUSMAX_INPUT_CLASS; 2932 dip->next = dip->prev = AUDIO_MIXER_LAST; 2933 strlcpy(dip->label.name, AudioCinputs, sizeof dip->label.name); 2934 break; 2935 2936 case GUSMAX_OUTPUT_CLASS: /* output class descriptor */ 2937 dip->type = AUDIO_MIXER_CLASS; 2938 dip->mixer_class = GUSMAX_OUTPUT_CLASS; 2939 dip->next = dip->prev = AUDIO_MIXER_LAST; 2940 strlcpy(dip->label.name, AudioCoutputs, sizeof dip->label.name); 2941 break; 2942 2943 case GUSMAX_MONITOR_CLASS: /* monitor class descriptor */ 2944 dip->type = AUDIO_MIXER_CLASS; 2945 dip->mixer_class = GUSMAX_MONITOR_CLASS; 2946 dip->next = dip->prev = AUDIO_MIXER_LAST; 2947 strlcpy(dip->label.name, AudioCmonitor, sizeof dip->label.name); 2948 break; 2949 2950 case GUSMAX_RECORD_CLASS: /* record source class */ 2951 dip->type = AUDIO_MIXER_CLASS; 2952 dip->mixer_class = GUSMAX_RECORD_CLASS; 2953 dip->next = dip->prev = AUDIO_MIXER_LAST; 2954 strlcpy(dip->label.name, AudioCrecord, sizeof dip->label.name); 2955 break; 2956 2957 default: 2958 return ENXIO; 2959 /*NOTREACHED*/ 2960 } 2961 DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name)); 2962 return 0; 2963 } 2964 2965 int 2966 gus_mixer_query_devinfo(void *addr, mixer_devinfo_t *dip) 2967 { 2968 struct gus_softc *sc = addr; 2969 2970 DPRINTF(("gusmax_query_devinfo: index=%d\n", dip->index)); 2971 2972 if (!HAS_MIXER(sc) && dip->index > GUSICS_MASTER_MUTE) 2973 return ENXIO; 2974 2975 switch(dip->index) { 2976 2977 case GUSICS_MIC_IN_LVL: /* Microphone */ 2978 dip->type = AUDIO_MIXER_VALUE; 2979 dip->mixer_class = GUSICS_INPUT_CLASS; 2980 dip->prev = AUDIO_MIXER_LAST; 2981 dip->next = GUSICS_MIC_IN_MUTE; 2982 strlcpy(dip->label.name, AudioNmicrophone, 2983 sizeof dip->label.name); 2984 dip->un.v.num_channels = 2; 2985 strlcpy(dip->un.v.units.name, AudioNvolume, 2986 sizeof dip->un.v.units.name); 2987 break; 2988 2989 case GUSICS_LINE_IN_LVL: /* line */ 2990 dip->type = AUDIO_MIXER_VALUE; 2991 dip->mixer_class = GUSICS_INPUT_CLASS; 2992 dip->prev = AUDIO_MIXER_LAST; 2993 dip->next = GUSICS_LINE_IN_MUTE; 2994 strlcpy(dip->label.name, AudioNline, sizeof dip->label.name); 2995 dip->un.v.num_channels = 2; 2996 strlcpy(dip->un.v.units.name, AudioNvolume, 2997 sizeof dip->un.v.units.name); 2998 break; 2999 3000 case GUSICS_CD_LVL: /* cd */ 3001 dip->type = AUDIO_MIXER_VALUE; 3002 dip->mixer_class = GUSICS_INPUT_CLASS; 3003 dip->prev = AUDIO_MIXER_LAST; 3004 dip->next = GUSICS_CD_MUTE; 3005 strlcpy(dip->label.name, AudioNcd, sizeof dip->label.name); 3006 dip->un.v.num_channels = 2; 3007 strlcpy(dip->un.v.units.name, AudioNvolume, 3008 sizeof dip->un.v.units.name); 3009 break; 3010 3011 case GUSICS_DAC_LVL: /* dacout */ 3012 dip->type = AUDIO_MIXER_VALUE; 3013 dip->mixer_class = GUSICS_INPUT_CLASS; 3014 dip->prev = AUDIO_MIXER_LAST; 3015 dip->next = GUSICS_DAC_MUTE; 3016 strlcpy(dip->label.name, AudioNdac, sizeof dip->label.name); 3017 dip->un.v.num_channels = 2; 3018 strlcpy(dip->un.v.units.name, AudioNvolume, 3019 sizeof dip->un.v.units.name); 3020 break; 3021 3022 case GUSICS_MASTER_LVL: /* master output */ 3023 dip->type = AUDIO_MIXER_VALUE; 3024 dip->mixer_class = GUSICS_OUTPUT_CLASS; 3025 dip->prev = AUDIO_MIXER_LAST; 3026 dip->next = GUSICS_MASTER_MUTE; 3027 strlcpy(dip->label.name, AudioNmaster, sizeof dip->label.name); 3028 dip->un.v.num_channels = 2; 3029 strlcpy(dip->un.v.units.name, AudioNvolume, 3030 sizeof dip->un.v.units.name); 3031 break; 3032 3033 3034 case GUSICS_LINE_IN_MUTE: 3035 dip->mixer_class = GUSICS_INPUT_CLASS; 3036 dip->type = AUDIO_MIXER_ENUM; 3037 dip->prev = GUSICS_LINE_IN_LVL; 3038 dip->next = AUDIO_MIXER_LAST; 3039 goto mute; 3040 3041 case GUSICS_DAC_MUTE: 3042 dip->mixer_class = GUSICS_INPUT_CLASS; 3043 dip->type = AUDIO_MIXER_ENUM; 3044 dip->prev = GUSICS_DAC_LVL; 3045 dip->next = AUDIO_MIXER_LAST; 3046 goto mute; 3047 3048 case GUSICS_CD_MUTE: 3049 dip->mixer_class = GUSICS_INPUT_CLASS; 3050 dip->type = AUDIO_MIXER_ENUM; 3051 dip->prev = GUSICS_CD_LVL; 3052 dip->next = AUDIO_MIXER_LAST; 3053 goto mute; 3054 3055 case GUSICS_MIC_IN_MUTE: 3056 dip->mixer_class = GUSICS_INPUT_CLASS; 3057 dip->type = AUDIO_MIXER_ENUM; 3058 dip->prev = GUSICS_MIC_IN_LVL; 3059 dip->next = AUDIO_MIXER_LAST; 3060 goto mute; 3061 3062 case GUSICS_MASTER_MUTE: 3063 dip->mixer_class = GUSICS_OUTPUT_CLASS; 3064 dip->type = AUDIO_MIXER_ENUM; 3065 dip->prev = GUSICS_MASTER_LVL; 3066 dip->next = AUDIO_MIXER_LAST; 3067 mute: 3068 strlcpy(dip->label.name, AudioNmute, sizeof dip->label.name); 3069 dip->un.e.num_mem = 2; 3070 strlcpy(dip->un.e.member[0].label.name, AudioNoff, 3071 sizeof dip->un.e.member[0].label.name); 3072 dip->un.e.member[0].ord = 0; 3073 strlcpy(dip->un.e.member[1].label.name, AudioNon, 3074 sizeof dip->un.e.member[1].label.name); 3075 dip->un.e.member[1].ord = 1; 3076 break; 3077 3078 case GUSICS_RECORD_SOURCE: 3079 dip->mixer_class = GUSICS_RECORD_CLASS; 3080 dip->type = AUDIO_MIXER_ENUM; 3081 dip->prev = dip->next = AUDIO_MIXER_LAST; 3082 strlcpy(dip->label.name, AudioNsource, sizeof dip->label.name); 3083 dip->un.e.num_mem = 1; 3084 strlcpy(dip->un.e.member[0].label.name, AudioNoutput, 3085 sizeof dip->un.e.member[0].label.name); 3086 dip->un.e.member[0].ord = GUSICS_MASTER_LVL; 3087 break; 3088 3089 case GUSICS_INPUT_CLASS: 3090 dip->type = AUDIO_MIXER_CLASS; 3091 dip->mixer_class = GUSICS_INPUT_CLASS; 3092 dip->next = dip->prev = AUDIO_MIXER_LAST; 3093 strlcpy(dip->label.name, AudioCinputs, sizeof dip->label.name); 3094 break; 3095 3096 case GUSICS_OUTPUT_CLASS: 3097 dip->type = AUDIO_MIXER_CLASS; 3098 dip->mixer_class = GUSICS_OUTPUT_CLASS; 3099 dip->next = dip->prev = AUDIO_MIXER_LAST; 3100 strlcpy(dip->label.name, AudioCoutputs, sizeof dip->label.name); 3101 break; 3102 3103 case GUSICS_RECORD_CLASS: 3104 dip->type = AUDIO_MIXER_CLASS; 3105 dip->mixer_class = GUSICS_RECORD_CLASS; 3106 dip->next = dip->prev = AUDIO_MIXER_LAST; 3107 strlcpy(dip->label.name, AudioCrecord, sizeof dip->label.name); 3108 break; 3109 3110 default: 3111 return ENXIO; 3112 /*NOTREACHED*/ 3113 } 3114 DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name)); 3115 return 0; 3116 } 3117 3118 int 3119 gus_query_encoding(void *addr, struct audio_encoding *fp) 3120 { 3121 switch (fp->index) { 3122 case 0: 3123 strlcpy(fp->name, AudioEslinear, sizeof fp->name); 3124 fp->encoding = AUDIO_ENCODING_SLINEAR; 3125 fp->precision = 8; 3126 fp->flags = 0; 3127 break; 3128 case 1: 3129 strlcpy(fp->name, AudioEslinear_le, sizeof fp->name); 3130 fp->encoding = AUDIO_ENCODING_SLINEAR_LE; 3131 fp->precision = 16; 3132 fp->flags = 0; 3133 break; 3134 case 2: 3135 strlcpy(fp->name, AudioEulinear, sizeof fp->name); 3136 fp->encoding = AUDIO_ENCODING_ULINEAR; 3137 fp->precision = 8; 3138 fp->flags = 0; 3139 break; 3140 case 3: 3141 strlcpy(fp->name, AudioEulinear_le, sizeof fp->name); 3142 fp->encoding = AUDIO_ENCODING_ULINEAR_LE; 3143 fp->precision = 16; 3144 fp->flags = 0; 3145 break; 3146 default: 3147 return(EINVAL); 3148 /*NOTREACHED*/ 3149 } 3150 fp->bps = AUDIO_BPS(fp->precision); 3151 fp->msb = 1; 3152 3153 return (0); 3154 } 3155 3156 void * 3157 gus_malloc(void *addr, int direction, size_t size, int pool, int flags) 3158 { 3159 struct gus_softc *sc = addr; 3160 int drq; 3161 3162 if (direction == AUMODE_PLAY) 3163 drq = sc->sc_drq; 3164 else 3165 drq = sc->sc_recdrq; 3166 3167 return isa_malloc(sc->sc_isa, drq, size, pool, flags); 3168 } 3169 3170 void 3171 gus_free(void *addr, void *ptr, int pool) 3172 { 3173 isa_free(ptr, pool); 3174 } 3175 3176 size_t 3177 gus_round(void *addr, int direction, size_t size) 3178 { 3179 if (size > MAX_ISADMA) 3180 size = MAX_ISADMA; 3181 return size; 3182 } 3183 3184 paddr_t 3185 gus_mappage(void *addr, void *mem, off_t off, int prot) 3186 { 3187 return isa_mappage(mem, off, prot); 3188 } 3189 3190 /* 3191 * Setup the ICS mixer in "transparent" mode: reset everything to a sensible 3192 * level. Levels as suggested by GUS SDK code. 3193 */ 3194 3195 void 3196 gus_init_ics2101(struct gus_softc *sc) 3197 { 3198 struct ics2101_softc *ic = &sc->sc_mixer; 3199 sc->sc_mixer.sc_iot = sc->sc_iot; 3200 sc->sc_mixer.sc_selio = GUS_MIXER_SELECT; 3201 sc->sc_mixer.sc_selio_ioh = sc->sc_ioh3; 3202 sc->sc_mixer.sc_dataio = GUS_MIXER_DATA; 3203 sc->sc_mixer.sc_dataio_ioh = sc->sc_ioh2; 3204 sc->sc_mixer.sc_flags = (sc->sc_revision == 5) ? ICS_FLIP : 0; 3205 3206 ics2101_mix_attenuate(ic, 3207 GUSMIX_CHAN_MIC, 3208 ICSMIX_LEFT, 3209 ICSMIX_MIN_ATTN); 3210 ics2101_mix_attenuate(ic, 3211 GUSMIX_CHAN_MIC, 3212 ICSMIX_RIGHT, 3213 ICSMIX_MIN_ATTN); 3214 /* 3215 * Start with microphone muted by the mixer... 3216 */ 3217 gusics_mic_mute(ic, 1); 3218 3219 /* ... and enabled by the GUS master mix control */ 3220 gus_mic_ctl(sc, SPKR_ON); 3221 3222 ics2101_mix_attenuate(ic, 3223 GUSMIX_CHAN_LINE, 3224 ICSMIX_LEFT, 3225 ICSMIX_MIN_ATTN); 3226 ics2101_mix_attenuate(ic, 3227 GUSMIX_CHAN_LINE, 3228 ICSMIX_RIGHT, 3229 ICSMIX_MIN_ATTN); 3230 3231 ics2101_mix_attenuate(ic, 3232 GUSMIX_CHAN_CD, 3233 ICSMIX_LEFT, 3234 ICSMIX_MIN_ATTN); 3235 ics2101_mix_attenuate(ic, 3236 GUSMIX_CHAN_CD, 3237 ICSMIX_RIGHT, 3238 ICSMIX_MIN_ATTN); 3239 3240 ics2101_mix_attenuate(ic, 3241 GUSMIX_CHAN_DAC, 3242 ICSMIX_LEFT, 3243 ICSMIX_MIN_ATTN); 3244 ics2101_mix_attenuate(ic, 3245 GUSMIX_CHAN_DAC, 3246 ICSMIX_RIGHT, 3247 ICSMIX_MIN_ATTN); 3248 3249 ics2101_mix_attenuate(ic, 3250 ICSMIX_CHAN_4, 3251 ICSMIX_LEFT, 3252 ICSMIX_MAX_ATTN); 3253 ics2101_mix_attenuate(ic, 3254 ICSMIX_CHAN_4, 3255 ICSMIX_RIGHT, 3256 ICSMIX_MAX_ATTN); 3257 3258 ics2101_mix_attenuate(ic, 3259 GUSMIX_CHAN_MASTER, 3260 ICSMIX_LEFT, 3261 ICSMIX_MIN_ATTN); 3262 ics2101_mix_attenuate(ic, 3263 GUSMIX_CHAN_MASTER, 3264 ICSMIX_RIGHT, 3265 ICSMIX_MIN_ATTN); 3266 /* unmute other stuff: */ 3267 gusics_cd_mute(ic, 0); 3268 gusics_dac_mute(ic, 0); 3269 gusics_linein_mute(ic, 0); 3270 return; 3271 } 3272 3273 3274 3275 void 3276 gus_subattach(struct gus_softc *sc, struct isa_attach_args *ia) 3277 { 3278 int i; 3279 bus_space_tag_t iot; 3280 unsigned char c,d,m; 3281 3282 iot = sc->sc_iot; 3283 3284 /* 3285 * Figure out our board rev, and see if we need to initialize the 3286 * mixer 3287 */ 3288 3289 c = bus_space_read_1(iot, sc->sc_ioh3, GUS_BOARD_REV); 3290 if (c != 0xff) 3291 sc->sc_revision = c; 3292 else 3293 sc->sc_revision = 0; 3294 3295 SELECT_GUS_REG(iot, sc->sc_ioh2, GUSREG_RESET); 3296 bus_space_write_1(iot, sc->sc_ioh2, GUS_DATA_HIGH, 0x00); 3297 3298 gusreset(sc, GUS_MAX_VOICES); /* initialize all voices */ 3299 gusreset(sc, GUS_MIN_VOICES); /* then set to just the ones we use */ 3300 3301 /* 3302 * Setup the IRQ and DRQ lines in software, using values from 3303 * config file 3304 */ 3305 3306 m = GUSMASK_LINE_IN|GUSMASK_LINE_OUT; /* disable all */ 3307 3308 c = ((unsigned char) gus_irq_map[ia->ia_irq]) | GUSMASK_BOTH_RQ; 3309 3310 if (sc->sc_recdrq == sc->sc_drq) 3311 d = (unsigned char) (gus_drq_map[sc->sc_drq] | 3312 GUSMASK_BOTH_RQ); 3313 else 3314 d = (unsigned char) (gus_drq_map[sc->sc_drq] | 3315 gus_drq_map[sc->sc_recdrq] << 3); 3316 3317 /* 3318 * Program the IRQ and DMA channels on the GUS. Note that we hardwire 3319 * the GUS to only use one IRQ channel, but we give the user the 3320 * option of using two DMA channels (the other one given by the drq2 3321 * option in the config file). Two DMA channels are needed for full- 3322 * duplex operation. 3323 * 3324 * The order of these operations is very magical. 3325 */ 3326 3327 disable_intr(); /* XXX needed? */ 3328 3329 bus_space_write_1(iot, sc->sc_ioh1, GUS_REG_CONTROL, GUS_REG_IRQCTL); 3330 bus_space_write_1(iot, sc->sc_ioh1, GUS_MIX_CONTROL, m); 3331 bus_space_write_1(iot, sc->sc_ioh1, GUS_IRQCTL_CONTROL, 0x00); 3332 bus_space_write_1(iot, sc->sc_ioh1, 0x0f, 0x00); 3333 3334 bus_space_write_1(iot, sc->sc_ioh1, GUS_MIX_CONTROL, m); 3335 3336 /* magic reset? */ 3337 bus_space_write_1(iot, sc->sc_ioh1, GUS_DMA_CONTROL, d | 0x80); 3338 3339 bus_space_write_1(iot, sc->sc_ioh1, GUS_MIX_CONTROL, 3340 m | GUSMASK_CONTROL_SEL); 3341 bus_space_write_1(iot, sc->sc_ioh1, GUS_IRQ_CONTROL, c); 3342 3343 bus_space_write_1(iot, sc->sc_ioh1, GUS_MIX_CONTROL, m); 3344 bus_space_write_1(iot, sc->sc_ioh1, GUS_DMA_CONTROL, d); 3345 3346 bus_space_write_1(iot, sc->sc_ioh1, GUS_MIX_CONTROL, 3347 m | GUSMASK_CONTROL_SEL); 3348 bus_space_write_1(iot, sc->sc_ioh1, GUS_IRQ_CONTROL, c); 3349 3350 bus_space_write_1(iot, sc->sc_ioh2, GUS_VOICE_SELECT, 0x00); 3351 3352 /* enable line in, line out. leave mic disabled. */ 3353 bus_space_write_1(iot, sc->sc_ioh1, GUS_MIX_CONTROL, 3354 (m | GUSMASK_LATCHES) & ~(GUSMASK_LINE_OUT|GUSMASK_LINE_IN)); 3355 bus_space_write_1(iot, sc->sc_ioh2, GUS_VOICE_SELECT, 0x00); 3356 3357 enable_intr(); 3358 3359 sc->sc_mixcontrol = 3360 (m | GUSMASK_LATCHES) & ~(GUSMASK_LINE_OUT|GUSMASK_LINE_IN); 3361 3362 sc->sc_codec.sc_isa = sc->sc_isa; 3363 3364 if (sc->sc_revision >= 5 && sc->sc_revision <= 9) { 3365 sc->sc_flags |= GUS_MIXER_INSTALLED; 3366 gus_init_ics2101(sc); 3367 } 3368 if (sc->sc_revision < 10 || !gus_init_cs4231(sc)) { 3369 /* Not using the CS4231, so create our DMA maps. */ 3370 if (sc->sc_drq != -1) { 3371 if (isa_dmamap_create(sc->sc_isa, sc->sc_drq, 3372 MAX_ISADMA, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) { 3373 printf("%s: can't create map for drq %d\n", 3374 sc->sc_dev.dv_xname, sc->sc_drq); 3375 return; 3376 } 3377 } 3378 if (sc->sc_recdrq != -1 && sc->sc_recdrq != sc->sc_drq) { 3379 if (isa_dmamap_create(sc->sc_isa, sc->sc_recdrq, 3380 MAX_ISADMA, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) { 3381 printf("%s: can't create map for drq %d\n", 3382 sc->sc_dev.dv_xname, sc->sc_recdrq); 3383 return; 3384 } 3385 } 3386 } 3387 3388 timeout_set(&sc->sc_dma_tmo, gus_dmaout_timeout, sc); 3389 3390 SELECT_GUS_REG(iot, sc->sc_ioh2, GUSREG_RESET); 3391 /* 3392 * Check to see how much memory we have on this card; see if any 3393 * "mirroring" occurs. We're assuming at least 256K already exists 3394 * on the card; otherwise the initial probe would have failed 3395 */ 3396 3397 guspoke(iot, sc->sc_ioh2, 0L, 0x00); 3398 for(i = 1; i < 1024; i++) { 3399 u_long loc; 3400 3401 /* 3402 * See if we've run into mirroring yet 3403 */ 3404 3405 if (guspeek(iot, sc->sc_ioh2, 0L) != 0) 3406 break; 3407 3408 loc = i << 10; 3409 3410 guspoke(iot, sc->sc_ioh2, loc, 0xaa); 3411 if (guspeek(iot, sc->sc_ioh2, loc) != 0xaa) 3412 break; 3413 } 3414 3415 sc->sc_dsize = i; 3416 /* 3417 * The "official" (3.x) version number cannot easily be obtained. 3418 * The revision register does not correspond to the minor number 3419 * of the board version. Simply use the revision register as 3420 * identification. 3421 */ 3422 snprintf(gus_device.version, sizeof gus_device.version, "%d", 3423 sc->sc_revision); 3424 3425 printf(": ver %d", sc->sc_revision); 3426 if (sc->sc_revision >= 10) 3427 printf(", MAX"); 3428 else { 3429 if (HAS_MIXER(sc)) 3430 printf(", ICS2101 mixer"); 3431 if (HAS_CODEC(sc)) 3432 printf(", %s codec/mixer", sc->sc_codec.chip_name); 3433 } 3434 printf(", %dKB DRAM, ", sc->sc_dsize); 3435 if (sc->sc_recdrq == sc->sc_drq) { 3436 printf("half-duplex"); 3437 } else { 3438 printf("full-duplex, record drq %d", sc->sc_recdrq); 3439 } 3440 3441 printf("\n"); 3442 3443 /* 3444 * Setup a default interrupt handler 3445 */ 3446 3447 sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq, 3448 IST_EDGE, IPL_AUDIO | IPL_MPSAFE, 3449 gusintr, sc /* sc->sc_gusdsp */, sc->sc_dev.dv_xname); 3450 3451 /* 3452 * Set some default values 3453 * XXX others start with 8kHz mono mulaw 3454 */ 3455 3456 sc->sc_irate = sc->sc_orate = 44100; 3457 sc->sc_encoding = AUDIO_ENCODING_SLINEAR_LE; 3458 sc->sc_precision = 16; 3459 sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_DATA_SIZE16; 3460 sc->sc_voc[GUS_VOICE_RIGHT].voccntl |= GUSMASK_DATA_SIZE16; 3461 sc->sc_channels = 1; 3462 sc->sc_ogain = 340; 3463 gus_commit_settings(sc); 3464 3465 /* 3466 * We always put the left channel full left & right channel 3467 * full right. 3468 * For mono playback, we set up both voices playing the same buffer. 3469 */ 3470 bus_space_write_1(iot, sc->sc_ioh2, GUS_VOICE_SELECT, 3471 (u_char)GUS_VOICE_LEFT); 3472 SELECT_GUS_REG(iot, sc->sc_ioh2, GUSREG_PAN_POS); 3473 bus_space_write_1(iot, sc->sc_ioh2, GUS_DATA_HIGH, GUS_PAN_FULL_LEFT); 3474 3475 bus_space_write_1(iot, sc->sc_ioh2, GUS_VOICE_SELECT, 3476 (u_char)GUS_VOICE_RIGHT); 3477 SELECT_GUS_REG(iot, sc->sc_ioh2, GUSREG_PAN_POS); 3478 bus_space_write_1(iot, sc->sc_ioh2, GUS_DATA_HIGH, GUS_PAN_FULL_RIGHT); 3479 3480 /* 3481 * Attach to the generic audio layer 3482 */ 3483 3484 audio_attach_mi(&gus_hw_if, HAS_CODEC(sc) ? (void *)&sc->sc_codec : 3485 (void *)sc, &sc->sc_dev); 3486 } 3487 3488 /* 3489 * Test to see if a particular I/O base is valid for the GUS. Return true 3490 * if it is. 3491 */ 3492 3493 int 3494 gus_test_iobase (bus_space_tag_t iot, int iobase) 3495 { 3496 bus_space_handle_t ioh1, ioh2, ioh3, ioh4; 3497 u_char s1, s2; 3498 int rv = 0; 3499 3500 /* Map i/o space */ 3501 if (bus_space_map(iot, iobase, GUS_NPORT1, 0, &ioh1)) 3502 return 0; 3503 if (bus_space_map(iot, iobase+GUS_IOH2_OFFSET, GUS_NPORT2, 0, &ioh2)) 3504 goto bad1; 3505 3506 /* XXX Maybe we shouldn't fail on mapping this, but just assume 3507 * the card is of revision 0? */ 3508 if (bus_space_map(iot, iobase+GUS_IOH3_OFFSET, GUS_NPORT3, 0, &ioh3)) 3509 goto bad2; 3510 3511 if (bus_space_map(iot, iobase+GUS_IOH4_OFFSET, GUS_NPORT4, 0, &ioh4)) 3512 goto bad3; 3513 3514 /* 3515 * Reset GUS to an initial state before we do anything. 3516 */ 3517 3518 mtx_enter(&audio_lock); 3519 delay(500); 3520 3521 SELECT_GUS_REG(iot, ioh2, GUSREG_RESET); 3522 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00); 3523 3524 delay(500); 3525 3526 SELECT_GUS_REG(iot, ioh2, GUSREG_RESET); 3527 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, GUSMASK_MASTER_RESET); 3528 3529 delay(500); 3530 3531 mtx_leave(&audio_lock); 3532 3533 /* 3534 * See if we can write to the board's memory 3535 */ 3536 3537 s1 = guspeek(iot, ioh2, 0L); 3538 s2 = guspeek(iot, ioh2, 1L); 3539 3540 guspoke(iot, ioh2, 0L, 0xaa); 3541 guspoke(iot, ioh2, 1L, 0x55); 3542 3543 if (guspeek(iot, ioh2, 0L) != 0xaa) 3544 goto bad; 3545 3546 guspoke(iot, ioh2, 0L, s1); 3547 guspoke(iot, ioh2, 1L, s2); 3548 3549 rv = 1; 3550 3551 bad: 3552 bus_space_unmap(iot, ioh4, GUS_NPORT4); 3553 bad3: 3554 bus_space_unmap(iot, ioh3, GUS_NPORT3); 3555 bad2: 3556 bus_space_unmap(iot, ioh2, GUS_NPORT2); 3557 bad1: 3558 bus_space_unmap(iot, ioh1, GUS_NPORT1); 3559 return rv; 3560 } 3561