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