gus.c revision 1.50
1/* $NetBSD: gus.c,v 1.50 1998/01/13 19:33:29 drochner 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 void gus_init_cs4231 __P((struct gus_softc *)); 390STATIC void gus_init_ics2101 __P((struct gus_softc *)); 391 392STATIC void gus_set_chan_addrs __P((struct gus_softc *)); 393STATIC void gusreset __P((struct gus_softc *, int)); 394STATIC void gus_set_voices __P((struct gus_softc *, int)); 395STATIC void gus_set_volume __P((struct gus_softc *, int, int)); 396STATIC void gus_set_samprate __P((struct gus_softc *, int, int)); 397STATIC void gus_set_recrate __P((struct gus_softc *, u_long)); 398STATIC void gus_start_voice __P((struct gus_softc *, int, int)); 399STATIC void gus_stop_voice __P((struct gus_softc *, int, int)); 400STATIC void gus_set_endaddr __P((struct gus_softc *, int, u_long)); 401#ifdef GUSPLAYDEBUG 402STATIC void gus_set_curaddr __P((struct gus_softc *, int, u_long)); 403STATIC u_long gus_get_curaddr __P((struct gus_softc *, int)); 404#endif 405STATIC int gus_dmaout_intr __P((struct gus_softc *)); 406STATIC void gus_dmaout_dointr __P((struct gus_softc *)); 407STATIC void gus_dmaout_timeout __P((void *)); 408STATIC int gus_dmain_intr __P((struct gus_softc *)); 409STATIC int gus_voice_intr __P((struct gus_softc *)); 410STATIC void gus_start_playing __P((struct gus_softc *, int)); 411STATIC int gus_continue_playing __P((struct gus_softc *, int)); 412STATIC u_char guspeek __P((bus_space_tag_t, bus_space_handle_t, u_long)); 413STATIC u_long convert_to_16bit __P((u_long)); 414STATIC int gus_mixer_set_port __P((void *, mixer_ctrl_t *)); 415STATIC int gus_mixer_get_port __P((void *, mixer_ctrl_t *)); 416STATIC int gusmax_mixer_set_port __P((void *, mixer_ctrl_t *)); 417STATIC int gusmax_mixer_get_port __P((void *, mixer_ctrl_t *)); 418STATIC int gus_mixer_query_devinfo __P((void *, mixer_devinfo_t *)); 419STATIC int gusmax_mixer_query_devinfo __P((void *, mixer_devinfo_t *)); 420STATIC int gus_query_encoding __P((void *, struct audio_encoding *)); 421STATIC int gus_get_props __P((void *)); 422STATIC int gusmax_get_props __P((void *)); 423 424STATIC void gusics_master_mute __P((struct ics2101_softc *, int)); 425STATIC void gusics_dac_mute __P((struct ics2101_softc *, int)); 426STATIC void gusics_mic_mute __P((struct ics2101_softc *, int)); 427STATIC void gusics_linein_mute __P((struct ics2101_softc *, int)); 428STATIC void gusics_cd_mute __P((struct ics2101_softc *, int)); 429 430STATIC __inline int gus_to_vol __P((mixer_ctrl_t *, struct ad1848_volume *)); 431STATIC __inline int gus_from_vol __P((mixer_ctrl_t *, struct ad1848_volume *)); 432 433void stereo_dmaintr __P((void *)); 434 435/* 436 * ISA bus driver routines 437 */ 438 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) { 933 gus_init_cs4231(sc); 934 } else { 935 /* Not using the CS4231, so create our DMA maps. */ 936 if (sc->sc_drq != -1) { 937 if (isa_dmamap_create(sc->sc_isa, sc->sc_drq, 938 MAX_ISADMA, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) { 939 printf("%s: can't create map for drq %d\n", 940 sc->sc_dev.dv_xname, sc->sc_drq); 941 return; 942 } 943 } 944 if (sc->sc_recdrq != -1 && sc->sc_recdrq != sc->sc_drq) { 945 if (isa_dmamap_create(sc->sc_isa, sc->sc_recdrq, 946 MAX_ISADMA, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) { 947 printf("%s: can't create map for drq %d\n", 948 sc->sc_dev.dv_xname, sc->sc_recdrq); 949 return; 950 } 951 } 952 } 953 954 SELECT_GUS_REG(iot, ioh2, GUSREG_RESET); 955 /* 956 * Check to see how much memory we have on this card; see if any 957 * "mirroring" occurs. We're assuming at least 256K already exists 958 * on the card; otherwise the initial probe would have failed 959 */ 960 961 guspoke(iot, ioh2, 0L, 0x00); 962 for(i = 1; i < 1024; i++) { 963 u_long loc; 964 965 /* 966 * See if we've run into mirroring yet 967 */ 968 969 if (guspeek(iot, ioh2, 0L) != 0) 970 break; 971 972 loc = i << 10; 973 974 guspoke(iot, ioh2, loc, 0xaa); 975 if (guspeek(iot, ioh2, loc) != 0xaa) 976 break; 977 } 978 979 sc->sc_dsize = i; 980 sprintf(gus_device.version, "3.%d", sc->sc_revision); 981 982 printf("\n <Gravis UltraSound version 3.%d, %dKB DRAM, ", 983 sc->sc_revision, sc->sc_dsize); 984 if (HAS_MIXER(sc)) 985 printf("ICS2101 mixer, "); 986 if (HAS_CODEC(sc)) 987 printf("%s codec/mixer, ", sc->sc_codec.chip_name); 988 if (sc->sc_recdrq == sc->sc_drq) { 989 printf("half-duplex"); 990 } else { 991 printf("full-duplex, record drq %d", sc->sc_recdrq); 992 } 993 994 printf(">\n"); 995 996 /* 997 * Setup a default interrupt handler 998 */ 999 1000 /* XXX we shouldn't have to use splgus == splclock, nor should 1001 * we use IPL_CLOCK. 1002 */ 1003 sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq, IST_EDGE, 1004 IPL_AUDIO, gusintr, sc /* sc->sc_gusdsp */); 1005 1006 /* 1007 * Set some default values 1008 * XXX others start with 8kHz mono mulaw 1009 */ 1010 1011 sc->sc_irate = sc->sc_orate = 44100; 1012 sc->sc_encoding = AUDIO_ENCODING_SLINEAR_LE; 1013 sc->sc_precision = 16; 1014 sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_DATA_SIZE16; 1015 sc->sc_voc[GUS_VOICE_RIGHT].voccntl |= GUSMASK_DATA_SIZE16; 1016 sc->sc_channels = 1; 1017 sc->sc_ogain = 340; 1018 gus_commit_settings(sc); 1019 1020 /* 1021 * We always put the left channel full left & right channel 1022 * full right. 1023 * For mono playback, we set up both voices playing the same buffer. 1024 */ 1025 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) GUS_VOICE_LEFT); 1026 SELECT_GUS_REG(iot, ioh2, GUSREG_PAN_POS); 1027 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, GUS_PAN_FULL_LEFT); 1028 1029 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) GUS_VOICE_RIGHT); 1030 SELECT_GUS_REG(iot, ioh2, GUSREG_PAN_POS); 1031 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, GUS_PAN_FULL_RIGHT); 1032 1033 /* 1034 * Attach to the generic audio layer 1035 */ 1036 1037 audio_attach_mi(&gus_hw_if, 0, HAS_CODEC(sc) ? (void *)&sc->sc_codec : (void *)sc, &sc->sc_dev); 1038} 1039 1040int 1041gusopen(addr, flags) 1042 void *addr; 1043 int flags; 1044{ 1045 struct gus_softc *sc = addr; 1046 1047 DPRINTF(("gusopen() called\n")); 1048 1049 if (sc->sc_flags & GUS_OPEN) 1050 return EBUSY; 1051 1052 /* 1053 * Some initialization 1054 */ 1055 1056 sc->sc_flags |= GUS_OPEN; 1057 sc->sc_dmabuf = 0; 1058 sc->sc_playbuf = -1; 1059 sc->sc_bufcnt = 0; 1060 sc->sc_voc[GUS_VOICE_LEFT].start_addr = GUS_MEM_OFFSET - 1; 1061 sc->sc_voc[GUS_VOICE_LEFT].current_addr = GUS_MEM_OFFSET; 1062 1063 if (HAS_CODEC(sc)) { 1064 ad1848_open(&sc->sc_codec, flags); 1065 sc->sc_codec.aux1_mute = 0; 1066 ad1848_mute_aux1(&sc->sc_codec, 0); /* turn on DAC output */ 1067 if (flags & FREAD) { 1068 sc->sc_codec.mono_mute = 0; 1069 cs4231_mute_mono(&sc->sc_codec, 0); 1070 } 1071 } else if (flags & FREAD) { 1072 /* enable/unmute the microphone */ 1073 if (HAS_MIXER(sc)) { 1074 gusics_mic_mute(&sc->sc_mixer, 0); 1075 } else 1076 gus_mic_ctl(sc, SPKR_ON); 1077 } 1078 if (sc->sc_nbufs == 0) 1079 gus_round_blocksize(sc, GUS_BUFFER_MULTIPLE); /* default blksiz */ 1080 return 0; 1081} 1082 1083int 1084gusmaxopen(addr, flags) 1085 void *addr; 1086 int flags; 1087{ 1088 struct ad1848_softc *ac = addr; 1089 return gusopen(ac->parent, flags); 1090} 1091 1092STATIC void 1093gus_deinterleave(sc, buf, size) 1094 struct gus_softc *sc; 1095 void *buf; 1096 int size; 1097{ 1098 /* deinterleave the stereo data. We can use sc->sc_deintr_buf 1099 for scratch space. */ 1100 int i; 1101 1102 if (size > sc->sc_blocksize) { 1103 printf("gus: deinterleave %d > %d\n", size, sc->sc_blocksize); 1104 return; 1105 } else if (size < sc->sc_blocksize) { 1106 DPRINTF(("gus: deinterleave %d < %d\n", size, sc->sc_blocksize)); 1107 } 1108 1109 /* 1110 * size is in bytes. 1111 */ 1112 if (sc->sc_precision == 16) { 1113 u_short *dei = sc->sc_deintr_buf; 1114 u_short *sbuf = buf; 1115 size >>= 1; /* bytecnt to shortcnt */ 1116 /* copy 2nd of each pair of samples to the staging area, while 1117 compacting the 1st of each pair into the original area. */ 1118 for (i = 0; i < size/2-1; i++) { 1119 dei[i] = sbuf[i*2+1]; 1120 sbuf[i+1] = sbuf[i*2+2]; 1121 } 1122 /* 1123 * this has copied one less sample than half of the 1124 * buffer. The first sample of the 1st stream was 1125 * already in place and didn't need copying. 1126 * Therefore, we've moved all of the 1st stream's 1127 * samples into place. We have one sample from 2nd 1128 * stream in the last slot of original area, not 1129 * copied to the staging area (But we don't need to!). 1130 * Copy the remainder of the original stream into place. 1131 */ 1132 bcopy(dei, &sbuf[size/2], i * sizeof(short)); 1133 } else { 1134 u_char *dei = sc->sc_deintr_buf; 1135 u_char *sbuf = buf; 1136 for (i = 0; i < size/2-1; i++) { 1137 dei[i] = sbuf[i*2+1]; 1138 sbuf[i+1] = sbuf[i*2+2]; 1139 } 1140 bcopy(dei, &sbuf[size/2], i); 1141 } 1142} 1143 1144/* 1145 * Actually output a buffer to the DSP chip 1146 */ 1147 1148int 1149gusmax_dma_output(addr, buf, size, intr, arg) 1150 void * addr; 1151 void *buf; 1152 int size; 1153 void (*intr) __P((void *)); 1154 void *arg; 1155{ 1156 struct ad1848_softc *ac = addr; 1157 return gus_dma_output(ac->parent, buf, size, intr, arg); 1158} 1159 1160/* 1161 * called at splgus() from interrupt handler. 1162 */ 1163void 1164stereo_dmaintr(arg) 1165 void *arg; 1166{ 1167 struct gus_softc *sc = arg; 1168 struct stereo_dma_intr *sa = &sc->sc_stereo; 1169 1170 DMAPRINTF(("stereo_dmaintr")); 1171 1172 /* 1173 * Put other half in its place, then call the real interrupt routine :) 1174 */ 1175 1176 sc->sc_dmaoutintr = sa->intr; 1177 sc->sc_outarg = sa->arg; 1178 1179#ifdef GUSPLAYDEBUG 1180 if (gusstats) { 1181 microtime(&dmarecords[dmarecord_index].tv); 1182 dmarecords[dmarecord_index].gusaddr = sa->dmabuf; 1183 dmarecords[dmarecord_index].bsdaddr = sa->buffer; 1184 dmarecords[dmarecord_index].count = sa->size; 1185 dmarecords[dmarecord_index].channel = 1; 1186 dmarecords[dmarecord_index].direction = 1; 1187 dmarecord_index = ++dmarecord_index % NDMARECS; 1188 } 1189#endif 1190 1191 gusdmaout(sc, sa->flags, sa->dmabuf, (caddr_t) sa->buffer, sa->size); 1192 1193 sa->flags = 0; 1194 sa->dmabuf = 0; 1195 sa->buffer = 0; 1196 sa->size = 0; 1197 sa->intr = 0; 1198 sa->arg = 0; 1199} 1200 1201/* 1202 * Start up DMA output to the card. 1203 * Called at splgus/splaudio already, either from intr handler or from 1204 * generic audio code. 1205 */ 1206int 1207gus_dma_output(addr, buf, size, intr, arg) 1208 void * addr; 1209 void *buf; 1210 int size; 1211 void (*intr) __P((void *)); 1212 void *arg; 1213{ 1214 struct gus_softc *sc = addr; 1215 u_char *buffer = buf; 1216 u_long boarddma; 1217 int flags; 1218 1219 DMAPRINTF(("gus_dma_output %d @ %p\n", size, buf)); 1220 1221 if (size != sc->sc_blocksize) { 1222 DPRINTF(("gus_dma_output reqsize %d not sc_blocksize %d\n", 1223 size, sc->sc_blocksize)); 1224 return EINVAL; 1225 } 1226 1227 flags = GUSMASK_DMA_WRITE; 1228 if (sc->sc_precision == 16) 1229 flags |= GUSMASK_DMA_DATA_SIZE; 1230 if (sc->sc_encoding == AUDIO_ENCODING_ULAW || 1231 sc->sc_encoding == AUDIO_ENCODING_ALAW || 1232 sc->sc_encoding == AUDIO_ENCODING_ULINEAR_BE || 1233 sc->sc_encoding == AUDIO_ENCODING_ULINEAR_LE) 1234 flags |= GUSMASK_DMA_INVBIT; 1235 1236 if (sc->sc_channels == 2) { 1237 if (sc->sc_precision == 16) { 1238 if (size & 3) { 1239 DPRINTF(("gus_dma_output: unpaired 16bit samples")); 1240 size &= 3; 1241 } 1242 } else if (size & 1) { 1243 DPRINTF(("gus_dma_output: unpaired samples")); 1244 size &= 1; 1245 } 1246 if (size == 0) 1247 return 0; 1248 1249 gus_deinterleave(sc, (void *)buffer, size); 1250 1251 size >>= 1; 1252 1253 boarddma = size * sc->sc_dmabuf + GUS_MEM_OFFSET; 1254 1255 sc->sc_stereo.intr = intr; 1256 sc->sc_stereo.arg = arg; 1257 sc->sc_stereo.size = size; 1258 sc->sc_stereo.dmabuf = boarddma + GUS_LEFT_RIGHT_OFFSET; 1259 sc->sc_stereo.buffer = buffer + size; 1260 sc->sc_stereo.flags = flags; 1261 if (gus_dostereo) { 1262 intr = stereo_dmaintr; 1263 arg = sc; 1264 } 1265 } else 1266 boarddma = size * sc->sc_dmabuf + GUS_MEM_OFFSET; 1267 1268 1269 sc->sc_flags |= GUS_LOCKED; 1270 sc->sc_dmaoutintr = intr; 1271 sc->sc_outarg = arg; 1272 1273#ifdef GUSPLAYDEBUG 1274 if (gusstats) { 1275 microtime(&dmarecords[dmarecord_index].tv); 1276 dmarecords[dmarecord_index].gusaddr = boarddma; 1277 dmarecords[dmarecord_index].bsdaddr = buffer; 1278 dmarecords[dmarecord_index].count = size; 1279 dmarecords[dmarecord_index].channel = 0; 1280 dmarecords[dmarecord_index].direction = 1; 1281 dmarecord_index = ++dmarecord_index % NDMARECS; 1282 } 1283#endif 1284 1285 gusdmaout(sc, flags, boarddma, (caddr_t) buffer, size); 1286 1287 return 0; 1288} 1289 1290void 1291gusmax_close(addr) 1292 void *addr; 1293{ 1294 struct ad1848_softc *ac = addr; 1295 struct gus_softc *sc = ac->parent; 1296#if 0 1297 ac->aux1_mute = 1; 1298 ad1848_mute_aux1(ac, 1); /* turn off DAC output */ 1299#endif 1300 ad1848_close(ac); 1301 gusclose(sc); 1302} 1303 1304/* 1305 * Close out device stuff. Called at splgus() from generic audio layer. 1306 */ 1307void 1308gusclose(addr) 1309 void *addr; 1310{ 1311 struct gus_softc *sc = addr; 1312 1313 DPRINTF(("gus_close: sc=%p\n", sc)); 1314 1315 1316/* if (sc->sc_flags & GUS_DMAOUT_ACTIVE) */ { 1317 gus_halt_out_dma(sc); 1318 } 1319/* if (sc->sc_flags & GUS_DMAIN_ACTIVE) */ { 1320 gus_halt_in_dma(sc); 1321 } 1322 sc->sc_flags &= ~(GUS_OPEN|GUS_LOCKED|GUS_DMAOUT_ACTIVE|GUS_DMAIN_ACTIVE); 1323 1324 if (sc->sc_deintr_buf) { 1325 FREE(sc->sc_deintr_buf, M_DEVBUF); 1326 sc->sc_deintr_buf = NULL; 1327 } 1328 /* turn off speaker, etc. */ 1329 1330 /* make sure the voices shut up: */ 1331 gus_stop_voice(sc, GUS_VOICE_LEFT, 1); 1332 gus_stop_voice(sc, GUS_VOICE_RIGHT, 0); 1333} 1334 1335/* 1336 * Service interrupts. Farm them off to helper routines if we are using the 1337 * GUS for simple playback/record 1338 */ 1339 1340#ifdef DIAGNOSTIC 1341int gusintrcnt; 1342int gusdmaintrcnt; 1343int gusvocintrcnt; 1344#endif 1345 1346int 1347gusintr(arg) 1348 void *arg; 1349{ 1350 struct gus_softc *sc = arg; 1351 bus_space_tag_t iot = sc->sc_iot; 1352 bus_space_handle_t ioh1 = sc->sc_ioh1; 1353 bus_space_handle_t ioh2 = sc->sc_ioh2; 1354 unsigned char intr; 1355 1356 int retval = 0; 1357 1358 DPRINTF(("gusintr\n")); 1359#ifdef DIAGNOSTIC 1360 gusintrcnt++; 1361#endif 1362 if (HAS_CODEC(sc)) 1363 retval = ad1848_intr(&sc->sc_codec); 1364 if ((intr = bus_space_read_1(iot, ioh1, GUS_IRQ_STATUS)) & GUSMASK_IRQ_DMATC) { 1365 DMAPRINTF(("gusintr dma flags=%x\n", sc->sc_flags)); 1366#ifdef DIAGNOSTIC 1367 gusdmaintrcnt++; 1368#endif 1369 retval += gus_dmaout_intr(sc); 1370 if (sc->sc_flags & GUS_DMAIN_ACTIVE) { 1371 SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL); 1372 intr = bus_space_read_1(iot, ioh2, GUS_DATA_HIGH); 1373 if (intr & GUSMASK_SAMPLE_DMATC) { 1374 retval += gus_dmain_intr(sc); 1375 } 1376 } 1377 } 1378 if (intr & (GUSMASK_IRQ_VOICE | GUSMASK_IRQ_VOLUME)) { 1379 DMAPRINTF(("gusintr voice flags=%x\n", sc->sc_flags)); 1380#ifdef DIAGNOSTIC 1381 gusvocintrcnt++; 1382#endif 1383 retval += gus_voice_intr(sc); 1384 } 1385 if (retval) 1386 return 1; 1387 return retval; 1388} 1389 1390int gus_bufcnt[GUS_MEM_FOR_BUFFERS / GUS_BUFFER_MULTIPLE]; 1391int gus_restart; /* how many restarts? */ 1392int gus_stops; /* how many times did voice stop? */ 1393int gus_falsestops; /* stopped but not done? */ 1394int gus_continues; 1395 1396struct playcont { 1397 struct timeval tv; 1398 u_int playbuf; 1399 u_int dmabuf; 1400 u_char bufcnt; 1401 u_char vaction; 1402 u_char voccntl; 1403 u_char volcntl; 1404 u_long curaddr; 1405 u_long endaddr; 1406} playstats[NDMARECS]; 1407 1408int playcntr; 1409 1410STATIC void 1411gus_dmaout_timeout(arg) 1412 void *arg; 1413{ 1414 struct gus_softc *sc = arg; 1415 bus_space_tag_t iot = sc->sc_iot; 1416 bus_space_handle_t ioh2 = sc->sc_ioh2; 1417 int s; 1418 1419 printf("%s: dmaout timeout\n", sc->sc_dev.dv_xname); 1420 /* 1421 * Stop any DMA. 1422 */ 1423 1424 s = splgus(); 1425 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL); 1426 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0); 1427 1428#if 0 1429 /* XXX we will dmadone below? */ 1430 isa_dmaabort(sc->sc_dev.dv_parent, sc->sc_drq); 1431#endif 1432 1433 gus_dmaout_dointr(sc); 1434 splx(s); 1435} 1436 1437 1438/* 1439 * Service DMA interrupts. This routine will only get called if we're doing 1440 * a DMA transfer for playback/record requests from the audio layer. 1441 */ 1442 1443STATIC int 1444gus_dmaout_intr(sc) 1445 struct gus_softc *sc; 1446{ 1447 bus_space_tag_t iot = sc->sc_iot; 1448 bus_space_handle_t ioh2 = sc->sc_ioh2; 1449 1450 /* 1451 * If we got a DMA transfer complete from the GUS DRAM, then deal 1452 * with it. 1453 */ 1454 1455 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL); 1456 if (bus_space_read_1(iot, ioh2, GUS_DATA_HIGH) & GUSMASK_DMA_IRQPEND) { 1457 untimeout(gus_dmaout_timeout, sc); 1458 gus_dmaout_dointr(sc); 1459 return 1; 1460 } 1461 return 0; 1462} 1463 1464STATIC void 1465gus_dmaout_dointr(sc) 1466 struct gus_softc *sc; 1467{ 1468 bus_space_tag_t iot = sc->sc_iot; 1469 bus_space_handle_t ioh2 = sc->sc_ioh2; 1470 1471 /* sc->sc_dmaoutcnt - 1 because DMA controller counts from zero?. */ 1472 isa_dmadone(sc->sc_dev.dv_parent, sc->sc_drq); 1473 sc->sc_flags &= ~GUS_DMAOUT_ACTIVE; /* pending DMA is done */ 1474 DMAPRINTF(("gus_dmaout_dointr %d @ %p\n", sc->sc_dmaoutcnt, 1475 sc->sc_dmaoutaddr)); 1476 1477 /* 1478 * to prevent clicking, we need to copy last sample 1479 * from last buffer to scratch area just before beginning of 1480 * buffer. However, if we're doing formats that are converted by 1481 * the card during the DMA process, we need to pick up the converted 1482 * byte rather than the one we have in memory. 1483 */ 1484 if (sc->sc_dmabuf == sc->sc_nbufs - 1) { 1485 int i; 1486 switch (sc->sc_encoding) { 1487 case AUDIO_ENCODING_SLINEAR_LE: 1488 case AUDIO_ENCODING_SLINEAR_BE: 1489 if (sc->sc_precision == 8) 1490 goto byte; 1491 /* we have the native format */ 1492 for (i = 1; i <= 2; i++) 1493 guspoke(iot, ioh2, sc->sc_gusaddr - 1494 (sc->sc_nbufs - 1) * sc->sc_chanblocksize - i, 1495 sc->sc_dmaoutaddr[sc->sc_dmaoutcnt-i]); 1496 break; 1497 case AUDIO_ENCODING_ULINEAR_LE: 1498 case AUDIO_ENCODING_ULINEAR_BE: 1499 guspoke(iot, ioh2, sc->sc_gusaddr - 1500 (sc->sc_nbufs - 1) * sc->sc_chanblocksize - 2, 1501 guspeek(iot, ioh2, 1502 sc->sc_gusaddr + sc->sc_chanblocksize - 2)); 1503 case AUDIO_ENCODING_ALAW: 1504 case AUDIO_ENCODING_ULAW: 1505 byte: 1506 /* we need to fetch the translated byte, then stuff it. */ 1507 guspoke(iot, ioh2, sc->sc_gusaddr - 1508 (sc->sc_nbufs - 1) * sc->sc_chanblocksize - 1, 1509 guspeek(iot, ioh2, 1510 sc->sc_gusaddr + sc->sc_chanblocksize - 1)); 1511 break; 1512 } 1513 } 1514 /* 1515 * If this is the first half of stereo, "ignore" this one 1516 * and copy out the second half. 1517 */ 1518 if (sc->sc_dmaoutintr == stereo_dmaintr) { 1519 (*sc->sc_dmaoutintr)(sc->sc_outarg); 1520 return; 1521 } 1522 /* 1523 * If the voice is stopped, then start it. Reset the loop 1524 * and roll bits. Call the audio layer routine, since if 1525 * we're starting a stopped voice, that means that the next 1526 * buffer can be filled 1527 */ 1528 1529 sc->sc_flags &= ~GUS_LOCKED; 1530 if (sc->sc_voc[GUS_VOICE_LEFT].voccntl & 1531 GUSMASK_VOICE_STOPPED) { 1532 if (sc->sc_flags & GUS_PLAYING) { 1533 printf("%s: playing yet stopped?\n", sc->sc_dev.dv_xname); 1534 } 1535 sc->sc_bufcnt++; /* another yet to be played */ 1536 gus_start_playing(sc, sc->sc_dmabuf); 1537 gus_restart++; 1538 } else { 1539 /* 1540 * set the sound action based on which buffer we 1541 * just transferred. If we just transferred buffer 0 1542 * we want the sound to loop when it gets to the nth 1543 * buffer; if we just transferred 1544 * any other buffer, we want the sound to roll over 1545 * at least one more time. The voice interrupt 1546 * handlers will take care of accounting & 1547 * setting control bits if it's not caught up to us 1548 * yet. 1549 */ 1550 if (++sc->sc_bufcnt == 2) { 1551 /* 1552 * XXX 1553 * If we're too slow in reaction here, 1554 * the voice could be just approaching the 1555 * end of its run. It should be set to stop, 1556 * so these adjustments might not DTRT. 1557 */ 1558 if (sc->sc_dmabuf == 0 && 1559 sc->sc_playbuf == sc->sc_nbufs - 1) { 1560 /* player is just at the last buf, we're at the 1561 first. Turn on looping, turn off rolling. */ 1562 sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_LOOP_ENABLE; 1563 sc->sc_voc[GUS_VOICE_LEFT].volcntl &= ~GUSMASK_VOICE_ROLL; 1564 playstats[playcntr].vaction = 3; 1565 } else { 1566 /* player is at previous buf: 1567 turn on rolling, turn off looping */ 1568 sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~GUSMASK_LOOP_ENABLE; 1569 sc->sc_voc[GUS_VOICE_LEFT].volcntl |= GUSMASK_VOICE_ROLL; 1570 playstats[playcntr].vaction = 4; 1571 } 1572#ifdef GUSPLAYDEBUG 1573 if (gusstats) { 1574 microtime(&playstats[playcntr].tv); 1575 playstats[playcntr].endaddr = sc->sc_voc[GUS_VOICE_LEFT].end_addr; 1576 playstats[playcntr].voccntl = sc->sc_voc[GUS_VOICE_LEFT].voccntl; 1577 playstats[playcntr].volcntl = sc->sc_voc[GUS_VOICE_LEFT].volcntl; 1578 playstats[playcntr].playbuf = sc->sc_playbuf; 1579 playstats[playcntr].dmabuf = sc->sc_dmabuf; 1580 playstats[playcntr].bufcnt = sc->sc_bufcnt; 1581 playstats[playcntr].curaddr = gus_get_curaddr(sc, GUS_VOICE_LEFT); 1582 playcntr = ++playcntr % NDMARECS; 1583 } 1584#endif 1585 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, GUS_VOICE_LEFT); 1586 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL); 1587 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_LEFT].voccntl); 1588 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL); 1589 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_LEFT].volcntl); 1590 } 1591 } 1592 gus_bufcnt[sc->sc_bufcnt-1]++; 1593 /* 1594 * flip to the next DMA buffer 1595 */ 1596 1597 sc->sc_dmabuf = ++sc->sc_dmabuf % sc->sc_nbufs; 1598 /* 1599 * See comments below about DMA admission control strategy. 1600 * We can call the upper level here if we have an 1601 * idle buffer (not currently playing) to DMA into. 1602 */ 1603 if (sc->sc_dmaoutintr && sc->sc_bufcnt < sc->sc_nbufs) { 1604 /* clean out to prevent double calls */ 1605 void (*pfunc) __P((void *)) = sc->sc_dmaoutintr; 1606 void *arg = sc->sc_outarg; 1607 1608 sc->sc_outarg = 0; 1609 sc->sc_dmaoutintr = 0; 1610 (*pfunc)(arg); 1611 } 1612} 1613 1614/* 1615 * Service voice interrupts 1616 */ 1617 1618STATIC int 1619gus_voice_intr(sc) 1620 struct gus_softc *sc; 1621{ 1622 bus_space_tag_t iot = sc->sc_iot; 1623 bus_space_handle_t ioh2 = sc->sc_ioh2; 1624 int ignore = 0, voice, rval = 0; 1625 unsigned char intr, status; 1626 1627 /* 1628 * The point of this may not be obvious at first. A voice can 1629 * interrupt more than once; according to the GUS SDK we are supposed 1630 * to ignore multiple interrupts for the same voice. 1631 */ 1632 1633 while(1) { 1634 SELECT_GUS_REG(iot, ioh2, GUSREG_IRQ_STATUS); 1635 intr = bus_space_read_1(iot, ioh2, GUS_DATA_HIGH); 1636 1637 if ((intr & (GUSMASK_WIRQ_VOLUME | GUSMASK_WIRQ_VOICE)) 1638 == (GUSMASK_WIRQ_VOLUME | GUSMASK_WIRQ_VOICE)) 1639 /* 1640 * No more interrupts, time to return 1641 */ 1642 return rval; 1643 1644 if ((intr & GUSMASK_WIRQ_VOICE) == 0) { 1645 1646 /* 1647 * We've got a voice interrupt. Ignore previous 1648 * interrupts by the same voice. 1649 */ 1650 1651 rval = 1; 1652 voice = intr & GUSMASK_WIRQ_VOICEMASK; 1653 1654 if ((1 << voice) & ignore) 1655 break; 1656 1657 ignore |= 1 << voice; 1658 1659 /* 1660 * If the voice is stopped, then force it to stop 1661 * (this stops it from continuously generating IRQs) 1662 */ 1663 1664 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL+0x80); 1665 status = bus_space_read_1(iot, ioh2, GUS_DATA_HIGH); 1666 if (status & GUSMASK_VOICE_STOPPED) { 1667 if (voice != GUS_VOICE_LEFT) { 1668 DMAPRINTF(("%s: spurious voice %d stop?\n", 1669 sc->sc_dev.dv_xname, voice)); 1670 gus_stop_voice(sc, voice, 0); 1671 continue; 1672 } 1673 gus_stop_voice(sc, voice, 1); 1674 /* also kill right voice */ 1675 gus_stop_voice(sc, GUS_VOICE_RIGHT, 0); 1676 sc->sc_bufcnt--; /* it finished a buffer */ 1677 if (sc->sc_bufcnt > 0) { 1678 /* 1679 * probably a race to get here: the voice 1680 * stopped while the DMA code was just trying to 1681 * get the next buffer in place. 1682 * Start the voice again. 1683 */ 1684 printf("%s: stopped voice not drained? (%x)\n", 1685 sc->sc_dev.dv_xname, sc->sc_bufcnt); 1686 gus_falsestops++; 1687 1688 sc->sc_playbuf = ++sc->sc_playbuf % sc->sc_nbufs; 1689 gus_start_playing(sc, sc->sc_playbuf); 1690 } else if (sc->sc_bufcnt < 0) { 1691#ifdef DDB 1692 printf("%s: negative bufcnt in stopped voice\n", 1693 sc->sc_dev.dv_xname); 1694 Debugger(); 1695#else 1696 panic("%s: negative bufcnt in stopped voice", 1697 sc->sc_dev.dv_xname); 1698#endif 1699 } else { 1700 sc->sc_playbuf = -1; /* none are active */ 1701 gus_stops++; 1702 } 1703 /* fall through to callback and admit another 1704 buffer.... */ 1705 } else if (sc->sc_bufcnt != 0) { 1706 /* 1707 * This should always be taken if the voice 1708 * is not stopped. 1709 */ 1710 gus_continues++; 1711 if (gus_continue_playing(sc, voice)) { 1712 /* 1713 * we shouldn't have continued--active DMA 1714 * is in the way in the ring, for 1715 * some as-yet undebugged reason. 1716 */ 1717 gus_stop_voice(sc, GUS_VOICE_LEFT, 1); 1718 /* also kill right voice */ 1719 gus_stop_voice(sc, GUS_VOICE_RIGHT, 0); 1720 sc->sc_playbuf = -1; 1721 gus_stops++; 1722 } 1723 } 1724 /* 1725 * call the upper level to send on down another 1726 * block. We do admission rate control as follows: 1727 * 1728 * When starting up output (in the first N 1729 * blocks), call the upper layer after the DMA is 1730 * complete (see above in gus_dmaout_intr()). 1731 * 1732 * When output is already in progress and we have 1733 * no more GUS buffers to use for DMA, the DMA 1734 * output routines do not call the upper layer. 1735 * Instead, we call the DMA completion routine 1736 * here, after the voice interrupts indicating 1737 * that it's finished with a buffer. 1738 * 1739 * However, don't call anything here if the DMA 1740 * output flag is set, (which shouldn't happen) 1741 * because we'll squish somebody else's DMA if 1742 * that's the case. When DMA is done, it will 1743 * call back if there is a spare buffer. 1744 */ 1745 if (sc->sc_dmaoutintr && !(sc->sc_flags & GUS_LOCKED)) { 1746 if (sc->sc_dmaoutintr == stereo_dmaintr) 1747 printf("gusdmaout botch?\n"); 1748 else { 1749 /* clean out to avoid double calls */ 1750 void (*pfunc) __P((void *)) = sc->sc_dmaoutintr; 1751 void *arg = sc->sc_outarg; 1752 1753 sc->sc_outarg = 0; 1754 sc->sc_dmaoutintr = 0; 1755 (*pfunc)(arg); 1756 } 1757 } 1758 } 1759 1760 /* 1761 * Ignore other interrupts for now 1762 */ 1763 } 1764 return 0; 1765} 1766 1767STATIC void 1768gus_start_playing(sc, bufno) 1769 struct gus_softc *sc; 1770 int bufno; 1771{ 1772 bus_space_tag_t iot = sc->sc_iot; 1773 bus_space_handle_t ioh2 = sc->sc_ioh2; 1774 /* 1775 * Start the voices playing, with buffer BUFNO. 1776 */ 1777 1778 /* 1779 * Loop or roll if we have buffers ready. 1780 */ 1781 1782 if (sc->sc_bufcnt == 1) { 1783 sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~(GUSMASK_LOOP_ENABLE); 1784 sc->sc_voc[GUS_VOICE_LEFT].volcntl &= ~(GUSMASK_VOICE_ROLL); 1785 } else { 1786 if (bufno == sc->sc_nbufs - 1) { 1787 sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_LOOP_ENABLE; 1788 sc->sc_voc[GUS_VOICE_LEFT].volcntl &= ~(GUSMASK_VOICE_ROLL); 1789 } else { 1790 sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~GUSMASK_LOOP_ENABLE; 1791 sc->sc_voc[GUS_VOICE_LEFT].volcntl |= GUSMASK_VOICE_ROLL; 1792 } 1793 } 1794 1795 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, GUS_VOICE_LEFT); 1796 1797 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL); 1798 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_LEFT].voccntl); 1799 1800 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL); 1801 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_LEFT].volcntl); 1802 1803 sc->sc_voc[GUS_VOICE_LEFT].current_addr = 1804 GUS_MEM_OFFSET + sc->sc_chanblocksize * bufno; 1805 sc->sc_voc[GUS_VOICE_LEFT].end_addr = 1806 sc->sc_voc[GUS_VOICE_LEFT].current_addr + sc->sc_chanblocksize - 1; 1807 sc->sc_voc[GUS_VOICE_RIGHT].current_addr = 1808 sc->sc_voc[GUS_VOICE_LEFT].current_addr + 1809 (gus_dostereo && sc->sc_channels == 2 ? GUS_LEFT_RIGHT_OFFSET : 0); 1810 /* 1811 * set up right channel to just loop forever, no interrupts, 1812 * starting at the buffer we just filled. We'll feed it data 1813 * at the same time as left channel. 1814 */ 1815 sc->sc_voc[GUS_VOICE_RIGHT].voccntl |= GUSMASK_LOOP_ENABLE; 1816 sc->sc_voc[GUS_VOICE_RIGHT].volcntl &= ~(GUSMASK_VOICE_ROLL); 1817 1818#ifdef GUSPLAYDEBUG 1819 if (gusstats) { 1820 microtime(&playstats[playcntr].tv); 1821 playstats[playcntr].curaddr = sc->sc_voc[GUS_VOICE_LEFT].current_addr; 1822 1823 playstats[playcntr].voccntl = sc->sc_voc[GUS_VOICE_LEFT].voccntl; 1824 playstats[playcntr].volcntl = sc->sc_voc[GUS_VOICE_LEFT].volcntl; 1825 playstats[playcntr].endaddr = sc->sc_voc[GUS_VOICE_LEFT].end_addr; 1826 playstats[playcntr].playbuf = bufno; 1827 playstats[playcntr].dmabuf = sc->sc_dmabuf; 1828 playstats[playcntr].bufcnt = sc->sc_bufcnt; 1829 playstats[playcntr].vaction = 5; 1830 playcntr = ++playcntr % NDMARECS; 1831 } 1832#endif 1833 1834 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, GUS_VOICE_RIGHT); 1835 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL); 1836 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_RIGHT].voccntl); 1837 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL); 1838 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_RIGHT].volcntl); 1839 1840 gus_start_voice(sc, GUS_VOICE_RIGHT, 0); 1841 gus_start_voice(sc, GUS_VOICE_LEFT, 1); 1842 if (sc->sc_playbuf == -1) 1843 /* mark start of playing */ 1844 sc->sc_playbuf = bufno; 1845} 1846 1847STATIC int 1848gus_continue_playing(sc, voice) 1849 struct gus_softc *sc; 1850 int voice; 1851{ 1852 bus_space_tag_t iot = sc->sc_iot; 1853 bus_space_handle_t ioh2 = sc->sc_ioh2; 1854 1855 /* 1856 * stop this voice from interrupting while we work. 1857 */ 1858 1859 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL); 1860 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl & ~(GUSMASK_VOICE_IRQ)); 1861 1862 /* 1863 * update playbuf to point to the buffer the hardware just started 1864 * playing 1865 */ 1866 sc->sc_playbuf = ++sc->sc_playbuf % sc->sc_nbufs; 1867 1868 /* 1869 * account for buffer just finished 1870 */ 1871 if (--sc->sc_bufcnt == 0) { 1872 DPRINTF(("gus: bufcnt 0 on continuing voice?\n")); 1873 } 1874 if (sc->sc_playbuf == sc->sc_dmabuf && (sc->sc_flags & GUS_LOCKED)) { 1875 printf("%s: continue into active dmabuf?\n", sc->sc_dev.dv_xname); 1876 return 1; 1877 } 1878 1879 /* 1880 * Select the end of the buffer based on the currently active 1881 * buffer, [plus extra contiguous buffers (if ready)]. 1882 */ 1883 1884 /* 1885 * set endpoint at end of buffer we just started playing. 1886 * 1887 * The total gets -1 because end addrs are one less than you might 1888 * think (the end_addr is the address of the last sample to play) 1889 */ 1890 gus_set_endaddr(sc, voice, GUS_MEM_OFFSET + 1891 sc->sc_chanblocksize * (sc->sc_playbuf + 1) - 1); 1892 1893 if (sc->sc_bufcnt < 2) { 1894 /* 1895 * Clear out the loop and roll flags, and rotate the currently 1896 * playing buffer. That way, if we don't manage to get more 1897 * data before this buffer finishes, we'll just stop. 1898 */ 1899 sc->sc_voc[voice].voccntl &= ~GUSMASK_LOOP_ENABLE; 1900 sc->sc_voc[voice].volcntl &= ~GUSMASK_VOICE_ROLL; 1901 playstats[playcntr].vaction = 0; 1902 } else { 1903 /* 1904 * We have some buffers to play. set LOOP if we're on the 1905 * last buffer in the ring, otherwise set ROLL. 1906 */ 1907 if (sc->sc_playbuf == sc->sc_nbufs - 1) { 1908 sc->sc_voc[voice].voccntl |= GUSMASK_LOOP_ENABLE; 1909 sc->sc_voc[voice].volcntl &= ~GUSMASK_VOICE_ROLL; 1910 playstats[playcntr].vaction = 1; 1911 } else { 1912 sc->sc_voc[voice].voccntl &= ~GUSMASK_LOOP_ENABLE; 1913 sc->sc_voc[voice].volcntl |= GUSMASK_VOICE_ROLL; 1914 playstats[playcntr].vaction = 2; 1915 } 1916 } 1917#ifdef GUSPLAYDEBUG 1918 if (gusstats) { 1919 microtime(&playstats[playcntr].tv); 1920 playstats[playcntr].curaddr = gus_get_curaddr(sc, voice); 1921 1922 playstats[playcntr].voccntl = sc->sc_voc[voice].voccntl; 1923 playstats[playcntr].volcntl = sc->sc_voc[voice].volcntl; 1924 playstats[playcntr].endaddr = sc->sc_voc[voice].end_addr; 1925 playstats[playcntr].playbuf = sc->sc_playbuf; 1926 playstats[playcntr].dmabuf = sc->sc_dmabuf; 1927 playstats[playcntr].bufcnt = sc->sc_bufcnt; 1928 playcntr = ++playcntr % NDMARECS; 1929 } 1930#endif 1931 1932 /* 1933 * (re-)set voice parameters. This will reenable interrupts from this 1934 * voice. 1935 */ 1936 1937 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL); 1938 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl); 1939 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL); 1940 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].volcntl); 1941 return 0; 1942} 1943 1944/* 1945 * Send/receive data into GUS's DRAM using DMA. Called at splgus() 1946 */ 1947 1948STATIC void 1949gusdmaout(sc, flags, gusaddr, buffaddr, length) 1950 struct gus_softc *sc; 1951 int flags, length; 1952 u_long gusaddr; 1953 caddr_t buffaddr; 1954{ 1955 unsigned char c = (unsigned char) flags; 1956 bus_space_tag_t iot = sc->sc_iot; 1957 bus_space_handle_t ioh2 = sc->sc_ioh2; 1958 1959 DMAPRINTF(("gusdmaout flags=%x scflags=%x\n", flags, sc->sc_flags)); 1960 1961 sc->sc_gusaddr = gusaddr; 1962 1963 /* 1964 * If we're using a 16 bit DMA channel, we have to jump through some 1965 * extra hoops; this includes translating the DRAM address a bit 1966 */ 1967 1968 if (sc->sc_drq >= 4) { 1969 c |= GUSMASK_DMA_WIDTH; 1970 gusaddr = convert_to_16bit(gusaddr); 1971 } 1972 1973 /* 1974 * Add flag bits that we always set - fast DMA, enable IRQ 1975 */ 1976 1977 c |= GUSMASK_DMA_ENABLE | GUSMASK_DMA_R0 | GUSMASK_DMA_IRQ; 1978 1979 /* 1980 * Make sure the GUS _isn't_ setup for DMA 1981 */ 1982 1983 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL); 1984 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0); 1985 1986 /* 1987 * Tell the PC DMA controller to start doing DMA 1988 */ 1989 1990 sc->sc_dmaoutaddr = (u_char *) buffaddr; 1991 sc->sc_dmaoutcnt = length; 1992 isa_dmastart(sc->sc_dev.dv_parent, sc->sc_drq, buffaddr, length, 1993 NULL, DMAMODE_WRITE, BUS_DMA_NOWAIT); 1994 1995 /* 1996 * Set up DMA address - use the upper 16 bits ONLY 1997 */ 1998 1999 sc->sc_flags |= GUS_DMAOUT_ACTIVE; 2000 2001 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_START); 2002 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, (int) (gusaddr >> 4)); 2003 2004 /* 2005 * Tell the GUS to start doing DMA 2006 */ 2007 2008 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL); 2009 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, c); 2010 2011 /* 2012 * XXX If we don't finish in one second, give up... 2013 */ 2014 untimeout(gus_dmaout_timeout, sc); /* flush old one, if there is one */ 2015 timeout(gus_dmaout_timeout, sc, hz); 2016} 2017 2018/* 2019 * Start a voice playing on the GUS. Called from interrupt handler at 2020 * splgus(). 2021 */ 2022 2023STATIC void 2024gus_start_voice(sc, voice, intrs) 2025 struct gus_softc *sc; 2026 int voice; 2027 int intrs; 2028{ 2029 bus_space_tag_t iot = sc->sc_iot; 2030 bus_space_handle_t ioh2 = sc->sc_ioh2; 2031 u_long start; 2032 u_long current; 2033 u_long end; 2034 2035 /* 2036 * Pick all the values for the voice out of the gus_voice struct 2037 * and use those to program the voice 2038 */ 2039 2040 start = sc->sc_voc[voice].start_addr; 2041 current = sc->sc_voc[voice].current_addr; 2042 end = sc->sc_voc[voice].end_addr; 2043 2044 /* 2045 * If we're using 16 bit data, mangle the addresses a bit 2046 */ 2047 2048 if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16) { 2049 /* -1 on start so that we get onto sample boundary--other 2050 code always sets it for 1-byte rollover protection */ 2051 start = convert_to_16bit(start-1); 2052 current = convert_to_16bit(current); 2053 end = convert_to_16bit(end); 2054 } 2055 2056 /* 2057 * Select the voice we want to use, and program the data addresses 2058 */ 2059 2060 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice); 2061 2062 SELECT_GUS_REG(iot, ioh2, GUSREG_START_ADDR_HIGH); 2063 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(start)); 2064 SELECT_GUS_REG(iot, ioh2, GUSREG_START_ADDR_LOW); 2065 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(start)); 2066 2067 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH); 2068 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(current)); 2069 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW); 2070 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(current)); 2071 2072 SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_HIGH); 2073 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(end)); 2074 SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_LOW); 2075 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(end)); 2076 2077 /* 2078 * (maybe) enable interrupts, disable voice stopping 2079 */ 2080 2081 if (intrs) { 2082 sc->sc_flags |= GUS_PLAYING; /* playing is about to start */ 2083 sc->sc_voc[voice].voccntl |= GUSMASK_VOICE_IRQ; 2084 DMAPRINTF(("gus voice playing=%x\n", sc->sc_flags)); 2085 } else 2086 sc->sc_voc[voice].voccntl &= ~GUSMASK_VOICE_IRQ; 2087 sc->sc_voc[voice].voccntl &= ~(GUSMASK_VOICE_STOPPED | 2088 GUSMASK_STOP_VOICE); 2089 2090 /* 2091 * Tell the GUS about it. Note that we're doing volume ramping here 2092 * from 0 up to the set volume to help reduce clicks. 2093 */ 2094 2095 SELECT_GUS_REG(iot, ioh2, GUSREG_START_VOLUME); 2096 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00); 2097 SELECT_GUS_REG(iot, ioh2, GUSREG_END_VOLUME); 2098 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].current_volume >> 4); 2099 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME); 2100 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x00); 2101 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_RATE); 2102 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 63); 2103 2104 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL); 2105 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl); 2106 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL); 2107 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00); 2108 delay(50); 2109 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL); 2110 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl); 2111 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL); 2112 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00); 2113 2114} 2115 2116/* 2117 * Stop a given voice. called at splgus() 2118 */ 2119 2120STATIC void 2121gus_stop_voice(sc, voice, intrs_too) 2122 struct gus_softc *sc; 2123 int voice; 2124 int intrs_too; 2125{ 2126 bus_space_tag_t iot = sc->sc_iot; 2127 bus_space_handle_t ioh2 = sc->sc_ioh2; 2128 2129 sc->sc_voc[voice].voccntl |= GUSMASK_VOICE_STOPPED | 2130 GUSMASK_STOP_VOICE; 2131 if (intrs_too) { 2132 sc->sc_voc[voice].voccntl &= ~(GUSMASK_VOICE_IRQ); 2133 /* no more DMA to do */ 2134 sc->sc_flags &= ~GUS_PLAYING; 2135 } 2136 DMAPRINTF(("gusintr voice notplaying=%x\n", sc->sc_flags)); 2137 2138 guspoke(iot, ioh2, 0L, 0); 2139 2140 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice); 2141 2142 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME); 2143 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000); 2144 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL); 2145 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl); 2146 delay(100); 2147 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME); 2148 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000); 2149 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL); 2150 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl); 2151 2152 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH); 2153 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000); 2154 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW); 2155 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000); 2156 2157} 2158 2159 2160/* 2161 * Set the volume of a given voice. Called at splgus(). 2162 */ 2163STATIC void 2164gus_set_volume(sc, voice, volume) 2165 struct gus_softc *sc; 2166 int voice, volume; 2167{ 2168 bus_space_tag_t iot = sc->sc_iot; 2169 bus_space_handle_t ioh2 = sc->sc_ioh2; 2170 unsigned int gusvol; 2171 2172 gusvol = gus_log_volumes[volume < 512 ? volume : 511]; 2173 2174 sc->sc_voc[voice].current_volume = gusvol; 2175 2176 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice); 2177 2178 SELECT_GUS_REG(iot, ioh2, GUSREG_START_VOLUME); 2179 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (unsigned char) (gusvol >> 4)); 2180 2181 SELECT_GUS_REG(iot, ioh2, GUSREG_END_VOLUME); 2182 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (unsigned char) (gusvol >> 4)); 2183 2184 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME); 2185 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, gusvol << 4); 2186 delay(500); 2187 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, gusvol << 4); 2188 2189} 2190 2191/* 2192 * Interface to the audio layer. 2193 */ 2194 2195int 2196gusmax_set_params(addr, setmode, usemode, p, r) 2197 void *addr; 2198 int setmode, usemode; 2199 struct audio_params *p, *r; 2200{ 2201 struct ad1848_softc *ac = addr; 2202 struct gus_softc *sc = ac->parent; 2203 int error; 2204 2205 error = ad1848_set_params(ac, setmode, usemode, p, r); 2206 if (error) 2207 return error; 2208 error = gus_set_params(sc, setmode, usemode, p, r); 2209 return error; 2210} 2211 2212int 2213gus_set_params(addr, setmode, usemode, p, r) 2214 void *addr; 2215 int setmode, usemode; 2216 struct audio_params *p, *r; 2217{ 2218 struct gus_softc *sc = addr; 2219 int s; 2220 2221 switch (p->encoding) { 2222 case AUDIO_ENCODING_ULAW: 2223 case AUDIO_ENCODING_ALAW: 2224 case AUDIO_ENCODING_SLINEAR_LE: 2225 case AUDIO_ENCODING_ULINEAR_LE: 2226 case AUDIO_ENCODING_SLINEAR_BE: 2227 case AUDIO_ENCODING_ULINEAR_BE: 2228 break; 2229 default: 2230 return (EINVAL); 2231 } 2232 2233 s = splaudio(); 2234 2235 if (p->precision == 8) { 2236 sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~GUSMASK_DATA_SIZE16; 2237 sc->sc_voc[GUS_VOICE_RIGHT].voccntl &= ~GUSMASK_DATA_SIZE16; 2238 } else { 2239 sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_DATA_SIZE16; 2240 sc->sc_voc[GUS_VOICE_RIGHT].voccntl |= GUSMASK_DATA_SIZE16; 2241 } 2242 2243 sc->sc_encoding = p->encoding; 2244 sc->sc_precision = p->precision; 2245 sc->sc_channels = p->channels; 2246 2247 splx(s); 2248 2249 if (p->sample_rate > gus_max_frequency[sc->sc_voices - GUS_MIN_VOICES]) 2250 p->sample_rate = gus_max_frequency[sc->sc_voices - GUS_MIN_VOICES]; 2251 if (setmode & AUMODE_RECORD) 2252 sc->sc_irate = p->sample_rate; 2253 if (setmode & AUMODE_PLAY) 2254 sc->sc_orate = p->sample_rate; 2255 2256 switch (p->encoding) { 2257 case AUDIO_ENCODING_ULAW: 2258 p->sw_code = mulaw_to_ulinear8; 2259 r->sw_code = ulinear8_to_mulaw; 2260 break; 2261 case AUDIO_ENCODING_ALAW: 2262 p->sw_code = alaw_to_ulinear8; 2263 r->sw_code = ulinear8_to_alaw; 2264 break; 2265 case AUDIO_ENCODING_ULINEAR_BE: 2266 case AUDIO_ENCODING_SLINEAR_BE: 2267 r->sw_code = p->sw_code = swap_bytes; 2268 break; 2269 } 2270 2271 return 0; 2272} 2273 2274/* 2275 * Interface to the audio layer - set the blocksize to the correct number 2276 * of units 2277 */ 2278 2279int 2280gusmax_round_blocksize(addr, blocksize) 2281 void * addr; 2282 int blocksize; 2283{ 2284 struct ad1848_softc *ac = addr; 2285 struct gus_softc *sc = ac->parent; 2286 2287/* blocksize = ad1848_round_blocksize(ac, blocksize);*/ 2288 return gus_round_blocksize(sc, blocksize); 2289} 2290 2291int 2292gus_round_blocksize(addr, blocksize) 2293 void * addr; 2294 int blocksize; 2295{ 2296 struct gus_softc *sc = addr; 2297 2298 DPRINTF(("gus_round_blocksize called\n")); 2299 2300 if ((sc->sc_encoding == AUDIO_ENCODING_ULAW || 2301 sc->sc_encoding == AUDIO_ENCODING_ALAW) && blocksize > 32768) 2302 blocksize = 32768; 2303 else if (blocksize > 65536) 2304 blocksize = 65536; 2305 2306 if ((blocksize % GUS_BUFFER_MULTIPLE) != 0) 2307 blocksize = (blocksize / GUS_BUFFER_MULTIPLE + 1) * 2308 GUS_BUFFER_MULTIPLE; 2309 2310 /* set up temporary buffer to hold the deinterleave, if necessary 2311 for stereo output */ 2312 if (sc->sc_deintr_buf) { 2313 FREE(sc->sc_deintr_buf, M_DEVBUF); 2314 sc->sc_deintr_buf = NULL; 2315 } 2316 MALLOC(sc->sc_deintr_buf, void *, blocksize>>1, M_DEVBUF, M_WAITOK); 2317 2318 sc->sc_blocksize = blocksize; 2319 /* multi-buffering not quite working yet. */ 2320 sc->sc_nbufs = /*GUS_MEM_FOR_BUFFERS / blocksize*/ 2; 2321 2322 gus_set_chan_addrs(sc); 2323 2324 return blocksize; 2325} 2326 2327int 2328gus_get_out_gain(addr) 2329 caddr_t addr; 2330{ 2331 struct gus_softc *sc = (struct gus_softc *) addr; 2332 2333 DPRINTF(("gus_get_out_gain called\n")); 2334 return sc->sc_ogain / 2; 2335} 2336 2337STATIC inline void gus_set_voices(sc, voices) 2338struct gus_softc *sc; 2339int voices; 2340{ 2341 bus_space_tag_t iot = sc->sc_iot; 2342 bus_space_handle_t ioh2 = sc->sc_ioh2; 2343 /* 2344 * Select the active number of voices 2345 */ 2346 2347 SELECT_GUS_REG(iot, ioh2, GUSREG_ACTIVE_VOICES); 2348 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (voices-1) | 0xc0); 2349 2350 sc->sc_voices = voices; 2351} 2352 2353/* 2354 * Actually set the settings of various values on the card 2355 */ 2356 2357int 2358gusmax_commit_settings(addr) 2359 void * addr; 2360{ 2361 struct ad1848_softc *ac = addr; 2362 struct gus_softc *sc = ac->parent; 2363 int error; 2364 2365 error = ad1848_commit_settings(ac); 2366 if (error) 2367 return error; 2368 return gus_commit_settings(sc); 2369} 2370 2371/* 2372 * Commit the settings. Called at normal IPL. 2373 */ 2374int 2375gus_commit_settings(addr) 2376 void * addr; 2377{ 2378 struct gus_softc *sc = addr; 2379 int s; 2380 2381 DPRINTF(("gus_commit_settings called (gain = %d)\n",sc->sc_ogain)); 2382 2383 2384 s = splgus(); 2385 2386 gus_set_recrate(sc, sc->sc_irate); 2387 gus_set_volume(sc, GUS_VOICE_LEFT, sc->sc_ogain); 2388 gus_set_volume(sc, GUS_VOICE_RIGHT, sc->sc_ogain); 2389 gus_set_samprate(sc, GUS_VOICE_LEFT, sc->sc_orate); 2390 gus_set_samprate(sc, GUS_VOICE_RIGHT, sc->sc_orate); 2391 splx(s); 2392 gus_set_chan_addrs(sc); 2393 2394 return 0; 2395} 2396 2397STATIC void 2398gus_set_chan_addrs(sc) 2399struct gus_softc *sc; 2400{ 2401 /* 2402 * We use sc_nbufs * blocksize bytes of storage in the on-board GUS 2403 * ram. 2404 * For mono, each of the sc_nbufs buffers is DMA'd to in one chunk, 2405 * and both left & right channels play the same buffer. 2406 * 2407 * For stereo, each channel gets a contiguous half of the memory, 2408 * and each has sc_nbufs buffers of size blocksize/2. 2409 * Stereo data are deinterleaved in main memory before the DMA out 2410 * routines are called to queue the output. 2411 * 2412 * The blocksize per channel is kept in sc_chanblocksize. 2413 */ 2414 if (sc->sc_channels == 2) 2415 sc->sc_chanblocksize = sc->sc_blocksize/2; 2416 else 2417 sc->sc_chanblocksize = sc->sc_blocksize; 2418 2419 sc->sc_voc[GUS_VOICE_LEFT].start_addr = GUS_MEM_OFFSET - 1; 2420 sc->sc_voc[GUS_VOICE_RIGHT].start_addr = 2421 (gus_dostereo && sc->sc_channels == 2 ? GUS_LEFT_RIGHT_OFFSET : 0) 2422 + GUS_MEM_OFFSET - 1; 2423 sc->sc_voc[GUS_VOICE_RIGHT].current_addr = 2424 sc->sc_voc[GUS_VOICE_RIGHT].start_addr + 1; 2425 sc->sc_voc[GUS_VOICE_RIGHT].end_addr = 2426 sc->sc_voc[GUS_VOICE_RIGHT].start_addr + 2427 sc->sc_nbufs * sc->sc_chanblocksize; 2428 2429} 2430 2431/* 2432 * Set the sample rate of the given voice. Called at splgus(). 2433 */ 2434 2435STATIC void 2436gus_set_samprate(sc, voice, freq) 2437 struct gus_softc *sc; 2438 int voice, freq; 2439{ 2440 bus_space_tag_t iot = sc->sc_iot; 2441 bus_space_handle_t ioh2 = sc->sc_ioh2; 2442 unsigned int fc; 2443 u_long temp, f = (u_long) freq; 2444 2445 /* 2446 * calculate fc based on the number of active voices; 2447 * we need to use longs to preserve enough bits 2448 */ 2449 2450 temp = (u_long) gus_max_frequency[sc->sc_voices-GUS_MIN_VOICES]; 2451 2452 fc = (unsigned int)(((f << 9L) + (temp >> 1L)) / temp); 2453 2454 fc <<= 1; 2455 2456 2457 /* 2458 * Program the voice frequency, and set it in the voice data record 2459 */ 2460 2461 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice); 2462 SELECT_GUS_REG(iot, ioh2, GUSREG_FREQ_CONTROL); 2463 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, fc); 2464 2465 sc->sc_voc[voice].rate = freq; 2466 2467} 2468 2469/* 2470 * Set the sample rate of the recording frequency. Formula is from the GUS 2471 * SDK. Called at splgus(). 2472 */ 2473 2474STATIC void 2475gus_set_recrate(sc, rate) 2476 struct gus_softc *sc; 2477 u_long rate; 2478{ 2479 bus_space_tag_t iot = sc->sc_iot; 2480 bus_space_handle_t ioh2 = sc->sc_ioh2; 2481 u_char realrate; 2482 DPRINTF(("gus_set_recrate %lu\n", rate)); 2483 2484#if 0 2485 realrate = 9878400/(16*(rate+2)); /* formula from GUS docs */ 2486#endif 2487 realrate = (9878400 >> 4)/rate - 2; /* formula from code, sigh. */ 2488 2489 SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_FREQ); 2490 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, realrate); 2491} 2492 2493/* 2494 * Interface to the audio layer - turn the output on or off. Note that some 2495 * of these bits are flipped in the register 2496 */ 2497 2498int 2499gusmax_speaker_ctl(addr, newstate) 2500 void * addr; 2501 int newstate; 2502{ 2503 struct ad1848_softc *sc = addr; 2504 return gus_speaker_ctl(sc->parent, newstate); 2505} 2506 2507int 2508gus_speaker_ctl(addr, newstate) 2509 void * addr; 2510 int newstate; 2511{ 2512 struct gus_softc *sc = (struct gus_softc *) addr; 2513 bus_space_tag_t iot = sc->sc_iot; 2514 bus_space_handle_t ioh1 = sc->sc_ioh1; 2515 2516 /* Line out bit is flipped: 0 enables, 1 disables */ 2517 if ((newstate == SPKR_ON) && 2518 (sc->sc_mixcontrol & GUSMASK_LINE_OUT)) { 2519 sc->sc_mixcontrol &= ~GUSMASK_LINE_OUT; 2520 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol); 2521 } 2522 if ((newstate == SPKR_OFF) && 2523 (sc->sc_mixcontrol & GUSMASK_LINE_OUT) == 0) { 2524 sc->sc_mixcontrol |= GUSMASK_LINE_OUT; 2525 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol); 2526 } 2527 2528 return 0; 2529} 2530 2531STATIC int 2532gus_linein_ctl(addr, newstate) 2533 void * addr; 2534 int newstate; 2535{ 2536 struct gus_softc *sc = (struct gus_softc *) addr; 2537 bus_space_tag_t iot = sc->sc_iot; 2538 bus_space_handle_t ioh1 = sc->sc_ioh1; 2539 2540 /* Line in bit is flipped: 0 enables, 1 disables */ 2541 if ((newstate == SPKR_ON) && 2542 (sc->sc_mixcontrol & GUSMASK_LINE_IN)) { 2543 sc->sc_mixcontrol &= ~GUSMASK_LINE_IN; 2544 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol); 2545 } 2546 if ((newstate == SPKR_OFF) && 2547 (sc->sc_mixcontrol & GUSMASK_LINE_IN) == 0) { 2548 sc->sc_mixcontrol |= GUSMASK_LINE_IN; 2549 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol); 2550 } 2551 2552 return 0; 2553} 2554 2555STATIC int 2556gus_mic_ctl(addr, newstate) 2557 void * addr; 2558 int newstate; 2559{ 2560 struct gus_softc *sc = (struct gus_softc *) addr; 2561 bus_space_tag_t iot = sc->sc_iot; 2562 bus_space_handle_t ioh1 = sc->sc_ioh1; 2563 2564 /* Mic bit is normal: 1 enables, 0 disables */ 2565 if ((newstate == SPKR_ON) && 2566 (sc->sc_mixcontrol & GUSMASK_MIC_IN) == 0) { 2567 sc->sc_mixcontrol |= GUSMASK_MIC_IN; 2568 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol); 2569 } 2570 if ((newstate == SPKR_OFF) && 2571 (sc->sc_mixcontrol & GUSMASK_MIC_IN)) { 2572 sc->sc_mixcontrol &= ~GUSMASK_MIC_IN; 2573 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol); 2574 } 2575 2576 return 0; 2577} 2578 2579/* 2580 * Set the end address of a give voice. Called at splgus() 2581 */ 2582 2583STATIC void 2584gus_set_endaddr(sc, voice, addr) 2585 struct gus_softc *sc; 2586 int voice; 2587 u_long addr; 2588{ 2589 bus_space_tag_t iot = sc->sc_iot; 2590 bus_space_handle_t ioh2 = sc->sc_ioh2; 2591 2592 sc->sc_voc[voice].end_addr = addr; 2593 2594 if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16) 2595 addr = convert_to_16bit(addr); 2596 2597 SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_HIGH); 2598 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(addr)); 2599 SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_LOW); 2600 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(addr)); 2601 2602} 2603 2604#ifdef GUSPLAYDEBUG 2605/* 2606 * Set current address. called at splgus() 2607 */ 2608STATIC void 2609gus_set_curaddr(sc, voice, addr) 2610 struct gus_softc *sc; 2611 int voice; 2612 u_long addr; 2613{ 2614 bus_space_tag_t iot = sc->sc_iot; 2615 bus_space_handle_t ioh2 = sc->sc_ioh2; 2616 2617 sc->sc_voc[voice].current_addr = addr; 2618 2619 if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16) 2620 addr = convert_to_16bit(addr); 2621 2622 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice); 2623 2624 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH); 2625 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(addr)); 2626 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW); 2627 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(addr)); 2628 2629} 2630 2631/* 2632 * Get current GUS playback address. Called at splgus(). 2633 */ 2634STATIC u_long 2635gus_get_curaddr(sc, voice) 2636 struct gus_softc *sc; 2637 int voice; 2638{ 2639 bus_space_tag_t iot = sc->sc_iot; 2640 bus_space_handle_t ioh2 = sc->sc_ioh2; 2641 u_long addr; 2642 2643 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice); 2644 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH|GUSREG_READ); 2645 addr = (bus_space_read_2(iot, ioh2, GUS_DATA_LOW) & 0x1fff) << 7; 2646 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW|GUSREG_READ); 2647 addr |= (bus_space_read_2(iot, ioh2, GUS_DATA_LOW) >> 9L) & 0x7f; 2648 2649 if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16) 2650 addr = (addr & 0xc0000) | ((addr & 0x1ffff) << 1); /* undo 16-bit change */ 2651 DPRINTF(("gus voice %d curaddr %ld end_addr %ld\n", 2652 voice, addr, sc->sc_voc[voice].end_addr)); 2653 /* XXX sanity check the address? */ 2654 2655 return(addr); 2656} 2657#endif 2658 2659/* 2660 * Convert an address value to a "16 bit" value - why this is necessary I 2661 * have NO idea 2662 */ 2663 2664STATIC u_long 2665convert_to_16bit(address) 2666 u_long address; 2667{ 2668 u_long old_address; 2669 2670 old_address = address; 2671 address >>= 1; 2672 address &= 0x0001ffffL; 2673 address |= (old_address & 0x000c0000L); 2674 2675 return (address); 2676} 2677 2678/* 2679 * Write a value into the GUS's DRAM 2680 */ 2681 2682STATIC void 2683guspoke(iot, ioh2, address, value) 2684 bus_space_tag_t iot; 2685 bus_space_handle_t ioh2; 2686 long address; 2687 unsigned char value; 2688{ 2689 2690 /* 2691 * Select the DRAM address 2692 */ 2693 2694 SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_LOW); 2695 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, (unsigned int) (address & 0xffff)); 2696 SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_HIGH); 2697 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (unsigned char) ((address >> 16) & 0xff)); 2698 2699 /* 2700 * Actually write the data 2701 */ 2702 2703 bus_space_write_1(iot, ioh2, GUS_DRAM_DATA, value); 2704} 2705 2706/* 2707 * Read a value from the GUS's DRAM 2708 */ 2709 2710STATIC unsigned char 2711guspeek(iot, ioh2, address) 2712 bus_space_tag_t iot; 2713 bus_space_handle_t ioh2; 2714 u_long address; 2715{ 2716 2717 /* 2718 * Select the DRAM address 2719 */ 2720 2721 SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_LOW); 2722 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, (unsigned int) (address & 0xffff)); 2723 SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_HIGH); 2724 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (unsigned char) ((address >> 16) & 0xff)); 2725 2726 /* 2727 * Read in the data from the board 2728 */ 2729 2730 return (unsigned char) bus_space_read_1(iot, ioh2, GUS_DRAM_DATA); 2731} 2732 2733/* 2734 * Reset the Gravis UltraSound card, completely 2735 */ 2736 2737STATIC void 2738gusreset(sc, voices) 2739 struct gus_softc *sc; 2740 int voices; 2741{ 2742 bus_space_tag_t iot = sc->sc_iot; 2743 bus_space_handle_t ioh1 = sc->sc_ioh1; 2744 bus_space_handle_t ioh2 = sc->sc_ioh2; 2745 bus_space_handle_t ioh4 = sc->sc_ioh4; 2746 int i,s; 2747 2748 s = splgus(); 2749 2750 /* 2751 * Reset the GF1 chip 2752 */ 2753 2754 SELECT_GUS_REG(iot, ioh2, GUSREG_RESET); 2755 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00); 2756 2757 delay(500); 2758 2759 /* 2760 * Release reset 2761 */ 2762 2763 SELECT_GUS_REG(iot, ioh2, GUSREG_RESET); 2764 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, GUSMASK_MASTER_RESET); 2765 2766 delay(500); 2767 2768 /* 2769 * Reset MIDI port as well 2770 */ 2771 2772 bus_space_write_1(iot, ioh4, GUS_MIDI_CONTROL, MIDI_RESET); 2773 2774 delay(500); 2775 2776 bus_space_write_1(iot, ioh4, GUS_MIDI_CONTROL, 0x00); 2777 2778 /* 2779 * Clear interrupts 2780 */ 2781 2782 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL); 2783 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00); 2784 SELECT_GUS_REG(iot, ioh2, GUSREG_TIMER_CONTROL); 2785 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00); 2786 SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL); 2787 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00); 2788 2789 gus_set_voices(sc, voices); 2790 2791 bus_space_read_1(iot, ioh1, GUS_IRQ_STATUS); 2792 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL); 2793 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH); 2794 SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL); 2795 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH); 2796 SELECT_GUS_REG(iot, ioh2, GUSREG_IRQ_STATUS); 2797 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH); 2798 2799 /* 2800 * Reset voice specific information 2801 */ 2802 2803 for(i = 0; i < voices; i++) { 2804 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) i); 2805 2806 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL); 2807 2808 sc->sc_voc[i].voccntl = GUSMASK_VOICE_STOPPED | 2809 GUSMASK_STOP_VOICE; 2810 2811 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[i].voccntl); 2812 2813 sc->sc_voc[i].volcntl = GUSMASK_VOLUME_STOPPED | 2814 GUSMASK_STOP_VOLUME; 2815 2816 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL); 2817 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[i].volcntl); 2818 2819 delay(100); 2820 2821 gus_set_samprate(sc, i, 8000); 2822 SELECT_GUS_REG(iot, ioh2, GUSREG_START_ADDR_HIGH); 2823 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000); 2824 SELECT_GUS_REG(iot, ioh2, GUSREG_START_ADDR_LOW); 2825 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000); 2826 SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_HIGH); 2827 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000); 2828 SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_LOW); 2829 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000); 2830 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_RATE); 2831 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x01); 2832 SELECT_GUS_REG(iot, ioh2, GUSREG_START_VOLUME); 2833 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x10); 2834 SELECT_GUS_REG(iot, ioh2, GUSREG_END_VOLUME); 2835 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0xe0); 2836 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME); 2837 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000); 2838 2839 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH); 2840 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000); 2841 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW); 2842 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000); 2843 SELECT_GUS_REG(iot, ioh2, GUSREG_PAN_POS); 2844 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x07); 2845 } 2846 2847 /* 2848 * Clear out any pending IRQs 2849 */ 2850 2851 bus_space_read_1(iot, ioh1, GUS_IRQ_STATUS); 2852 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL); 2853 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH); 2854 SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL); 2855 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH); 2856 SELECT_GUS_REG(iot, ioh2, GUSREG_IRQ_STATUS); 2857 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH); 2858 2859 SELECT_GUS_REG(iot, ioh2, GUSREG_RESET); 2860 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, GUSMASK_MASTER_RESET | GUSMASK_DAC_ENABLE | 2861 GUSMASK_IRQ_ENABLE); 2862 2863 splx(s); 2864} 2865 2866 2867STATIC void 2868gus_init_cs4231(sc) 2869 struct gus_softc *sc; 2870{ 2871 bus_space_tag_t iot = sc->sc_iot; 2872 bus_space_handle_t ioh1 = sc->sc_ioh1; 2873 int port = sc->sc_iobase; 2874 u_char ctrl; 2875 2876 ctrl = (port & 0xf0) >> 4; /* set port address middle nibble */ 2877 /* 2878 * The codec is a bit weird--swapped dma channels. 2879 */ 2880 ctrl |= GUS_MAX_CODEC_ENABLE; 2881 if (sc->sc_drq >= 4) 2882 ctrl |= GUS_MAX_RECCHAN16; 2883 if (sc->sc_recdrq >= 4) 2884 ctrl |= GUS_MAX_PLAYCHAN16; 2885 2886 bus_space_write_1(iot, ioh1, GUS_MAX_CTRL, ctrl); 2887 2888 sc->sc_codec.sc_iot = sc->sc_iot; 2889 sc->sc_codec.sc_iobase = port+GUS_MAX_CODEC_BASE; 2890 2891 if (ad1848_probe(&sc->sc_codec) == 0) { 2892 sc->sc_flags &= ~GUS_CODEC_INSTALLED; 2893 } else { 2894 struct ad1848_volume vol = {AUDIO_MAX_GAIN, AUDIO_MAX_GAIN}; 2895 sc->sc_flags |= GUS_CODEC_INSTALLED; 2896 sc->sc_codec.parent = sc; 2897 sc->sc_codec.sc_drq = sc->sc_recdrq; 2898 sc->sc_codec.sc_recdrq = sc->sc_drq; 2899 gus_hw_if = gusmax_hw_if; 2900 /* enable line in and mic in the GUS mixer; the codec chip 2901 will do the real mixing for them. */ 2902 sc->sc_mixcontrol &= ~GUSMASK_LINE_IN; /* 0 enables. */ 2903 sc->sc_mixcontrol |= GUSMASK_MIC_IN; /* 1 enables. */ 2904 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol); 2905 2906 ad1848_attach(&sc->sc_codec); 2907 /* turn on pre-MUX microphone gain. */ 2908 ad1848_set_mic_gain(&sc->sc_codec, &vol); 2909 } 2910} 2911 2912 2913/* 2914 * Return info about the audio device, for the AUDIO_GETINFO ioctl 2915 */ 2916 2917int 2918gus_getdev(addr, dev) 2919 void * addr; 2920 struct audio_device *dev; 2921{ 2922 *dev = gus_device; 2923 return 0; 2924} 2925 2926/* 2927 * stubs (XXX) 2928 */ 2929 2930int 2931gus_set_in_gain(addr, gain, balance) 2932 caddr_t addr; 2933 u_int gain; 2934 u_char balance; 2935{ 2936 DPRINTF(("gus_set_in_gain called\n")); 2937 return 0; 2938} 2939 2940int 2941gus_get_in_gain(addr) 2942 caddr_t addr; 2943{ 2944 DPRINTF(("gus_get_in_gain called\n")); 2945 return 0; 2946} 2947 2948int 2949gusmax_dma_input(addr, buf, size, callback, arg) 2950 void * addr; 2951 void *buf; 2952 int size; 2953 void (*callback) __P((void *)); 2954 void *arg; 2955{ 2956 struct ad1848_softc *sc = addr; 2957 return gus_dma_input(sc->parent, buf, size, callback, arg); 2958} 2959 2960/* 2961 * Start sampling the input source into the requested DMA buffer. 2962 * Called at splgus(), either from top-half or from interrupt handler. 2963 */ 2964int 2965gus_dma_input(addr, buf, size, callback, arg) 2966 void * addr; 2967 void *buf; 2968 int size; 2969 void (*callback) __P((void *)); 2970 void *arg; 2971{ 2972 struct gus_softc *sc = addr; 2973 bus_space_tag_t iot = sc->sc_iot; 2974 bus_space_handle_t ioh2 = sc->sc_ioh2; 2975 u_char dmac; 2976 DMAPRINTF(("gus_dma_input called\n")); 2977 2978 /* 2979 * Sample SIZE bytes of data from the card, into buffer at BUF. 2980 */ 2981 2982 if (sc->sc_precision == 16) 2983 return EINVAL; /* XXX */ 2984 2985 /* set DMA modes */ 2986 dmac = GUSMASK_SAMPLE_IRQ|GUSMASK_SAMPLE_START; 2987 if (sc->sc_recdrq >= 4) 2988 dmac |= GUSMASK_SAMPLE_DATA16; 2989 if (sc->sc_encoding == AUDIO_ENCODING_ULAW || 2990 sc->sc_encoding == AUDIO_ENCODING_ALAW || 2991 sc->sc_encoding == AUDIO_ENCODING_ULINEAR_LE || 2992 sc->sc_encoding == AUDIO_ENCODING_ULINEAR_BE) 2993 dmac |= GUSMASK_SAMPLE_INVBIT; 2994 if (sc->sc_channels == 2) 2995 dmac |= GUSMASK_SAMPLE_STEREO; 2996 isa_dmastart(sc->sc_dev.dv_parent, sc->sc_recdrq, buf, size, 2997 NULL, DMAMODE_READ, BUS_DMA_NOWAIT); 2998 2999 DMAPRINTF(("gus_dma_input isa_dmastarted\n")); 3000 sc->sc_flags |= GUS_DMAIN_ACTIVE; 3001 sc->sc_dmainintr = callback; 3002 sc->sc_inarg = arg; 3003 sc->sc_dmaincnt = size; 3004 sc->sc_dmainaddr = buf; 3005 3006 SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL); 3007 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, dmac); /* Go! */ 3008 3009 3010 DMAPRINTF(("gus_dma_input returning\n")); 3011 3012 return 0; 3013} 3014 3015STATIC int 3016gus_dmain_intr(sc) 3017 struct gus_softc *sc; 3018{ 3019 void (*callback) __P((void *)); 3020 void *arg; 3021 3022 DMAPRINTF(("gus_dmain_intr called\n")); 3023 if (sc->sc_dmainintr) { 3024 isa_dmadone(sc->sc_dev.dv_parent, sc->sc_recdrq); 3025 callback = sc->sc_dmainintr; 3026 arg = sc->sc_inarg; 3027 3028 sc->sc_dmainaddr = 0; 3029 sc->sc_dmaincnt = 0; 3030 sc->sc_dmainintr = 0; 3031 sc->sc_inarg = 0; 3032 3033 sc->sc_flags &= ~GUS_DMAIN_ACTIVE; 3034 DMAPRINTF(("calling dmain_intr callback %p(%p)\n", callback, arg)); 3035 (*callback)(arg); 3036 return 1; 3037 } else { 3038 DMAPRINTF(("gus_dmain_intr false?\n")); 3039 return 0; /* XXX ??? */ 3040 } 3041} 3042 3043int 3044gusmax_halt_out_dma(addr) 3045 void * addr; 3046{ 3047 struct ad1848_softc *sc = addr; 3048 return gus_halt_out_dma(sc->parent); 3049} 3050 3051 3052int 3053gusmax_halt_in_dma(addr) 3054 void * addr; 3055{ 3056 struct ad1848_softc *sc = addr; 3057 return gus_halt_in_dma(sc->parent); 3058} 3059 3060/* 3061 * Stop any DMA output. Called at splgus(). 3062 */ 3063int 3064gus_halt_out_dma(addr) 3065 void * addr; 3066{ 3067 struct gus_softc *sc = addr; 3068 bus_space_tag_t iot = sc->sc_iot; 3069 bus_space_handle_t ioh2 = sc->sc_ioh2; 3070 3071 DMAPRINTF(("gus_halt_out_dma called\n")); 3072 /* 3073 * Make sure the GUS _isn't_ setup for DMA 3074 */ 3075 3076 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL); 3077 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0); 3078 3079 untimeout(gus_dmaout_timeout, sc); 3080 isa_dmaabort(sc->sc_dev.dv_parent, sc->sc_drq); 3081 sc->sc_flags &= ~(GUS_DMAOUT_ACTIVE|GUS_LOCKED); 3082 sc->sc_dmaoutintr = 0; 3083 sc->sc_outarg = 0; 3084 sc->sc_dmaoutaddr = 0; 3085 sc->sc_dmaoutcnt = 0; 3086 sc->sc_dmabuf = 0; 3087 sc->sc_bufcnt = 0; 3088 sc->sc_playbuf = -1; 3089 /* also stop playing */ 3090 gus_stop_voice(sc, GUS_VOICE_LEFT, 1); 3091 gus_stop_voice(sc, GUS_VOICE_RIGHT, 0); 3092 3093 return 0; 3094} 3095 3096/* 3097 * Stop any DMA output. Called at splgus(). 3098 */ 3099int 3100gus_halt_in_dma(addr) 3101 void * addr; 3102{ 3103 struct gus_softc *sc = addr; 3104 bus_space_tag_t iot = sc->sc_iot; 3105 bus_space_handle_t ioh2 = sc->sc_ioh2; 3106 DMAPRINTF(("gus_halt_in_dma called\n")); 3107 3108 /* 3109 * Make sure the GUS _isn't_ setup for DMA 3110 */ 3111 3112 SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL); 3113 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 3114 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH) & ~(GUSMASK_SAMPLE_START|GUSMASK_SAMPLE_IRQ)); 3115 3116 isa_dmaabort(sc->sc_dev.dv_parent, sc->sc_recdrq); 3117 sc->sc_flags &= ~GUS_DMAIN_ACTIVE; 3118 sc->sc_dmainintr = 0; 3119 sc->sc_inarg = 0; 3120 sc->sc_dmainaddr = 0; 3121 sc->sc_dmaincnt = 0; 3122 3123 return 0; 3124} 3125 3126STATIC __inline int 3127gus_to_vol(cp, vol) 3128 mixer_ctrl_t *cp; 3129 struct ad1848_volume *vol; 3130{ 3131 if (cp->un.value.num_channels == 1) { 3132 vol->left = vol->right = cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]; 3133 return(1); 3134 } 3135 else if (cp->un.value.num_channels == 2) { 3136 vol->left = cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT]; 3137 vol->right = cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT]; 3138 return(1); 3139 } 3140 return(0); 3141} 3142 3143STATIC __inline int 3144gus_from_vol(cp, vol) 3145 mixer_ctrl_t *cp; 3146 struct ad1848_volume *vol; 3147{ 3148 if (cp->un.value.num_channels == 1) { 3149 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = vol->left; 3150 return(1); 3151 } 3152 else if (cp->un.value.num_channels == 2) { 3153 cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = vol->left; 3154 cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = vol->right; 3155 return(1); 3156 } 3157 return(0); 3158} 3159 3160STATIC int 3161gusmax_mixer_get_port(addr, cp) 3162 void *addr; 3163 mixer_ctrl_t *cp; 3164{ 3165 struct ad1848_softc *ac = addr; 3166 struct gus_softc *sc = ac->parent; 3167 struct ad1848_volume vol; 3168 int error = EINVAL; 3169 3170 DPRINTF(("gusmax_mixer_get_port: port=%d\n", cp->dev)); 3171 3172 switch (cp->dev) { 3173#if 0 /* use mono level instead */ 3174 case GUSMAX_MIC_IN_LVL: /* Microphone */ 3175 if (cp->type == AUDIO_MIXER_VALUE) { 3176 error = ad1848_get_mic_gain(ac, &vol); 3177 if (!error) 3178 gus_from_vol(cp, &vol); 3179 } 3180 break; 3181#endif 3182 3183 case GUSMAX_DAC_LVL: /* dac out */ 3184 if (cp->type == AUDIO_MIXER_VALUE) { 3185 error = ad1848_get_aux1_gain(ac, &vol); 3186 if (!error) 3187 gus_from_vol(cp, &vol); 3188 } 3189 break; 3190 3191 case GUSMAX_LINE_IN_LVL: /* line in */ 3192 if (cp->type == AUDIO_MIXER_VALUE) { 3193 error = cs4231_get_linein_gain(ac, &vol); 3194 if (!error) 3195 gus_from_vol(cp, &vol); 3196 } 3197 break; 3198 3199 case GUSMAX_MONO_LVL: /* mono */ 3200 if (cp->type == AUDIO_MIXER_VALUE && 3201 cp->un.value.num_channels == 1) { 3202 error = cs4231_get_mono_gain(ac, &vol); 3203 if (!error) 3204 gus_from_vol(cp, &vol); 3205 } 3206 break; 3207 3208 case GUSMAX_CD_LVL: /* CD */ 3209 if (cp->type == AUDIO_MIXER_VALUE) { 3210 error = ad1848_get_aux2_gain(ac, &vol); 3211 if (!error) 3212 gus_from_vol(cp, &vol); 3213 } 3214 break; 3215 3216 case GUSMAX_MONITOR_LVL: /* monitor level */ 3217 if (cp->type == AUDIO_MIXER_VALUE && 3218 cp->un.value.num_channels == 1) { 3219 error = ad1848_get_mon_gain(ac, &vol); 3220 if (!error) 3221 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = 3222 vol.left; 3223 } 3224 break; 3225 3226 case GUSMAX_OUT_LVL: /* output level */ 3227 if (cp->type == AUDIO_MIXER_VALUE) { 3228 error = ad1848_get_out_gain(ac, &vol); 3229 if (!error) 3230 gus_from_vol(cp, &vol); 3231 } 3232 break; 3233 3234 case GUSMAX_SPEAKER_LVL: /* fake speaker for mute naming */ 3235 if (cp->type == AUDIO_MIXER_VALUE) { 3236 if (sc->sc_mixcontrol & GUSMASK_LINE_OUT) 3237 vol.left = vol.right = AUDIO_MAX_GAIN; 3238 else 3239 vol.left = vol.right = AUDIO_MIN_GAIN; 3240 error = 0; 3241 gus_from_vol(cp, &vol); 3242 } 3243 break; 3244 3245 case GUSMAX_LINE_IN_MUTE: 3246 if (cp->type == AUDIO_MIXER_ENUM) { 3247 cp->un.ord = ac->line_mute; 3248 error = 0; 3249 } 3250 break; 3251 3252 3253 case GUSMAX_DAC_MUTE: 3254 if (cp->type == AUDIO_MIXER_ENUM) { 3255 cp->un.ord = ac->aux1_mute; 3256 error = 0; 3257 } 3258 break; 3259 3260 case GUSMAX_CD_MUTE: 3261 if (cp->type == AUDIO_MIXER_ENUM) { 3262 cp->un.ord = ac->aux2_mute; 3263 error = 0; 3264 } 3265 break; 3266 3267 case GUSMAX_MONO_MUTE: 3268 if (cp->type == AUDIO_MIXER_ENUM) { 3269 cp->un.ord = ac->mono_mute; 3270 error = 0; 3271 } 3272 break; 3273 3274 case GUSMAX_MONITOR_MUTE: 3275 if (cp->type == AUDIO_MIXER_ENUM) { 3276 cp->un.ord = ac->mon_mute; 3277 error = 0; 3278 } 3279 break; 3280 3281 case GUSMAX_SPEAKER_MUTE: 3282 if (cp->type == AUDIO_MIXER_ENUM) { 3283 cp->un.ord = sc->sc_mixcontrol & GUSMASK_LINE_OUT ? 1 : 0; 3284 error = 0; 3285 } 3286 break; 3287 3288 case GUSMAX_REC_LVL: /* record level */ 3289 if (cp->type == AUDIO_MIXER_VALUE) { 3290 error = ad1848_get_rec_gain(ac, &vol); 3291 if (!error) 3292 gus_from_vol(cp, &vol); 3293 } 3294 break; 3295 3296 case GUSMAX_RECORD_SOURCE: 3297 if (cp->type == AUDIO_MIXER_ENUM) { 3298 cp->un.ord = ad1848_get_rec_port(ac); 3299 error = 0; 3300 } 3301 break; 3302 3303 default: 3304 error = ENXIO; 3305 break; 3306 } 3307 3308 return(error); 3309} 3310 3311STATIC int 3312gus_mixer_get_port(addr, cp) 3313 void *addr; 3314 mixer_ctrl_t *cp; 3315{ 3316 struct gus_softc *sc = addr; 3317 struct ics2101_softc *ic = &sc->sc_mixer; 3318 struct ad1848_volume vol; 3319 int error = EINVAL; 3320 3321 DPRINTF(("gus_mixer_get_port: dev=%d type=%d\n", cp->dev, cp->type)); 3322 3323 if (!HAS_MIXER(sc) && cp->dev > GUSICS_MASTER_MUTE) 3324 return ENXIO; 3325 3326 switch (cp->dev) { 3327 3328 case GUSICS_MIC_IN_MUTE: /* Microphone */ 3329 if (cp->type == AUDIO_MIXER_ENUM) { 3330 if (HAS_MIXER(sc)) 3331 cp->un.ord = ic->sc_mute[GUSMIX_CHAN_MIC][ICSMIX_LEFT]; 3332 else 3333 cp->un.ord = 3334 sc->sc_mixcontrol & GUSMASK_MIC_IN ? 0 : 1; 3335 error = 0; 3336 } 3337 break; 3338 3339 case GUSICS_LINE_IN_MUTE: 3340 if (cp->type == AUDIO_MIXER_ENUM) { 3341 if (HAS_MIXER(sc)) 3342 cp->un.ord = ic->sc_mute[GUSMIX_CHAN_LINE][ICSMIX_LEFT]; 3343 else 3344 cp->un.ord = 3345 sc->sc_mixcontrol & GUSMASK_LINE_IN ? 1 : 0; 3346 error = 0; 3347 } 3348 break; 3349 3350 case GUSICS_MASTER_MUTE: 3351 if (cp->type == AUDIO_MIXER_ENUM) { 3352 if (HAS_MIXER(sc)) 3353 cp->un.ord = ic->sc_mute[GUSMIX_CHAN_MASTER][ICSMIX_LEFT]; 3354 else 3355 cp->un.ord = 3356 sc->sc_mixcontrol & GUSMASK_LINE_OUT ? 1 : 0; 3357 error = 0; 3358 } 3359 break; 3360 3361 case GUSICS_DAC_MUTE: 3362 if (cp->type == AUDIO_MIXER_ENUM) { 3363 cp->un.ord = ic->sc_mute[GUSMIX_CHAN_DAC][ICSMIX_LEFT]; 3364 error = 0; 3365 } 3366 break; 3367 3368 case GUSICS_CD_MUTE: 3369 if (cp->type == AUDIO_MIXER_ENUM) { 3370 cp->un.ord = ic->sc_mute[GUSMIX_CHAN_CD][ICSMIX_LEFT]; 3371 error = 0; 3372 } 3373 break; 3374 3375 case GUSICS_MASTER_LVL: 3376 if (cp->type == AUDIO_MIXER_VALUE) { 3377 vol.left = ic->sc_setting[GUSMIX_CHAN_MASTER][ICSMIX_LEFT]; 3378 vol.right = ic->sc_setting[GUSMIX_CHAN_MASTER][ICSMIX_RIGHT]; 3379 if (gus_from_vol(cp, &vol)) 3380 error = 0; 3381 } 3382 break; 3383 3384 case GUSICS_MIC_IN_LVL: /* Microphone */ 3385 if (cp->type == AUDIO_MIXER_VALUE) { 3386 vol.left = ic->sc_setting[GUSMIX_CHAN_MIC][ICSMIX_LEFT]; 3387 vol.right = ic->sc_setting[GUSMIX_CHAN_MIC][ICSMIX_RIGHT]; 3388 if (gus_from_vol(cp, &vol)) 3389 error = 0; 3390 } 3391 break; 3392 3393 case GUSICS_LINE_IN_LVL: /* line in */ 3394 if (cp->type == AUDIO_MIXER_VALUE) { 3395 vol.left = ic->sc_setting[GUSMIX_CHAN_LINE][ICSMIX_LEFT]; 3396 vol.right = ic->sc_setting[GUSMIX_CHAN_LINE][ICSMIX_RIGHT]; 3397 if (gus_from_vol(cp, &vol)) 3398 error = 0; 3399 } 3400 break; 3401 3402 3403 case GUSICS_CD_LVL: 3404 if (cp->type == AUDIO_MIXER_VALUE) { 3405 vol.left = ic->sc_setting[GUSMIX_CHAN_CD][ICSMIX_LEFT]; 3406 vol.right = ic->sc_setting[GUSMIX_CHAN_CD][ICSMIX_RIGHT]; 3407 if (gus_from_vol(cp, &vol)) 3408 error = 0; 3409 } 3410 break; 3411 3412 case GUSICS_DAC_LVL: /* dac out */ 3413 if (cp->type == AUDIO_MIXER_VALUE) { 3414 vol.left = ic->sc_setting[GUSMIX_CHAN_DAC][ICSMIX_LEFT]; 3415 vol.right = ic->sc_setting[GUSMIX_CHAN_DAC][ICSMIX_RIGHT]; 3416 if (gus_from_vol(cp, &vol)) 3417 error = 0; 3418 } 3419 break; 3420 3421 3422 case GUSICS_RECORD_SOURCE: 3423 if (cp->type == AUDIO_MIXER_ENUM) { 3424 /* Can't set anything else useful, sigh. */ 3425 cp->un.ord = 0; 3426 } 3427 break; 3428 3429 default: 3430 return ENXIO; 3431 /*NOTREACHED*/ 3432 } 3433 return error; 3434} 3435 3436STATIC void 3437gusics_master_mute(ic, mute) 3438 struct ics2101_softc *ic; 3439 int mute; 3440{ 3441 ics2101_mix_mute(ic, GUSMIX_CHAN_MASTER, ICSMIX_LEFT, mute); 3442 ics2101_mix_mute(ic, GUSMIX_CHAN_MASTER, ICSMIX_RIGHT, mute); 3443} 3444 3445STATIC void 3446gusics_mic_mute(ic, mute) 3447 struct ics2101_softc *ic; 3448 int mute; 3449{ 3450 ics2101_mix_mute(ic, GUSMIX_CHAN_MIC, ICSMIX_LEFT, mute); 3451 ics2101_mix_mute(ic, GUSMIX_CHAN_MIC, ICSMIX_RIGHT, mute); 3452} 3453 3454STATIC void 3455gusics_linein_mute(ic, mute) 3456 struct ics2101_softc *ic; 3457 int mute; 3458{ 3459 ics2101_mix_mute(ic, GUSMIX_CHAN_LINE, ICSMIX_LEFT, mute); 3460 ics2101_mix_mute(ic, GUSMIX_CHAN_LINE, ICSMIX_RIGHT, mute); 3461} 3462 3463STATIC void 3464gusics_cd_mute(ic, mute) 3465 struct ics2101_softc *ic; 3466 int mute; 3467{ 3468 ics2101_mix_mute(ic, GUSMIX_CHAN_CD, ICSMIX_LEFT, mute); 3469 ics2101_mix_mute(ic, GUSMIX_CHAN_CD, ICSMIX_RIGHT, mute); 3470} 3471 3472STATIC void 3473gusics_dac_mute(ic, mute) 3474 struct ics2101_softc *ic; 3475 int mute; 3476{ 3477 ics2101_mix_mute(ic, GUSMIX_CHAN_DAC, ICSMIX_LEFT, mute); 3478 ics2101_mix_mute(ic, GUSMIX_CHAN_DAC, ICSMIX_RIGHT, mute); 3479} 3480 3481STATIC int 3482gusmax_mixer_set_port(addr, cp) 3483 void *addr; 3484 mixer_ctrl_t *cp; 3485{ 3486 struct ad1848_softc *ac = addr; 3487 struct gus_softc *sc = ac->parent; 3488 struct ad1848_volume vol; 3489 int error = EINVAL; 3490 3491 DPRINTF(("gusmax_mixer_set_port: dev=%d type=%d\n", cp->dev, cp->type)); 3492 3493 switch (cp->dev) { 3494#if 0 3495 case GUSMAX_MIC_IN_LVL: /* Microphone */ 3496 if (cp->type == AUDIO_MIXER_VALUE && 3497 cp->un.value.num_channels == 1) { 3498 /* XXX enable/disable pre-MUX fixed gain */ 3499 if (gus_to_vol(cp, &vol)) 3500 error = ad1848_set_mic_gain(ac, &vol); 3501 } 3502 break; 3503#endif 3504 3505 case GUSMAX_DAC_LVL: /* dac out */ 3506 if (cp->type == AUDIO_MIXER_VALUE) { 3507 if (gus_to_vol(cp, &vol)) 3508 error = ad1848_set_aux1_gain(ac, &vol); 3509 } 3510 break; 3511 3512 case GUSMAX_LINE_IN_LVL: /* line in */ 3513 if (cp->type == AUDIO_MIXER_VALUE) { 3514 if (gus_to_vol(cp, &vol)) 3515 error = cs4231_set_linein_gain(ac, &vol); 3516 } 3517 break; 3518 3519 case GUSMAX_MONO_LVL: /* mic/mono in */ 3520 if (cp->type == AUDIO_MIXER_VALUE && 3521 cp->un.value.num_channels == 1) { 3522 if (gus_to_vol(cp, &vol)) 3523 error = cs4231_set_mono_gain(ac, &vol); 3524 } 3525 break; 3526 3527 case GUSMAX_CD_LVL: /* CD: AUX2 */ 3528 if (cp->type == AUDIO_MIXER_VALUE) { 3529 if (gus_to_vol(cp, &vol)) 3530 error = ad1848_set_aux2_gain(ac, &vol); 3531 } 3532 break; 3533 3534 case GUSMAX_MONITOR_LVL: 3535 if (cp->type == AUDIO_MIXER_VALUE && 3536 cp->un.value.num_channels == 1) { 3537 vol.left = cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]; 3538 error = ad1848_set_mon_gain(ac, &vol); 3539 } 3540 break; 3541 3542 case GUSMAX_OUT_LVL: /* output volume */ 3543 if (cp->type == AUDIO_MIXER_VALUE) { 3544 if (gus_to_vol(cp, &vol)) 3545 error = ad1848_set_out_gain(ac, &vol); 3546 } 3547 break; 3548 3549 case GUSMAX_SPEAKER_LVL: 3550 if (cp->type == AUDIO_MIXER_VALUE && 3551 cp->un.value.num_channels == 1) { 3552 if (gus_to_vol(cp, &vol)) { 3553 gus_speaker_ctl(sc, vol.left > AUDIO_MIN_GAIN ? 3554 SPKR_ON : SPKR_OFF); 3555 error = 0; 3556 } 3557 } 3558 break; 3559 3560 case GUSMAX_LINE_IN_MUTE: 3561 if (cp->type == AUDIO_MIXER_ENUM) { 3562 ac->line_mute = cp->un.ord ? 1 : 0; 3563 DPRINTF(("line mute %d\n", cp->un.ord)); 3564 cs4231_mute_line(ac, ac->line_mute); 3565 gus_linein_ctl(sc, ac->line_mute ? SPKR_OFF : SPKR_ON); 3566 error = 0; 3567 } 3568 break; 3569 3570 case GUSMAX_DAC_MUTE: 3571 if (cp->type == AUDIO_MIXER_ENUM) { 3572 ac->aux1_mute = cp->un.ord ? 1 : 0; 3573 DPRINTF(("dac mute %d\n", cp->un.ord)); 3574 ad1848_mute_aux1(ac, ac->aux1_mute); 3575 error = 0; 3576 } 3577 break; 3578 3579 case GUSMAX_CD_MUTE: 3580 if (cp->type == AUDIO_MIXER_ENUM) { 3581 ac->aux2_mute = cp->un.ord ? 1 : 0; 3582 DPRINTF(("cd mute %d\n", cp->un.ord)); 3583 ad1848_mute_aux2(ac, ac->aux2_mute); 3584 error = 0; 3585 } 3586 break; 3587 3588 case GUSMAX_MONO_MUTE: /* Microphone */ 3589 if (cp->type == AUDIO_MIXER_ENUM) { 3590 ac->mono_mute = cp->un.ord ? 1 : 0; 3591 DPRINTF(("mono mute %d\n", cp->un.ord)); 3592 cs4231_mute_mono(ac, ac->mono_mute); 3593 gus_mic_ctl(sc, ac->mono_mute ? SPKR_OFF : SPKR_ON); 3594 error = 0; 3595 } 3596 break; 3597 3598 case GUSMAX_MONITOR_MUTE: 3599 if (cp->type == AUDIO_MIXER_ENUM) { 3600 ac->mon_mute = cp->un.ord ? 1 : 0; 3601 DPRINTF(("mono mute %d\n", cp->un.ord)); 3602 cs4231_mute_monitor(ac, ac->mon_mute); 3603 error = 0; 3604 } 3605 break; 3606 3607 case GUSMAX_SPEAKER_MUTE: 3608 if (cp->type == AUDIO_MIXER_ENUM) { 3609 gus_speaker_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON); 3610 error = 0; 3611 } 3612 break; 3613 3614 case GUSMAX_REC_LVL: /* record level */ 3615 if (cp->type == AUDIO_MIXER_VALUE) { 3616 if (gus_to_vol(cp, &vol)) 3617 error = ad1848_set_rec_gain(ac, &vol); 3618 } 3619 break; 3620 3621 case GUSMAX_RECORD_SOURCE: 3622 if (cp->type == AUDIO_MIXER_ENUM) { 3623 error = ad1848_set_rec_port(ac, cp->un.ord); 3624 } 3625 break; 3626 3627 default: 3628 return ENXIO; 3629 /*NOTREACHED*/ 3630 } 3631 return error; 3632} 3633 3634STATIC int 3635gus_mixer_set_port(addr, cp) 3636 void *addr; 3637 mixer_ctrl_t *cp; 3638{ 3639 struct gus_softc *sc = addr; 3640 struct ics2101_softc *ic = &sc->sc_mixer; 3641 struct ad1848_volume vol; 3642 int error = EINVAL; 3643 3644 DPRINTF(("gus_mixer_set_port: dev=%d type=%d\n", cp->dev, cp->type)); 3645 3646 if (!HAS_MIXER(sc) && cp->dev > GUSICS_MASTER_MUTE) 3647 return ENXIO; 3648 3649 switch (cp->dev) { 3650 3651 case GUSICS_MIC_IN_MUTE: /* Microphone */ 3652 if (cp->type == AUDIO_MIXER_ENUM) { 3653 DPRINTF(("mic mute %d\n", cp->un.ord)); 3654 if (HAS_MIXER(sc)) { 3655 gusics_mic_mute(ic, cp->un.ord); 3656 } 3657 gus_mic_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON); 3658 error = 0; 3659 } 3660 break; 3661 3662 case GUSICS_LINE_IN_MUTE: 3663 if (cp->type == AUDIO_MIXER_ENUM) { 3664 DPRINTF(("linein mute %d\n", cp->un.ord)); 3665 if (HAS_MIXER(sc)) { 3666 gusics_linein_mute(ic, cp->un.ord); 3667 } 3668 gus_linein_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON); 3669 error = 0; 3670 } 3671 break; 3672 3673 case GUSICS_MASTER_MUTE: 3674 if (cp->type == AUDIO_MIXER_ENUM) { 3675 DPRINTF(("master mute %d\n", cp->un.ord)); 3676 if (HAS_MIXER(sc)) { 3677 gusics_master_mute(ic, cp->un.ord); 3678 } 3679 gus_speaker_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON); 3680 error = 0; 3681 } 3682 break; 3683 3684 case GUSICS_DAC_MUTE: 3685 if (cp->type == AUDIO_MIXER_ENUM) { 3686 gusics_dac_mute(ic, cp->un.ord); 3687 error = 0; 3688 } 3689 break; 3690 3691 case GUSICS_CD_MUTE: 3692 if (cp->type == AUDIO_MIXER_ENUM) { 3693 gusics_cd_mute(ic, cp->un.ord); 3694 error = 0; 3695 } 3696 break; 3697 3698 case GUSICS_MASTER_LVL: 3699 if (cp->type == AUDIO_MIXER_VALUE) { 3700 if (gus_to_vol(cp, &vol)) { 3701 ics2101_mix_attenuate(ic, 3702 GUSMIX_CHAN_MASTER, 3703 ICSMIX_LEFT, 3704 vol.left); 3705 ics2101_mix_attenuate(ic, 3706 GUSMIX_CHAN_MASTER, 3707 ICSMIX_RIGHT, 3708 vol.right); 3709 error = 0; 3710 } 3711 } 3712 break; 3713 3714 case GUSICS_MIC_IN_LVL: /* Microphone */ 3715 if (cp->type == AUDIO_MIXER_VALUE) { 3716 if (gus_to_vol(cp, &vol)) { 3717 ics2101_mix_attenuate(ic, 3718 GUSMIX_CHAN_MIC, 3719 ICSMIX_LEFT, 3720 vol.left); 3721 ics2101_mix_attenuate(ic, 3722 GUSMIX_CHAN_MIC, 3723 ICSMIX_RIGHT, 3724 vol.right); 3725 error = 0; 3726 } 3727 } 3728 break; 3729 3730 case GUSICS_LINE_IN_LVL: /* line in */ 3731 if (cp->type == AUDIO_MIXER_VALUE) { 3732 if (gus_to_vol(cp, &vol)) { 3733 ics2101_mix_attenuate(ic, 3734 GUSMIX_CHAN_LINE, 3735 ICSMIX_LEFT, 3736 vol.left); 3737 ics2101_mix_attenuate(ic, 3738 GUSMIX_CHAN_LINE, 3739 ICSMIX_RIGHT, 3740 vol.right); 3741 error = 0; 3742 } 3743 } 3744 break; 3745 3746 3747 case GUSICS_CD_LVL: 3748 if (cp->type == AUDIO_MIXER_VALUE) { 3749 if (gus_to_vol(cp, &vol)) { 3750 ics2101_mix_attenuate(ic, 3751 GUSMIX_CHAN_CD, 3752 ICSMIX_LEFT, 3753 vol.left); 3754 ics2101_mix_attenuate(ic, 3755 GUSMIX_CHAN_CD, 3756 ICSMIX_RIGHT, 3757 vol.right); 3758 error = 0; 3759 } 3760 } 3761 break; 3762 3763 case GUSICS_DAC_LVL: /* dac out */ 3764 if (cp->type == AUDIO_MIXER_VALUE) { 3765 if (gus_to_vol(cp, &vol)) { 3766 ics2101_mix_attenuate(ic, 3767 GUSMIX_CHAN_DAC, 3768 ICSMIX_LEFT, 3769 vol.left); 3770 ics2101_mix_attenuate(ic, 3771 GUSMIX_CHAN_DAC, 3772 ICSMIX_RIGHT, 3773 vol.right); 3774 error = 0; 3775 } 3776 } 3777 break; 3778 3779 3780 case GUSICS_RECORD_SOURCE: 3781 if (cp->type == AUDIO_MIXER_ENUM && cp->un.ord == 0) { 3782 /* Can't set anything else useful, sigh. */ 3783 error = 0; 3784 } 3785 break; 3786 3787 default: 3788 return ENXIO; 3789 /*NOTREACHED*/ 3790 } 3791 return error; 3792} 3793 3794STATIC int 3795gus_get_props(addr) 3796 void *addr; 3797{ 3798 struct gus_softc *sc = addr; 3799 return sc->sc_recdrq == sc->sc_drq ? 0 : AUDIO_PROP_FULLDUPLEX; 3800} 3801 3802STATIC int 3803gusmax_get_props(addr) 3804 void *addr; 3805{ 3806 struct ad1848_softc *ac = addr; 3807 return gus_get_props(ac->parent); 3808} 3809 3810STATIC int 3811gusmax_mixer_query_devinfo(addr, dip) 3812 void *addr; 3813 mixer_devinfo_t *dip; 3814{ 3815 DPRINTF(("gusmax_query_devinfo: index=%d\n", dip->index)); 3816 3817 switch(dip->index) { 3818#if 0 3819 case GUSMAX_MIC_IN_LVL: /* Microphone */ 3820 dip->type = AUDIO_MIXER_VALUE; 3821 dip->mixer_class = GUSMAX_INPUT_CLASS; 3822 dip->prev = AUDIO_MIXER_LAST; 3823 dip->next = GUSMAX_MIC_IN_MUTE; 3824 strcpy(dip->label.name, AudioNmicrophone); 3825 dip->un.v.num_channels = 2; 3826 strcpy(dip->un.v.units.name, AudioNvolume); 3827 break; 3828#endif 3829 3830 case GUSMAX_MONO_LVL: /* mono/microphone mixer */ 3831 dip->type = AUDIO_MIXER_VALUE; 3832 dip->mixer_class = GUSMAX_INPUT_CLASS; 3833 dip->prev = AUDIO_MIXER_LAST; 3834 dip->next = GUSMAX_MONO_MUTE; 3835 strcpy(dip->label.name, AudioNmicrophone); 3836 dip->un.v.num_channels = 1; 3837 strcpy(dip->un.v.units.name, AudioNvolume); 3838 break; 3839 3840 case GUSMAX_DAC_LVL: /* dacout */ 3841 dip->type = AUDIO_MIXER_VALUE; 3842 dip->mixer_class = GUSMAX_INPUT_CLASS; 3843 dip->prev = AUDIO_MIXER_LAST; 3844 dip->next = GUSMAX_DAC_MUTE; 3845 strcpy(dip->label.name, AudioNdac); 3846 dip->un.v.num_channels = 2; 3847 strcpy(dip->un.v.units.name, AudioNvolume); 3848 break; 3849 3850 case GUSMAX_LINE_IN_LVL: /* line */ 3851 dip->type = AUDIO_MIXER_VALUE; 3852 dip->mixer_class = GUSMAX_INPUT_CLASS; 3853 dip->prev = AUDIO_MIXER_LAST; 3854 dip->next = GUSMAX_LINE_IN_MUTE; 3855 strcpy(dip->label.name, AudioNline); 3856 dip->un.v.num_channels = 2; 3857 strcpy(dip->un.v.units.name, AudioNvolume); 3858 break; 3859 3860 case GUSMAX_CD_LVL: /* cd */ 3861 dip->type = AUDIO_MIXER_VALUE; 3862 dip->mixer_class = GUSMAX_INPUT_CLASS; 3863 dip->prev = AUDIO_MIXER_LAST; 3864 dip->next = GUSMAX_CD_MUTE; 3865 strcpy(dip->label.name, AudioNcd); 3866 dip->un.v.num_channels = 2; 3867 strcpy(dip->un.v.units.name, AudioNvolume); 3868 break; 3869 3870 3871 case GUSMAX_MONITOR_LVL: /* monitor level */ 3872 dip->type = AUDIO_MIXER_VALUE; 3873 dip->mixer_class = GUSMAX_MONITOR_CLASS; 3874 dip->next = GUSMAX_MONITOR_MUTE; 3875 dip->prev = AUDIO_MIXER_LAST; 3876 strcpy(dip->label.name, AudioNmonitor); 3877 dip->un.v.num_channels = 1; 3878 strcpy(dip->un.v.units.name, AudioNvolume); 3879 break; 3880 3881 case GUSMAX_OUT_LVL: /* cs4231 output volume: not useful? */ 3882 dip->type = AUDIO_MIXER_VALUE; 3883 dip->mixer_class = GUSMAX_MONITOR_CLASS; 3884 dip->prev = dip->next = AUDIO_MIXER_LAST; 3885 strcpy(dip->label.name, AudioNoutput); 3886 dip->un.v.num_channels = 2; 3887 strcpy(dip->un.v.units.name, AudioNvolume); 3888 break; 3889 3890 case GUSMAX_SPEAKER_LVL: /* fake speaker volume */ 3891 dip->type = AUDIO_MIXER_VALUE; 3892 dip->mixer_class = GUSMAX_MONITOR_CLASS; 3893 dip->prev = AUDIO_MIXER_LAST; 3894 dip->next = GUSMAX_SPEAKER_MUTE; 3895 strcpy(dip->label.name, AudioNmaster); 3896 dip->un.v.num_channels = 2; 3897 strcpy(dip->un.v.units.name, AudioNvolume); 3898 break; 3899 3900 case GUSMAX_LINE_IN_MUTE: 3901 dip->mixer_class = GUSMAX_INPUT_CLASS; 3902 dip->type = AUDIO_MIXER_ENUM; 3903 dip->prev = GUSMAX_LINE_IN_LVL; 3904 dip->next = AUDIO_MIXER_LAST; 3905 goto mute; 3906 3907 case GUSMAX_DAC_MUTE: 3908 dip->mixer_class = GUSMAX_INPUT_CLASS; 3909 dip->type = AUDIO_MIXER_ENUM; 3910 dip->prev = GUSMAX_DAC_LVL; 3911 dip->next = AUDIO_MIXER_LAST; 3912 goto mute; 3913 3914 case GUSMAX_CD_MUTE: 3915 dip->mixer_class = GUSMAX_INPUT_CLASS; 3916 dip->type = AUDIO_MIXER_ENUM; 3917 dip->prev = GUSMAX_CD_LVL; 3918 dip->next = AUDIO_MIXER_LAST; 3919 goto mute; 3920 3921 case GUSMAX_MONO_MUTE: 3922 dip->mixer_class = GUSMAX_INPUT_CLASS; 3923 dip->type = AUDIO_MIXER_ENUM; 3924 dip->prev = GUSMAX_MONO_LVL; 3925 dip->next = AUDIO_MIXER_LAST; 3926 goto mute; 3927 3928 case GUSMAX_MONITOR_MUTE: 3929 dip->mixer_class = GUSMAX_OUTPUT_CLASS; 3930 dip->type = AUDIO_MIXER_ENUM; 3931 dip->prev = GUSMAX_MONITOR_LVL; 3932 dip->next = AUDIO_MIXER_LAST; 3933 goto mute; 3934 3935 case GUSMAX_SPEAKER_MUTE: 3936 dip->mixer_class = GUSMAX_OUTPUT_CLASS; 3937 dip->type = AUDIO_MIXER_ENUM; 3938 dip->prev = GUSMAX_SPEAKER_LVL; 3939 dip->next = AUDIO_MIXER_LAST; 3940 mute: 3941 strcpy(dip->label.name, AudioNmute); 3942 dip->un.e.num_mem = 2; 3943 strcpy(dip->un.e.member[0].label.name, AudioNoff); 3944 dip->un.e.member[0].ord = 0; 3945 strcpy(dip->un.e.member[1].label.name, AudioNon); 3946 dip->un.e.member[1].ord = 1; 3947 break; 3948 3949 case GUSMAX_REC_LVL: /* record level */ 3950 dip->type = AUDIO_MIXER_VALUE; 3951 dip->mixer_class = GUSMAX_RECORD_CLASS; 3952 dip->prev = AUDIO_MIXER_LAST; 3953 dip->next = GUSMAX_RECORD_SOURCE; 3954 strcpy(dip->label.name, AudioNrecord); 3955 dip->un.v.num_channels = 2; 3956 strcpy(dip->un.v.units.name, AudioNvolume); 3957 break; 3958 3959 case GUSMAX_RECORD_SOURCE: 3960 dip->mixer_class = GUSMAX_RECORD_CLASS; 3961 dip->type = AUDIO_MIXER_ENUM; 3962 dip->prev = GUSMAX_REC_LVL; 3963 dip->next = AUDIO_MIXER_LAST; 3964 strcpy(dip->label.name, AudioNsource); 3965 dip->un.e.num_mem = 4; 3966 strcpy(dip->un.e.member[0].label.name, AudioNoutput); 3967 dip->un.e.member[0].ord = DAC_IN_PORT; 3968 strcpy(dip->un.e.member[1].label.name, AudioNmicrophone); 3969 dip->un.e.member[1].ord = MIC_IN_PORT; 3970 strcpy(dip->un.e.member[2].label.name, AudioNdac); 3971 dip->un.e.member[2].ord = AUX1_IN_PORT; 3972 strcpy(dip->un.e.member[3].label.name, AudioNline); 3973 dip->un.e.member[3].ord = LINE_IN_PORT; 3974 break; 3975 3976 case GUSMAX_INPUT_CLASS: /* input class descriptor */ 3977 dip->type = AUDIO_MIXER_CLASS; 3978 dip->mixer_class = GUSMAX_INPUT_CLASS; 3979 dip->next = dip->prev = AUDIO_MIXER_LAST; 3980 strcpy(dip->label.name, AudioCinputs); 3981 break; 3982 3983 case GUSMAX_OUTPUT_CLASS: /* output class descriptor */ 3984 dip->type = AUDIO_MIXER_CLASS; 3985 dip->mixer_class = GUSMAX_OUTPUT_CLASS; 3986 dip->next = dip->prev = AUDIO_MIXER_LAST; 3987 strcpy(dip->label.name, AudioCoutputs); 3988 break; 3989 3990 case GUSMAX_MONITOR_CLASS: /* monitor class descriptor */ 3991 dip->type = AUDIO_MIXER_CLASS; 3992 dip->mixer_class = GUSMAX_MONITOR_CLASS; 3993 dip->next = dip->prev = AUDIO_MIXER_LAST; 3994 strcpy(dip->label.name, AudioCmonitor); 3995 break; 3996 3997 case GUSMAX_RECORD_CLASS: /* record source class */ 3998 dip->type = AUDIO_MIXER_CLASS; 3999 dip->mixer_class = GUSMAX_RECORD_CLASS; 4000 dip->next = dip->prev = AUDIO_MIXER_LAST; 4001 strcpy(dip->label.name, AudioCrecord); 4002 break; 4003 4004 default: 4005 return ENXIO; 4006 /*NOTREACHED*/ 4007 } 4008 DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name)); 4009 return 0; 4010} 4011 4012STATIC int 4013gus_mixer_query_devinfo(addr, dip) 4014 void *addr; 4015 mixer_devinfo_t *dip; 4016{ 4017 struct gus_softc *sc = addr; 4018 4019 DPRINTF(("gusmax_query_devinfo: index=%d\n", dip->index)); 4020 4021 if (!HAS_MIXER(sc) && dip->index > GUSICS_MASTER_MUTE) 4022 return ENXIO; 4023 4024 switch(dip->index) { 4025 4026 case GUSICS_MIC_IN_LVL: /* Microphone */ 4027 dip->type = AUDIO_MIXER_VALUE; 4028 dip->mixer_class = GUSICS_INPUT_CLASS; 4029 dip->prev = AUDIO_MIXER_LAST; 4030 dip->next = GUSICS_MIC_IN_MUTE; 4031 strcpy(dip->label.name, AudioNmicrophone); 4032 dip->un.v.num_channels = 2; 4033 strcpy(dip->un.v.units.name, AudioNvolume); 4034 break; 4035 4036 case GUSICS_LINE_IN_LVL: /* line */ 4037 dip->type = AUDIO_MIXER_VALUE; 4038 dip->mixer_class = GUSICS_INPUT_CLASS; 4039 dip->prev = AUDIO_MIXER_LAST; 4040 dip->next = GUSICS_LINE_IN_MUTE; 4041 strcpy(dip->label.name, AudioNline); 4042 dip->un.v.num_channels = 2; 4043 strcpy(dip->un.v.units.name, AudioNvolume); 4044 break; 4045 4046 case GUSICS_CD_LVL: /* cd */ 4047 dip->type = AUDIO_MIXER_VALUE; 4048 dip->mixer_class = GUSICS_INPUT_CLASS; 4049 dip->prev = AUDIO_MIXER_LAST; 4050 dip->next = GUSICS_CD_MUTE; 4051 strcpy(dip->label.name, AudioNcd); 4052 dip->un.v.num_channels = 2; 4053 strcpy(dip->un.v.units.name, AudioNvolume); 4054 break; 4055 4056 case GUSICS_DAC_LVL: /* dacout */ 4057 dip->type = AUDIO_MIXER_VALUE; 4058 dip->mixer_class = GUSICS_INPUT_CLASS; 4059 dip->prev = AUDIO_MIXER_LAST; 4060 dip->next = GUSICS_DAC_MUTE; 4061 strcpy(dip->label.name, AudioNdac); 4062 dip->un.v.num_channels = 2; 4063 strcpy(dip->un.v.units.name, AudioNvolume); 4064 break; 4065 4066 case GUSICS_MASTER_LVL: /* master output */ 4067 dip->type = AUDIO_MIXER_VALUE; 4068 dip->mixer_class = GUSICS_OUTPUT_CLASS; 4069 dip->prev = AUDIO_MIXER_LAST; 4070 dip->next = GUSICS_MASTER_MUTE; 4071 strcpy(dip->label.name, AudioNmaster); 4072 dip->un.v.num_channels = 2; 4073 strcpy(dip->un.v.units.name, AudioNvolume); 4074 break; 4075 4076 4077 case GUSICS_LINE_IN_MUTE: 4078 dip->mixer_class = GUSICS_INPUT_CLASS; 4079 dip->type = AUDIO_MIXER_ENUM; 4080 dip->prev = GUSICS_LINE_IN_LVL; 4081 dip->next = AUDIO_MIXER_LAST; 4082 goto mute; 4083 4084 case GUSICS_DAC_MUTE: 4085 dip->mixer_class = GUSICS_INPUT_CLASS; 4086 dip->type = AUDIO_MIXER_ENUM; 4087 dip->prev = GUSICS_DAC_LVL; 4088 dip->next = AUDIO_MIXER_LAST; 4089 goto mute; 4090 4091 case GUSICS_CD_MUTE: 4092 dip->mixer_class = GUSICS_INPUT_CLASS; 4093 dip->type = AUDIO_MIXER_ENUM; 4094 dip->prev = GUSICS_CD_LVL; 4095 dip->next = AUDIO_MIXER_LAST; 4096 goto mute; 4097 4098 case GUSICS_MIC_IN_MUTE: 4099 dip->mixer_class = GUSICS_INPUT_CLASS; 4100 dip->type = AUDIO_MIXER_ENUM; 4101 dip->prev = GUSICS_MIC_IN_LVL; 4102 dip->next = AUDIO_MIXER_LAST; 4103 goto mute; 4104 4105 case GUSICS_MASTER_MUTE: 4106 dip->mixer_class = GUSICS_OUTPUT_CLASS; 4107 dip->type = AUDIO_MIXER_ENUM; 4108 dip->prev = GUSICS_MASTER_LVL; 4109 dip->next = AUDIO_MIXER_LAST; 4110mute: 4111 strcpy(dip->label.name, AudioNmute); 4112 dip->un.e.num_mem = 2; 4113 strcpy(dip->un.e.member[0].label.name, AudioNoff); 4114 dip->un.e.member[0].ord = 0; 4115 strcpy(dip->un.e.member[1].label.name, AudioNon); 4116 dip->un.e.member[1].ord = 1; 4117 break; 4118 4119 case GUSICS_RECORD_SOURCE: 4120 dip->mixer_class = GUSICS_RECORD_CLASS; 4121 dip->type = AUDIO_MIXER_ENUM; 4122 dip->prev = dip->next = AUDIO_MIXER_LAST; 4123 strcpy(dip->label.name, AudioNsource); 4124 dip->un.e.num_mem = 1; 4125 strcpy(dip->un.e.member[0].label.name, AudioNoutput); 4126 dip->un.e.member[0].ord = GUSICS_MASTER_LVL; 4127 break; 4128 4129 case GUSICS_INPUT_CLASS: 4130 dip->type = AUDIO_MIXER_CLASS; 4131 dip->mixer_class = GUSICS_INPUT_CLASS; 4132 dip->next = dip->prev = AUDIO_MIXER_LAST; 4133 strcpy(dip->label.name, AudioCinputs); 4134 break; 4135 4136 case GUSICS_OUTPUT_CLASS: 4137 dip->type = AUDIO_MIXER_CLASS; 4138 dip->mixer_class = GUSICS_OUTPUT_CLASS; 4139 dip->next = dip->prev = AUDIO_MIXER_LAST; 4140 strcpy(dip->label.name, AudioCoutputs); 4141 break; 4142 4143 case GUSICS_RECORD_CLASS: 4144 dip->type = AUDIO_MIXER_CLASS; 4145 dip->mixer_class = GUSICS_RECORD_CLASS; 4146 dip->next = dip->prev = AUDIO_MIXER_LAST; 4147 strcpy(dip->label.name, AudioCrecord); 4148 break; 4149 4150 default: 4151 return ENXIO; 4152 /*NOTREACHED*/ 4153 } 4154 DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name)); 4155 return 0; 4156} 4157 4158STATIC int 4159gus_query_encoding(addr, fp) 4160 void *addr; 4161 struct audio_encoding *fp; 4162{ 4163 switch (fp->index) { 4164 case 0: 4165 strcpy(fp->name, AudioEmulaw); 4166 fp->encoding = AUDIO_ENCODING_ULAW; 4167 fp->precision = 8; 4168 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 4169 break; 4170 case 1: 4171 strcpy(fp->name, AudioEslinear); 4172 fp->encoding = AUDIO_ENCODING_SLINEAR; 4173 fp->precision = 8; 4174 fp->flags = 0; 4175 break; 4176 case 2: 4177 strcpy(fp->name, AudioEslinear_le); 4178 fp->encoding = AUDIO_ENCODING_SLINEAR_LE; 4179 fp->precision = 16; 4180 fp->flags = 0; 4181 break; 4182 case 3: 4183 strcpy(fp->name, AudioEulinear); 4184 fp->encoding = AUDIO_ENCODING_ULINEAR; 4185 fp->precision = 8; 4186 fp->flags = 0; 4187 break; 4188 case 4: 4189 strcpy(fp->name, AudioEulinear_le); 4190 fp->encoding = AUDIO_ENCODING_ULINEAR_LE; 4191 fp->precision = 16; 4192 fp->flags = 0; 4193 break; 4194 case 5: 4195 strcpy(fp->name, AudioEslinear_be); 4196 fp->encoding = AUDIO_ENCODING_SLINEAR_BE; 4197 fp->precision = 16; 4198 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 4199 break; 4200 case 6: 4201 strcpy(fp->name, AudioEulinear_be); 4202 fp->encoding = AUDIO_ENCODING_ULINEAR_BE; 4203 fp->precision = 16; 4204 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 4205 break; 4206 case 7: 4207 strcpy(fp->name, AudioEalaw); 4208 fp->encoding = AUDIO_ENCODING_ALAW; 4209 fp->precision = 8; 4210 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 4211 break; 4212 4213 default: 4214 return(EINVAL); 4215 /*NOTREACHED*/ 4216 } 4217 return (0); 4218} 4219 4220/* 4221 * Setup the ICS mixer in "transparent" mode: reset everything to a sensible 4222 * level. Levels as suggested by GUS SDK code. 4223 */ 4224 4225STATIC void 4226gus_init_ics2101(sc) 4227 struct gus_softc *sc; 4228{ 4229 struct ics2101_softc *ic = &sc->sc_mixer; 4230 sc->sc_mixer.sc_iot = sc->sc_iot; 4231 sc->sc_mixer.sc_selio = GUS_MIXER_SELECT; 4232 sc->sc_mixer.sc_selio_ioh = sc->sc_ioh3; 4233 sc->sc_mixer.sc_dataio = GUS_MIXER_DATA; 4234 sc->sc_mixer.sc_dataio_ioh = sc->sc_ioh2; 4235 sc->sc_mixer.sc_flags = (sc->sc_revision == 5) ? ICS_FLIP : 0; 4236 4237 ics2101_mix_attenuate(ic, 4238 GUSMIX_CHAN_MIC, 4239 ICSMIX_LEFT, 4240 ICSMIX_MIN_ATTN); 4241 ics2101_mix_attenuate(ic, 4242 GUSMIX_CHAN_MIC, 4243 ICSMIX_RIGHT, 4244 ICSMIX_MIN_ATTN); 4245 /* 4246 * Start with microphone muted by the mixer... 4247 */ 4248 gusics_mic_mute(ic, 1); 4249 4250 /* ... and enabled by the GUS master mix control */ 4251 gus_mic_ctl(sc, SPKR_ON); 4252 4253 ics2101_mix_attenuate(ic, 4254 GUSMIX_CHAN_LINE, 4255 ICSMIX_LEFT, 4256 ICSMIX_MIN_ATTN); 4257 ics2101_mix_attenuate(ic, 4258 GUSMIX_CHAN_LINE, 4259 ICSMIX_RIGHT, 4260 ICSMIX_MIN_ATTN); 4261 4262 ics2101_mix_attenuate(ic, 4263 GUSMIX_CHAN_CD, 4264 ICSMIX_LEFT, 4265 ICSMIX_MIN_ATTN); 4266 ics2101_mix_attenuate(ic, 4267 GUSMIX_CHAN_CD, 4268 ICSMIX_RIGHT, 4269 ICSMIX_MIN_ATTN); 4270 4271 ics2101_mix_attenuate(ic, 4272 GUSMIX_CHAN_DAC, 4273 ICSMIX_LEFT, 4274 ICSMIX_MIN_ATTN); 4275 ics2101_mix_attenuate(ic, 4276 GUSMIX_CHAN_DAC, 4277 ICSMIX_RIGHT, 4278 ICSMIX_MIN_ATTN); 4279 4280 ics2101_mix_attenuate(ic, 4281 ICSMIX_CHAN_4, 4282 ICSMIX_LEFT, 4283 ICSMIX_MAX_ATTN); 4284 ics2101_mix_attenuate(ic, 4285 ICSMIX_CHAN_4, 4286 ICSMIX_RIGHT, 4287 ICSMIX_MAX_ATTN); 4288 4289 ics2101_mix_attenuate(ic, 4290 GUSMIX_CHAN_MASTER, 4291 ICSMIX_LEFT, 4292 ICSMIX_MIN_ATTN); 4293 ics2101_mix_attenuate(ic, 4294 GUSMIX_CHAN_MASTER, 4295 ICSMIX_RIGHT, 4296 ICSMIX_MIN_ATTN); 4297 /* unmute other stuff: */ 4298 gusics_cd_mute(ic, 0); 4299 gusics_dac_mute(ic, 0); 4300 gusics_linein_mute(ic, 0); 4301 return; 4302} 4303 4304 4305#endif /* NGUS */ 4306