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