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