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