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