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