1 /* $OpenBSD: gus.c,v 1.33 2009/08/26 22:29:09 jasper 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 1577 return 0; 1578 } 1579 1580 /* 1581 * Interface to the audio layer - set the blocksize to the correct number 1582 * of units 1583 */ 1584 1585 int 1586 gusmax_round_blocksize(addr, blocksize) 1587 void * addr; 1588 int blocksize; 1589 { 1590 struct ad1848_softc *ac = addr; 1591 struct gus_softc *sc = ac->parent; 1592 1593 /* blocksize = ad1848_round_blocksize(ac, blocksize);*/ 1594 return gus_round_blocksize(sc, blocksize); 1595 } 1596 1597 int 1598 gus_round_blocksize(addr, blocksize) 1599 void * addr; 1600 int blocksize; 1601 { 1602 struct gus_softc *sc = addr; 1603 1604 DPRINTF(("gus_round_blocksize called\n")); 1605 1606 if ((sc->sc_encoding == AUDIO_ENCODING_ULAW || 1607 sc->sc_encoding == AUDIO_ENCODING_ALAW) && blocksize > 32768) 1608 blocksize = 32768; 1609 else if (blocksize > 65536) 1610 blocksize = 65536; 1611 1612 if ((blocksize % GUS_BUFFER_MULTIPLE) != 0) 1613 blocksize = (blocksize / GUS_BUFFER_MULTIPLE + 1) * 1614 GUS_BUFFER_MULTIPLE; 1615 1616 /* set up temporary buffer to hold the deinterleave, if necessary 1617 for stereo output */ 1618 if (sc->sc_deintr_buf) { 1619 free(sc->sc_deintr_buf, M_DEVBUF); 1620 sc->sc_deintr_buf = NULL; 1621 } 1622 sc->sc_deintr_buf = malloc(blocksize/2, M_DEVBUF, M_WAITOK); 1623 1624 sc->sc_blocksize = blocksize; 1625 /* multi-buffering not quite working yet. */ 1626 sc->sc_nbufs = /*GUS_MEM_FOR_BUFFERS / blocksize*/ 2; 1627 1628 gus_set_chan_addrs(sc); 1629 1630 return blocksize; 1631 } 1632 1633 int 1634 gus_get_out_gain(addr) 1635 caddr_t addr; 1636 { 1637 struct gus_softc *sc = (struct gus_softc *) addr; 1638 1639 DPRINTF(("gus_get_out_gain called\n")); 1640 return sc->sc_ogain / 2; 1641 } 1642 1643 inline void gus_set_voices(sc, voices) 1644 struct gus_softc *sc; 1645 int voices; 1646 { 1647 bus_space_tag_t iot = sc->sc_iot; 1648 bus_space_handle_t ioh2 = sc->sc_ioh2; 1649 /* 1650 * Select the active number of voices 1651 */ 1652 1653 SELECT_GUS_REG(iot, ioh2, GUSREG_ACTIVE_VOICES); 1654 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (voices-1) | 0xc0); 1655 1656 sc->sc_voices = voices; 1657 } 1658 1659 /* 1660 * Actually set the settings of various values on the card 1661 */ 1662 1663 int 1664 gusmax_commit_settings(addr) 1665 void * addr; 1666 { 1667 struct ad1848_softc *ac = addr; 1668 struct gus_softc *sc = ac->parent; 1669 int error; 1670 1671 error = ad1848_commit_settings(ac); 1672 if (error) 1673 return error; 1674 return gus_commit_settings(sc); 1675 } 1676 1677 /* 1678 * Commit the settings. Called at normal IPL. 1679 */ 1680 int 1681 gus_commit_settings(addr) 1682 void * addr; 1683 { 1684 struct gus_softc *sc = addr; 1685 int s; 1686 1687 DPRINTF(("gus_commit_settings called (gain = %d)\n",sc->sc_ogain)); 1688 1689 1690 s = splgus(); 1691 1692 gus_set_recrate(sc, sc->sc_irate); 1693 gus_set_volume(sc, GUS_VOICE_LEFT, sc->sc_ogain); 1694 gus_set_volume(sc, GUS_VOICE_RIGHT, sc->sc_ogain); 1695 gus_set_samprate(sc, GUS_VOICE_LEFT, sc->sc_orate); 1696 gus_set_samprate(sc, GUS_VOICE_RIGHT, sc->sc_orate); 1697 splx(s); 1698 gus_set_chan_addrs(sc); 1699 1700 return 0; 1701 } 1702 1703 void 1704 gus_set_chan_addrs(sc) 1705 struct gus_softc *sc; 1706 { 1707 /* 1708 * We use sc_nbufs * blocksize bytes of storage in the on-board GUS 1709 * ram. 1710 * For mono, each of the sc_nbufs buffers is DMA'd to in one chunk, 1711 * and both left & right channels play the same buffer. 1712 * 1713 * For stereo, each channel gets a contiguous half of the memory, 1714 * and each has sc_nbufs buffers of size blocksize/2. 1715 * Stereo data are deinterleaved in main memory before the DMA out 1716 * routines are called to queue the output. 1717 * 1718 * The blocksize per channel is kept in sc_chanblocksize. 1719 */ 1720 if (sc->sc_channels == 2) 1721 sc->sc_chanblocksize = sc->sc_blocksize/2; 1722 else 1723 sc->sc_chanblocksize = sc->sc_blocksize; 1724 1725 sc->sc_voc[GUS_VOICE_LEFT].start_addr = GUS_MEM_OFFSET - 1; 1726 sc->sc_voc[GUS_VOICE_RIGHT].start_addr = 1727 (gus_dostereo && sc->sc_channels == 2 ? GUS_LEFT_RIGHT_OFFSET : 0) 1728 + GUS_MEM_OFFSET - 1; 1729 sc->sc_voc[GUS_VOICE_RIGHT].current_addr = 1730 sc->sc_voc[GUS_VOICE_RIGHT].start_addr + 1; 1731 sc->sc_voc[GUS_VOICE_RIGHT].end_addr = 1732 sc->sc_voc[GUS_VOICE_RIGHT].start_addr + 1733 sc->sc_nbufs * sc->sc_chanblocksize; 1734 1735 } 1736 1737 /* 1738 * Set the sample rate of the given voice. Called at splgus(). 1739 */ 1740 1741 void 1742 gus_set_samprate(sc, voice, freq) 1743 struct gus_softc *sc; 1744 int voice, freq; 1745 { 1746 bus_space_tag_t iot = sc->sc_iot; 1747 bus_space_handle_t ioh2 = sc->sc_ioh2; 1748 unsigned int fc; 1749 u_long temp, f = (u_long) freq; 1750 1751 /* 1752 * calculate fc based on the number of active voices; 1753 * we need to use longs to preserve enough bits 1754 */ 1755 1756 temp = (u_long) gus_max_frequency[sc->sc_voices-GUS_MIN_VOICES]; 1757 1758 fc = (unsigned int)(((f << 9L) + (temp >> 1L)) / temp); 1759 1760 fc <<= 1; 1761 1762 1763 /* 1764 * Program the voice frequency, and set it in the voice data record 1765 */ 1766 1767 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice); 1768 SELECT_GUS_REG(iot, ioh2, GUSREG_FREQ_CONTROL); 1769 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, fc); 1770 1771 sc->sc_voc[voice].rate = freq; 1772 1773 } 1774 1775 /* 1776 * Set the sample rate of the recording frequency. Formula is from the GUS 1777 * SDK. Called at splgus(). 1778 */ 1779 1780 void 1781 gus_set_recrate(sc, rate) 1782 struct gus_softc *sc; 1783 u_long rate; 1784 { 1785 bus_space_tag_t iot = sc->sc_iot; 1786 bus_space_handle_t ioh2 = sc->sc_ioh2; 1787 u_char realrate; 1788 DPRINTF(("gus_set_recrate %lu\n", rate)); 1789 1790 #if 0 1791 realrate = 9878400/(16*(rate+2)); /* formula from GUS docs */ 1792 #endif 1793 realrate = (9878400 >> 4)/rate - 2; /* formula from code, sigh. */ 1794 1795 SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_FREQ); 1796 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, realrate); 1797 } 1798 1799 /* 1800 * Interface to the audio layer - turn the output on or off. Note that some 1801 * of these bits are flipped in the register 1802 */ 1803 1804 int 1805 gusmax_speaker_ctl(addr, newstate) 1806 void * addr; 1807 int newstate; 1808 { 1809 struct ad1848_softc *sc = addr; 1810 return gus_speaker_ctl(sc->parent, newstate); 1811 } 1812 1813 int 1814 gus_speaker_ctl(addr, newstate) 1815 void * addr; 1816 int newstate; 1817 { 1818 struct gus_softc *sc = (struct gus_softc *) addr; 1819 bus_space_tag_t iot = sc->sc_iot; 1820 bus_space_handle_t ioh1 = sc->sc_ioh1; 1821 1822 /* Line out bit is flipped: 0 enables, 1 disables */ 1823 if ((newstate == SPKR_ON) && 1824 (sc->sc_mixcontrol & GUSMASK_LINE_OUT)) { 1825 sc->sc_mixcontrol &= ~GUSMASK_LINE_OUT; 1826 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol); 1827 } 1828 if ((newstate == SPKR_OFF) && 1829 (sc->sc_mixcontrol & GUSMASK_LINE_OUT) == 0) { 1830 sc->sc_mixcontrol |= GUSMASK_LINE_OUT; 1831 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol); 1832 } 1833 1834 return 0; 1835 } 1836 1837 int 1838 gus_linein_ctl(addr, newstate) 1839 void * addr; 1840 int newstate; 1841 { 1842 struct gus_softc *sc = (struct gus_softc *) addr; 1843 bus_space_tag_t iot = sc->sc_iot; 1844 bus_space_handle_t ioh1 = sc->sc_ioh1; 1845 1846 /* Line in bit is flipped: 0 enables, 1 disables */ 1847 if ((newstate == SPKR_ON) && 1848 (sc->sc_mixcontrol & GUSMASK_LINE_IN)) { 1849 sc->sc_mixcontrol &= ~GUSMASK_LINE_IN; 1850 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol); 1851 } 1852 if ((newstate == SPKR_OFF) && 1853 (sc->sc_mixcontrol & GUSMASK_LINE_IN) == 0) { 1854 sc->sc_mixcontrol |= GUSMASK_LINE_IN; 1855 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol); 1856 } 1857 1858 return 0; 1859 } 1860 1861 int 1862 gus_mic_ctl(addr, newstate) 1863 void * addr; 1864 int newstate; 1865 { 1866 struct gus_softc *sc = (struct gus_softc *) addr; 1867 bus_space_tag_t iot = sc->sc_iot; 1868 bus_space_handle_t ioh1 = sc->sc_ioh1; 1869 1870 /* Mic bit is normal: 1 enables, 0 disables */ 1871 if ((newstate == SPKR_ON) && 1872 (sc->sc_mixcontrol & GUSMASK_MIC_IN) == 0) { 1873 sc->sc_mixcontrol |= GUSMASK_MIC_IN; 1874 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol); 1875 } 1876 if ((newstate == SPKR_OFF) && 1877 (sc->sc_mixcontrol & GUSMASK_MIC_IN)) { 1878 sc->sc_mixcontrol &= ~GUSMASK_MIC_IN; 1879 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol); 1880 } 1881 1882 return 0; 1883 } 1884 1885 /* 1886 * Set the end address of a give voice. Called at splgus() 1887 */ 1888 1889 void 1890 gus_set_endaddr(sc, voice, addr) 1891 struct gus_softc *sc; 1892 int voice; 1893 u_long addr; 1894 { 1895 bus_space_tag_t iot = sc->sc_iot; 1896 bus_space_handle_t ioh2 = sc->sc_ioh2; 1897 1898 sc->sc_voc[voice].end_addr = addr; 1899 1900 if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16) 1901 addr = convert_to_16bit(addr); 1902 1903 SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_HIGH); 1904 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(addr)); 1905 SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_LOW); 1906 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(addr)); 1907 1908 } 1909 1910 #ifdef GUSPLAYDEBUG 1911 /* 1912 * Set current address. called at splgus() 1913 */ 1914 void 1915 gus_set_curaddr(sc, voice, addr) 1916 struct gus_softc *sc; 1917 int voice; 1918 u_long addr; 1919 { 1920 bus_space_tag_t iot = sc->sc_iot; 1921 bus_space_handle_t ioh2 = sc->sc_ioh2; 1922 1923 sc->sc_voc[voice].current_addr = addr; 1924 1925 if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16) 1926 addr = convert_to_16bit(addr); 1927 1928 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice); 1929 1930 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH); 1931 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(addr)); 1932 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW); 1933 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(addr)); 1934 1935 } 1936 1937 /* 1938 * Get current GUS playback address. Called at splgus(). 1939 */ 1940 u_long 1941 gus_get_curaddr(sc, voice) 1942 struct gus_softc *sc; 1943 int voice; 1944 { 1945 bus_space_tag_t iot = sc->sc_iot; 1946 bus_space_handle_t ioh2 = sc->sc_ioh2; 1947 u_long addr; 1948 1949 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice); 1950 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH|GUSREG_READ); 1951 addr = (bus_space_read_2(iot, ioh2, GUS_DATA_LOW) & 0x1fff) << 7; 1952 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW|GUSREG_READ); 1953 addr |= (bus_space_read_2(iot, ioh2, GUS_DATA_LOW) >> 9L) & 0x7f; 1954 1955 if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16) 1956 addr = (addr & 0xc0000) | ((addr & 0x1ffff) << 1); /* undo 16-bit change */ 1957 DPRINTF(("gus voice %d curaddr %ld end_addr %ld\n", 1958 voice, addr, sc->sc_voc[voice].end_addr)); 1959 /* XXX sanity check the address? */ 1960 1961 return(addr); 1962 } 1963 #endif 1964 1965 /* 1966 * Convert an address value to a "16 bit" value - why this is necessary I 1967 * have NO idea 1968 */ 1969 1970 u_long 1971 convert_to_16bit(address) 1972 u_long address; 1973 { 1974 u_long old_address; 1975 1976 old_address = address; 1977 address >>= 1; 1978 address &= 0x0001ffffL; 1979 address |= (old_address & 0x000c0000L); 1980 1981 return (address); 1982 } 1983 1984 /* 1985 * Write a value into the GUS's DRAM 1986 */ 1987 1988 void 1989 guspoke(iot, ioh2, address, value) 1990 bus_space_tag_t iot; 1991 bus_space_handle_t ioh2; 1992 long address; 1993 unsigned char value; 1994 { 1995 1996 /* 1997 * Select the DRAM address 1998 */ 1999 2000 SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_LOW); 2001 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, (unsigned int) (address & 0xffff)); 2002 SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_HIGH); 2003 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (unsigned char) ((address >> 16) & 0xff)); 2004 2005 /* 2006 * Actually write the data 2007 */ 2008 2009 bus_space_write_1(iot, ioh2, GUS_DRAM_DATA, value); 2010 } 2011 2012 /* 2013 * Read a value from the GUS's DRAM 2014 */ 2015 2016 unsigned char 2017 guspeek(iot, ioh2, address) 2018 bus_space_tag_t iot; 2019 bus_space_handle_t ioh2; 2020 u_long address; 2021 { 2022 2023 /* 2024 * Select the DRAM address 2025 */ 2026 2027 SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_LOW); 2028 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, (unsigned int) (address & 0xffff)); 2029 SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_HIGH); 2030 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (unsigned char) ((address >> 16) & 0xff)); 2031 2032 /* 2033 * Read in the data from the board 2034 */ 2035 2036 return (unsigned char) bus_space_read_1(iot, ioh2, GUS_DRAM_DATA); 2037 } 2038 2039 /* 2040 * Reset the Gravis UltraSound card, completely 2041 */ 2042 2043 void 2044 gusreset(sc, voices) 2045 struct gus_softc *sc; 2046 int voices; 2047 { 2048 bus_space_tag_t iot = sc->sc_iot; 2049 bus_space_handle_t ioh1 = sc->sc_ioh1; 2050 bus_space_handle_t ioh2 = sc->sc_ioh2; 2051 bus_space_handle_t ioh4 = sc->sc_ioh4; 2052 int i,s; 2053 2054 s = splgus(); 2055 2056 /* 2057 * Reset the GF1 chip 2058 */ 2059 2060 SELECT_GUS_REG(iot, ioh2, GUSREG_RESET); 2061 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00); 2062 2063 delay(500); 2064 2065 /* 2066 * Release reset 2067 */ 2068 2069 SELECT_GUS_REG(iot, ioh2, GUSREG_RESET); 2070 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, GUSMASK_MASTER_RESET); 2071 2072 delay(500); 2073 2074 /* 2075 * Reset MIDI port as well 2076 */ 2077 2078 bus_space_write_1(iot, ioh4, GUS_MIDI_CONTROL, MIDI_RESET); 2079 2080 delay(500); 2081 2082 bus_space_write_1(iot, ioh4, GUS_MIDI_CONTROL, 0x00); 2083 2084 /* 2085 * Clear interrupts 2086 */ 2087 2088 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL); 2089 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00); 2090 SELECT_GUS_REG(iot, ioh2, GUSREG_TIMER_CONTROL); 2091 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00); 2092 SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL); 2093 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00); 2094 2095 gus_set_voices(sc, voices); 2096 2097 bus_space_read_1(iot, ioh1, GUS_IRQ_STATUS); 2098 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL); 2099 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH); 2100 SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL); 2101 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH); 2102 SELECT_GUS_REG(iot, ioh2, GUSREG_IRQ_STATUS); 2103 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH); 2104 2105 /* 2106 * Reset voice specific information 2107 */ 2108 2109 for(i = 0; i < voices; i++) { 2110 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) i); 2111 2112 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL); 2113 2114 sc->sc_voc[i].voccntl = GUSMASK_VOICE_STOPPED | 2115 GUSMASK_STOP_VOICE; 2116 2117 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[i].voccntl); 2118 2119 sc->sc_voc[i].volcntl = GUSMASK_VOLUME_STOPPED | 2120 GUSMASK_STOP_VOLUME; 2121 2122 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL); 2123 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[i].volcntl); 2124 2125 delay(100); 2126 2127 gus_set_samprate(sc, i, 8000); 2128 SELECT_GUS_REG(iot, ioh2, GUSREG_START_ADDR_HIGH); 2129 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000); 2130 SELECT_GUS_REG(iot, ioh2, GUSREG_START_ADDR_LOW); 2131 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000); 2132 SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_HIGH); 2133 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000); 2134 SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_LOW); 2135 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000); 2136 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_RATE); 2137 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x01); 2138 SELECT_GUS_REG(iot, ioh2, GUSREG_START_VOLUME); 2139 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x10); 2140 SELECT_GUS_REG(iot, ioh2, GUSREG_END_VOLUME); 2141 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0xe0); 2142 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME); 2143 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000); 2144 2145 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH); 2146 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000); 2147 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW); 2148 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000); 2149 SELECT_GUS_REG(iot, ioh2, GUSREG_PAN_POS); 2150 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x07); 2151 } 2152 2153 /* 2154 * Clear out any pending IRQs 2155 */ 2156 2157 bus_space_read_1(iot, ioh1, GUS_IRQ_STATUS); 2158 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL); 2159 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH); 2160 SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL); 2161 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH); 2162 SELECT_GUS_REG(iot, ioh2, GUSREG_IRQ_STATUS); 2163 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH); 2164 2165 SELECT_GUS_REG(iot, ioh2, GUSREG_RESET); 2166 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, GUSMASK_MASTER_RESET | GUSMASK_DAC_ENABLE | 2167 GUSMASK_IRQ_ENABLE); 2168 2169 splx(s); 2170 } 2171 2172 2173 int 2174 gus_init_cs4231(sc) 2175 struct gus_softc *sc; 2176 { 2177 bus_space_tag_t iot = sc->sc_iot; 2178 bus_space_handle_t ioh1 = sc->sc_ioh1; 2179 int port = sc->sc_iobase; 2180 u_char ctrl; 2181 2182 ctrl = (port & 0xf0) >> 4; /* set port address middle nibble */ 2183 /* 2184 * The codec is a bit weird--swapped dma channels. 2185 */ 2186 ctrl |= GUS_MAX_CODEC_ENABLE; 2187 if (sc->sc_drq >= 4) 2188 ctrl |= GUS_MAX_RECCHAN16; 2189 if (sc->sc_recdrq >= 4) 2190 ctrl |= GUS_MAX_PLAYCHAN16; 2191 2192 bus_space_write_1(iot, ioh1, GUS_MAX_CTRL, ctrl); 2193 2194 sc->sc_codec.sc_iot = sc->sc_iot; 2195 sc->sc_codec.sc_iobase = port+GUS_MAX_CODEC_BASE; 2196 2197 if (ad1848_mapprobe(&sc->sc_codec, sc->sc_codec.sc_iobase) == 0) { 2198 sc->sc_flags &= ~GUS_CODEC_INSTALLED; 2199 return (0); 2200 } else { 2201 struct ad1848_volume vol = {AUDIO_MAX_GAIN, AUDIO_MAX_GAIN}; 2202 sc->sc_flags |= GUS_CODEC_INSTALLED; 2203 sc->sc_codec.parent = sc; 2204 sc->sc_codec.sc_drq = sc->sc_recdrq; 2205 sc->sc_codec.sc_recdrq = sc->sc_drq; 2206 gus_hw_if = gusmax_hw_if; 2207 /* enable line in and mic in the GUS mixer; the codec chip 2208 will do the real mixing for them. */ 2209 sc->sc_mixcontrol &= ~GUSMASK_LINE_IN; /* 0 enables. */ 2210 sc->sc_mixcontrol |= GUSMASK_MIC_IN; /* 1 enables. */ 2211 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol); 2212 2213 ad1848_attach(&sc->sc_codec); 2214 /* turn on pre-MUX microphone gain. */ 2215 ad1848_set_mic_gain(&sc->sc_codec, &vol); 2216 2217 return (1); 2218 } 2219 } 2220 2221 2222 /* 2223 * Return info about the audio device, for the AUDIO_GETINFO ioctl 2224 */ 2225 2226 int 2227 gus_getdev(addr, dev) 2228 void * addr; 2229 struct audio_device *dev; 2230 { 2231 *dev = gus_device; 2232 return 0; 2233 } 2234 2235 /* 2236 * stubs (XXX) 2237 */ 2238 2239 int 2240 gus_set_in_gain(addr, gain, balance) 2241 caddr_t addr; 2242 u_int gain; 2243 u_char balance; 2244 { 2245 DPRINTF(("gus_set_in_gain called\n")); 2246 return 0; 2247 } 2248 2249 int 2250 gus_get_in_gain(addr) 2251 caddr_t addr; 2252 { 2253 DPRINTF(("gus_get_in_gain called\n")); 2254 return 0; 2255 } 2256 2257 int 2258 gusmax_dma_input(addr, buf, size, callback, arg) 2259 void * addr; 2260 void *buf; 2261 int size; 2262 void (*callback)(void *); 2263 void *arg; 2264 { 2265 struct ad1848_softc *sc = addr; 2266 return gus_dma_input(sc->parent, buf, size, callback, arg); 2267 } 2268 2269 /* 2270 * Start sampling the input source into the requested DMA buffer. 2271 * Called at splgus(), either from top-half or from interrupt handler. 2272 */ 2273 int 2274 gus_dma_input(addr, buf, size, callback, arg) 2275 void * addr; 2276 void *buf; 2277 int size; 2278 void (*callback)(void *); 2279 void *arg; 2280 { 2281 struct gus_softc *sc = addr; 2282 bus_space_tag_t iot = sc->sc_iot; 2283 bus_space_handle_t ioh2 = sc->sc_ioh2; 2284 u_char dmac; 2285 DMAPRINTF(("gus_dma_input called\n")); 2286 2287 /* 2288 * Sample SIZE bytes of data from the card, into buffer at BUF. 2289 */ 2290 2291 if (sc->sc_precision == 16) 2292 return EINVAL; /* XXX */ 2293 2294 /* set DMA modes */ 2295 dmac = GUSMASK_SAMPLE_IRQ|GUSMASK_SAMPLE_START; 2296 if (sc->sc_recdrq >= 4) 2297 dmac |= GUSMASK_SAMPLE_DATA16; 2298 if (sc->sc_encoding == AUDIO_ENCODING_ULAW || 2299 sc->sc_encoding == AUDIO_ENCODING_ALAW || 2300 sc->sc_encoding == AUDIO_ENCODING_ULINEAR_LE || 2301 sc->sc_encoding == AUDIO_ENCODING_ULINEAR_BE) 2302 dmac |= GUSMASK_SAMPLE_INVBIT; 2303 if (sc->sc_channels == 2) 2304 dmac |= GUSMASK_SAMPLE_STEREO; 2305 isa_dmastart(sc->sc_dev.dv_parent, sc->sc_recdrq, buf, size, 2306 NULL, DMAMODE_READ, BUS_DMA_NOWAIT); 2307 2308 DMAPRINTF(("gus_dma_input isadma_started\n")); 2309 sc->sc_flags |= GUS_DMAIN_ACTIVE; 2310 sc->sc_dmainintr = callback; 2311 sc->sc_inarg = arg; 2312 sc->sc_dmaincnt = size; 2313 sc->sc_dmainaddr = buf; 2314 2315 SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL); 2316 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, dmac); /* Go! */ 2317 2318 2319 DMAPRINTF(("gus_dma_input returning\n")); 2320 2321 return 0; 2322 } 2323 2324 int 2325 gus_dmain_intr(sc) 2326 struct gus_softc *sc; 2327 { 2328 void (*callback)(void *); 2329 void *arg; 2330 2331 DMAPRINTF(("gus_dmain_intr called\n")); 2332 if (sc->sc_dmainintr) { 2333 isa_dmadone(sc->sc_dev.dv_parent, sc->sc_recdrq); 2334 callback = sc->sc_dmainintr; 2335 arg = sc->sc_inarg; 2336 2337 sc->sc_dmainaddr = 0; 2338 sc->sc_dmaincnt = 0; 2339 sc->sc_dmainintr = 0; 2340 sc->sc_inarg = 0; 2341 2342 sc->sc_flags &= ~GUS_DMAIN_ACTIVE; 2343 DMAPRINTF(("calling dmain_intr callback %p(%p)\n", callback, arg)); 2344 (*callback)(arg); 2345 return 1; 2346 } else { 2347 DMAPRINTF(("gus_dmain_intr false?\n")); 2348 return 0; /* XXX ??? */ 2349 } 2350 } 2351 2352 int 2353 gusmax_halt_out_dma(addr) 2354 void * addr; 2355 { 2356 struct ad1848_softc *sc = addr; 2357 return gus_halt_out_dma(sc->parent); 2358 } 2359 2360 2361 int 2362 gusmax_halt_in_dma(addr) 2363 void * addr; 2364 { 2365 struct ad1848_softc *sc = addr; 2366 return gus_halt_in_dma(sc->parent); 2367 } 2368 2369 /* 2370 * Stop any DMA output. Called at splgus(). 2371 */ 2372 int 2373 gus_halt_out_dma(addr) 2374 void * addr; 2375 { 2376 struct gus_softc *sc = addr; 2377 bus_space_tag_t iot = sc->sc_iot; 2378 bus_space_handle_t ioh2 = sc->sc_ioh2; 2379 2380 DMAPRINTF(("gus_halt_out_dma called\n")); 2381 /* 2382 * Make sure the GUS _isn't_ setup for DMA 2383 */ 2384 2385 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL); 2386 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0); 2387 2388 timeout_del(&sc->sc_dma_tmo); 2389 isa_dmaabort(sc->sc_dev.dv_parent, sc->sc_drq); 2390 sc->sc_flags &= ~(GUS_DMAOUT_ACTIVE|GUS_LOCKED); 2391 sc->sc_dmaoutintr = 0; 2392 sc->sc_outarg = 0; 2393 sc->sc_dmaoutaddr = 0; 2394 sc->sc_dmaoutcnt = 0; 2395 sc->sc_dmabuf = 0; 2396 sc->sc_bufcnt = 0; 2397 sc->sc_playbuf = -1; 2398 /* also stop playing */ 2399 gus_stop_voice(sc, GUS_VOICE_LEFT, 1); 2400 gus_stop_voice(sc, GUS_VOICE_RIGHT, 0); 2401 2402 return 0; 2403 } 2404 2405 /* 2406 * Stop any DMA output. Called at splgus(). 2407 */ 2408 int 2409 gus_halt_in_dma(addr) 2410 void * addr; 2411 { 2412 struct gus_softc *sc = addr; 2413 bus_space_tag_t iot = sc->sc_iot; 2414 bus_space_handle_t ioh2 = sc->sc_ioh2; 2415 DMAPRINTF(("gus_halt_in_dma called\n")); 2416 2417 /* 2418 * Make sure the GUS _isn't_ setup for DMA 2419 */ 2420 2421 SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL); 2422 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 2423 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH) & ~(GUSMASK_SAMPLE_START|GUSMASK_SAMPLE_IRQ)); 2424 2425 isa_dmaabort(sc->sc_dev.dv_parent, sc->sc_recdrq); 2426 sc->sc_flags &= ~GUS_DMAIN_ACTIVE; 2427 sc->sc_dmainintr = 0; 2428 sc->sc_inarg = 0; 2429 sc->sc_dmainaddr = 0; 2430 sc->sc_dmaincnt = 0; 2431 2432 return 0; 2433 } 2434 2435 2436 ad1848_devmap_t gusmapping[] = { 2437 {GUSMAX_DAC_LVL, AD1848_KIND_LVL, AD1848_AUX1_CHANNEL}, 2438 {GUSMAX_LINE_IN_LVL, AD1848_KIND_LVL, AD1848_LINE_CHANNEL}, 2439 {GUSMAX_MONO_LVL, AD1848_KIND_LVL, AD1848_MONO_CHANNEL}, 2440 {GUSMAX_CD_LVL, AD1848_KIND_LVL, AD1848_AUX2_CHANNEL}, 2441 {GUSMAX_MONITOR_LVL, AD1848_KIND_LVL, AD1848_MONITOR_CHANNEL}, 2442 {GUSMAX_OUT_LVL, AD1848_KIND_LVL, AD1848_DAC_CHANNEL}, 2443 {GUSMAX_DAC_MUTE, AD1848_KIND_MUTE, AD1848_AUX1_CHANNEL}, 2444 {GUSMAX_LINE_IN_MUTE, AD1848_KIND_MUTE, AD1848_LINE_CHANNEL}, 2445 {GUSMAX_MONO_MUTE, AD1848_KIND_MUTE, AD1848_MONO_CHANNEL}, 2446 {GUSMAX_CD_MUTE, AD1848_KIND_MUTE, AD1848_AUX2_CHANNEL}, 2447 {GUSMAX_MONITOR_MUTE, AD1848_KIND_MUTE, AD1848_MONITOR_CHANNEL}, 2448 {GUSMAX_REC_LVL, AD1848_KIND_RECORDGAIN, -1}, 2449 {GUSMAX_RECORD_SOURCE, AD1848_KIND_RECORDSOURCE, -1} 2450 }; 2451 2452 int nummap = sizeof(gusmapping) / sizeof(gusmapping[0]); 2453 2454 int 2455 gusmax_mixer_get_port(addr, cp) 2456 void *addr; 2457 mixer_ctrl_t *cp; 2458 { 2459 struct ad1848_softc *ac = addr; 2460 struct gus_softc *sc = ac->parent; 2461 struct ad1848_volume vol; 2462 int error = ad1848_mixer_get_port(ac, gusmapping, nummap, cp); 2463 2464 if (error != ENXIO) 2465 return (error); 2466 2467 error = EINVAL; 2468 2469 switch (cp->dev) { 2470 case GUSMAX_SPEAKER_LVL: /* fake speaker for mute naming */ 2471 if (cp->type == AUDIO_MIXER_VALUE) { 2472 if (sc->sc_mixcontrol & GUSMASK_LINE_OUT) 2473 vol.left = vol.right = AUDIO_MAX_GAIN; 2474 else 2475 vol.left = vol.right = AUDIO_MIN_GAIN; 2476 error = 0; 2477 ad1848_from_vol(cp, &vol); 2478 } 2479 break; 2480 2481 case GUSMAX_SPEAKER_MUTE: 2482 if (cp->type == AUDIO_MIXER_ENUM) { 2483 cp->un.ord = sc->sc_mixcontrol & GUSMASK_LINE_OUT ? 1 : 0; 2484 error = 0; 2485 } 2486 break; 2487 default: 2488 error = ENXIO; 2489 break; 2490 } 2491 2492 return(error); 2493 } 2494 2495 int 2496 gus_mixer_get_port(addr, cp) 2497 void *addr; 2498 mixer_ctrl_t *cp; 2499 { 2500 struct gus_softc *sc = addr; 2501 struct ics2101_softc *ic = &sc->sc_mixer; 2502 struct ad1848_volume vol; 2503 int error = EINVAL; 2504 2505 DPRINTF(("gus_mixer_get_port: dev=%d type=%d\n", cp->dev, cp->type)); 2506 2507 if (!HAS_MIXER(sc) && cp->dev > GUSICS_MASTER_MUTE) 2508 return ENXIO; 2509 2510 switch (cp->dev) { 2511 2512 case GUSICS_MIC_IN_MUTE: /* Microphone */ 2513 if (cp->type == AUDIO_MIXER_ENUM) { 2514 if (HAS_MIXER(sc)) 2515 cp->un.ord = ic->sc_mute[GUSMIX_CHAN_MIC][ICSMIX_LEFT]; 2516 else 2517 cp->un.ord = 2518 sc->sc_mixcontrol & GUSMASK_MIC_IN ? 0 : 1; 2519 error = 0; 2520 } 2521 break; 2522 2523 case GUSICS_LINE_IN_MUTE: 2524 if (cp->type == AUDIO_MIXER_ENUM) { 2525 if (HAS_MIXER(sc)) 2526 cp->un.ord = ic->sc_mute[GUSMIX_CHAN_LINE][ICSMIX_LEFT]; 2527 else 2528 cp->un.ord = 2529 sc->sc_mixcontrol & GUSMASK_LINE_IN ? 1 : 0; 2530 error = 0; 2531 } 2532 break; 2533 2534 case GUSICS_MASTER_MUTE: 2535 if (cp->type == AUDIO_MIXER_ENUM) { 2536 if (HAS_MIXER(sc)) 2537 cp->un.ord = ic->sc_mute[GUSMIX_CHAN_MASTER][ICSMIX_LEFT]; 2538 else 2539 cp->un.ord = 2540 sc->sc_mixcontrol & GUSMASK_LINE_OUT ? 1 : 0; 2541 error = 0; 2542 } 2543 break; 2544 2545 case GUSICS_DAC_MUTE: 2546 if (cp->type == AUDIO_MIXER_ENUM) { 2547 cp->un.ord = ic->sc_mute[GUSMIX_CHAN_DAC][ICSMIX_LEFT]; 2548 error = 0; 2549 } 2550 break; 2551 2552 case GUSICS_CD_MUTE: 2553 if (cp->type == AUDIO_MIXER_ENUM) { 2554 cp->un.ord = ic->sc_mute[GUSMIX_CHAN_CD][ICSMIX_LEFT]; 2555 error = 0; 2556 } 2557 break; 2558 2559 case GUSICS_MASTER_LVL: 2560 if (cp->type == AUDIO_MIXER_VALUE) { 2561 vol.left = ic->sc_setting[GUSMIX_CHAN_MASTER][ICSMIX_LEFT]; 2562 vol.right = ic->sc_setting[GUSMIX_CHAN_MASTER][ICSMIX_RIGHT]; 2563 if (ad1848_from_vol(cp, &vol)) 2564 error = 0; 2565 } 2566 break; 2567 2568 case GUSICS_MIC_IN_LVL: /* Microphone */ 2569 if (cp->type == AUDIO_MIXER_VALUE) { 2570 vol.left = ic->sc_setting[GUSMIX_CHAN_MIC][ICSMIX_LEFT]; 2571 vol.right = ic->sc_setting[GUSMIX_CHAN_MIC][ICSMIX_RIGHT]; 2572 if (ad1848_from_vol(cp, &vol)) 2573 error = 0; 2574 } 2575 break; 2576 2577 case GUSICS_LINE_IN_LVL: /* line in */ 2578 if (cp->type == AUDIO_MIXER_VALUE) { 2579 vol.left = ic->sc_setting[GUSMIX_CHAN_LINE][ICSMIX_LEFT]; 2580 vol.right = ic->sc_setting[GUSMIX_CHAN_LINE][ICSMIX_RIGHT]; 2581 if (ad1848_from_vol(cp, &vol)) 2582 error = 0; 2583 } 2584 break; 2585 2586 2587 case GUSICS_CD_LVL: 2588 if (cp->type == AUDIO_MIXER_VALUE) { 2589 vol.left = ic->sc_setting[GUSMIX_CHAN_CD][ICSMIX_LEFT]; 2590 vol.right = ic->sc_setting[GUSMIX_CHAN_CD][ICSMIX_RIGHT]; 2591 if (ad1848_from_vol(cp, &vol)) 2592 error = 0; 2593 } 2594 break; 2595 2596 case GUSICS_DAC_LVL: /* dac out */ 2597 if (cp->type == AUDIO_MIXER_VALUE) { 2598 vol.left = ic->sc_setting[GUSMIX_CHAN_DAC][ICSMIX_LEFT]; 2599 vol.right = ic->sc_setting[GUSMIX_CHAN_DAC][ICSMIX_RIGHT]; 2600 if (ad1848_from_vol(cp, &vol)) 2601 error = 0; 2602 } 2603 break; 2604 2605 2606 case GUSICS_RECORD_SOURCE: 2607 if (cp->type == AUDIO_MIXER_ENUM) { 2608 /* Can't set anything else useful, sigh. */ 2609 cp->un.ord = 0; 2610 } 2611 break; 2612 2613 default: 2614 return ENXIO; 2615 /*NOTREACHED*/ 2616 } 2617 return error; 2618 } 2619 2620 void 2621 gusics_master_mute(ic, mute) 2622 struct ics2101_softc *ic; 2623 int mute; 2624 { 2625 ics2101_mix_mute(ic, GUSMIX_CHAN_MASTER, ICSMIX_LEFT, mute); 2626 ics2101_mix_mute(ic, GUSMIX_CHAN_MASTER, ICSMIX_RIGHT, mute); 2627 } 2628 2629 void 2630 gusics_mic_mute(ic, mute) 2631 struct ics2101_softc *ic; 2632 int mute; 2633 { 2634 ics2101_mix_mute(ic, GUSMIX_CHAN_MIC, ICSMIX_LEFT, mute); 2635 ics2101_mix_mute(ic, GUSMIX_CHAN_MIC, ICSMIX_RIGHT, mute); 2636 } 2637 2638 void 2639 gusics_linein_mute(ic, mute) 2640 struct ics2101_softc *ic; 2641 int mute; 2642 { 2643 ics2101_mix_mute(ic, GUSMIX_CHAN_LINE, ICSMIX_LEFT, mute); 2644 ics2101_mix_mute(ic, GUSMIX_CHAN_LINE, ICSMIX_RIGHT, mute); 2645 } 2646 2647 void 2648 gusics_cd_mute(ic, mute) 2649 struct ics2101_softc *ic; 2650 int mute; 2651 { 2652 ics2101_mix_mute(ic, GUSMIX_CHAN_CD, ICSMIX_LEFT, mute); 2653 ics2101_mix_mute(ic, GUSMIX_CHAN_CD, ICSMIX_RIGHT, mute); 2654 } 2655 2656 void 2657 gusics_dac_mute(ic, mute) 2658 struct ics2101_softc *ic; 2659 int mute; 2660 { 2661 ics2101_mix_mute(ic, GUSMIX_CHAN_DAC, ICSMIX_LEFT, mute); 2662 ics2101_mix_mute(ic, GUSMIX_CHAN_DAC, ICSMIX_RIGHT, mute); 2663 } 2664 2665 int 2666 gusmax_mixer_set_port(addr, cp) 2667 void *addr; 2668 mixer_ctrl_t *cp; 2669 { 2670 struct ad1848_softc *ac = addr; 2671 struct gus_softc *sc = ac->parent; 2672 struct ad1848_volume vol; 2673 int error = ad1848_mixer_set_port(ac, gusmapping, nummap, cp); 2674 2675 if (error != ENXIO) 2676 return (error); 2677 2678 DPRINTF(("gusmax_mixer_set_port: dev=%d type=%d\n", cp->dev, cp->type)); 2679 2680 switch (cp->dev) { 2681 case GUSMAX_SPEAKER_LVL: 2682 if (cp->type == AUDIO_MIXER_VALUE && 2683 cp->un.value.num_channels == 1) { 2684 if (ad1848_to_vol(cp, &vol)) { 2685 gus_speaker_ctl(sc, vol.left > AUDIO_MIN_GAIN ? 2686 SPKR_ON : SPKR_OFF); 2687 error = 0; 2688 } 2689 } 2690 break; 2691 2692 case GUSMAX_SPEAKER_MUTE: 2693 if (cp->type == AUDIO_MIXER_ENUM) { 2694 gus_speaker_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON); 2695 error = 0; 2696 } 2697 break; 2698 2699 default: 2700 return ENXIO; 2701 /*NOTREACHED*/ 2702 } 2703 return error; 2704 } 2705 2706 int 2707 gus_mixer_set_port(addr, cp) 2708 void *addr; 2709 mixer_ctrl_t *cp; 2710 { 2711 struct gus_softc *sc = addr; 2712 struct ics2101_softc *ic = &sc->sc_mixer; 2713 struct ad1848_volume vol; 2714 int error = EINVAL; 2715 2716 DPRINTF(("gus_mixer_set_port: dev=%d type=%d\n", cp->dev, cp->type)); 2717 2718 if (!HAS_MIXER(sc) && cp->dev > GUSICS_MASTER_MUTE) 2719 return ENXIO; 2720 2721 switch (cp->dev) { 2722 2723 case GUSICS_MIC_IN_MUTE: /* Microphone */ 2724 if (cp->type == AUDIO_MIXER_ENUM) { 2725 DPRINTF(("mic mute %d\n", cp->un.ord)); 2726 if (HAS_MIXER(sc)) { 2727 gusics_mic_mute(ic, cp->un.ord); 2728 } 2729 gus_mic_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON); 2730 error = 0; 2731 } 2732 break; 2733 2734 case GUSICS_LINE_IN_MUTE: 2735 if (cp->type == AUDIO_MIXER_ENUM) { 2736 DPRINTF(("linein mute %d\n", cp->un.ord)); 2737 if (HAS_MIXER(sc)) { 2738 gusics_linein_mute(ic, cp->un.ord); 2739 } 2740 gus_linein_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON); 2741 error = 0; 2742 } 2743 break; 2744 2745 case GUSICS_MASTER_MUTE: 2746 if (cp->type == AUDIO_MIXER_ENUM) { 2747 DPRINTF(("master mute %d\n", cp->un.ord)); 2748 if (HAS_MIXER(sc)) { 2749 gusics_master_mute(ic, cp->un.ord); 2750 } 2751 gus_speaker_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON); 2752 error = 0; 2753 } 2754 break; 2755 2756 case GUSICS_DAC_MUTE: 2757 if (cp->type == AUDIO_MIXER_ENUM) { 2758 gusics_dac_mute(ic, cp->un.ord); 2759 error = 0; 2760 } 2761 break; 2762 2763 case GUSICS_CD_MUTE: 2764 if (cp->type == AUDIO_MIXER_ENUM) { 2765 gusics_cd_mute(ic, cp->un.ord); 2766 error = 0; 2767 } 2768 break; 2769 2770 case GUSICS_MASTER_LVL: 2771 if (cp->type == AUDIO_MIXER_VALUE) { 2772 if (ad1848_to_vol(cp, &vol)) { 2773 ics2101_mix_attenuate(ic, 2774 GUSMIX_CHAN_MASTER, 2775 ICSMIX_LEFT, 2776 vol.left); 2777 ics2101_mix_attenuate(ic, 2778 GUSMIX_CHAN_MASTER, 2779 ICSMIX_RIGHT, 2780 vol.right); 2781 error = 0; 2782 } 2783 } 2784 break; 2785 2786 case GUSICS_MIC_IN_LVL: /* Microphone */ 2787 if (cp->type == AUDIO_MIXER_VALUE) { 2788 if (ad1848_to_vol(cp, &vol)) { 2789 ics2101_mix_attenuate(ic, 2790 GUSMIX_CHAN_MIC, 2791 ICSMIX_LEFT, 2792 vol.left); 2793 ics2101_mix_attenuate(ic, 2794 GUSMIX_CHAN_MIC, 2795 ICSMIX_RIGHT, 2796 vol.right); 2797 error = 0; 2798 } 2799 } 2800 break; 2801 2802 case GUSICS_LINE_IN_LVL: /* line in */ 2803 if (cp->type == AUDIO_MIXER_VALUE) { 2804 if (ad1848_to_vol(cp, &vol)) { 2805 ics2101_mix_attenuate(ic, 2806 GUSMIX_CHAN_LINE, 2807 ICSMIX_LEFT, 2808 vol.left); 2809 ics2101_mix_attenuate(ic, 2810 GUSMIX_CHAN_LINE, 2811 ICSMIX_RIGHT, 2812 vol.right); 2813 error = 0; 2814 } 2815 } 2816 break; 2817 2818 2819 case GUSICS_CD_LVL: 2820 if (cp->type == AUDIO_MIXER_VALUE) { 2821 if (ad1848_to_vol(cp, &vol)) { 2822 ics2101_mix_attenuate(ic, 2823 GUSMIX_CHAN_CD, 2824 ICSMIX_LEFT, 2825 vol.left); 2826 ics2101_mix_attenuate(ic, 2827 GUSMIX_CHAN_CD, 2828 ICSMIX_RIGHT, 2829 vol.right); 2830 error = 0; 2831 } 2832 } 2833 break; 2834 2835 case GUSICS_DAC_LVL: /* dac out */ 2836 if (cp->type == AUDIO_MIXER_VALUE) { 2837 if (ad1848_to_vol(cp, &vol)) { 2838 ics2101_mix_attenuate(ic, 2839 GUSMIX_CHAN_DAC, 2840 ICSMIX_LEFT, 2841 vol.left); 2842 ics2101_mix_attenuate(ic, 2843 GUSMIX_CHAN_DAC, 2844 ICSMIX_RIGHT, 2845 vol.right); 2846 error = 0; 2847 } 2848 } 2849 break; 2850 2851 2852 case GUSICS_RECORD_SOURCE: 2853 if (cp->type == AUDIO_MIXER_ENUM && cp->un.ord == 0) { 2854 /* Can't set anything else useful, sigh. */ 2855 error = 0; 2856 } 2857 break; 2858 2859 default: 2860 return ENXIO; 2861 /*NOTREACHED*/ 2862 } 2863 return error; 2864 } 2865 2866 int 2867 gus_get_props(addr) 2868 void *addr; 2869 { 2870 struct gus_softc *sc = addr; 2871 return AUDIO_PROP_MMAP | 2872 (sc->sc_recdrq == sc->sc_drq ? 0 : AUDIO_PROP_FULLDUPLEX); 2873 } 2874 2875 int 2876 gusmax_get_props(addr) 2877 void *addr; 2878 { 2879 struct ad1848_softc *ac = addr; 2880 return gus_get_props(ac->parent); 2881 } 2882 2883 int 2884 gusmax_mixer_query_devinfo(addr, dip) 2885 void *addr; 2886 mixer_devinfo_t *dip; 2887 { 2888 DPRINTF(("gusmax_query_devinfo: index=%d\n", dip->index)); 2889 2890 switch(dip->index) { 2891 #if 0 2892 case GUSMAX_MIC_IN_LVL: /* Microphone */ 2893 dip->type = AUDIO_MIXER_VALUE; 2894 dip->mixer_class = GUSMAX_INPUT_CLASS; 2895 dip->prev = AUDIO_MIXER_LAST; 2896 dip->next = GUSMAX_MIC_IN_MUTE; 2897 strlcpy(dip->label.name, AudioNmicrophone, sizeof dip->label.name); 2898 dip->un.v.num_channels = 2; 2899 strlcpy(dip->un.v.units.name, AudioNvolume, 2900 sizeof dip->un.v.units.name); 2901 break; 2902 #endif 2903 2904 case GUSMAX_MONO_LVL: /* mono/microphone mixer */ 2905 dip->type = AUDIO_MIXER_VALUE; 2906 dip->mixer_class = GUSMAX_INPUT_CLASS; 2907 dip->prev = AUDIO_MIXER_LAST; 2908 dip->next = GUSMAX_MONO_MUTE; 2909 strlcpy(dip->label.name, AudioNmicrophone, sizeof dip->label.name); 2910 dip->un.v.num_channels = 1; 2911 strlcpy(dip->un.v.units.name, AudioNvolume, 2912 sizeof dip->un.v.units.name); 2913 break; 2914 2915 case GUSMAX_DAC_LVL: /* dacout */ 2916 dip->type = AUDIO_MIXER_VALUE; 2917 dip->mixer_class = GUSMAX_INPUT_CLASS; 2918 dip->prev = AUDIO_MIXER_LAST; 2919 dip->next = GUSMAX_DAC_MUTE; 2920 strlcpy(dip->label.name, AudioNdac, sizeof dip->label.name); 2921 dip->un.v.num_channels = 2; 2922 strlcpy(dip->un.v.units.name, AudioNvolume, 2923 sizeof dip->un.v.units.name); 2924 break; 2925 2926 case GUSMAX_LINE_IN_LVL: /* line */ 2927 dip->type = AUDIO_MIXER_VALUE; 2928 dip->mixer_class = GUSMAX_INPUT_CLASS; 2929 dip->prev = AUDIO_MIXER_LAST; 2930 dip->next = GUSMAX_LINE_IN_MUTE; 2931 strlcpy(dip->label.name, AudioNline, sizeof dip->label.name); 2932 dip->un.v.num_channels = 2; 2933 strlcpy(dip->un.v.units.name, AudioNvolume, 2934 sizeof dip->un.v.units.name); 2935 break; 2936 2937 case GUSMAX_CD_LVL: /* cd */ 2938 dip->type = AUDIO_MIXER_VALUE; 2939 dip->mixer_class = GUSMAX_INPUT_CLASS; 2940 dip->prev = AUDIO_MIXER_LAST; 2941 dip->next = GUSMAX_CD_MUTE; 2942 strlcpy(dip->label.name, AudioNcd, sizeof dip->label.name); 2943 dip->un.v.num_channels = 2; 2944 strlcpy(dip->un.v.units.name, AudioNvolume, 2945 sizeof dip->un.v.units.name); 2946 break; 2947 2948 2949 case GUSMAX_MONITOR_LVL: /* monitor level */ 2950 dip->type = AUDIO_MIXER_VALUE; 2951 dip->mixer_class = GUSMAX_MONITOR_CLASS; 2952 dip->next = GUSMAX_MONITOR_MUTE; 2953 dip->prev = AUDIO_MIXER_LAST; 2954 strlcpy(dip->label.name, AudioNmonitor, sizeof dip->label.name); 2955 dip->un.v.num_channels = 1; 2956 strlcpy(dip->un.v.units.name, AudioNvolume, 2957 sizeof dip->un.v.units.name); 2958 break; 2959 2960 case GUSMAX_OUT_LVL: /* cs4231 output volume: not useful? */ 2961 dip->type = AUDIO_MIXER_VALUE; 2962 dip->mixer_class = GUSMAX_MONITOR_CLASS; 2963 dip->prev = dip->next = AUDIO_MIXER_LAST; 2964 strlcpy(dip->label.name, AudioNoutput, sizeof dip->label.name); 2965 dip->un.v.num_channels = 2; 2966 strlcpy(dip->un.v.units.name, AudioNvolume, 2967 sizeof dip->un.v.units.name); 2968 break; 2969 2970 case GUSMAX_SPEAKER_LVL: /* fake speaker volume */ 2971 dip->type = AUDIO_MIXER_VALUE; 2972 dip->mixer_class = GUSMAX_MONITOR_CLASS; 2973 dip->prev = AUDIO_MIXER_LAST; 2974 dip->next = GUSMAX_SPEAKER_MUTE; 2975 strlcpy(dip->label.name, AudioNmaster, sizeof dip->label.name); 2976 dip->un.v.num_channels = 2; 2977 strlcpy(dip->un.v.units.name, AudioNvolume, 2978 sizeof dip->un.v.units.name); 2979 break; 2980 2981 case GUSMAX_LINE_IN_MUTE: 2982 dip->mixer_class = GUSMAX_INPUT_CLASS; 2983 dip->type = AUDIO_MIXER_ENUM; 2984 dip->prev = GUSMAX_LINE_IN_LVL; 2985 dip->next = AUDIO_MIXER_LAST; 2986 goto mute; 2987 2988 case GUSMAX_DAC_MUTE: 2989 dip->mixer_class = GUSMAX_INPUT_CLASS; 2990 dip->type = AUDIO_MIXER_ENUM; 2991 dip->prev = GUSMAX_DAC_LVL; 2992 dip->next = AUDIO_MIXER_LAST; 2993 goto mute; 2994 2995 case GUSMAX_CD_MUTE: 2996 dip->mixer_class = GUSMAX_INPUT_CLASS; 2997 dip->type = AUDIO_MIXER_ENUM; 2998 dip->prev = GUSMAX_CD_LVL; 2999 dip->next = AUDIO_MIXER_LAST; 3000 goto mute; 3001 3002 case GUSMAX_MONO_MUTE: 3003 dip->mixer_class = GUSMAX_INPUT_CLASS; 3004 dip->type = AUDIO_MIXER_ENUM; 3005 dip->prev = GUSMAX_MONO_LVL; 3006 dip->next = AUDIO_MIXER_LAST; 3007 goto mute; 3008 3009 case GUSMAX_MONITOR_MUTE: 3010 dip->mixer_class = GUSMAX_OUTPUT_CLASS; 3011 dip->type = AUDIO_MIXER_ENUM; 3012 dip->prev = GUSMAX_MONITOR_LVL; 3013 dip->next = AUDIO_MIXER_LAST; 3014 goto mute; 3015 3016 case GUSMAX_SPEAKER_MUTE: 3017 dip->mixer_class = GUSMAX_OUTPUT_CLASS; 3018 dip->type = AUDIO_MIXER_ENUM; 3019 dip->prev = GUSMAX_SPEAKER_LVL; 3020 dip->next = AUDIO_MIXER_LAST; 3021 mute: 3022 strlcpy(dip->label.name, AudioNmute, sizeof dip->label.name); 3023 dip->un.e.num_mem = 2; 3024 strlcpy(dip->un.e.member[0].label.name, AudioNoff, 3025 sizeof dip->un.e.member[0].label.name); 3026 dip->un.e.member[0].ord = 0; 3027 strlcpy(dip->un.e.member[1].label.name, AudioNon, 3028 sizeof dip->un.e.member[1].label.name); 3029 dip->un.e.member[1].ord = 1; 3030 break; 3031 3032 case GUSMAX_REC_LVL: /* record level */ 3033 dip->type = AUDIO_MIXER_VALUE; 3034 dip->mixer_class = GUSMAX_RECORD_CLASS; 3035 dip->prev = AUDIO_MIXER_LAST; 3036 dip->next = GUSMAX_RECORD_SOURCE; 3037 strlcpy(dip->label.name, AudioNrecord, sizeof dip->label.name); 3038 dip->un.v.num_channels = 2; 3039 strlcpy(dip->un.v.units.name, AudioNvolume, sizeof dip->un.v.units.name); 3040 break; 3041 3042 case GUSMAX_RECORD_SOURCE: 3043 dip->mixer_class = GUSMAX_RECORD_CLASS; 3044 dip->type = AUDIO_MIXER_ENUM; 3045 dip->prev = GUSMAX_REC_LVL; 3046 dip->next = AUDIO_MIXER_LAST; 3047 strlcpy(dip->label.name, AudioNsource, sizeof dip->label.name); 3048 dip->un.e.num_mem = 4; 3049 strlcpy(dip->un.e.member[0].label.name, AudioNoutput, 3050 sizeof dip->un.e.member[0].label.name); 3051 dip->un.e.member[0].ord = DAC_IN_PORT; 3052 strlcpy(dip->un.e.member[1].label.name, AudioNmicrophone, 3053 sizeof dip->un.e.member[1].label.name); 3054 dip->un.e.member[1].ord = MIC_IN_PORT; 3055 strlcpy(dip->un.e.member[2].label.name, AudioNdac, 3056 sizeof dip->un.e.member[2].label.name); 3057 dip->un.e.member[2].ord = AUX1_IN_PORT; 3058 strlcpy(dip->un.e.member[3].label.name, AudioNline, 3059 sizeof dip->un.e.member[3].label.name); 3060 dip->un.e.member[3].ord = LINE_IN_PORT; 3061 break; 3062 3063 case GUSMAX_INPUT_CLASS: /* input class descriptor */ 3064 dip->type = AUDIO_MIXER_CLASS; 3065 dip->mixer_class = GUSMAX_INPUT_CLASS; 3066 dip->next = dip->prev = AUDIO_MIXER_LAST; 3067 strlcpy(dip->label.name, AudioCinputs, sizeof dip->label.name); 3068 break; 3069 3070 case GUSMAX_OUTPUT_CLASS: /* output class descriptor */ 3071 dip->type = AUDIO_MIXER_CLASS; 3072 dip->mixer_class = GUSMAX_OUTPUT_CLASS; 3073 dip->next = dip->prev = AUDIO_MIXER_LAST; 3074 strlcpy(dip->label.name, AudioCoutputs, sizeof dip->label.name); 3075 break; 3076 3077 case GUSMAX_MONITOR_CLASS: /* monitor class descriptor */ 3078 dip->type = AUDIO_MIXER_CLASS; 3079 dip->mixer_class = GUSMAX_MONITOR_CLASS; 3080 dip->next = dip->prev = AUDIO_MIXER_LAST; 3081 strlcpy(dip->label.name, AudioCmonitor, sizeof dip->label.name); 3082 break; 3083 3084 case GUSMAX_RECORD_CLASS: /* record source class */ 3085 dip->type = AUDIO_MIXER_CLASS; 3086 dip->mixer_class = GUSMAX_RECORD_CLASS; 3087 dip->next = dip->prev = AUDIO_MIXER_LAST; 3088 strlcpy(dip->label.name, AudioCrecord, sizeof dip->label.name); 3089 break; 3090 3091 default: 3092 return ENXIO; 3093 /*NOTREACHED*/ 3094 } 3095 DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name)); 3096 return 0; 3097 } 3098 3099 int 3100 gus_mixer_query_devinfo(addr, dip) 3101 void *addr; 3102 mixer_devinfo_t *dip; 3103 { 3104 struct gus_softc *sc = addr; 3105 3106 DPRINTF(("gusmax_query_devinfo: index=%d\n", dip->index)); 3107 3108 if (!HAS_MIXER(sc) && dip->index > GUSICS_MASTER_MUTE) 3109 return ENXIO; 3110 3111 switch(dip->index) { 3112 3113 case GUSICS_MIC_IN_LVL: /* Microphone */ 3114 dip->type = AUDIO_MIXER_VALUE; 3115 dip->mixer_class = GUSICS_INPUT_CLASS; 3116 dip->prev = AUDIO_MIXER_LAST; 3117 dip->next = GUSICS_MIC_IN_MUTE; 3118 strlcpy(dip->label.name, AudioNmicrophone, 3119 sizeof dip->label.name); 3120 dip->un.v.num_channels = 2; 3121 strlcpy(dip->un.v.units.name, AudioNvolume, 3122 sizeof dip->un.v.units.name); 3123 break; 3124 3125 case GUSICS_LINE_IN_LVL: /* line */ 3126 dip->type = AUDIO_MIXER_VALUE; 3127 dip->mixer_class = GUSICS_INPUT_CLASS; 3128 dip->prev = AUDIO_MIXER_LAST; 3129 dip->next = GUSICS_LINE_IN_MUTE; 3130 strlcpy(dip->label.name, AudioNline, sizeof dip->label.name); 3131 dip->un.v.num_channels = 2; 3132 strlcpy(dip->un.v.units.name, AudioNvolume, 3133 sizeof dip->un.v.units.name); 3134 break; 3135 3136 case GUSICS_CD_LVL: /* cd */ 3137 dip->type = AUDIO_MIXER_VALUE; 3138 dip->mixer_class = GUSICS_INPUT_CLASS; 3139 dip->prev = AUDIO_MIXER_LAST; 3140 dip->next = GUSICS_CD_MUTE; 3141 strlcpy(dip->label.name, AudioNcd, sizeof dip->label.name); 3142 dip->un.v.num_channels = 2; 3143 strlcpy(dip->un.v.units.name, AudioNvolume, 3144 sizeof dip->un.v.units.name); 3145 break; 3146 3147 case GUSICS_DAC_LVL: /* dacout */ 3148 dip->type = AUDIO_MIXER_VALUE; 3149 dip->mixer_class = GUSICS_INPUT_CLASS; 3150 dip->prev = AUDIO_MIXER_LAST; 3151 dip->next = GUSICS_DAC_MUTE; 3152 strlcpy(dip->label.name, AudioNdac, sizeof dip->label.name); 3153 dip->un.v.num_channels = 2; 3154 strlcpy(dip->un.v.units.name, AudioNvolume, 3155 sizeof dip->un.v.units.name); 3156 break; 3157 3158 case GUSICS_MASTER_LVL: /* master output */ 3159 dip->type = AUDIO_MIXER_VALUE; 3160 dip->mixer_class = GUSICS_OUTPUT_CLASS; 3161 dip->prev = AUDIO_MIXER_LAST; 3162 dip->next = GUSICS_MASTER_MUTE; 3163 strlcpy(dip->label.name, AudioNmaster, sizeof dip->label.name); 3164 dip->un.v.num_channels = 2; 3165 strlcpy(dip->un.v.units.name, AudioNvolume, 3166 sizeof dip->un.v.units.name); 3167 break; 3168 3169 3170 case GUSICS_LINE_IN_MUTE: 3171 dip->mixer_class = GUSICS_INPUT_CLASS; 3172 dip->type = AUDIO_MIXER_ENUM; 3173 dip->prev = GUSICS_LINE_IN_LVL; 3174 dip->next = AUDIO_MIXER_LAST; 3175 goto mute; 3176 3177 case GUSICS_DAC_MUTE: 3178 dip->mixer_class = GUSICS_INPUT_CLASS; 3179 dip->type = AUDIO_MIXER_ENUM; 3180 dip->prev = GUSICS_DAC_LVL; 3181 dip->next = AUDIO_MIXER_LAST; 3182 goto mute; 3183 3184 case GUSICS_CD_MUTE: 3185 dip->mixer_class = GUSICS_INPUT_CLASS; 3186 dip->type = AUDIO_MIXER_ENUM; 3187 dip->prev = GUSICS_CD_LVL; 3188 dip->next = AUDIO_MIXER_LAST; 3189 goto mute; 3190 3191 case GUSICS_MIC_IN_MUTE: 3192 dip->mixer_class = GUSICS_INPUT_CLASS; 3193 dip->type = AUDIO_MIXER_ENUM; 3194 dip->prev = GUSICS_MIC_IN_LVL; 3195 dip->next = AUDIO_MIXER_LAST; 3196 goto mute; 3197 3198 case GUSICS_MASTER_MUTE: 3199 dip->mixer_class = GUSICS_OUTPUT_CLASS; 3200 dip->type = AUDIO_MIXER_ENUM; 3201 dip->prev = GUSICS_MASTER_LVL; 3202 dip->next = AUDIO_MIXER_LAST; 3203 mute: 3204 strlcpy(dip->label.name, AudioNmute, sizeof dip->label.name); 3205 dip->un.e.num_mem = 2; 3206 strlcpy(dip->un.e.member[0].label.name, AudioNoff, 3207 sizeof dip->un.e.member[0].label.name); 3208 dip->un.e.member[0].ord = 0; 3209 strlcpy(dip->un.e.member[1].label.name, AudioNon, 3210 sizeof dip->un.e.member[1].label.name); 3211 dip->un.e.member[1].ord = 1; 3212 break; 3213 3214 case GUSICS_RECORD_SOURCE: 3215 dip->mixer_class = GUSICS_RECORD_CLASS; 3216 dip->type = AUDIO_MIXER_ENUM; 3217 dip->prev = dip->next = AUDIO_MIXER_LAST; 3218 strlcpy(dip->label.name, AudioNsource, sizeof dip->label.name); 3219 dip->un.e.num_mem = 1; 3220 strlcpy(dip->un.e.member[0].label.name, AudioNoutput, 3221 sizeof dip->un.e.member[0].label.name); 3222 dip->un.e.member[0].ord = GUSICS_MASTER_LVL; 3223 break; 3224 3225 case GUSICS_INPUT_CLASS: 3226 dip->type = AUDIO_MIXER_CLASS; 3227 dip->mixer_class = GUSICS_INPUT_CLASS; 3228 dip->next = dip->prev = AUDIO_MIXER_LAST; 3229 strlcpy(dip->label.name, AudioCinputs, sizeof dip->label.name); 3230 break; 3231 3232 case GUSICS_OUTPUT_CLASS: 3233 dip->type = AUDIO_MIXER_CLASS; 3234 dip->mixer_class = GUSICS_OUTPUT_CLASS; 3235 dip->next = dip->prev = AUDIO_MIXER_LAST; 3236 strlcpy(dip->label.name, AudioCoutputs, sizeof dip->label.name); 3237 break; 3238 3239 case GUSICS_RECORD_CLASS: 3240 dip->type = AUDIO_MIXER_CLASS; 3241 dip->mixer_class = GUSICS_RECORD_CLASS; 3242 dip->next = dip->prev = AUDIO_MIXER_LAST; 3243 strlcpy(dip->label.name, AudioCrecord, sizeof dip->label.name); 3244 break; 3245 3246 default: 3247 return ENXIO; 3248 /*NOTREACHED*/ 3249 } 3250 DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name)); 3251 return 0; 3252 } 3253 3254 int 3255 gus_query_encoding(addr, fp) 3256 void *addr; 3257 struct audio_encoding *fp; 3258 { 3259 switch (fp->index) { 3260 case 0: 3261 strlcpy(fp->name, AudioEmulaw, sizeof fp->name); 3262 fp->encoding = AUDIO_ENCODING_ULAW; 3263 fp->precision = 8; 3264 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 3265 break; 3266 case 1: 3267 strlcpy(fp->name, AudioEslinear, sizeof fp->name); 3268 fp->encoding = AUDIO_ENCODING_SLINEAR; 3269 fp->precision = 8; 3270 fp->flags = 0; 3271 break; 3272 case 2: 3273 strlcpy(fp->name, AudioEslinear_le, sizeof fp->name); 3274 fp->encoding = AUDIO_ENCODING_SLINEAR_LE; 3275 fp->precision = 16; 3276 fp->flags = 0; 3277 break; 3278 case 3: 3279 strlcpy(fp->name, AudioEulinear, sizeof fp->name); 3280 fp->encoding = AUDIO_ENCODING_ULINEAR; 3281 fp->precision = 8; 3282 fp->flags = 0; 3283 break; 3284 case 4: 3285 strlcpy(fp->name, AudioEulinear_le, sizeof fp->name); 3286 fp->encoding = AUDIO_ENCODING_ULINEAR_LE; 3287 fp->precision = 16; 3288 fp->flags = 0; 3289 break; 3290 case 5: 3291 strlcpy(fp->name, AudioEslinear_be, sizeof fp->name); 3292 fp->encoding = AUDIO_ENCODING_SLINEAR_BE; 3293 fp->precision = 16; 3294 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 3295 break; 3296 case 6: 3297 strlcpy(fp->name, AudioEulinear_be, sizeof fp->name); 3298 fp->encoding = AUDIO_ENCODING_ULINEAR_BE; 3299 fp->precision = 16; 3300 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 3301 break; 3302 case 7: 3303 strlcpy(fp->name, AudioEalaw, sizeof fp->name); 3304 fp->encoding = AUDIO_ENCODING_ALAW; 3305 fp->precision = 8; 3306 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 3307 break; 3308 3309 default: 3310 return(EINVAL); 3311 /*NOTREACHED*/ 3312 } 3313 return (0); 3314 } 3315 3316 /* 3317 * Setup the ICS mixer in "transparent" mode: reset everything to a sensible 3318 * level. Levels as suggested by GUS SDK code. 3319 */ 3320 3321 void 3322 gus_init_ics2101(sc) 3323 struct gus_softc *sc; 3324 { 3325 struct ics2101_softc *ic = &sc->sc_mixer; 3326 sc->sc_mixer.sc_iot = sc->sc_iot; 3327 sc->sc_mixer.sc_selio = GUS_MIXER_SELECT; 3328 sc->sc_mixer.sc_selio_ioh = sc->sc_ioh3; 3329 sc->sc_mixer.sc_dataio = GUS_MIXER_DATA; 3330 sc->sc_mixer.sc_dataio_ioh = sc->sc_ioh2; 3331 sc->sc_mixer.sc_flags = (sc->sc_revision == 5) ? ICS_FLIP : 0; 3332 3333 ics2101_mix_attenuate(ic, 3334 GUSMIX_CHAN_MIC, 3335 ICSMIX_LEFT, 3336 ICSMIX_MIN_ATTN); 3337 ics2101_mix_attenuate(ic, 3338 GUSMIX_CHAN_MIC, 3339 ICSMIX_RIGHT, 3340 ICSMIX_MIN_ATTN); 3341 /* 3342 * Start with microphone muted by the mixer... 3343 */ 3344 gusics_mic_mute(ic, 1); 3345 3346 /* ... and enabled by the GUS master mix control */ 3347 gus_mic_ctl(sc, SPKR_ON); 3348 3349 ics2101_mix_attenuate(ic, 3350 GUSMIX_CHAN_LINE, 3351 ICSMIX_LEFT, 3352 ICSMIX_MIN_ATTN); 3353 ics2101_mix_attenuate(ic, 3354 GUSMIX_CHAN_LINE, 3355 ICSMIX_RIGHT, 3356 ICSMIX_MIN_ATTN); 3357 3358 ics2101_mix_attenuate(ic, 3359 GUSMIX_CHAN_CD, 3360 ICSMIX_LEFT, 3361 ICSMIX_MIN_ATTN); 3362 ics2101_mix_attenuate(ic, 3363 GUSMIX_CHAN_CD, 3364 ICSMIX_RIGHT, 3365 ICSMIX_MIN_ATTN); 3366 3367 ics2101_mix_attenuate(ic, 3368 GUSMIX_CHAN_DAC, 3369 ICSMIX_LEFT, 3370 ICSMIX_MIN_ATTN); 3371 ics2101_mix_attenuate(ic, 3372 GUSMIX_CHAN_DAC, 3373 ICSMIX_RIGHT, 3374 ICSMIX_MIN_ATTN); 3375 3376 ics2101_mix_attenuate(ic, 3377 ICSMIX_CHAN_4, 3378 ICSMIX_LEFT, 3379 ICSMIX_MAX_ATTN); 3380 ics2101_mix_attenuate(ic, 3381 ICSMIX_CHAN_4, 3382 ICSMIX_RIGHT, 3383 ICSMIX_MAX_ATTN); 3384 3385 ics2101_mix_attenuate(ic, 3386 GUSMIX_CHAN_MASTER, 3387 ICSMIX_LEFT, 3388 ICSMIX_MIN_ATTN); 3389 ics2101_mix_attenuate(ic, 3390 GUSMIX_CHAN_MASTER, 3391 ICSMIX_RIGHT, 3392 ICSMIX_MIN_ATTN); 3393 /* unmute other stuff: */ 3394 gusics_cd_mute(ic, 0); 3395 gusics_dac_mute(ic, 0); 3396 gusics_linein_mute(ic, 0); 3397 return; 3398 } 3399 3400 3401 3402 void 3403 gus_subattach(sc, ia) 3404 struct gus_softc *sc; 3405 struct isa_attach_args *ia; 3406 { 3407 int i; 3408 bus_space_tag_t iot; 3409 unsigned char c,d,m; 3410 3411 iot = sc->sc_iot; 3412 3413 /* 3414 * Figure out our board rev, and see if we need to initialize the 3415 * mixer 3416 */ 3417 3418 c = bus_space_read_1(iot, sc->sc_ioh3, GUS_BOARD_REV); 3419 if (c != 0xff) 3420 sc->sc_revision = c; 3421 else 3422 sc->sc_revision = 0; 3423 3424 SELECT_GUS_REG(iot, sc->sc_ioh2, GUSREG_RESET); 3425 bus_space_write_1(iot, sc->sc_ioh2, GUS_DATA_HIGH, 0x00); 3426 3427 gusreset(sc, GUS_MAX_VOICES); /* initialize all voices */ 3428 gusreset(sc, GUS_MIN_VOICES); /* then set to just the ones we use */ 3429 3430 /* 3431 * Setup the IRQ and DRQ lines in software, using values from 3432 * config file 3433 */ 3434 3435 m = GUSMASK_LINE_IN|GUSMASK_LINE_OUT; /* disable all */ 3436 3437 c = ((unsigned char) gus_irq_map[ia->ia_irq]) | GUSMASK_BOTH_RQ; 3438 3439 if (sc->sc_recdrq == sc->sc_drq) 3440 d = (unsigned char) (gus_drq_map[sc->sc_drq] | 3441 GUSMASK_BOTH_RQ); 3442 else 3443 d = (unsigned char) (gus_drq_map[sc->sc_drq] | 3444 gus_drq_map[sc->sc_recdrq] << 3); 3445 3446 /* 3447 * Program the IRQ and DMA channels on the GUS. Note that we hardwire 3448 * the GUS to only use one IRQ channel, but we give the user the 3449 * option of using two DMA channels (the other one given by the drq2 3450 * option in the config file). Two DMA channels are needed for full- 3451 * duplex operation. 3452 * 3453 * The order of these operations is very magical. 3454 */ 3455 3456 disable_intr(); /* XXX needed? */ 3457 3458 bus_space_write_1(iot, sc->sc_ioh1, GUS_REG_CONTROL, GUS_REG_IRQCTL); 3459 bus_space_write_1(iot, sc->sc_ioh1, GUS_MIX_CONTROL, m); 3460 bus_space_write_1(iot, sc->sc_ioh1, GUS_IRQCTL_CONTROL, 0x00); 3461 bus_space_write_1(iot, sc->sc_ioh1, 0x0f, 0x00); 3462 3463 bus_space_write_1(iot, sc->sc_ioh1, GUS_MIX_CONTROL, m); 3464 3465 /* magic reset? */ 3466 bus_space_write_1(iot, sc->sc_ioh1, GUS_DMA_CONTROL, d | 0x80); 3467 3468 bus_space_write_1(iot, sc->sc_ioh1, GUS_MIX_CONTROL, 3469 m | GUSMASK_CONTROL_SEL); 3470 bus_space_write_1(iot, sc->sc_ioh1, GUS_IRQ_CONTROL, c); 3471 3472 bus_space_write_1(iot, sc->sc_ioh1, GUS_MIX_CONTROL, m); 3473 bus_space_write_1(iot, sc->sc_ioh1, GUS_DMA_CONTROL, d); 3474 3475 bus_space_write_1(iot, sc->sc_ioh1, GUS_MIX_CONTROL, 3476 m | GUSMASK_CONTROL_SEL); 3477 bus_space_write_1(iot, sc->sc_ioh1, GUS_IRQ_CONTROL, c); 3478 3479 bus_space_write_1(iot, sc->sc_ioh2, GUS_VOICE_SELECT, 0x00); 3480 3481 /* enable line in, line out. leave mic disabled. */ 3482 bus_space_write_1(iot, sc->sc_ioh1, GUS_MIX_CONTROL, 3483 (m | GUSMASK_LATCHES) & ~(GUSMASK_LINE_OUT|GUSMASK_LINE_IN)); 3484 bus_space_write_1(iot, sc->sc_ioh2, GUS_VOICE_SELECT, 0x00); 3485 3486 enable_intr(); 3487 3488 sc->sc_mixcontrol = 3489 (m | GUSMASK_LATCHES) & ~(GUSMASK_LINE_OUT|GUSMASK_LINE_IN); 3490 3491 sc->sc_codec.sc_isa = sc->sc_isa; 3492 3493 if (sc->sc_revision >= 5 && sc->sc_revision <= 9) { 3494 sc->sc_flags |= GUS_MIXER_INSTALLED; 3495 gus_init_ics2101(sc); 3496 } 3497 if (sc->sc_revision < 10 || !gus_init_cs4231(sc)) { 3498 /* Not using the CS4231, so create our DMA maps. */ 3499 if (sc->sc_drq != -1) { 3500 if (isa_dmamap_create(sc->sc_isa, sc->sc_drq, 3501 MAX_ISADMA, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) { 3502 printf("%s: can't create map for drq %d\n", 3503 sc->sc_dev.dv_xname, sc->sc_drq); 3504 return; 3505 } 3506 } 3507 if (sc->sc_recdrq != -1 && sc->sc_recdrq != sc->sc_drq) { 3508 if (isa_dmamap_create(sc->sc_isa, sc->sc_recdrq, 3509 MAX_ISADMA, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) { 3510 printf("%s: can't create map for drq %d\n", 3511 sc->sc_dev.dv_xname, sc->sc_recdrq); 3512 return; 3513 } 3514 } 3515 } 3516 3517 timeout_set(&sc->sc_dma_tmo, gus_dmaout_timeout, sc); 3518 3519 SELECT_GUS_REG(iot, sc->sc_ioh2, GUSREG_RESET); 3520 /* 3521 * Check to see how much memory we have on this card; see if any 3522 * "mirroring" occurs. We're assuming at least 256K already exists 3523 * on the card; otherwise the initial probe would have failed 3524 */ 3525 3526 guspoke(iot, sc->sc_ioh2, 0L, 0x00); 3527 for(i = 1; i < 1024; i++) { 3528 u_long loc; 3529 3530 /* 3531 * See if we've run into mirroring yet 3532 */ 3533 3534 if (guspeek(iot, sc->sc_ioh2, 0L) != 0) 3535 break; 3536 3537 loc = i << 10; 3538 3539 guspoke(iot, sc->sc_ioh2, loc, 0xaa); 3540 if (guspeek(iot, sc->sc_ioh2, loc) != 0xaa) 3541 break; 3542 } 3543 3544 sc->sc_dsize = i; 3545 /* 3546 * The "official" (3.x) version number cannot easily be obtained. 3547 * The revision register does not correspond to the minor number 3548 * of the board version. Simply use the revision register as 3549 * identification. 3550 */ 3551 snprintf(gus_device.version, sizeof gus_device.version, "%d", 3552 sc->sc_revision); 3553 3554 printf(": ver %d", sc->sc_revision); 3555 if (sc->sc_revision >= 10) 3556 printf(", MAX"); 3557 else { 3558 if (HAS_MIXER(sc)) 3559 printf(", ICS2101 mixer"); 3560 if (HAS_CODEC(sc)) 3561 printf(", %s codec/mixer", sc->sc_codec.chip_name); 3562 } 3563 printf(", %dKB DRAM, ", sc->sc_dsize); 3564 if (sc->sc_recdrq == sc->sc_drq) { 3565 printf("half-duplex"); 3566 } else { 3567 printf("full-duplex, record drq %d", sc->sc_recdrq); 3568 } 3569 3570 printf("\n"); 3571 3572 /* 3573 * Setup a default interrupt handler 3574 */ 3575 3576 /* XXX we shouldn't have to use splgus == splclock, nor should 3577 * we use IPL_CLOCK. 3578 */ 3579 sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq, IST_EDGE, 3580 IPL_AUDIO, gusintr, sc /* sc->sc_gusdsp */, sc->sc_dev.dv_xname); 3581 3582 /* 3583 * Set some default values 3584 * XXX others start with 8kHz mono mulaw 3585 */ 3586 3587 sc->sc_irate = sc->sc_orate = 44100; 3588 sc->sc_encoding = AUDIO_ENCODING_SLINEAR_LE; 3589 sc->sc_precision = 16; 3590 sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_DATA_SIZE16; 3591 sc->sc_voc[GUS_VOICE_RIGHT].voccntl |= GUSMASK_DATA_SIZE16; 3592 sc->sc_channels = 1; 3593 sc->sc_ogain = 340; 3594 gus_commit_settings(sc); 3595 3596 /* 3597 * We always put the left channel full left & right channel 3598 * full right. 3599 * For mono playback, we set up both voices playing the same buffer. 3600 */ 3601 bus_space_write_1(iot, sc->sc_ioh2, GUS_VOICE_SELECT, 3602 (u_char)GUS_VOICE_LEFT); 3603 SELECT_GUS_REG(iot, sc->sc_ioh2, GUSREG_PAN_POS); 3604 bus_space_write_1(iot, sc->sc_ioh2, GUS_DATA_HIGH, GUS_PAN_FULL_LEFT); 3605 3606 bus_space_write_1(iot, sc->sc_ioh2, GUS_VOICE_SELECT, 3607 (u_char)GUS_VOICE_RIGHT); 3608 SELECT_GUS_REG(iot, sc->sc_ioh2, GUSREG_PAN_POS); 3609 bus_space_write_1(iot, sc->sc_ioh2, GUS_DATA_HIGH, GUS_PAN_FULL_RIGHT); 3610 3611 /* 3612 * Attach to the generic audio layer 3613 */ 3614 3615 audio_attach_mi(&gus_hw_if, HAS_CODEC(sc) ? (void *)&sc->sc_codec : 3616 (void *)sc, &sc->sc_dev); 3617 } 3618 3619 /* 3620 * Test to see if a particular I/O base is valid for the GUS. Return true 3621 * if it is. 3622 */ 3623 3624 int 3625 gus_test_iobase (iot, iobase) 3626 bus_space_tag_t iot; 3627 int iobase; 3628 { 3629 bus_space_handle_t ioh1, ioh2, ioh3, ioh4; 3630 u_char s1, s2; 3631 int s, rv = 0; 3632 3633 /* Map i/o space */ 3634 if (bus_space_map(iot, iobase, GUS_NPORT1, 0, &ioh1)) 3635 return 0; 3636 if (bus_space_map(iot, iobase+GUS_IOH2_OFFSET, GUS_NPORT2, 0, &ioh2)) 3637 goto bad1; 3638 3639 /* XXX Maybe we shouldn't fail on mapping this, but just assume 3640 * the card is of revision 0? */ 3641 if (bus_space_map(iot, iobase+GUS_IOH3_OFFSET, GUS_NPORT3, 0, &ioh3)) 3642 goto bad2; 3643 3644 if (bus_space_map(iot, iobase+GUS_IOH4_OFFSET, GUS_NPORT4, 0, &ioh4)) 3645 goto bad3; 3646 3647 /* 3648 * Reset GUS to an initial state before we do anything. 3649 */ 3650 3651 s = splgus(); 3652 delay(500); 3653 3654 SELECT_GUS_REG(iot, ioh2, GUSREG_RESET); 3655 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00); 3656 3657 delay(500); 3658 3659 SELECT_GUS_REG(iot, ioh2, GUSREG_RESET); 3660 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, GUSMASK_MASTER_RESET); 3661 3662 delay(500); 3663 3664 splx(s); 3665 3666 /* 3667 * See if we can write to the board's memory 3668 */ 3669 3670 s1 = guspeek(iot, ioh2, 0L); 3671 s2 = guspeek(iot, ioh2, 1L); 3672 3673 guspoke(iot, ioh2, 0L, 0xaa); 3674 guspoke(iot, ioh2, 1L, 0x55); 3675 3676 if (guspeek(iot, ioh2, 0L) != 0xaa) 3677 goto bad; 3678 3679 guspoke(iot, ioh2, 0L, s1); 3680 guspoke(iot, ioh2, 1L, s2); 3681 3682 rv = 1; 3683 3684 bad: 3685 bus_space_unmap(iot, ioh4, GUS_NPORT4); 3686 bad3: 3687 bus_space_unmap(iot, ioh3, GUS_NPORT3); 3688 bad2: 3689 bus_space_unmap(iot, ioh2, GUS_NPORT2); 3690 bad1: 3691 bus_space_unmap(iot, ioh1, GUS_NPORT1); 3692 return rv; 3693 } 3694