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