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