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