1 /* $OpenBSD: gus.c,v 1.34 2010/07/15 03:43:11 jakemsr 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 2079 */ 2080 2081 bus_space_write_1(iot, ioh4, GUS_MIDI_CONTROL, MIDI_RESET); 2082 2083 delay(500); 2084 2085 bus_space_write_1(iot, ioh4, GUS_MIDI_CONTROL, 0x00); 2086 2087 /* 2088 * Clear interrupts 2089 */ 2090 2091 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL); 2092 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00); 2093 SELECT_GUS_REG(iot, ioh2, GUSREG_TIMER_CONTROL); 2094 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00); 2095 SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL); 2096 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00); 2097 2098 gus_set_voices(sc, voices); 2099 2100 bus_space_read_1(iot, ioh1, GUS_IRQ_STATUS); 2101 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL); 2102 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH); 2103 SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL); 2104 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH); 2105 SELECT_GUS_REG(iot, ioh2, GUSREG_IRQ_STATUS); 2106 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH); 2107 2108 /* 2109 * Reset voice specific information 2110 */ 2111 2112 for(i = 0; i < voices; i++) { 2113 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) i); 2114 2115 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL); 2116 2117 sc->sc_voc[i].voccntl = GUSMASK_VOICE_STOPPED | 2118 GUSMASK_STOP_VOICE; 2119 2120 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[i].voccntl); 2121 2122 sc->sc_voc[i].volcntl = GUSMASK_VOLUME_STOPPED | 2123 GUSMASK_STOP_VOLUME; 2124 2125 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL); 2126 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[i].volcntl); 2127 2128 delay(100); 2129 2130 gus_set_samprate(sc, i, 8000); 2131 SELECT_GUS_REG(iot, ioh2, GUSREG_START_ADDR_HIGH); 2132 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000); 2133 SELECT_GUS_REG(iot, ioh2, GUSREG_START_ADDR_LOW); 2134 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000); 2135 SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_HIGH); 2136 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000); 2137 SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_LOW); 2138 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000); 2139 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_RATE); 2140 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x01); 2141 SELECT_GUS_REG(iot, ioh2, GUSREG_START_VOLUME); 2142 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x10); 2143 SELECT_GUS_REG(iot, ioh2, GUSREG_END_VOLUME); 2144 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0xe0); 2145 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME); 2146 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000); 2147 2148 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH); 2149 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000); 2150 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW); 2151 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000); 2152 SELECT_GUS_REG(iot, ioh2, GUSREG_PAN_POS); 2153 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x07); 2154 } 2155 2156 /* 2157 * Clear out any pending IRQs 2158 */ 2159 2160 bus_space_read_1(iot, ioh1, GUS_IRQ_STATUS); 2161 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL); 2162 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH); 2163 SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL); 2164 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH); 2165 SELECT_GUS_REG(iot, ioh2, GUSREG_IRQ_STATUS); 2166 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH); 2167 2168 SELECT_GUS_REG(iot, ioh2, GUSREG_RESET); 2169 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, GUSMASK_MASTER_RESET | GUSMASK_DAC_ENABLE | 2170 GUSMASK_IRQ_ENABLE); 2171 2172 splx(s); 2173 } 2174 2175 2176 int 2177 gus_init_cs4231(sc) 2178 struct gus_softc *sc; 2179 { 2180 bus_space_tag_t iot = sc->sc_iot; 2181 bus_space_handle_t ioh1 = sc->sc_ioh1; 2182 int port = sc->sc_iobase; 2183 u_char ctrl; 2184 2185 ctrl = (port & 0xf0) >> 4; /* set port address middle nibble */ 2186 /* 2187 * The codec is a bit weird--swapped dma channels. 2188 */ 2189 ctrl |= GUS_MAX_CODEC_ENABLE; 2190 if (sc->sc_drq >= 4) 2191 ctrl |= GUS_MAX_RECCHAN16; 2192 if (sc->sc_recdrq >= 4) 2193 ctrl |= GUS_MAX_PLAYCHAN16; 2194 2195 bus_space_write_1(iot, ioh1, GUS_MAX_CTRL, ctrl); 2196 2197 sc->sc_codec.sc_iot = sc->sc_iot; 2198 sc->sc_codec.sc_iobase = port+GUS_MAX_CODEC_BASE; 2199 2200 if (ad1848_mapprobe(&sc->sc_codec, sc->sc_codec.sc_iobase) == 0) { 2201 sc->sc_flags &= ~GUS_CODEC_INSTALLED; 2202 return (0); 2203 } else { 2204 struct ad1848_volume vol = {AUDIO_MAX_GAIN, AUDIO_MAX_GAIN}; 2205 sc->sc_flags |= GUS_CODEC_INSTALLED; 2206 sc->sc_codec.parent = sc; 2207 sc->sc_codec.sc_drq = sc->sc_recdrq; 2208 sc->sc_codec.sc_recdrq = sc->sc_drq; 2209 gus_hw_if = gusmax_hw_if; 2210 /* enable line in and mic in the GUS mixer; the codec chip 2211 will do the real mixing for them. */ 2212 sc->sc_mixcontrol &= ~GUSMASK_LINE_IN; /* 0 enables. */ 2213 sc->sc_mixcontrol |= GUSMASK_MIC_IN; /* 1 enables. */ 2214 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol); 2215 2216 ad1848_attach(&sc->sc_codec); 2217 /* turn on pre-MUX microphone gain. */ 2218 ad1848_set_mic_gain(&sc->sc_codec, &vol); 2219 2220 return (1); 2221 } 2222 } 2223 2224 2225 /* 2226 * Return info about the audio device, for the AUDIO_GETINFO ioctl 2227 */ 2228 2229 int 2230 gus_getdev(addr, dev) 2231 void * addr; 2232 struct audio_device *dev; 2233 { 2234 *dev = gus_device; 2235 return 0; 2236 } 2237 2238 /* 2239 * stubs (XXX) 2240 */ 2241 2242 int 2243 gus_set_in_gain(addr, gain, balance) 2244 caddr_t addr; 2245 u_int gain; 2246 u_char balance; 2247 { 2248 DPRINTF(("gus_set_in_gain called\n")); 2249 return 0; 2250 } 2251 2252 int 2253 gus_get_in_gain(addr) 2254 caddr_t addr; 2255 { 2256 DPRINTF(("gus_get_in_gain called\n")); 2257 return 0; 2258 } 2259 2260 int 2261 gusmax_dma_input(addr, buf, size, callback, arg) 2262 void * addr; 2263 void *buf; 2264 int size; 2265 void (*callback)(void *); 2266 void *arg; 2267 { 2268 struct ad1848_softc *sc = addr; 2269 return gus_dma_input(sc->parent, buf, size, callback, arg); 2270 } 2271 2272 /* 2273 * Start sampling the input source into the requested DMA buffer. 2274 * Called at splgus(), either from top-half or from interrupt handler. 2275 */ 2276 int 2277 gus_dma_input(addr, buf, size, callback, arg) 2278 void * addr; 2279 void *buf; 2280 int size; 2281 void (*callback)(void *); 2282 void *arg; 2283 { 2284 struct gus_softc *sc = addr; 2285 bus_space_tag_t iot = sc->sc_iot; 2286 bus_space_handle_t ioh2 = sc->sc_ioh2; 2287 u_char dmac; 2288 DMAPRINTF(("gus_dma_input called\n")); 2289 2290 /* 2291 * Sample SIZE bytes of data from the card, into buffer at BUF. 2292 */ 2293 2294 if (sc->sc_precision == 16) 2295 return EINVAL; /* XXX */ 2296 2297 /* set DMA modes */ 2298 dmac = GUSMASK_SAMPLE_IRQ|GUSMASK_SAMPLE_START; 2299 if (sc->sc_recdrq >= 4) 2300 dmac |= GUSMASK_SAMPLE_DATA16; 2301 if (sc->sc_encoding == AUDIO_ENCODING_ULAW || 2302 sc->sc_encoding == AUDIO_ENCODING_ALAW || 2303 sc->sc_encoding == AUDIO_ENCODING_ULINEAR_LE || 2304 sc->sc_encoding == AUDIO_ENCODING_ULINEAR_BE) 2305 dmac |= GUSMASK_SAMPLE_INVBIT; 2306 if (sc->sc_channels == 2) 2307 dmac |= GUSMASK_SAMPLE_STEREO; 2308 isa_dmastart(sc->sc_dev.dv_parent, sc->sc_recdrq, buf, size, 2309 NULL, DMAMODE_READ, BUS_DMA_NOWAIT); 2310 2311 DMAPRINTF(("gus_dma_input isadma_started\n")); 2312 sc->sc_flags |= GUS_DMAIN_ACTIVE; 2313 sc->sc_dmainintr = callback; 2314 sc->sc_inarg = arg; 2315 sc->sc_dmaincnt = size; 2316 sc->sc_dmainaddr = buf; 2317 2318 SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL); 2319 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, dmac); /* Go! */ 2320 2321 2322 DMAPRINTF(("gus_dma_input returning\n")); 2323 2324 return 0; 2325 } 2326 2327 int 2328 gus_dmain_intr(sc) 2329 struct gus_softc *sc; 2330 { 2331 void (*callback)(void *); 2332 void *arg; 2333 2334 DMAPRINTF(("gus_dmain_intr called\n")); 2335 if (sc->sc_dmainintr) { 2336 isa_dmadone(sc->sc_dev.dv_parent, sc->sc_recdrq); 2337 callback = sc->sc_dmainintr; 2338 arg = sc->sc_inarg; 2339 2340 sc->sc_dmainaddr = 0; 2341 sc->sc_dmaincnt = 0; 2342 sc->sc_dmainintr = 0; 2343 sc->sc_inarg = 0; 2344 2345 sc->sc_flags &= ~GUS_DMAIN_ACTIVE; 2346 DMAPRINTF(("calling dmain_intr callback %p(%p)\n", callback, arg)); 2347 (*callback)(arg); 2348 return 1; 2349 } else { 2350 DMAPRINTF(("gus_dmain_intr false?\n")); 2351 return 0; /* XXX ??? */ 2352 } 2353 } 2354 2355 int 2356 gusmax_halt_out_dma(addr) 2357 void * addr; 2358 { 2359 struct ad1848_softc *sc = addr; 2360 return gus_halt_out_dma(sc->parent); 2361 } 2362 2363 2364 int 2365 gusmax_halt_in_dma(addr) 2366 void * addr; 2367 { 2368 struct ad1848_softc *sc = addr; 2369 return gus_halt_in_dma(sc->parent); 2370 } 2371 2372 /* 2373 * Stop any DMA output. Called at splgus(). 2374 */ 2375 int 2376 gus_halt_out_dma(addr) 2377 void * addr; 2378 { 2379 struct gus_softc *sc = addr; 2380 bus_space_tag_t iot = sc->sc_iot; 2381 bus_space_handle_t ioh2 = sc->sc_ioh2; 2382 2383 DMAPRINTF(("gus_halt_out_dma called\n")); 2384 /* 2385 * Make sure the GUS _isn't_ setup for DMA 2386 */ 2387 2388 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL); 2389 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0); 2390 2391 timeout_del(&sc->sc_dma_tmo); 2392 isa_dmaabort(sc->sc_dev.dv_parent, sc->sc_drq); 2393 sc->sc_flags &= ~(GUS_DMAOUT_ACTIVE|GUS_LOCKED); 2394 sc->sc_dmaoutintr = 0; 2395 sc->sc_outarg = 0; 2396 sc->sc_dmaoutaddr = 0; 2397 sc->sc_dmaoutcnt = 0; 2398 sc->sc_dmabuf = 0; 2399 sc->sc_bufcnt = 0; 2400 sc->sc_playbuf = -1; 2401 /* also stop playing */ 2402 gus_stop_voice(sc, GUS_VOICE_LEFT, 1); 2403 gus_stop_voice(sc, GUS_VOICE_RIGHT, 0); 2404 2405 return 0; 2406 } 2407 2408 /* 2409 * Stop any DMA output. Called at splgus(). 2410 */ 2411 int 2412 gus_halt_in_dma(addr) 2413 void * addr; 2414 { 2415 struct gus_softc *sc = addr; 2416 bus_space_tag_t iot = sc->sc_iot; 2417 bus_space_handle_t ioh2 = sc->sc_ioh2; 2418 DMAPRINTF(("gus_halt_in_dma called\n")); 2419 2420 /* 2421 * Make sure the GUS _isn't_ setup for DMA 2422 */ 2423 2424 SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL); 2425 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 2426 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH) & ~(GUSMASK_SAMPLE_START|GUSMASK_SAMPLE_IRQ)); 2427 2428 isa_dmaabort(sc->sc_dev.dv_parent, sc->sc_recdrq); 2429 sc->sc_flags &= ~GUS_DMAIN_ACTIVE; 2430 sc->sc_dmainintr = 0; 2431 sc->sc_inarg = 0; 2432 sc->sc_dmainaddr = 0; 2433 sc->sc_dmaincnt = 0; 2434 2435 return 0; 2436 } 2437 2438 2439 ad1848_devmap_t gusmapping[] = { 2440 {GUSMAX_DAC_LVL, AD1848_KIND_LVL, AD1848_AUX1_CHANNEL}, 2441 {GUSMAX_LINE_IN_LVL, AD1848_KIND_LVL, AD1848_LINE_CHANNEL}, 2442 {GUSMAX_MONO_LVL, AD1848_KIND_LVL, AD1848_MONO_CHANNEL}, 2443 {GUSMAX_CD_LVL, AD1848_KIND_LVL, AD1848_AUX2_CHANNEL}, 2444 {GUSMAX_MONITOR_LVL, AD1848_KIND_LVL, AD1848_MONITOR_CHANNEL}, 2445 {GUSMAX_OUT_LVL, AD1848_KIND_LVL, AD1848_DAC_CHANNEL}, 2446 {GUSMAX_DAC_MUTE, AD1848_KIND_MUTE, AD1848_AUX1_CHANNEL}, 2447 {GUSMAX_LINE_IN_MUTE, AD1848_KIND_MUTE, AD1848_LINE_CHANNEL}, 2448 {GUSMAX_MONO_MUTE, AD1848_KIND_MUTE, AD1848_MONO_CHANNEL}, 2449 {GUSMAX_CD_MUTE, AD1848_KIND_MUTE, AD1848_AUX2_CHANNEL}, 2450 {GUSMAX_MONITOR_MUTE, AD1848_KIND_MUTE, AD1848_MONITOR_CHANNEL}, 2451 {GUSMAX_REC_LVL, AD1848_KIND_RECORDGAIN, -1}, 2452 {GUSMAX_RECORD_SOURCE, AD1848_KIND_RECORDSOURCE, -1} 2453 }; 2454 2455 int nummap = sizeof(gusmapping) / sizeof(gusmapping[0]); 2456 2457 int 2458 gusmax_mixer_get_port(addr, cp) 2459 void *addr; 2460 mixer_ctrl_t *cp; 2461 { 2462 struct ad1848_softc *ac = addr; 2463 struct gus_softc *sc = ac->parent; 2464 struct ad1848_volume vol; 2465 int error = ad1848_mixer_get_port(ac, gusmapping, nummap, cp); 2466 2467 if (error != ENXIO) 2468 return (error); 2469 2470 error = EINVAL; 2471 2472 switch (cp->dev) { 2473 case GUSMAX_SPEAKER_LVL: /* fake speaker for mute naming */ 2474 if (cp->type == AUDIO_MIXER_VALUE) { 2475 if (sc->sc_mixcontrol & GUSMASK_LINE_OUT) 2476 vol.left = vol.right = AUDIO_MAX_GAIN; 2477 else 2478 vol.left = vol.right = AUDIO_MIN_GAIN; 2479 error = 0; 2480 ad1848_from_vol(cp, &vol); 2481 } 2482 break; 2483 2484 case GUSMAX_SPEAKER_MUTE: 2485 if (cp->type == AUDIO_MIXER_ENUM) { 2486 cp->un.ord = sc->sc_mixcontrol & GUSMASK_LINE_OUT ? 1 : 0; 2487 error = 0; 2488 } 2489 break; 2490 default: 2491 error = ENXIO; 2492 break; 2493 } 2494 2495 return(error); 2496 } 2497 2498 int 2499 gus_mixer_get_port(addr, cp) 2500 void *addr; 2501 mixer_ctrl_t *cp; 2502 { 2503 struct gus_softc *sc = addr; 2504 struct ics2101_softc *ic = &sc->sc_mixer; 2505 struct ad1848_volume vol; 2506 int error = EINVAL; 2507 2508 DPRINTF(("gus_mixer_get_port: dev=%d type=%d\n", cp->dev, cp->type)); 2509 2510 if (!HAS_MIXER(sc) && cp->dev > GUSICS_MASTER_MUTE) 2511 return ENXIO; 2512 2513 switch (cp->dev) { 2514 2515 case GUSICS_MIC_IN_MUTE: /* Microphone */ 2516 if (cp->type == AUDIO_MIXER_ENUM) { 2517 if (HAS_MIXER(sc)) 2518 cp->un.ord = ic->sc_mute[GUSMIX_CHAN_MIC][ICSMIX_LEFT]; 2519 else 2520 cp->un.ord = 2521 sc->sc_mixcontrol & GUSMASK_MIC_IN ? 0 : 1; 2522 error = 0; 2523 } 2524 break; 2525 2526 case GUSICS_LINE_IN_MUTE: 2527 if (cp->type == AUDIO_MIXER_ENUM) { 2528 if (HAS_MIXER(sc)) 2529 cp->un.ord = ic->sc_mute[GUSMIX_CHAN_LINE][ICSMIX_LEFT]; 2530 else 2531 cp->un.ord = 2532 sc->sc_mixcontrol & GUSMASK_LINE_IN ? 1 : 0; 2533 error = 0; 2534 } 2535 break; 2536 2537 case GUSICS_MASTER_MUTE: 2538 if (cp->type == AUDIO_MIXER_ENUM) { 2539 if (HAS_MIXER(sc)) 2540 cp->un.ord = ic->sc_mute[GUSMIX_CHAN_MASTER][ICSMIX_LEFT]; 2541 else 2542 cp->un.ord = 2543 sc->sc_mixcontrol & GUSMASK_LINE_OUT ? 1 : 0; 2544 error = 0; 2545 } 2546 break; 2547 2548 case GUSICS_DAC_MUTE: 2549 if (cp->type == AUDIO_MIXER_ENUM) { 2550 cp->un.ord = ic->sc_mute[GUSMIX_CHAN_DAC][ICSMIX_LEFT]; 2551 error = 0; 2552 } 2553 break; 2554 2555 case GUSICS_CD_MUTE: 2556 if (cp->type == AUDIO_MIXER_ENUM) { 2557 cp->un.ord = ic->sc_mute[GUSMIX_CHAN_CD][ICSMIX_LEFT]; 2558 error = 0; 2559 } 2560 break; 2561 2562 case GUSICS_MASTER_LVL: 2563 if (cp->type == AUDIO_MIXER_VALUE) { 2564 vol.left = ic->sc_setting[GUSMIX_CHAN_MASTER][ICSMIX_LEFT]; 2565 vol.right = ic->sc_setting[GUSMIX_CHAN_MASTER][ICSMIX_RIGHT]; 2566 if (ad1848_from_vol(cp, &vol)) 2567 error = 0; 2568 } 2569 break; 2570 2571 case GUSICS_MIC_IN_LVL: /* Microphone */ 2572 if (cp->type == AUDIO_MIXER_VALUE) { 2573 vol.left = ic->sc_setting[GUSMIX_CHAN_MIC][ICSMIX_LEFT]; 2574 vol.right = ic->sc_setting[GUSMIX_CHAN_MIC][ICSMIX_RIGHT]; 2575 if (ad1848_from_vol(cp, &vol)) 2576 error = 0; 2577 } 2578 break; 2579 2580 case GUSICS_LINE_IN_LVL: /* line in */ 2581 if (cp->type == AUDIO_MIXER_VALUE) { 2582 vol.left = ic->sc_setting[GUSMIX_CHAN_LINE][ICSMIX_LEFT]; 2583 vol.right = ic->sc_setting[GUSMIX_CHAN_LINE][ICSMIX_RIGHT]; 2584 if (ad1848_from_vol(cp, &vol)) 2585 error = 0; 2586 } 2587 break; 2588 2589 2590 case GUSICS_CD_LVL: 2591 if (cp->type == AUDIO_MIXER_VALUE) { 2592 vol.left = ic->sc_setting[GUSMIX_CHAN_CD][ICSMIX_LEFT]; 2593 vol.right = ic->sc_setting[GUSMIX_CHAN_CD][ICSMIX_RIGHT]; 2594 if (ad1848_from_vol(cp, &vol)) 2595 error = 0; 2596 } 2597 break; 2598 2599 case GUSICS_DAC_LVL: /* dac out */ 2600 if (cp->type == AUDIO_MIXER_VALUE) { 2601 vol.left = ic->sc_setting[GUSMIX_CHAN_DAC][ICSMIX_LEFT]; 2602 vol.right = ic->sc_setting[GUSMIX_CHAN_DAC][ICSMIX_RIGHT]; 2603 if (ad1848_from_vol(cp, &vol)) 2604 error = 0; 2605 } 2606 break; 2607 2608 2609 case GUSICS_RECORD_SOURCE: 2610 if (cp->type == AUDIO_MIXER_ENUM) { 2611 /* Can't set anything else useful, sigh. */ 2612 cp->un.ord = 0; 2613 } 2614 break; 2615 2616 default: 2617 return ENXIO; 2618 /*NOTREACHED*/ 2619 } 2620 return error; 2621 } 2622 2623 void 2624 gusics_master_mute(ic, mute) 2625 struct ics2101_softc *ic; 2626 int mute; 2627 { 2628 ics2101_mix_mute(ic, GUSMIX_CHAN_MASTER, ICSMIX_LEFT, mute); 2629 ics2101_mix_mute(ic, GUSMIX_CHAN_MASTER, ICSMIX_RIGHT, mute); 2630 } 2631 2632 void 2633 gusics_mic_mute(ic, mute) 2634 struct ics2101_softc *ic; 2635 int mute; 2636 { 2637 ics2101_mix_mute(ic, GUSMIX_CHAN_MIC, ICSMIX_LEFT, mute); 2638 ics2101_mix_mute(ic, GUSMIX_CHAN_MIC, ICSMIX_RIGHT, mute); 2639 } 2640 2641 void 2642 gusics_linein_mute(ic, mute) 2643 struct ics2101_softc *ic; 2644 int mute; 2645 { 2646 ics2101_mix_mute(ic, GUSMIX_CHAN_LINE, ICSMIX_LEFT, mute); 2647 ics2101_mix_mute(ic, GUSMIX_CHAN_LINE, ICSMIX_RIGHT, mute); 2648 } 2649 2650 void 2651 gusics_cd_mute(ic, mute) 2652 struct ics2101_softc *ic; 2653 int mute; 2654 { 2655 ics2101_mix_mute(ic, GUSMIX_CHAN_CD, ICSMIX_LEFT, mute); 2656 ics2101_mix_mute(ic, GUSMIX_CHAN_CD, ICSMIX_RIGHT, mute); 2657 } 2658 2659 void 2660 gusics_dac_mute(ic, mute) 2661 struct ics2101_softc *ic; 2662 int mute; 2663 { 2664 ics2101_mix_mute(ic, GUSMIX_CHAN_DAC, ICSMIX_LEFT, mute); 2665 ics2101_mix_mute(ic, GUSMIX_CHAN_DAC, ICSMIX_RIGHT, mute); 2666 } 2667 2668 int 2669 gusmax_mixer_set_port(addr, cp) 2670 void *addr; 2671 mixer_ctrl_t *cp; 2672 { 2673 struct ad1848_softc *ac = addr; 2674 struct gus_softc *sc = ac->parent; 2675 struct ad1848_volume vol; 2676 int error = ad1848_mixer_set_port(ac, gusmapping, nummap, cp); 2677 2678 if (error != ENXIO) 2679 return (error); 2680 2681 DPRINTF(("gusmax_mixer_set_port: dev=%d type=%d\n", cp->dev, cp->type)); 2682 2683 switch (cp->dev) { 2684 case GUSMAX_SPEAKER_LVL: 2685 if (cp->type == AUDIO_MIXER_VALUE && 2686 cp->un.value.num_channels == 1) { 2687 if (ad1848_to_vol(cp, &vol)) { 2688 gus_speaker_ctl(sc, vol.left > AUDIO_MIN_GAIN ? 2689 SPKR_ON : SPKR_OFF); 2690 error = 0; 2691 } 2692 } 2693 break; 2694 2695 case GUSMAX_SPEAKER_MUTE: 2696 if (cp->type == AUDIO_MIXER_ENUM) { 2697 gus_speaker_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON); 2698 error = 0; 2699 } 2700 break; 2701 2702 default: 2703 return ENXIO; 2704 /*NOTREACHED*/ 2705 } 2706 return error; 2707 } 2708 2709 int 2710 gus_mixer_set_port(addr, cp) 2711 void *addr; 2712 mixer_ctrl_t *cp; 2713 { 2714 struct gus_softc *sc = addr; 2715 struct ics2101_softc *ic = &sc->sc_mixer; 2716 struct ad1848_volume vol; 2717 int error = EINVAL; 2718 2719 DPRINTF(("gus_mixer_set_port: dev=%d type=%d\n", cp->dev, cp->type)); 2720 2721 if (!HAS_MIXER(sc) && cp->dev > GUSICS_MASTER_MUTE) 2722 return ENXIO; 2723 2724 switch (cp->dev) { 2725 2726 case GUSICS_MIC_IN_MUTE: /* Microphone */ 2727 if (cp->type == AUDIO_MIXER_ENUM) { 2728 DPRINTF(("mic mute %d\n", cp->un.ord)); 2729 if (HAS_MIXER(sc)) { 2730 gusics_mic_mute(ic, cp->un.ord); 2731 } 2732 gus_mic_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON); 2733 error = 0; 2734 } 2735 break; 2736 2737 case GUSICS_LINE_IN_MUTE: 2738 if (cp->type == AUDIO_MIXER_ENUM) { 2739 DPRINTF(("linein mute %d\n", cp->un.ord)); 2740 if (HAS_MIXER(sc)) { 2741 gusics_linein_mute(ic, cp->un.ord); 2742 } 2743 gus_linein_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON); 2744 error = 0; 2745 } 2746 break; 2747 2748 case GUSICS_MASTER_MUTE: 2749 if (cp->type == AUDIO_MIXER_ENUM) { 2750 DPRINTF(("master mute %d\n", cp->un.ord)); 2751 if (HAS_MIXER(sc)) { 2752 gusics_master_mute(ic, cp->un.ord); 2753 } 2754 gus_speaker_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON); 2755 error = 0; 2756 } 2757 break; 2758 2759 case GUSICS_DAC_MUTE: 2760 if (cp->type == AUDIO_MIXER_ENUM) { 2761 gusics_dac_mute(ic, cp->un.ord); 2762 error = 0; 2763 } 2764 break; 2765 2766 case GUSICS_CD_MUTE: 2767 if (cp->type == AUDIO_MIXER_ENUM) { 2768 gusics_cd_mute(ic, cp->un.ord); 2769 error = 0; 2770 } 2771 break; 2772 2773 case GUSICS_MASTER_LVL: 2774 if (cp->type == AUDIO_MIXER_VALUE) { 2775 if (ad1848_to_vol(cp, &vol)) { 2776 ics2101_mix_attenuate(ic, 2777 GUSMIX_CHAN_MASTER, 2778 ICSMIX_LEFT, 2779 vol.left); 2780 ics2101_mix_attenuate(ic, 2781 GUSMIX_CHAN_MASTER, 2782 ICSMIX_RIGHT, 2783 vol.right); 2784 error = 0; 2785 } 2786 } 2787 break; 2788 2789 case GUSICS_MIC_IN_LVL: /* Microphone */ 2790 if (cp->type == AUDIO_MIXER_VALUE) { 2791 if (ad1848_to_vol(cp, &vol)) { 2792 ics2101_mix_attenuate(ic, 2793 GUSMIX_CHAN_MIC, 2794 ICSMIX_LEFT, 2795 vol.left); 2796 ics2101_mix_attenuate(ic, 2797 GUSMIX_CHAN_MIC, 2798 ICSMIX_RIGHT, 2799 vol.right); 2800 error = 0; 2801 } 2802 } 2803 break; 2804 2805 case GUSICS_LINE_IN_LVL: /* line in */ 2806 if (cp->type == AUDIO_MIXER_VALUE) { 2807 if (ad1848_to_vol(cp, &vol)) { 2808 ics2101_mix_attenuate(ic, 2809 GUSMIX_CHAN_LINE, 2810 ICSMIX_LEFT, 2811 vol.left); 2812 ics2101_mix_attenuate(ic, 2813 GUSMIX_CHAN_LINE, 2814 ICSMIX_RIGHT, 2815 vol.right); 2816 error = 0; 2817 } 2818 } 2819 break; 2820 2821 2822 case GUSICS_CD_LVL: 2823 if (cp->type == AUDIO_MIXER_VALUE) { 2824 if (ad1848_to_vol(cp, &vol)) { 2825 ics2101_mix_attenuate(ic, 2826 GUSMIX_CHAN_CD, 2827 ICSMIX_LEFT, 2828 vol.left); 2829 ics2101_mix_attenuate(ic, 2830 GUSMIX_CHAN_CD, 2831 ICSMIX_RIGHT, 2832 vol.right); 2833 error = 0; 2834 } 2835 } 2836 break; 2837 2838 case GUSICS_DAC_LVL: /* dac out */ 2839 if (cp->type == AUDIO_MIXER_VALUE) { 2840 if (ad1848_to_vol(cp, &vol)) { 2841 ics2101_mix_attenuate(ic, 2842 GUSMIX_CHAN_DAC, 2843 ICSMIX_LEFT, 2844 vol.left); 2845 ics2101_mix_attenuate(ic, 2846 GUSMIX_CHAN_DAC, 2847 ICSMIX_RIGHT, 2848 vol.right); 2849 error = 0; 2850 } 2851 } 2852 break; 2853 2854 2855 case GUSICS_RECORD_SOURCE: 2856 if (cp->type == AUDIO_MIXER_ENUM && cp->un.ord == 0) { 2857 /* Can't set anything else useful, sigh. */ 2858 error = 0; 2859 } 2860 break; 2861 2862 default: 2863 return ENXIO; 2864 /*NOTREACHED*/ 2865 } 2866 return error; 2867 } 2868 2869 int 2870 gus_get_props(addr) 2871 void *addr; 2872 { 2873 struct gus_softc *sc = addr; 2874 return AUDIO_PROP_MMAP | 2875 (sc->sc_recdrq == sc->sc_drq ? 0 : AUDIO_PROP_FULLDUPLEX); 2876 } 2877 2878 int 2879 gusmax_get_props(addr) 2880 void *addr; 2881 { 2882 struct ad1848_softc *ac = addr; 2883 return gus_get_props(ac->parent); 2884 } 2885 2886 int 2887 gusmax_mixer_query_devinfo(addr, dip) 2888 void *addr; 2889 mixer_devinfo_t *dip; 2890 { 2891 DPRINTF(("gusmax_query_devinfo: index=%d\n", dip->index)); 2892 2893 switch(dip->index) { 2894 #if 0 2895 case GUSMAX_MIC_IN_LVL: /* Microphone */ 2896 dip->type = AUDIO_MIXER_VALUE; 2897 dip->mixer_class = GUSMAX_INPUT_CLASS; 2898 dip->prev = AUDIO_MIXER_LAST; 2899 dip->next = GUSMAX_MIC_IN_MUTE; 2900 strlcpy(dip->label.name, AudioNmicrophone, sizeof dip->label.name); 2901 dip->un.v.num_channels = 2; 2902 strlcpy(dip->un.v.units.name, AudioNvolume, 2903 sizeof dip->un.v.units.name); 2904 break; 2905 #endif 2906 2907 case GUSMAX_MONO_LVL: /* mono/microphone mixer */ 2908 dip->type = AUDIO_MIXER_VALUE; 2909 dip->mixer_class = GUSMAX_INPUT_CLASS; 2910 dip->prev = AUDIO_MIXER_LAST; 2911 dip->next = GUSMAX_MONO_MUTE; 2912 strlcpy(dip->label.name, AudioNmicrophone, sizeof dip->label.name); 2913 dip->un.v.num_channels = 1; 2914 strlcpy(dip->un.v.units.name, AudioNvolume, 2915 sizeof dip->un.v.units.name); 2916 break; 2917 2918 case GUSMAX_DAC_LVL: /* dacout */ 2919 dip->type = AUDIO_MIXER_VALUE; 2920 dip->mixer_class = GUSMAX_INPUT_CLASS; 2921 dip->prev = AUDIO_MIXER_LAST; 2922 dip->next = GUSMAX_DAC_MUTE; 2923 strlcpy(dip->label.name, AudioNdac, sizeof dip->label.name); 2924 dip->un.v.num_channels = 2; 2925 strlcpy(dip->un.v.units.name, AudioNvolume, 2926 sizeof dip->un.v.units.name); 2927 break; 2928 2929 case GUSMAX_LINE_IN_LVL: /* line */ 2930 dip->type = AUDIO_MIXER_VALUE; 2931 dip->mixer_class = GUSMAX_INPUT_CLASS; 2932 dip->prev = AUDIO_MIXER_LAST; 2933 dip->next = GUSMAX_LINE_IN_MUTE; 2934 strlcpy(dip->label.name, AudioNline, sizeof dip->label.name); 2935 dip->un.v.num_channels = 2; 2936 strlcpy(dip->un.v.units.name, AudioNvolume, 2937 sizeof dip->un.v.units.name); 2938 break; 2939 2940 case GUSMAX_CD_LVL: /* cd */ 2941 dip->type = AUDIO_MIXER_VALUE; 2942 dip->mixer_class = GUSMAX_INPUT_CLASS; 2943 dip->prev = AUDIO_MIXER_LAST; 2944 dip->next = GUSMAX_CD_MUTE; 2945 strlcpy(dip->label.name, AudioNcd, sizeof dip->label.name); 2946 dip->un.v.num_channels = 2; 2947 strlcpy(dip->un.v.units.name, AudioNvolume, 2948 sizeof dip->un.v.units.name); 2949 break; 2950 2951 2952 case GUSMAX_MONITOR_LVL: /* monitor level */ 2953 dip->type = AUDIO_MIXER_VALUE; 2954 dip->mixer_class = GUSMAX_MONITOR_CLASS; 2955 dip->next = GUSMAX_MONITOR_MUTE; 2956 dip->prev = AUDIO_MIXER_LAST; 2957 strlcpy(dip->label.name, AudioNmonitor, sizeof dip->label.name); 2958 dip->un.v.num_channels = 1; 2959 strlcpy(dip->un.v.units.name, AudioNvolume, 2960 sizeof dip->un.v.units.name); 2961 break; 2962 2963 case GUSMAX_OUT_LVL: /* cs4231 output volume: not useful? */ 2964 dip->type = AUDIO_MIXER_VALUE; 2965 dip->mixer_class = GUSMAX_MONITOR_CLASS; 2966 dip->prev = dip->next = AUDIO_MIXER_LAST; 2967 strlcpy(dip->label.name, AudioNoutput, sizeof dip->label.name); 2968 dip->un.v.num_channels = 2; 2969 strlcpy(dip->un.v.units.name, AudioNvolume, 2970 sizeof dip->un.v.units.name); 2971 break; 2972 2973 case GUSMAX_SPEAKER_LVL: /* fake speaker volume */ 2974 dip->type = AUDIO_MIXER_VALUE; 2975 dip->mixer_class = GUSMAX_MONITOR_CLASS; 2976 dip->prev = AUDIO_MIXER_LAST; 2977 dip->next = GUSMAX_SPEAKER_MUTE; 2978 strlcpy(dip->label.name, AudioNmaster, sizeof dip->label.name); 2979 dip->un.v.num_channels = 2; 2980 strlcpy(dip->un.v.units.name, AudioNvolume, 2981 sizeof dip->un.v.units.name); 2982 break; 2983 2984 case GUSMAX_LINE_IN_MUTE: 2985 dip->mixer_class = GUSMAX_INPUT_CLASS; 2986 dip->type = AUDIO_MIXER_ENUM; 2987 dip->prev = GUSMAX_LINE_IN_LVL; 2988 dip->next = AUDIO_MIXER_LAST; 2989 goto mute; 2990 2991 case GUSMAX_DAC_MUTE: 2992 dip->mixer_class = GUSMAX_INPUT_CLASS; 2993 dip->type = AUDIO_MIXER_ENUM; 2994 dip->prev = GUSMAX_DAC_LVL; 2995 dip->next = AUDIO_MIXER_LAST; 2996 goto mute; 2997 2998 case GUSMAX_CD_MUTE: 2999 dip->mixer_class = GUSMAX_INPUT_CLASS; 3000 dip->type = AUDIO_MIXER_ENUM; 3001 dip->prev = GUSMAX_CD_LVL; 3002 dip->next = AUDIO_MIXER_LAST; 3003 goto mute; 3004 3005 case GUSMAX_MONO_MUTE: 3006 dip->mixer_class = GUSMAX_INPUT_CLASS; 3007 dip->type = AUDIO_MIXER_ENUM; 3008 dip->prev = GUSMAX_MONO_LVL; 3009 dip->next = AUDIO_MIXER_LAST; 3010 goto mute; 3011 3012 case GUSMAX_MONITOR_MUTE: 3013 dip->mixer_class = GUSMAX_OUTPUT_CLASS; 3014 dip->type = AUDIO_MIXER_ENUM; 3015 dip->prev = GUSMAX_MONITOR_LVL; 3016 dip->next = AUDIO_MIXER_LAST; 3017 goto mute; 3018 3019 case GUSMAX_SPEAKER_MUTE: 3020 dip->mixer_class = GUSMAX_OUTPUT_CLASS; 3021 dip->type = AUDIO_MIXER_ENUM; 3022 dip->prev = GUSMAX_SPEAKER_LVL; 3023 dip->next = AUDIO_MIXER_LAST; 3024 mute: 3025 strlcpy(dip->label.name, AudioNmute, sizeof dip->label.name); 3026 dip->un.e.num_mem = 2; 3027 strlcpy(dip->un.e.member[0].label.name, AudioNoff, 3028 sizeof dip->un.e.member[0].label.name); 3029 dip->un.e.member[0].ord = 0; 3030 strlcpy(dip->un.e.member[1].label.name, AudioNon, 3031 sizeof dip->un.e.member[1].label.name); 3032 dip->un.e.member[1].ord = 1; 3033 break; 3034 3035 case GUSMAX_REC_LVL: /* record level */ 3036 dip->type = AUDIO_MIXER_VALUE; 3037 dip->mixer_class = GUSMAX_RECORD_CLASS; 3038 dip->prev = AUDIO_MIXER_LAST; 3039 dip->next = GUSMAX_RECORD_SOURCE; 3040 strlcpy(dip->label.name, AudioNrecord, sizeof dip->label.name); 3041 dip->un.v.num_channels = 2; 3042 strlcpy(dip->un.v.units.name, AudioNvolume, sizeof dip->un.v.units.name); 3043 break; 3044 3045 case GUSMAX_RECORD_SOURCE: 3046 dip->mixer_class = GUSMAX_RECORD_CLASS; 3047 dip->type = AUDIO_MIXER_ENUM; 3048 dip->prev = GUSMAX_REC_LVL; 3049 dip->next = AUDIO_MIXER_LAST; 3050 strlcpy(dip->label.name, AudioNsource, sizeof dip->label.name); 3051 dip->un.e.num_mem = 4; 3052 strlcpy(dip->un.e.member[0].label.name, AudioNoutput, 3053 sizeof dip->un.e.member[0].label.name); 3054 dip->un.e.member[0].ord = DAC_IN_PORT; 3055 strlcpy(dip->un.e.member[1].label.name, AudioNmicrophone, 3056 sizeof dip->un.e.member[1].label.name); 3057 dip->un.e.member[1].ord = MIC_IN_PORT; 3058 strlcpy(dip->un.e.member[2].label.name, AudioNdac, 3059 sizeof dip->un.e.member[2].label.name); 3060 dip->un.e.member[2].ord = AUX1_IN_PORT; 3061 strlcpy(dip->un.e.member[3].label.name, AudioNline, 3062 sizeof dip->un.e.member[3].label.name); 3063 dip->un.e.member[3].ord = LINE_IN_PORT; 3064 break; 3065 3066 case GUSMAX_INPUT_CLASS: /* input class descriptor */ 3067 dip->type = AUDIO_MIXER_CLASS; 3068 dip->mixer_class = GUSMAX_INPUT_CLASS; 3069 dip->next = dip->prev = AUDIO_MIXER_LAST; 3070 strlcpy(dip->label.name, AudioCinputs, sizeof dip->label.name); 3071 break; 3072 3073 case GUSMAX_OUTPUT_CLASS: /* output class descriptor */ 3074 dip->type = AUDIO_MIXER_CLASS; 3075 dip->mixer_class = GUSMAX_OUTPUT_CLASS; 3076 dip->next = dip->prev = AUDIO_MIXER_LAST; 3077 strlcpy(dip->label.name, AudioCoutputs, sizeof dip->label.name); 3078 break; 3079 3080 case GUSMAX_MONITOR_CLASS: /* monitor class descriptor */ 3081 dip->type = AUDIO_MIXER_CLASS; 3082 dip->mixer_class = GUSMAX_MONITOR_CLASS; 3083 dip->next = dip->prev = AUDIO_MIXER_LAST; 3084 strlcpy(dip->label.name, AudioCmonitor, sizeof dip->label.name); 3085 break; 3086 3087 case GUSMAX_RECORD_CLASS: /* record source class */ 3088 dip->type = AUDIO_MIXER_CLASS; 3089 dip->mixer_class = GUSMAX_RECORD_CLASS; 3090 dip->next = dip->prev = AUDIO_MIXER_LAST; 3091 strlcpy(dip->label.name, AudioCrecord, sizeof dip->label.name); 3092 break; 3093 3094 default: 3095 return ENXIO; 3096 /*NOTREACHED*/ 3097 } 3098 DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name)); 3099 return 0; 3100 } 3101 3102 int 3103 gus_mixer_query_devinfo(addr, dip) 3104 void *addr; 3105 mixer_devinfo_t *dip; 3106 { 3107 struct gus_softc *sc = addr; 3108 3109 DPRINTF(("gusmax_query_devinfo: index=%d\n", dip->index)); 3110 3111 if (!HAS_MIXER(sc) && dip->index > GUSICS_MASTER_MUTE) 3112 return ENXIO; 3113 3114 switch(dip->index) { 3115 3116 case GUSICS_MIC_IN_LVL: /* Microphone */ 3117 dip->type = AUDIO_MIXER_VALUE; 3118 dip->mixer_class = GUSICS_INPUT_CLASS; 3119 dip->prev = AUDIO_MIXER_LAST; 3120 dip->next = GUSICS_MIC_IN_MUTE; 3121 strlcpy(dip->label.name, AudioNmicrophone, 3122 sizeof dip->label.name); 3123 dip->un.v.num_channels = 2; 3124 strlcpy(dip->un.v.units.name, AudioNvolume, 3125 sizeof dip->un.v.units.name); 3126 break; 3127 3128 case GUSICS_LINE_IN_LVL: /* line */ 3129 dip->type = AUDIO_MIXER_VALUE; 3130 dip->mixer_class = GUSICS_INPUT_CLASS; 3131 dip->prev = AUDIO_MIXER_LAST; 3132 dip->next = GUSICS_LINE_IN_MUTE; 3133 strlcpy(dip->label.name, AudioNline, sizeof dip->label.name); 3134 dip->un.v.num_channels = 2; 3135 strlcpy(dip->un.v.units.name, AudioNvolume, 3136 sizeof dip->un.v.units.name); 3137 break; 3138 3139 case GUSICS_CD_LVL: /* cd */ 3140 dip->type = AUDIO_MIXER_VALUE; 3141 dip->mixer_class = GUSICS_INPUT_CLASS; 3142 dip->prev = AUDIO_MIXER_LAST; 3143 dip->next = GUSICS_CD_MUTE; 3144 strlcpy(dip->label.name, AudioNcd, sizeof dip->label.name); 3145 dip->un.v.num_channels = 2; 3146 strlcpy(dip->un.v.units.name, AudioNvolume, 3147 sizeof dip->un.v.units.name); 3148 break; 3149 3150 case GUSICS_DAC_LVL: /* dacout */ 3151 dip->type = AUDIO_MIXER_VALUE; 3152 dip->mixer_class = GUSICS_INPUT_CLASS; 3153 dip->prev = AUDIO_MIXER_LAST; 3154 dip->next = GUSICS_DAC_MUTE; 3155 strlcpy(dip->label.name, AudioNdac, sizeof dip->label.name); 3156 dip->un.v.num_channels = 2; 3157 strlcpy(dip->un.v.units.name, AudioNvolume, 3158 sizeof dip->un.v.units.name); 3159 break; 3160 3161 case GUSICS_MASTER_LVL: /* master output */ 3162 dip->type = AUDIO_MIXER_VALUE; 3163 dip->mixer_class = GUSICS_OUTPUT_CLASS; 3164 dip->prev = AUDIO_MIXER_LAST; 3165 dip->next = GUSICS_MASTER_MUTE; 3166 strlcpy(dip->label.name, AudioNmaster, sizeof dip->label.name); 3167 dip->un.v.num_channels = 2; 3168 strlcpy(dip->un.v.units.name, AudioNvolume, 3169 sizeof dip->un.v.units.name); 3170 break; 3171 3172 3173 case GUSICS_LINE_IN_MUTE: 3174 dip->mixer_class = GUSICS_INPUT_CLASS; 3175 dip->type = AUDIO_MIXER_ENUM; 3176 dip->prev = GUSICS_LINE_IN_LVL; 3177 dip->next = AUDIO_MIXER_LAST; 3178 goto mute; 3179 3180 case GUSICS_DAC_MUTE: 3181 dip->mixer_class = GUSICS_INPUT_CLASS; 3182 dip->type = AUDIO_MIXER_ENUM; 3183 dip->prev = GUSICS_DAC_LVL; 3184 dip->next = AUDIO_MIXER_LAST; 3185 goto mute; 3186 3187 case GUSICS_CD_MUTE: 3188 dip->mixer_class = GUSICS_INPUT_CLASS; 3189 dip->type = AUDIO_MIXER_ENUM; 3190 dip->prev = GUSICS_CD_LVL; 3191 dip->next = AUDIO_MIXER_LAST; 3192 goto mute; 3193 3194 case GUSICS_MIC_IN_MUTE: 3195 dip->mixer_class = GUSICS_INPUT_CLASS; 3196 dip->type = AUDIO_MIXER_ENUM; 3197 dip->prev = GUSICS_MIC_IN_LVL; 3198 dip->next = AUDIO_MIXER_LAST; 3199 goto mute; 3200 3201 case GUSICS_MASTER_MUTE: 3202 dip->mixer_class = GUSICS_OUTPUT_CLASS; 3203 dip->type = AUDIO_MIXER_ENUM; 3204 dip->prev = GUSICS_MASTER_LVL; 3205 dip->next = AUDIO_MIXER_LAST; 3206 mute: 3207 strlcpy(dip->label.name, AudioNmute, sizeof dip->label.name); 3208 dip->un.e.num_mem = 2; 3209 strlcpy(dip->un.e.member[0].label.name, AudioNoff, 3210 sizeof dip->un.e.member[0].label.name); 3211 dip->un.e.member[0].ord = 0; 3212 strlcpy(dip->un.e.member[1].label.name, AudioNon, 3213 sizeof dip->un.e.member[1].label.name); 3214 dip->un.e.member[1].ord = 1; 3215 break; 3216 3217 case GUSICS_RECORD_SOURCE: 3218 dip->mixer_class = GUSICS_RECORD_CLASS; 3219 dip->type = AUDIO_MIXER_ENUM; 3220 dip->prev = dip->next = AUDIO_MIXER_LAST; 3221 strlcpy(dip->label.name, AudioNsource, sizeof dip->label.name); 3222 dip->un.e.num_mem = 1; 3223 strlcpy(dip->un.e.member[0].label.name, AudioNoutput, 3224 sizeof dip->un.e.member[0].label.name); 3225 dip->un.e.member[0].ord = GUSICS_MASTER_LVL; 3226 break; 3227 3228 case GUSICS_INPUT_CLASS: 3229 dip->type = AUDIO_MIXER_CLASS; 3230 dip->mixer_class = GUSICS_INPUT_CLASS; 3231 dip->next = dip->prev = AUDIO_MIXER_LAST; 3232 strlcpy(dip->label.name, AudioCinputs, sizeof dip->label.name); 3233 break; 3234 3235 case GUSICS_OUTPUT_CLASS: 3236 dip->type = AUDIO_MIXER_CLASS; 3237 dip->mixer_class = GUSICS_OUTPUT_CLASS; 3238 dip->next = dip->prev = AUDIO_MIXER_LAST; 3239 strlcpy(dip->label.name, AudioCoutputs, sizeof dip->label.name); 3240 break; 3241 3242 case GUSICS_RECORD_CLASS: 3243 dip->type = AUDIO_MIXER_CLASS; 3244 dip->mixer_class = GUSICS_RECORD_CLASS; 3245 dip->next = dip->prev = AUDIO_MIXER_LAST; 3246 strlcpy(dip->label.name, AudioCrecord, sizeof dip->label.name); 3247 break; 3248 3249 default: 3250 return ENXIO; 3251 /*NOTREACHED*/ 3252 } 3253 DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name)); 3254 return 0; 3255 } 3256 3257 int 3258 gus_query_encoding(addr, fp) 3259 void *addr; 3260 struct audio_encoding *fp; 3261 { 3262 switch (fp->index) { 3263 case 0: 3264 strlcpy(fp->name, AudioEmulaw, sizeof fp->name); 3265 fp->encoding = AUDIO_ENCODING_ULAW; 3266 fp->precision = 8; 3267 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 3268 break; 3269 case 1: 3270 strlcpy(fp->name, AudioEslinear, sizeof fp->name); 3271 fp->encoding = AUDIO_ENCODING_SLINEAR; 3272 fp->precision = 8; 3273 fp->flags = 0; 3274 break; 3275 case 2: 3276 strlcpy(fp->name, AudioEslinear_le, sizeof fp->name); 3277 fp->encoding = AUDIO_ENCODING_SLINEAR_LE; 3278 fp->precision = 16; 3279 fp->flags = 0; 3280 break; 3281 case 3: 3282 strlcpy(fp->name, AudioEulinear, sizeof fp->name); 3283 fp->encoding = AUDIO_ENCODING_ULINEAR; 3284 fp->precision = 8; 3285 fp->flags = 0; 3286 break; 3287 case 4: 3288 strlcpy(fp->name, AudioEulinear_le, sizeof fp->name); 3289 fp->encoding = AUDIO_ENCODING_ULINEAR_LE; 3290 fp->precision = 16; 3291 fp->flags = 0; 3292 break; 3293 case 5: 3294 strlcpy(fp->name, AudioEslinear_be, sizeof fp->name); 3295 fp->encoding = AUDIO_ENCODING_SLINEAR_BE; 3296 fp->precision = 16; 3297 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 3298 break; 3299 case 6: 3300 strlcpy(fp->name, AudioEulinear_be, sizeof fp->name); 3301 fp->encoding = AUDIO_ENCODING_ULINEAR_BE; 3302 fp->precision = 16; 3303 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 3304 break; 3305 case 7: 3306 strlcpy(fp->name, AudioEalaw, sizeof fp->name); 3307 fp->encoding = AUDIO_ENCODING_ALAW; 3308 fp->precision = 8; 3309 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 3310 break; 3311 3312 default: 3313 return(EINVAL); 3314 /*NOTREACHED*/ 3315 } 3316 fp->bps = AUDIO_BPS(fp->precision); 3317 fp->msb = 1; 3318 3319 return (0); 3320 } 3321 3322 /* 3323 * Setup the ICS mixer in "transparent" mode: reset everything to a sensible 3324 * level. Levels as suggested by GUS SDK code. 3325 */ 3326 3327 void 3328 gus_init_ics2101(sc) 3329 struct gus_softc *sc; 3330 { 3331 struct ics2101_softc *ic = &sc->sc_mixer; 3332 sc->sc_mixer.sc_iot = sc->sc_iot; 3333 sc->sc_mixer.sc_selio = GUS_MIXER_SELECT; 3334 sc->sc_mixer.sc_selio_ioh = sc->sc_ioh3; 3335 sc->sc_mixer.sc_dataio = GUS_MIXER_DATA; 3336 sc->sc_mixer.sc_dataio_ioh = sc->sc_ioh2; 3337 sc->sc_mixer.sc_flags = (sc->sc_revision == 5) ? ICS_FLIP : 0; 3338 3339 ics2101_mix_attenuate(ic, 3340 GUSMIX_CHAN_MIC, 3341 ICSMIX_LEFT, 3342 ICSMIX_MIN_ATTN); 3343 ics2101_mix_attenuate(ic, 3344 GUSMIX_CHAN_MIC, 3345 ICSMIX_RIGHT, 3346 ICSMIX_MIN_ATTN); 3347 /* 3348 * Start with microphone muted by the mixer... 3349 */ 3350 gusics_mic_mute(ic, 1); 3351 3352 /* ... and enabled by the GUS master mix control */ 3353 gus_mic_ctl(sc, SPKR_ON); 3354 3355 ics2101_mix_attenuate(ic, 3356 GUSMIX_CHAN_LINE, 3357 ICSMIX_LEFT, 3358 ICSMIX_MIN_ATTN); 3359 ics2101_mix_attenuate(ic, 3360 GUSMIX_CHAN_LINE, 3361 ICSMIX_RIGHT, 3362 ICSMIX_MIN_ATTN); 3363 3364 ics2101_mix_attenuate(ic, 3365 GUSMIX_CHAN_CD, 3366 ICSMIX_LEFT, 3367 ICSMIX_MIN_ATTN); 3368 ics2101_mix_attenuate(ic, 3369 GUSMIX_CHAN_CD, 3370 ICSMIX_RIGHT, 3371 ICSMIX_MIN_ATTN); 3372 3373 ics2101_mix_attenuate(ic, 3374 GUSMIX_CHAN_DAC, 3375 ICSMIX_LEFT, 3376 ICSMIX_MIN_ATTN); 3377 ics2101_mix_attenuate(ic, 3378 GUSMIX_CHAN_DAC, 3379 ICSMIX_RIGHT, 3380 ICSMIX_MIN_ATTN); 3381 3382 ics2101_mix_attenuate(ic, 3383 ICSMIX_CHAN_4, 3384 ICSMIX_LEFT, 3385 ICSMIX_MAX_ATTN); 3386 ics2101_mix_attenuate(ic, 3387 ICSMIX_CHAN_4, 3388 ICSMIX_RIGHT, 3389 ICSMIX_MAX_ATTN); 3390 3391 ics2101_mix_attenuate(ic, 3392 GUSMIX_CHAN_MASTER, 3393 ICSMIX_LEFT, 3394 ICSMIX_MIN_ATTN); 3395 ics2101_mix_attenuate(ic, 3396 GUSMIX_CHAN_MASTER, 3397 ICSMIX_RIGHT, 3398 ICSMIX_MIN_ATTN); 3399 /* unmute other stuff: */ 3400 gusics_cd_mute(ic, 0); 3401 gusics_dac_mute(ic, 0); 3402 gusics_linein_mute(ic, 0); 3403 return; 3404 } 3405 3406 3407 3408 void 3409 gus_subattach(sc, ia) 3410 struct gus_softc *sc; 3411 struct isa_attach_args *ia; 3412 { 3413 int i; 3414 bus_space_tag_t iot; 3415 unsigned char c,d,m; 3416 3417 iot = sc->sc_iot; 3418 3419 /* 3420 * Figure out our board rev, and see if we need to initialize the 3421 * mixer 3422 */ 3423 3424 c = bus_space_read_1(iot, sc->sc_ioh3, GUS_BOARD_REV); 3425 if (c != 0xff) 3426 sc->sc_revision = c; 3427 else 3428 sc->sc_revision = 0; 3429 3430 SELECT_GUS_REG(iot, sc->sc_ioh2, GUSREG_RESET); 3431 bus_space_write_1(iot, sc->sc_ioh2, GUS_DATA_HIGH, 0x00); 3432 3433 gusreset(sc, GUS_MAX_VOICES); /* initialize all voices */ 3434 gusreset(sc, GUS_MIN_VOICES); /* then set to just the ones we use */ 3435 3436 /* 3437 * Setup the IRQ and DRQ lines in software, using values from 3438 * config file 3439 */ 3440 3441 m = GUSMASK_LINE_IN|GUSMASK_LINE_OUT; /* disable all */ 3442 3443 c = ((unsigned char) gus_irq_map[ia->ia_irq]) | GUSMASK_BOTH_RQ; 3444 3445 if (sc->sc_recdrq == sc->sc_drq) 3446 d = (unsigned char) (gus_drq_map[sc->sc_drq] | 3447 GUSMASK_BOTH_RQ); 3448 else 3449 d = (unsigned char) (gus_drq_map[sc->sc_drq] | 3450 gus_drq_map[sc->sc_recdrq] << 3); 3451 3452 /* 3453 * Program the IRQ and DMA channels on the GUS. Note that we hardwire 3454 * the GUS to only use one IRQ channel, but we give the user the 3455 * option of using two DMA channels (the other one given by the drq2 3456 * option in the config file). Two DMA channels are needed for full- 3457 * duplex operation. 3458 * 3459 * The order of these operations is very magical. 3460 */ 3461 3462 disable_intr(); /* XXX needed? */ 3463 3464 bus_space_write_1(iot, sc->sc_ioh1, GUS_REG_CONTROL, GUS_REG_IRQCTL); 3465 bus_space_write_1(iot, sc->sc_ioh1, GUS_MIX_CONTROL, m); 3466 bus_space_write_1(iot, sc->sc_ioh1, GUS_IRQCTL_CONTROL, 0x00); 3467 bus_space_write_1(iot, sc->sc_ioh1, 0x0f, 0x00); 3468 3469 bus_space_write_1(iot, sc->sc_ioh1, GUS_MIX_CONTROL, m); 3470 3471 /* magic reset? */ 3472 bus_space_write_1(iot, sc->sc_ioh1, GUS_DMA_CONTROL, d | 0x80); 3473 3474 bus_space_write_1(iot, sc->sc_ioh1, GUS_MIX_CONTROL, 3475 m | GUSMASK_CONTROL_SEL); 3476 bus_space_write_1(iot, sc->sc_ioh1, GUS_IRQ_CONTROL, c); 3477 3478 bus_space_write_1(iot, sc->sc_ioh1, GUS_MIX_CONTROL, m); 3479 bus_space_write_1(iot, sc->sc_ioh1, GUS_DMA_CONTROL, d); 3480 3481 bus_space_write_1(iot, sc->sc_ioh1, GUS_MIX_CONTROL, 3482 m | GUSMASK_CONTROL_SEL); 3483 bus_space_write_1(iot, sc->sc_ioh1, GUS_IRQ_CONTROL, c); 3484 3485 bus_space_write_1(iot, sc->sc_ioh2, GUS_VOICE_SELECT, 0x00); 3486 3487 /* enable line in, line out. leave mic disabled. */ 3488 bus_space_write_1(iot, sc->sc_ioh1, GUS_MIX_CONTROL, 3489 (m | GUSMASK_LATCHES) & ~(GUSMASK_LINE_OUT|GUSMASK_LINE_IN)); 3490 bus_space_write_1(iot, sc->sc_ioh2, GUS_VOICE_SELECT, 0x00); 3491 3492 enable_intr(); 3493 3494 sc->sc_mixcontrol = 3495 (m | GUSMASK_LATCHES) & ~(GUSMASK_LINE_OUT|GUSMASK_LINE_IN); 3496 3497 sc->sc_codec.sc_isa = sc->sc_isa; 3498 3499 if (sc->sc_revision >= 5 && sc->sc_revision <= 9) { 3500 sc->sc_flags |= GUS_MIXER_INSTALLED; 3501 gus_init_ics2101(sc); 3502 } 3503 if (sc->sc_revision < 10 || !gus_init_cs4231(sc)) { 3504 /* Not using the CS4231, so create our DMA maps. */ 3505 if (sc->sc_drq != -1) { 3506 if (isa_dmamap_create(sc->sc_isa, sc->sc_drq, 3507 MAX_ISADMA, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) { 3508 printf("%s: can't create map for drq %d\n", 3509 sc->sc_dev.dv_xname, sc->sc_drq); 3510 return; 3511 } 3512 } 3513 if (sc->sc_recdrq != -1 && sc->sc_recdrq != sc->sc_drq) { 3514 if (isa_dmamap_create(sc->sc_isa, sc->sc_recdrq, 3515 MAX_ISADMA, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) { 3516 printf("%s: can't create map for drq %d\n", 3517 sc->sc_dev.dv_xname, sc->sc_recdrq); 3518 return; 3519 } 3520 } 3521 } 3522 3523 timeout_set(&sc->sc_dma_tmo, gus_dmaout_timeout, sc); 3524 3525 SELECT_GUS_REG(iot, sc->sc_ioh2, GUSREG_RESET); 3526 /* 3527 * Check to see how much memory we have on this card; see if any 3528 * "mirroring" occurs. We're assuming at least 256K already exists 3529 * on the card; otherwise the initial probe would have failed 3530 */ 3531 3532 guspoke(iot, sc->sc_ioh2, 0L, 0x00); 3533 for(i = 1; i < 1024; i++) { 3534 u_long loc; 3535 3536 /* 3537 * See if we've run into mirroring yet 3538 */ 3539 3540 if (guspeek(iot, sc->sc_ioh2, 0L) != 0) 3541 break; 3542 3543 loc = i << 10; 3544 3545 guspoke(iot, sc->sc_ioh2, loc, 0xaa); 3546 if (guspeek(iot, sc->sc_ioh2, loc) != 0xaa) 3547 break; 3548 } 3549 3550 sc->sc_dsize = i; 3551 /* 3552 * The "official" (3.x) version number cannot easily be obtained. 3553 * The revision register does not correspond to the minor number 3554 * of the board version. Simply use the revision register as 3555 * identification. 3556 */ 3557 snprintf(gus_device.version, sizeof gus_device.version, "%d", 3558 sc->sc_revision); 3559 3560 printf(": ver %d", sc->sc_revision); 3561 if (sc->sc_revision >= 10) 3562 printf(", MAX"); 3563 else { 3564 if (HAS_MIXER(sc)) 3565 printf(", ICS2101 mixer"); 3566 if (HAS_CODEC(sc)) 3567 printf(", %s codec/mixer", sc->sc_codec.chip_name); 3568 } 3569 printf(", %dKB DRAM, ", sc->sc_dsize); 3570 if (sc->sc_recdrq == sc->sc_drq) { 3571 printf("half-duplex"); 3572 } else { 3573 printf("full-duplex, record drq %d", sc->sc_recdrq); 3574 } 3575 3576 printf("\n"); 3577 3578 /* 3579 * Setup a default interrupt handler 3580 */ 3581 3582 /* XXX we shouldn't have to use splgus == splclock, nor should 3583 * we use IPL_CLOCK. 3584 */ 3585 sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq, IST_EDGE, 3586 IPL_AUDIO, gusintr, sc /* sc->sc_gusdsp */, sc->sc_dev.dv_xname); 3587 3588 /* 3589 * Set some default values 3590 * XXX others start with 8kHz mono mulaw 3591 */ 3592 3593 sc->sc_irate = sc->sc_orate = 44100; 3594 sc->sc_encoding = AUDIO_ENCODING_SLINEAR_LE; 3595 sc->sc_precision = 16; 3596 sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_DATA_SIZE16; 3597 sc->sc_voc[GUS_VOICE_RIGHT].voccntl |= GUSMASK_DATA_SIZE16; 3598 sc->sc_channels = 1; 3599 sc->sc_ogain = 340; 3600 gus_commit_settings(sc); 3601 3602 /* 3603 * We always put the left channel full left & right channel 3604 * full right. 3605 * For mono playback, we set up both voices playing the same buffer. 3606 */ 3607 bus_space_write_1(iot, sc->sc_ioh2, GUS_VOICE_SELECT, 3608 (u_char)GUS_VOICE_LEFT); 3609 SELECT_GUS_REG(iot, sc->sc_ioh2, GUSREG_PAN_POS); 3610 bus_space_write_1(iot, sc->sc_ioh2, GUS_DATA_HIGH, GUS_PAN_FULL_LEFT); 3611 3612 bus_space_write_1(iot, sc->sc_ioh2, GUS_VOICE_SELECT, 3613 (u_char)GUS_VOICE_RIGHT); 3614 SELECT_GUS_REG(iot, sc->sc_ioh2, GUSREG_PAN_POS); 3615 bus_space_write_1(iot, sc->sc_ioh2, GUS_DATA_HIGH, GUS_PAN_FULL_RIGHT); 3616 3617 /* 3618 * Attach to the generic audio layer 3619 */ 3620 3621 audio_attach_mi(&gus_hw_if, HAS_CODEC(sc) ? (void *)&sc->sc_codec : 3622 (void *)sc, &sc->sc_dev); 3623 } 3624 3625 /* 3626 * Test to see if a particular I/O base is valid for the GUS. Return true 3627 * if it is. 3628 */ 3629 3630 int 3631 gus_test_iobase (iot, iobase) 3632 bus_space_tag_t iot; 3633 int iobase; 3634 { 3635 bus_space_handle_t ioh1, ioh2, ioh3, ioh4; 3636 u_char s1, s2; 3637 int s, rv = 0; 3638 3639 /* Map i/o space */ 3640 if (bus_space_map(iot, iobase, GUS_NPORT1, 0, &ioh1)) 3641 return 0; 3642 if (bus_space_map(iot, iobase+GUS_IOH2_OFFSET, GUS_NPORT2, 0, &ioh2)) 3643 goto bad1; 3644 3645 /* XXX Maybe we shouldn't fail on mapping this, but just assume 3646 * the card is of revision 0? */ 3647 if (bus_space_map(iot, iobase+GUS_IOH3_OFFSET, GUS_NPORT3, 0, &ioh3)) 3648 goto bad2; 3649 3650 if (bus_space_map(iot, iobase+GUS_IOH4_OFFSET, GUS_NPORT4, 0, &ioh4)) 3651 goto bad3; 3652 3653 /* 3654 * Reset GUS to an initial state before we do anything. 3655 */ 3656 3657 s = splgus(); 3658 delay(500); 3659 3660 SELECT_GUS_REG(iot, ioh2, GUSREG_RESET); 3661 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00); 3662 3663 delay(500); 3664 3665 SELECT_GUS_REG(iot, ioh2, GUSREG_RESET); 3666 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, GUSMASK_MASTER_RESET); 3667 3668 delay(500); 3669 3670 splx(s); 3671 3672 /* 3673 * See if we can write to the board's memory 3674 */ 3675 3676 s1 = guspeek(iot, ioh2, 0L); 3677 s2 = guspeek(iot, ioh2, 1L); 3678 3679 guspoke(iot, ioh2, 0L, 0xaa); 3680 guspoke(iot, ioh2, 1L, 0x55); 3681 3682 if (guspeek(iot, ioh2, 0L) != 0xaa) 3683 goto bad; 3684 3685 guspoke(iot, ioh2, 0L, s1); 3686 guspoke(iot, ioh2, 1L, s2); 3687 3688 rv = 1; 3689 3690 bad: 3691 bus_space_unmap(iot, ioh4, GUS_NPORT4); 3692 bad3: 3693 bus_space_unmap(iot, ioh3, GUS_NPORT3); 3694 bad2: 3695 bus_space_unmap(iot, ioh2, GUS_NPORT2); 3696 bad1: 3697 bus_space_unmap(iot, ioh1, GUS_NPORT1); 3698 return rv; 3699 } 3700