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