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