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