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