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