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