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