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