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