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