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