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