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