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