1 /* $OpenBSD: gus.c,v 1.26 2003/06/08 00:41:47 miod 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 * http://www.gravis.com/Public/sdk/GUSDK222.ZIP 61 * 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)(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)(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)(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)(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_mapprobe(&sc->sc_codec, sc->sc_codec.sc_iobase) == 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)(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)(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)(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 strlcpy(dip->label.name, AudioNmicrophone, sizeof dip->label.name); 2907 dip->un.v.num_channels = 2; 2908 strlcpy(dip->un.v.units.name, AudioNvolume, 2909 sizeof dip->un.v.units.name); 2910 break; 2911 #endif 2912 2913 case GUSMAX_MONO_LVL: /* mono/microphone mixer */ 2914 dip->type = AUDIO_MIXER_VALUE; 2915 dip->mixer_class = GUSMAX_INPUT_CLASS; 2916 dip->prev = AUDIO_MIXER_LAST; 2917 dip->next = GUSMAX_MONO_MUTE; 2918 strlcpy(dip->label.name, AudioNmicrophone, sizeof dip->label.name); 2919 dip->un.v.num_channels = 1; 2920 strlcpy(dip->un.v.units.name, AudioNvolume, 2921 sizeof dip->un.v.units.name); 2922 break; 2923 2924 case GUSMAX_DAC_LVL: /* dacout */ 2925 dip->type = AUDIO_MIXER_VALUE; 2926 dip->mixer_class = GUSMAX_INPUT_CLASS; 2927 dip->prev = AUDIO_MIXER_LAST; 2928 dip->next = GUSMAX_DAC_MUTE; 2929 strlcpy(dip->label.name, AudioNdac, sizeof dip->label.name); 2930 dip->un.v.num_channels = 2; 2931 strlcpy(dip->un.v.units.name, AudioNvolume, 2932 sizeof dip->un.v.units.name); 2933 break; 2934 2935 case GUSMAX_LINE_IN_LVL: /* line */ 2936 dip->type = AUDIO_MIXER_VALUE; 2937 dip->mixer_class = GUSMAX_INPUT_CLASS; 2938 dip->prev = AUDIO_MIXER_LAST; 2939 dip->next = GUSMAX_LINE_IN_MUTE; 2940 strlcpy(dip->label.name, AudioNline, sizeof dip->label.name); 2941 dip->un.v.num_channels = 2; 2942 strlcpy(dip->un.v.units.name, AudioNvolume, 2943 sizeof dip->un.v.units.name); 2944 break; 2945 2946 case GUSMAX_CD_LVL: /* cd */ 2947 dip->type = AUDIO_MIXER_VALUE; 2948 dip->mixer_class = GUSMAX_INPUT_CLASS; 2949 dip->prev = AUDIO_MIXER_LAST; 2950 dip->next = GUSMAX_CD_MUTE; 2951 strlcpy(dip->label.name, AudioNcd, sizeof dip->label.name); 2952 dip->un.v.num_channels = 2; 2953 strlcpy(dip->un.v.units.name, AudioNvolume, 2954 sizeof dip->un.v.units.name); 2955 break; 2956 2957 2958 case GUSMAX_MONITOR_LVL: /* monitor level */ 2959 dip->type = AUDIO_MIXER_VALUE; 2960 dip->mixer_class = GUSMAX_MONITOR_CLASS; 2961 dip->next = GUSMAX_MONITOR_MUTE; 2962 dip->prev = AUDIO_MIXER_LAST; 2963 strlcpy(dip->label.name, AudioNmonitor, sizeof dip->label.name); 2964 dip->un.v.num_channels = 1; 2965 strlcpy(dip->un.v.units.name, AudioNvolume, 2966 sizeof dip->un.v.units.name); 2967 break; 2968 2969 case GUSMAX_OUT_LVL: /* cs4231 output volume: not useful? */ 2970 dip->type = AUDIO_MIXER_VALUE; 2971 dip->mixer_class = GUSMAX_MONITOR_CLASS; 2972 dip->prev = dip->next = AUDIO_MIXER_LAST; 2973 strlcpy(dip->label.name, AudioNoutput, sizeof dip->label.name); 2974 dip->un.v.num_channels = 2; 2975 strlcpy(dip->un.v.units.name, AudioNvolume, 2976 sizeof dip->un.v.units.name); 2977 break; 2978 2979 case GUSMAX_SPEAKER_LVL: /* fake speaker volume */ 2980 dip->type = AUDIO_MIXER_VALUE; 2981 dip->mixer_class = GUSMAX_MONITOR_CLASS; 2982 dip->prev = AUDIO_MIXER_LAST; 2983 dip->next = GUSMAX_SPEAKER_MUTE; 2984 strlcpy(dip->label.name, AudioNmaster, sizeof dip->label.name); 2985 dip->un.v.num_channels = 2; 2986 strlcpy(dip->un.v.units.name, AudioNvolume, 2987 sizeof dip->un.v.units.name); 2988 break; 2989 2990 case GUSMAX_LINE_IN_MUTE: 2991 dip->mixer_class = GUSMAX_INPUT_CLASS; 2992 dip->type = AUDIO_MIXER_ENUM; 2993 dip->prev = GUSMAX_LINE_IN_LVL; 2994 dip->next = AUDIO_MIXER_LAST; 2995 goto mute; 2996 2997 case GUSMAX_DAC_MUTE: 2998 dip->mixer_class = GUSMAX_INPUT_CLASS; 2999 dip->type = AUDIO_MIXER_ENUM; 3000 dip->prev = GUSMAX_DAC_LVL; 3001 dip->next = AUDIO_MIXER_LAST; 3002 goto mute; 3003 3004 case GUSMAX_CD_MUTE: 3005 dip->mixer_class = GUSMAX_INPUT_CLASS; 3006 dip->type = AUDIO_MIXER_ENUM; 3007 dip->prev = GUSMAX_CD_LVL; 3008 dip->next = AUDIO_MIXER_LAST; 3009 goto mute; 3010 3011 case GUSMAX_MONO_MUTE: 3012 dip->mixer_class = GUSMAX_INPUT_CLASS; 3013 dip->type = AUDIO_MIXER_ENUM; 3014 dip->prev = GUSMAX_MONO_LVL; 3015 dip->next = AUDIO_MIXER_LAST; 3016 goto mute; 3017 3018 case GUSMAX_MONITOR_MUTE: 3019 dip->mixer_class = GUSMAX_OUTPUT_CLASS; 3020 dip->type = AUDIO_MIXER_ENUM; 3021 dip->prev = GUSMAX_MONITOR_LVL; 3022 dip->next = AUDIO_MIXER_LAST; 3023 goto mute; 3024 3025 case GUSMAX_SPEAKER_MUTE: 3026 dip->mixer_class = GUSMAX_OUTPUT_CLASS; 3027 dip->type = AUDIO_MIXER_ENUM; 3028 dip->prev = GUSMAX_SPEAKER_LVL; 3029 dip->next = AUDIO_MIXER_LAST; 3030 mute: 3031 strlcpy(dip->label.name, AudioNmute, sizeof dip->label.name); 3032 dip->un.e.num_mem = 2; 3033 strlcpy(dip->un.e.member[0].label.name, AudioNoff, 3034 sizeof dip->un.e.member[0].label.name); 3035 dip->un.e.member[0].ord = 0; 3036 strlcpy(dip->un.e.member[1].label.name, AudioNon, 3037 sizeof dip->un.e.member[1].label.name); 3038 dip->un.e.member[1].ord = 1; 3039 break; 3040 3041 case GUSMAX_REC_LVL: /* record level */ 3042 dip->type = AUDIO_MIXER_VALUE; 3043 dip->mixer_class = GUSMAX_RECORD_CLASS; 3044 dip->prev = AUDIO_MIXER_LAST; 3045 dip->next = GUSMAX_RECORD_SOURCE; 3046 strlcpy(dip->label.name, AudioNrecord, sizeof dip->label.name); 3047 dip->un.v.num_channels = 2; 3048 strlcpy(dip->un.v.units.name, AudioNvolume, sizeof dip->un.v.units.name); 3049 break; 3050 3051 case GUSMAX_RECORD_SOURCE: 3052 dip->mixer_class = GUSMAX_RECORD_CLASS; 3053 dip->type = AUDIO_MIXER_ENUM; 3054 dip->prev = GUSMAX_REC_LVL; 3055 dip->next = AUDIO_MIXER_LAST; 3056 strlcpy(dip->label.name, AudioNsource, sizeof dip->label.name); 3057 dip->un.e.num_mem = 4; 3058 strlcpy(dip->un.e.member[0].label.name, AudioNoutput, 3059 sizeof dip->un.e.member[0].label.name); 3060 dip->un.e.member[0].ord = DAC_IN_PORT; 3061 strlcpy(dip->un.e.member[1].label.name, AudioNmicrophone, 3062 sizeof dip->un.e.member[1].label.name); 3063 dip->un.e.member[1].ord = MIC_IN_PORT; 3064 strlcpy(dip->un.e.member[2].label.name, AudioNdac, 3065 sizeof dip->un.e.member[2].label.name); 3066 dip->un.e.member[2].ord = AUX1_IN_PORT; 3067 strlcpy(dip->un.e.member[3].label.name, AudioNline, 3068 sizeof dip->un.e.member[3].label.name); 3069 dip->un.e.member[3].ord = LINE_IN_PORT; 3070 break; 3071 3072 case GUSMAX_INPUT_CLASS: /* input class descriptor */ 3073 dip->type = AUDIO_MIXER_CLASS; 3074 dip->mixer_class = GUSMAX_INPUT_CLASS; 3075 dip->next = dip->prev = AUDIO_MIXER_LAST; 3076 strlcpy(dip->label.name, AudioCinputs, sizeof dip->label.name); 3077 break; 3078 3079 case GUSMAX_OUTPUT_CLASS: /* output class descriptor */ 3080 dip->type = AUDIO_MIXER_CLASS; 3081 dip->mixer_class = GUSMAX_OUTPUT_CLASS; 3082 dip->next = dip->prev = AUDIO_MIXER_LAST; 3083 strlcpy(dip->label.name, AudioCoutputs, sizeof dip->label.name); 3084 break; 3085 3086 case GUSMAX_MONITOR_CLASS: /* monitor class descriptor */ 3087 dip->type = AUDIO_MIXER_CLASS; 3088 dip->mixer_class = GUSMAX_MONITOR_CLASS; 3089 dip->next = dip->prev = AUDIO_MIXER_LAST; 3090 strlcpy(dip->label.name, AudioCmonitor, sizeof dip->label.name); 3091 break; 3092 3093 case GUSMAX_RECORD_CLASS: /* record source class */ 3094 dip->type = AUDIO_MIXER_CLASS; 3095 dip->mixer_class = GUSMAX_RECORD_CLASS; 3096 dip->next = dip->prev = AUDIO_MIXER_LAST; 3097 strlcpy(dip->label.name, AudioCrecord, sizeof dip->label.name); 3098 break; 3099 3100 default: 3101 return ENXIO; 3102 /*NOTREACHED*/ 3103 } 3104 DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name)); 3105 return 0; 3106 } 3107 3108 int 3109 gus_mixer_query_devinfo(addr, dip) 3110 void *addr; 3111 mixer_devinfo_t *dip; 3112 { 3113 struct gus_softc *sc = addr; 3114 3115 DPRINTF(("gusmax_query_devinfo: index=%d\n", dip->index)); 3116 3117 if (!HAS_MIXER(sc) && dip->index > GUSICS_MASTER_MUTE) 3118 return ENXIO; 3119 3120 switch(dip->index) { 3121 3122 case GUSICS_MIC_IN_LVL: /* Microphone */ 3123 dip->type = AUDIO_MIXER_VALUE; 3124 dip->mixer_class = GUSICS_INPUT_CLASS; 3125 dip->prev = AUDIO_MIXER_LAST; 3126 dip->next = GUSICS_MIC_IN_MUTE; 3127 strlcpy(dip->label.name, AudioNmicrophone, 3128 sizeof dip->label.name); 3129 dip->un.v.num_channels = 2; 3130 strlcpy(dip->un.v.units.name, AudioNvolume, 3131 sizeof dip->un.v.units.name); 3132 break; 3133 3134 case GUSICS_LINE_IN_LVL: /* line */ 3135 dip->type = AUDIO_MIXER_VALUE; 3136 dip->mixer_class = GUSICS_INPUT_CLASS; 3137 dip->prev = AUDIO_MIXER_LAST; 3138 dip->next = GUSICS_LINE_IN_MUTE; 3139 strlcpy(dip->label.name, AudioNline, sizeof dip->label.name); 3140 dip->un.v.num_channels = 2; 3141 strlcpy(dip->un.v.units.name, AudioNvolume, 3142 sizeof dip->un.v.units.name); 3143 break; 3144 3145 case GUSICS_CD_LVL: /* cd */ 3146 dip->type = AUDIO_MIXER_VALUE; 3147 dip->mixer_class = GUSICS_INPUT_CLASS; 3148 dip->prev = AUDIO_MIXER_LAST; 3149 dip->next = GUSICS_CD_MUTE; 3150 strlcpy(dip->label.name, AudioNcd, sizeof dip->label.name); 3151 dip->un.v.num_channels = 2; 3152 strlcpy(dip->un.v.units.name, AudioNvolume, 3153 sizeof dip->un.v.units.name); 3154 break; 3155 3156 case GUSICS_DAC_LVL: /* dacout */ 3157 dip->type = AUDIO_MIXER_VALUE; 3158 dip->mixer_class = GUSICS_INPUT_CLASS; 3159 dip->prev = AUDIO_MIXER_LAST; 3160 dip->next = GUSICS_DAC_MUTE; 3161 strlcpy(dip->label.name, AudioNdac, sizeof dip->label.name); 3162 dip->un.v.num_channels = 2; 3163 strlcpy(dip->un.v.units.name, AudioNvolume, 3164 sizeof dip->un.v.units.name); 3165 break; 3166 3167 case GUSICS_MASTER_LVL: /* master output */ 3168 dip->type = AUDIO_MIXER_VALUE; 3169 dip->mixer_class = GUSICS_OUTPUT_CLASS; 3170 dip->prev = AUDIO_MIXER_LAST; 3171 dip->next = GUSICS_MASTER_MUTE; 3172 strlcpy(dip->label.name, AudioNmaster, sizeof dip->label.name); 3173 dip->un.v.num_channels = 2; 3174 strlcpy(dip->un.v.units.name, AudioNvolume, 3175 sizeof dip->un.v.units.name); 3176 break; 3177 3178 3179 case GUSICS_LINE_IN_MUTE: 3180 dip->mixer_class = GUSICS_INPUT_CLASS; 3181 dip->type = AUDIO_MIXER_ENUM; 3182 dip->prev = GUSICS_LINE_IN_LVL; 3183 dip->next = AUDIO_MIXER_LAST; 3184 goto mute; 3185 3186 case GUSICS_DAC_MUTE: 3187 dip->mixer_class = GUSICS_INPUT_CLASS; 3188 dip->type = AUDIO_MIXER_ENUM; 3189 dip->prev = GUSICS_DAC_LVL; 3190 dip->next = AUDIO_MIXER_LAST; 3191 goto mute; 3192 3193 case GUSICS_CD_MUTE: 3194 dip->mixer_class = GUSICS_INPUT_CLASS; 3195 dip->type = AUDIO_MIXER_ENUM; 3196 dip->prev = GUSICS_CD_LVL; 3197 dip->next = AUDIO_MIXER_LAST; 3198 goto mute; 3199 3200 case GUSICS_MIC_IN_MUTE: 3201 dip->mixer_class = GUSICS_INPUT_CLASS; 3202 dip->type = AUDIO_MIXER_ENUM; 3203 dip->prev = GUSICS_MIC_IN_LVL; 3204 dip->next = AUDIO_MIXER_LAST; 3205 goto mute; 3206 3207 case GUSICS_MASTER_MUTE: 3208 dip->mixer_class = GUSICS_OUTPUT_CLASS; 3209 dip->type = AUDIO_MIXER_ENUM; 3210 dip->prev = GUSICS_MASTER_LVL; 3211 dip->next = AUDIO_MIXER_LAST; 3212 mute: 3213 strlcpy(dip->label.name, AudioNmute, sizeof dip->label.name); 3214 dip->un.e.num_mem = 2; 3215 strlcpy(dip->un.e.member[0].label.name, AudioNoff, 3216 sizeof dip->un.e.member[0].label.name); 3217 dip->un.e.member[0].ord = 0; 3218 strlcpy(dip->un.e.member[1].label.name, AudioNon, 3219 sizeof dip->un.e.member[1].label.name); 3220 dip->un.e.member[1].ord = 1; 3221 break; 3222 3223 case GUSICS_RECORD_SOURCE: 3224 dip->mixer_class = GUSICS_RECORD_CLASS; 3225 dip->type = AUDIO_MIXER_ENUM; 3226 dip->prev = dip->next = AUDIO_MIXER_LAST; 3227 strlcpy(dip->label.name, AudioNsource, sizeof dip->label.name); 3228 dip->un.e.num_mem = 1; 3229 strlcpy(dip->un.e.member[0].label.name, AudioNoutput, 3230 sizeof dip->un.e.member[0].label.name); 3231 dip->un.e.member[0].ord = GUSICS_MASTER_LVL; 3232 break; 3233 3234 case GUSICS_INPUT_CLASS: 3235 dip->type = AUDIO_MIXER_CLASS; 3236 dip->mixer_class = GUSICS_INPUT_CLASS; 3237 dip->next = dip->prev = AUDIO_MIXER_LAST; 3238 strlcpy(dip->label.name, AudioCinputs, sizeof dip->label.name); 3239 break; 3240 3241 case GUSICS_OUTPUT_CLASS: 3242 dip->type = AUDIO_MIXER_CLASS; 3243 dip->mixer_class = GUSICS_OUTPUT_CLASS; 3244 dip->next = dip->prev = AUDIO_MIXER_LAST; 3245 strlcpy(dip->label.name, AudioCoutputs, sizeof dip->label.name); 3246 break; 3247 3248 case GUSICS_RECORD_CLASS: 3249 dip->type = AUDIO_MIXER_CLASS; 3250 dip->mixer_class = GUSICS_RECORD_CLASS; 3251 dip->next = dip->prev = AUDIO_MIXER_LAST; 3252 strlcpy(dip->label.name, AudioCrecord, sizeof dip->label.name); 3253 break; 3254 3255 default: 3256 return ENXIO; 3257 /*NOTREACHED*/ 3258 } 3259 DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name)); 3260 return 0; 3261 } 3262 3263 int 3264 gus_query_encoding(addr, fp) 3265 void *addr; 3266 struct audio_encoding *fp; 3267 { 3268 switch (fp->index) { 3269 case 0: 3270 strlcpy(fp->name, AudioEmulaw, sizeof fp->name); 3271 fp->encoding = AUDIO_ENCODING_ULAW; 3272 fp->precision = 8; 3273 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 3274 break; 3275 case 1: 3276 strlcpy(fp->name, AudioEslinear, sizeof fp->name); 3277 fp->encoding = AUDIO_ENCODING_SLINEAR; 3278 fp->precision = 8; 3279 fp->flags = 0; 3280 break; 3281 case 2: 3282 strlcpy(fp->name, AudioEslinear_le, sizeof fp->name); 3283 fp->encoding = AUDIO_ENCODING_SLINEAR_LE; 3284 fp->precision = 16; 3285 fp->flags = 0; 3286 break; 3287 case 3: 3288 strlcpy(fp->name, AudioEulinear, sizeof fp->name); 3289 fp->encoding = AUDIO_ENCODING_ULINEAR; 3290 fp->precision = 8; 3291 fp->flags = 0; 3292 break; 3293 case 4: 3294 strlcpy(fp->name, AudioEulinear_le, sizeof fp->name); 3295 fp->encoding = AUDIO_ENCODING_ULINEAR_LE; 3296 fp->precision = 16; 3297 fp->flags = 0; 3298 break; 3299 case 5: 3300 strlcpy(fp->name, AudioEslinear_be, sizeof fp->name); 3301 fp->encoding = AUDIO_ENCODING_SLINEAR_BE; 3302 fp->precision = 16; 3303 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 3304 break; 3305 case 6: 3306 strlcpy(fp->name, AudioEulinear_be, sizeof fp->name); 3307 fp->encoding = AUDIO_ENCODING_ULINEAR_BE; 3308 fp->precision = 16; 3309 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 3310 break; 3311 case 7: 3312 strlcpy(fp->name, AudioEalaw, sizeof fp->name); 3313 fp->encoding = AUDIO_ENCODING_ALAW; 3314 fp->precision = 8; 3315 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 3316 break; 3317 3318 default: 3319 return(EINVAL); 3320 /*NOTREACHED*/ 3321 } 3322 return (0); 3323 } 3324 3325 /* 3326 * Setup the ICS mixer in "transparent" mode: reset everything to a sensible 3327 * level. Levels as suggested by GUS SDK code. 3328 */ 3329 3330 void 3331 gus_init_ics2101(sc) 3332 struct gus_softc *sc; 3333 { 3334 struct ics2101_softc *ic = &sc->sc_mixer; 3335 sc->sc_mixer.sc_iot = sc->sc_iot; 3336 sc->sc_mixer.sc_selio = GUS_MIXER_SELECT; 3337 sc->sc_mixer.sc_selio_ioh = sc->sc_ioh3; 3338 sc->sc_mixer.sc_dataio = GUS_MIXER_DATA; 3339 sc->sc_mixer.sc_dataio_ioh = sc->sc_ioh2; 3340 sc->sc_mixer.sc_flags = (sc->sc_revision == 5) ? ICS_FLIP : 0; 3341 3342 ics2101_mix_attenuate(ic, 3343 GUSMIX_CHAN_MIC, 3344 ICSMIX_LEFT, 3345 ICSMIX_MIN_ATTN); 3346 ics2101_mix_attenuate(ic, 3347 GUSMIX_CHAN_MIC, 3348 ICSMIX_RIGHT, 3349 ICSMIX_MIN_ATTN); 3350 /* 3351 * Start with microphone muted by the mixer... 3352 */ 3353 gusics_mic_mute(ic, 1); 3354 3355 /* ... and enabled by the GUS master mix control */ 3356 gus_mic_ctl(sc, SPKR_ON); 3357 3358 ics2101_mix_attenuate(ic, 3359 GUSMIX_CHAN_LINE, 3360 ICSMIX_LEFT, 3361 ICSMIX_MIN_ATTN); 3362 ics2101_mix_attenuate(ic, 3363 GUSMIX_CHAN_LINE, 3364 ICSMIX_RIGHT, 3365 ICSMIX_MIN_ATTN); 3366 3367 ics2101_mix_attenuate(ic, 3368 GUSMIX_CHAN_CD, 3369 ICSMIX_LEFT, 3370 ICSMIX_MIN_ATTN); 3371 ics2101_mix_attenuate(ic, 3372 GUSMIX_CHAN_CD, 3373 ICSMIX_RIGHT, 3374 ICSMIX_MIN_ATTN); 3375 3376 ics2101_mix_attenuate(ic, 3377 GUSMIX_CHAN_DAC, 3378 ICSMIX_LEFT, 3379 ICSMIX_MIN_ATTN); 3380 ics2101_mix_attenuate(ic, 3381 GUSMIX_CHAN_DAC, 3382 ICSMIX_RIGHT, 3383 ICSMIX_MIN_ATTN); 3384 3385 ics2101_mix_attenuate(ic, 3386 ICSMIX_CHAN_4, 3387 ICSMIX_LEFT, 3388 ICSMIX_MAX_ATTN); 3389 ics2101_mix_attenuate(ic, 3390 ICSMIX_CHAN_4, 3391 ICSMIX_RIGHT, 3392 ICSMIX_MAX_ATTN); 3393 3394 ics2101_mix_attenuate(ic, 3395 GUSMIX_CHAN_MASTER, 3396 ICSMIX_LEFT, 3397 ICSMIX_MIN_ATTN); 3398 ics2101_mix_attenuate(ic, 3399 GUSMIX_CHAN_MASTER, 3400 ICSMIX_RIGHT, 3401 ICSMIX_MIN_ATTN); 3402 /* unmute other stuff: */ 3403 gusics_cd_mute(ic, 0); 3404 gusics_dac_mute(ic, 0); 3405 gusics_linein_mute(ic, 0); 3406 return; 3407 } 3408 3409 3410 3411 void 3412 gus_subattach(sc, ia) 3413 struct gus_softc *sc; 3414 struct isa_attach_args *ia; 3415 { 3416 int i; 3417 bus_space_tag_t iot; 3418 unsigned char c,d,m; 3419 3420 iot = sc->sc_iot; 3421 3422 /* 3423 * Figure out our board rev, and see if we need to initialize the 3424 * mixer 3425 */ 3426 3427 c = bus_space_read_1(iot, sc->sc_ioh3, GUS_BOARD_REV); 3428 if (c != 0xff) 3429 sc->sc_revision = c; 3430 else 3431 sc->sc_revision = 0; 3432 3433 SELECT_GUS_REG(iot, sc->sc_ioh2, GUSREG_RESET); 3434 bus_space_write_1(iot, sc->sc_ioh2, GUS_DATA_HIGH, 0x00); 3435 3436 gusreset(sc, GUS_MAX_VOICES); /* initialize all voices */ 3437 gusreset(sc, GUS_MIN_VOICES); /* then set to just the ones we use */ 3438 3439 /* 3440 * Setup the IRQ and DRQ lines in software, using values from 3441 * config file 3442 */ 3443 3444 m = GUSMASK_LINE_IN|GUSMASK_LINE_OUT; /* disable all */ 3445 3446 c = ((unsigned char) gus_irq_map[ia->ia_irq]) | GUSMASK_BOTH_RQ; 3447 3448 if (sc->sc_recdrq == sc->sc_drq) 3449 d = (unsigned char) (gus_drq_map[sc->sc_drq] | 3450 GUSMASK_BOTH_RQ); 3451 else 3452 d = (unsigned char) (gus_drq_map[sc->sc_drq] | 3453 gus_drq_map[sc->sc_recdrq] << 3); 3454 3455 /* 3456 * Program the IRQ and DMA channels on the GUS. Note that we hardwire 3457 * the GUS to only use one IRQ channel, but we give the user the 3458 * option of using two DMA channels (the other one given by the drq2 3459 * option in the config file). Two DMA channels are needed for full- 3460 * duplex operation. 3461 * 3462 * The order of these operations is very magical. 3463 */ 3464 3465 disable_intr(); /* XXX needed? */ 3466 3467 bus_space_write_1(iot, sc->sc_ioh1, GUS_REG_CONTROL, GUS_REG_IRQCTL); 3468 bus_space_write_1(iot, sc->sc_ioh1, GUS_MIX_CONTROL, m); 3469 bus_space_write_1(iot, sc->sc_ioh1, GUS_IRQCTL_CONTROL, 0x00); 3470 bus_space_write_1(iot, sc->sc_ioh1, 0x0f, 0x00); 3471 3472 bus_space_write_1(iot, sc->sc_ioh1, GUS_MIX_CONTROL, m); 3473 3474 /* magic reset? */ 3475 bus_space_write_1(iot, sc->sc_ioh1, GUS_DMA_CONTROL, d | 0x80); 3476 3477 bus_space_write_1(iot, sc->sc_ioh1, GUS_MIX_CONTROL, 3478 m | GUSMASK_CONTROL_SEL); 3479 bus_space_write_1(iot, sc->sc_ioh1, GUS_IRQ_CONTROL, c); 3480 3481 bus_space_write_1(iot, sc->sc_ioh1, GUS_MIX_CONTROL, m); 3482 bus_space_write_1(iot, sc->sc_ioh1, GUS_DMA_CONTROL, d); 3483 3484 bus_space_write_1(iot, sc->sc_ioh1, GUS_MIX_CONTROL, 3485 m | GUSMASK_CONTROL_SEL); 3486 bus_space_write_1(iot, sc->sc_ioh1, GUS_IRQ_CONTROL, c); 3487 3488 bus_space_write_1(iot, sc->sc_ioh2, GUS_VOICE_SELECT, 0x00); 3489 3490 /* enable line in, line out. leave mic disabled. */ 3491 bus_space_write_1(iot, sc->sc_ioh1, GUS_MIX_CONTROL, 3492 (m | GUSMASK_LATCHES) & ~(GUSMASK_LINE_OUT|GUSMASK_LINE_IN)); 3493 bus_space_write_1(iot, sc->sc_ioh2, GUS_VOICE_SELECT, 0x00); 3494 3495 enable_intr(); 3496 3497 sc->sc_mixcontrol = 3498 (m | GUSMASK_LATCHES) & ~(GUSMASK_LINE_OUT|GUSMASK_LINE_IN); 3499 3500 sc->sc_codec.sc_isa = sc->sc_isa; 3501 3502 if (sc->sc_revision >= 5 && sc->sc_revision <= 9) { 3503 sc->sc_flags |= GUS_MIXER_INSTALLED; 3504 gus_init_ics2101(sc); 3505 } 3506 if (sc->sc_revision < 10 || !gus_init_cs4231(sc)) { 3507 /* Not using the CS4231, so create our DMA maps. */ 3508 if (sc->sc_drq != -1) { 3509 if (isa_dmamap_create(sc->sc_isa, sc->sc_drq, 3510 MAX_ISADMA, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) { 3511 printf("%s: can't create map for drq %d\n", 3512 sc->sc_dev.dv_xname, sc->sc_drq); 3513 return; 3514 } 3515 } 3516 if (sc->sc_recdrq != -1 && sc->sc_recdrq != sc->sc_drq) { 3517 if (isa_dmamap_create(sc->sc_isa, sc->sc_recdrq, 3518 MAX_ISADMA, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) { 3519 printf("%s: can't create map for drq %d\n", 3520 sc->sc_dev.dv_xname, sc->sc_recdrq); 3521 return; 3522 } 3523 } 3524 } 3525 3526 timeout_set(&sc->sc_dma_tmo, gus_dmaout_timeout, sc); 3527 3528 SELECT_GUS_REG(iot, sc->sc_ioh2, GUSREG_RESET); 3529 /* 3530 * Check to see how much memory we have on this card; see if any 3531 * "mirroring" occurs. We're assuming at least 256K already exists 3532 * on the card; otherwise the initial probe would have failed 3533 */ 3534 3535 guspoke(iot, sc->sc_ioh2, 0L, 0x00); 3536 for(i = 1; i < 1024; i++) { 3537 u_long loc; 3538 3539 /* 3540 * See if we've run into mirroring yet 3541 */ 3542 3543 if (guspeek(iot, sc->sc_ioh2, 0L) != 0) 3544 break; 3545 3546 loc = i << 10; 3547 3548 guspoke(iot, sc->sc_ioh2, loc, 0xaa); 3549 if (guspeek(iot, sc->sc_ioh2, loc) != 0xaa) 3550 break; 3551 } 3552 3553 sc->sc_dsize = i; 3554 /* 3555 * The "official" (3.x) version number cannot easily be obtained. 3556 * The revision register does not correspond to the minor number 3557 * of the board version. Simply use the revision register as 3558 * identification. 3559 */ 3560 snprintf(gus_device.version, sizeof gus_device.version, "%d", 3561 sc->sc_revision); 3562 3563 printf(": ver %d", sc->sc_revision); 3564 if (sc->sc_revision >= 10) 3565 printf(", MAX"); 3566 else { 3567 if (HAS_MIXER(sc)) 3568 printf(", ICS2101 mixer"); 3569 if (HAS_CODEC(sc)) 3570 printf(", %s codec/mixer", sc->sc_codec.chip_name); 3571 } 3572 printf(", %dKB DRAM, ", sc->sc_dsize); 3573 if (sc->sc_recdrq == sc->sc_drq) { 3574 printf("half-duplex"); 3575 } else { 3576 printf("full-duplex, record drq %d", sc->sc_recdrq); 3577 } 3578 3579 printf("\n"); 3580 3581 /* 3582 * Setup a default interrupt handler 3583 */ 3584 3585 /* XXX we shouldn't have to use splgus == splclock, nor should 3586 * we use IPL_CLOCK. 3587 */ 3588 sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq, IST_EDGE, 3589 IPL_AUDIO, gusintr, sc /* sc->sc_gusdsp */, sc->sc_dev.dv_xname); 3590 3591 /* 3592 * Set some default values 3593 * XXX others start with 8kHz mono mulaw 3594 */ 3595 3596 sc->sc_irate = sc->sc_orate = 44100; 3597 sc->sc_encoding = AUDIO_ENCODING_SLINEAR_LE; 3598 sc->sc_precision = 16; 3599 sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_DATA_SIZE16; 3600 sc->sc_voc[GUS_VOICE_RIGHT].voccntl |= GUSMASK_DATA_SIZE16; 3601 sc->sc_channels = 1; 3602 sc->sc_ogain = 340; 3603 gus_commit_settings(sc); 3604 3605 /* 3606 * We always put the left channel full left & right channel 3607 * full right. 3608 * For mono playback, we set up both voices playing the same buffer. 3609 */ 3610 bus_space_write_1(iot, sc->sc_ioh2, GUS_VOICE_SELECT, 3611 (u_char)GUS_VOICE_LEFT); 3612 SELECT_GUS_REG(iot, sc->sc_ioh2, GUSREG_PAN_POS); 3613 bus_space_write_1(iot, sc->sc_ioh2, GUS_DATA_HIGH, GUS_PAN_FULL_LEFT); 3614 3615 bus_space_write_1(iot, sc->sc_ioh2, GUS_VOICE_SELECT, 3616 (u_char)GUS_VOICE_RIGHT); 3617 SELECT_GUS_REG(iot, sc->sc_ioh2, GUSREG_PAN_POS); 3618 bus_space_write_1(iot, sc->sc_ioh2, GUS_DATA_HIGH, GUS_PAN_FULL_RIGHT); 3619 3620 /* 3621 * Attach to the generic audio layer 3622 */ 3623 3624 audio_attach_mi(&gus_hw_if, HAS_CODEC(sc) ? (void *)&sc->sc_codec : 3625 (void *)sc, &sc->sc_dev); 3626 } 3627 3628 /* 3629 * Test to see if a particular I/O base is valid for the GUS. Return true 3630 * if it is. 3631 */ 3632 3633 int 3634 gus_test_iobase (iot, iobase) 3635 bus_space_tag_t iot; 3636 int iobase; 3637 { 3638 bus_space_handle_t ioh1, ioh2, ioh3, ioh4; 3639 u_char s1, s2; 3640 int s, rv = 0; 3641 3642 /* Map i/o space */ 3643 if (bus_space_map(iot, iobase, GUS_NPORT1, 0, &ioh1)) 3644 return 0; 3645 if (bus_space_map(iot, iobase+GUS_IOH2_OFFSET, GUS_NPORT2, 0, &ioh2)) 3646 goto bad1; 3647 3648 /* XXX Maybe we shouldn't fail on mapping this, but just assume 3649 * the card is of revision 0? */ 3650 if (bus_space_map(iot, iobase+GUS_IOH3_OFFSET, GUS_NPORT3, 0, &ioh3)) 3651 goto bad2; 3652 3653 if (bus_space_map(iot, iobase+GUS_IOH4_OFFSET, GUS_NPORT4, 0, &ioh4)) 3654 goto bad3; 3655 3656 /* 3657 * Reset GUS to an initial state before we do anything. 3658 */ 3659 3660 s = splgus(); 3661 delay(500); 3662 3663 SELECT_GUS_REG(iot, ioh2, GUSREG_RESET); 3664 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00); 3665 3666 delay(500); 3667 3668 SELECT_GUS_REG(iot, ioh2, GUSREG_RESET); 3669 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, GUSMASK_MASTER_RESET); 3670 3671 delay(500); 3672 3673 splx(s); 3674 3675 /* 3676 * See if we can write to the board's memory 3677 */ 3678 3679 s1 = guspeek(iot, ioh2, 0L); 3680 s2 = guspeek(iot, ioh2, 1L); 3681 3682 guspoke(iot, ioh2, 0L, 0xaa); 3683 guspoke(iot, ioh2, 1L, 0x55); 3684 3685 if (guspeek(iot, ioh2, 0L) != 0xaa) 3686 goto bad; 3687 3688 guspoke(iot, ioh2, 0L, s1); 3689 guspoke(iot, ioh2, 1L, s2); 3690 3691 rv = 1; 3692 3693 bad: 3694 bus_space_unmap(iot, ioh4, GUS_NPORT4); 3695 bad3: 3696 bus_space_unmap(iot, ioh3, GUS_NPORT3); 3697 bad2: 3698 bus_space_unmap(iot, ioh2, GUS_NPORT2); 3699 bad1: 3700 bus_space_unmap(iot, ioh1, GUS_NPORT1); 3701 return rv; 3702 } 3703