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