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