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