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