gus.c revision 1.88
1/* $NetBSD: gus.c,v 1.88 2005/02/27 00:27:17 perry 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.88 2005/02/27 00:27:17 perry 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}; 616 617static const struct audio_hw_if gusmax_hw_if = { 618 gusmaxopen, 619 gusmax_close, 620 NULL, /* drain */ 621 gus_query_encoding, /* query encoding */ 622 gusmax_set_params, 623 gusmax_round_blocksize, 624 gusmax_commit_settings, 625 NULL, 626 NULL, 627 gusmax_dma_output, 628 gusmax_dma_input, 629 gusmax_halt_out_dma, 630 gusmax_halt_in_dma, 631 gusmax_speaker_ctl, 632 gus_getdev, 633 NULL, 634 gusmax_mixer_set_port, 635 gusmax_mixer_get_port, 636 gusmax_mixer_query_devinfo, 637 ad1848_isa_malloc, 638 ad1848_isa_free, 639 ad1848_isa_round_buffersize, 640 ad1848_isa_mappage, 641 gusmax_get_props, 642 NULL, 643 NULL, 644 NULL, 645}; 646 647/* 648 * Some info about the current audio device 649 */ 650 651struct audio_device gus_device = { 652 "UltraSound", 653 "", 654 "gus", 655}; 656 657#define FLIP_REV 5 /* This rev has flipped mixer chans */ 658 659 660int 661gusprobe(struct device *parent, struct cfdata *match, void *aux) 662{ 663 struct isa_attach_args *ia; 664 int iobase, recdrq; 665 666 ia = aux; 667 if (ia->ia_nio < 1) 668 return 0; 669 if (ia->ia_nirq < 1) 670 return 0; 671 if (ia->ia_ndrq < 1) 672 return 0; 673 674 if (ISA_DIRECT_CONFIG(ia)) 675 return 0; 676 677 iobase = ia->ia_io[0].ir_addr; 678 if (ia->ia_ndrq > 1) 679 recdrq = ia->ia_drq[1].ir_drq; 680 else 681 recdrq = ISA_UNKNOWN_DRQ; 682 683 /* 684 * Before we do anything else, make sure requested IRQ and DRQ are 685 * valid for this card. 686 */ 687 688 /* XXX range check before indexing!! */ 689 if (ia->ia_irq[0].ir_irq == ISA_UNKNOWN_IRQ || 690 gus_irq_map[ia->ia_irq[0].ir_irq] == -1) { 691 printf("gus: invalid irq %d, card not probed\n", 692 ia->ia_irq[0].ir_irq); 693 return 0; 694 } 695 696 if (ia->ia_drq[0].ir_drq == ISA_UNKNOWN_DRQ || 697 gus_drq_map[ia->ia_drq[0].ir_drq] == -1) { 698 printf("gus: invalid drq %d, card not probed\n", 699 ia->ia_drq[0].ir_drq); 700 return 0; 701 } 702 703 if (recdrq != ISA_UNKNOWN_DRQ) { 704 if (recdrq > 7 || gus_drq_map[recdrq] == -1) { 705 printf("gus: invalid second DMA channel (%d), card not " 706 "probed\n", recdrq); 707 return 0; 708 } 709 } else 710 recdrq = ia->ia_drq[0].ir_drq; 711 712 if (iobase == ISA_UNKNOWN_PORT) { 713 int i; 714 for (i = 0; i < gus_addrs; i++) 715 if (gus_test_iobase(ia->ia_iot, gus_base_addrs[i])) { 716 iobase = gus_base_addrs[i]; 717 goto done; 718 } 719 return 0; 720 } else if (!gus_test_iobase(ia->ia_iot, iobase)) 721 return 0; 722 723done: 724 if (!isa_drq_isfree(ia->ia_ic, ia->ia_drq[0].ir_drq) || 725 (recdrq != ia->ia_drq[0].ir_drq && 726 !isa_drq_isfree(ia->ia_ic, recdrq))) 727 return 0; 728 729 ia->ia_nio = 1; 730 ia->ia_io[0].ir_addr = iobase; 731 ia->ia_io[0].ir_size = GUS_NPORT1; 732 733 ia->ia_nirq = 1; 734 ia->ia_ndrq = (recdrq != ia->ia_drq[0].ir_drq) ? 2 : 1; 735 736 ia->ia_niomem = 0; 737 738 return 1; 739} 740 741/* 742 * Test to see if a particular I/O base is valid for the GUS. Return true 743 * if it is. 744 */ 745 746STATIC int 747gus_test_iobase (bus_space_tag_t iot, int iobase) 748{ 749 bus_space_handle_t ioh1, ioh2, ioh3, ioh4; 750 u_char s1, s2; 751 int s, rv; 752 753 rv = 0; 754 /* Map i/o space */ 755 if (bus_space_map(iot, iobase, GUS_NPORT1, 0, &ioh1)) 756 return 0; 757 if (bus_space_map(iot, iobase+GUS_IOH2_OFFSET, GUS_NPORT2, 0, &ioh2)) 758 goto bad1; 759 760 /* XXX Maybe we shouldn't fail on mapping this, but just assume 761 * the card is of revision 0? */ 762 if (bus_space_map(iot, iobase+GUS_IOH3_OFFSET, GUS_NPORT3, 0, &ioh3)) 763 goto bad2; 764 765 if (bus_space_map(iot, iobase+GUS_IOH4_OFFSET, GUS_NPORT4, 0, &ioh4)) 766 goto bad3; 767 768 /* 769 * Reset GUS to an initial state before we do anything. 770 */ 771 772 s = splgus(); 773 delay(500); 774 775 SELECT_GUS_REG(iot, ioh2, GUSREG_RESET); 776 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00); 777 778 delay(500); 779 780 SELECT_GUS_REG(iot, ioh2, GUSREG_RESET); 781 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, GUSMASK_MASTER_RESET); 782 783 delay(500); 784 785 splx(s); 786 787 /* 788 * See if we can write to the board's memory 789 */ 790 791 s1 = guspeek(iot, ioh2, 0L); 792 s2 = guspeek(iot, ioh2, 1L); 793 794 guspoke(iot, ioh2, 0L, 0xaa); 795 guspoke(iot, ioh2, 1L, 0x55); 796 797 if (guspeek(iot, ioh2, 0L) != 0xaa) 798 goto bad; 799 800 guspoke(iot, ioh2, 0L, s1); 801 guspoke(iot, ioh2, 1L, s2); 802 803 rv = 1; 804 805bad: 806 bus_space_unmap(iot, ioh4, GUS_NPORT4); 807bad3: 808 bus_space_unmap(iot, ioh3, GUS_NPORT3); 809bad2: 810 bus_space_unmap(iot, ioh2, GUS_NPORT2); 811bad1: 812 bus_space_unmap(iot, ioh1, GUS_NPORT1); 813 return rv; 814} 815 816/* 817 * Setup the GUS for use; called shortly after probe 818 */ 819 820void 821gusattach(struct device *parent, struct device *self, void *aux) 822{ 823 struct gus_softc *sc; 824 struct isa_attach_args *ia; 825 bus_space_tag_t iot; 826 bus_space_handle_t ioh1, ioh2, ioh3, ioh4; 827 int iobase, i; 828 unsigned char c,d,m; 829 const struct audio_hw_if *hwif; 830 831 sc = (void *) self; 832 ia = aux; 833 callout_init(&sc->sc_dmaout_ch); 834 835 sc->sc_iot = iot = ia->ia_iot; 836 sc->sc_ic = ia->ia_ic; 837 iobase = ia->ia_io[0].ir_addr; 838 839 /* Map i/o space */ 840 if (bus_space_map(iot, iobase, GUS_NPORT1, 0, &ioh1)) 841 panic("%s: can't map io port range 1", self->dv_xname); 842 sc->sc_ioh1 = ioh1; 843 if (bus_space_map(iot, iobase+GUS_IOH2_OFFSET, GUS_NPORT2, 0, &ioh2)) 844 panic("%s: can't map io port range 2", self->dv_xname); 845 sc->sc_ioh2 = ioh2; 846 847 /* XXX Maybe we shouldn't fail on mapping this, but just assume 848 * the card is of revision 0? */ 849 if (bus_space_map(iot, iobase+GUS_IOH3_OFFSET, GUS_NPORT3, 0, &ioh3)) 850 panic("%s: can't map io port range 3", self->dv_xname); 851 sc->sc_ioh3 = ioh3; 852 853 if (bus_space_map(iot, iobase+GUS_IOH4_OFFSET, GUS_NPORT4, 0, &ioh4)) 854 panic("%s: can't map io port range 4", self->dv_xname); 855 sc->sc_ioh4 = ioh4; 856 857 sc->sc_iobase = iobase; 858 sc->sc_irq = ia->ia_irq[0].ir_irq; 859 sc->sc_playdrq = ia->ia_drq[0].ir_drq; 860 sc->sc_recdrq = (ia->ia_ndrq == 2) ? 861 ia->ia_drq[1].ir_drq : ia->ia_drq[0].ir_drq; 862 863 /* 864 * Figure out our board rev, and see if we need to initialize the 865 * mixer 866 */ 867 868 sc->sc_ic = ia->ia_ic; 869 870 delay(500); 871 872 c = bus_space_read_1(iot, ioh3, GUS_BOARD_REV); 873 if (c != 0xff) 874 sc->sc_revision = c; 875 else 876 sc->sc_revision = 0; 877 878 879 SELECT_GUS_REG(iot, ioh2, GUSREG_RESET); 880 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00); 881 882 gusreset(sc, GUS_MAX_VOICES); /* initialize all voices */ 883 gusreset(sc, GUS_MIN_VOICES); /* then set to just the ones we use */ 884 885 /* 886 * Setup the IRQ and DRQ lines in software, using values from 887 * config file 888 */ 889 890 m = GUSMASK_LINE_IN|GUSMASK_LINE_OUT; /* disable all */ 891 892 c = ((unsigned char) gus_irq_map[ia->ia_irq[0].ir_irq]) | 893 GUSMASK_BOTH_RQ; 894 895 if (sc->sc_recdrq == sc->sc_playdrq) 896 d = (unsigned char) (gus_drq_map[sc->sc_playdrq] | 897 GUSMASK_BOTH_RQ); 898 else 899 d = (unsigned char) (gus_drq_map[sc->sc_playdrq] | 900 gus_drq_map[sc->sc_recdrq] << 3); 901 902 /* 903 * Program the IRQ and DMA channels on the GUS. Note that we hardwire 904 * the GUS to only use one IRQ channel, but we give the user the 905 * option of using two DMA channels (the other one given by the drq2 906 * option in the config file). Two DMA channels are needed for full- 907 * duplex operation. 908 * 909 * The order of these operations is very magical. 910 */ 911 912 disable_intr(); /* XXX needed? */ 913 914 bus_space_write_1(iot, ioh1, GUS_REG_CONTROL, GUS_REG_IRQCTL); 915 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, m); 916 bus_space_write_1(iot, ioh1, GUS_IRQCTL_CONTROL, 0x00); 917 bus_space_write_1(iot, ioh1, 0x0f, 0x00); 918 919 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, m); 920 bus_space_write_1(iot, ioh1, GUS_DMA_CONTROL, d | 0x80); /* magic reset? */ 921 922 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, m | GUSMASK_CONTROL_SEL); 923 bus_space_write_1(iot, ioh1, GUS_IRQ_CONTROL, c); 924 925 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, m); 926 bus_space_write_1(iot, ioh1, GUS_DMA_CONTROL, d); 927 928 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, m | GUSMASK_CONTROL_SEL); 929 bus_space_write_1(iot, ioh1, GUS_IRQ_CONTROL, c); 930 931 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, 0x00); 932 933 /* enable line in, line out. leave mic disabled. */ 934 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, 935 (m | GUSMASK_LATCHES) & ~(GUSMASK_LINE_OUT|GUSMASK_LINE_IN)); 936 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, 0x00); 937 938 enable_intr(); 939 940 sc->sc_mixcontrol = 941 (m | GUSMASK_LATCHES) & ~(GUSMASK_LINE_OUT|GUSMASK_LINE_IN); 942 943 if (sc->sc_playdrq != -1) { 944 sc->sc_play_maxsize = isa_dmamaxsize(sc->sc_ic, 945 sc->sc_playdrq); 946 if (isa_drq_alloc(sc->sc_ic, sc->sc_playdrq) != 0) { 947 printf("%s: can't reserve drq %d\n", 948 sc->sc_dev.dv_xname, sc->sc_playdrq); 949 return; 950 } 951 if (isa_dmamap_create(sc->sc_ic, sc->sc_playdrq, 952 sc->sc_play_maxsize, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) { 953 printf("%s: can't create map for drq %d\n", 954 sc->sc_dev.dv_xname, sc->sc_playdrq); 955 return; 956 } 957 } 958 if (sc->sc_recdrq != -1 && sc->sc_recdrq != sc->sc_playdrq) { 959 sc->sc_req_maxsize = isa_dmamaxsize(sc->sc_ic, 960 sc->sc_recdrq); 961 if (isa_drq_alloc(sc->sc_ic, sc->sc_recdrq) != 0) { 962 printf("%s: can't reserve drq %d\n", 963 sc->sc_dev.dv_xname, sc->sc_recdrq); 964 return; 965 } 966 if (isa_dmamap_create(sc->sc_ic, sc->sc_recdrq, 967 sc->sc_req_maxsize, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) { 968 printf("%s: can't create map for drq %d\n", 969 sc->sc_dev.dv_xname, sc->sc_recdrq); 970 return; 971 } 972 } 973 974 /* XXX WILL THIS ALWAYS WORK THE WAY THEY'RE OVERLAYED?! */ 975 sc->sc_codec.sc_ic = sc->sc_ic; 976 977 if (sc->sc_revision >= 5 && sc->sc_revision <= 9) { 978 sc->sc_flags |= GUS_MIXER_INSTALLED; 979 gus_init_ics2101(sc); 980 } 981 hwif = &gus_hw_if; 982 if (sc->sc_revision >= 10) 983 if (gus_init_cs4231(sc)) 984 hwif = &gusmax_hw_if; 985 986 SELECT_GUS_REG(iot, ioh2, GUSREG_RESET); 987 /* 988 * Check to see how much memory we have on this card; see if any 989 * "mirroring" occurs. We're assuming at least 256K already exists 990 * on the card; otherwise the initial probe would have failed 991 */ 992 993 guspoke(iot, ioh2, 0L, 0x00); 994 for (i = 1; i < 1024; i++) { 995 u_long loc; 996 997 /* 998 * See if we've run into mirroring yet 999 */ 1000 1001 if (guspeek(iot, ioh2, 0L) != 0) 1002 break; 1003 1004 loc = i << 10; 1005 1006 guspoke(iot, ioh2, loc, 0xaa); 1007 if (guspeek(iot, ioh2, loc) != 0xaa) 1008 break; 1009 } 1010 1011 sc->sc_dsize = i; 1012 1013 /* The "official" (3.x) version number cannot easily be obtained. 1014 * The revision register does not correspond to the minor number 1015 * of the board version. Simply use the revision register as 1016 * identification. 1017 */ 1018 snprintf(gus_device.version, sizeof(gus_device.version), "%d", 1019 sc->sc_revision); 1020 1021 printf("\n%s: Gravis UltraSound", sc->sc_dev.dv_xname); 1022 if (sc->sc_revision >= 10) 1023 printf(" MAX"); 1024 else { 1025 if (HAS_MIXER(sc)) 1026 printf(", mixer"); 1027 if (HAS_CODEC(sc)) 1028 printf(" with CODEC module"); 1029 } 1030 printf(", %dKB memory\n", sc->sc_dsize); 1031 1032 /* A GUS MAX should always have a CODEC installed */ 1033 if ((sc->sc_revision >= 10) & !(HAS_CODEC(sc))) 1034 printf("%s: WARNING: did not attach CODEC on MAX\n", 1035 sc->sc_dev.dv_xname); 1036 1037 /* 1038 * Setup a default interrupt handler 1039 */ 1040 1041 /* XXX we shouldn't have to use splgus == splclock, nor should 1042 * we use IPL_CLOCK. 1043 */ 1044 sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq[0].ir_irq, 1045 IST_EDGE, IPL_AUDIO, gusintr, sc /* sc->sc_gusdsp */); 1046 1047 /* 1048 * Set some default values 1049 * XXX others start with 8kHz mono mu-law 1050 */ 1051 1052 sc->sc_irate = sc->sc_orate = 44100; 1053 sc->sc_encoding = AUDIO_ENCODING_SLINEAR_LE; 1054 sc->sc_precision = 16; 1055 sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_DATA_SIZE16; 1056 sc->sc_voc[GUS_VOICE_RIGHT].voccntl |= GUSMASK_DATA_SIZE16; 1057 sc->sc_channels = 1; 1058 sc->sc_ogain = 340; 1059 gus_commit_settings(sc); 1060 1061 /* 1062 * We always put the left channel full left & right channel 1063 * full right. 1064 * For mono playback, we set up both voices playing the same buffer. 1065 */ 1066 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) GUS_VOICE_LEFT); 1067 SELECT_GUS_REG(iot, ioh2, GUSREG_PAN_POS); 1068 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, GUS_PAN_FULL_LEFT); 1069 1070 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) GUS_VOICE_RIGHT); 1071 SELECT_GUS_REG(iot, ioh2, GUSREG_PAN_POS); 1072 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, GUS_PAN_FULL_RIGHT); 1073 1074 /* 1075 * Attach to the generic audio layer 1076 */ 1077 1078 audio_attach_mi(hwif, 1079 HAS_CODEC(sc) ? (void *)&sc->sc_codec : (void *)sc, &sc->sc_dev); 1080} 1081 1082int 1083gusopen(void *addr, int flags) 1084{ 1085 struct gus_softc *sc; 1086 1087 sc = addr; 1088 DPRINTF(("gusopen() called\n")); 1089 1090 if (sc->sc_flags & GUS_OPEN) 1091 return EBUSY; 1092 1093 /* 1094 * Some initialization 1095 */ 1096 1097 sc->sc_flags |= GUS_OPEN; 1098 sc->sc_dmabuf = 0; 1099 sc->sc_playbuf = -1; 1100 sc->sc_bufcnt = 0; 1101 sc->sc_voc[GUS_VOICE_LEFT].start_addr = GUS_MEM_OFFSET - 1; 1102 sc->sc_voc[GUS_VOICE_LEFT].current_addr = GUS_MEM_OFFSET; 1103 1104 if (HAS_CODEC(sc)) { 1105 ad1848_open(&sc->sc_codec.sc_ad1848, flags); 1106 sc->sc_codec.sc_ad1848.mute[AD1848_AUX1_CHANNEL] = 0; 1107 1108 /* turn on DAC output */ 1109 ad1848_mute_channel(&sc->sc_codec.sc_ad1848, 1110 AD1848_AUX1_CHANNEL, 0); 1111 if (flags & FREAD) { 1112 sc->sc_codec.sc_ad1848.mute[AD1848_MONO_CHANNEL] = 0; 1113 ad1848_mute_channel(&sc->sc_codec.sc_ad1848, 1114 AD1848_MONO_CHANNEL, 0); 1115 } 1116 } else if (flags & FREAD) { 1117 /* enable/unmute the microphone */ 1118 if (HAS_MIXER(sc)) { 1119 gusics_mic_mute(&sc->sc_mixer, 0); 1120 } else 1121 gus_mic_ctl(sc, SPKR_ON); 1122 } 1123 if (sc->sc_nbufs == 0) 1124 gus_round_blocksize(sc, GUS_BUFFER_MULTIPLE, /* default blksiz */ 1125 0, NULL); /* XXX */ 1126 return 0; 1127} 1128 1129int 1130gusmaxopen(void *addr, int flags) 1131{ 1132 struct ad1848_isa_softc *ac; 1133 1134 ac = addr; 1135 return gusopen(ac->sc_ad1848.parent, flags); 1136} 1137 1138STATIC void 1139gus_deinterleave(struct gus_softc *sc, void *buf, int size) 1140{ 1141 /* deinterleave the stereo data. We can use sc->sc_deintr_buf 1142 for scratch space. */ 1143 int i; 1144 1145 if (size > sc->sc_blocksize) { 1146 printf("gus: deinterleave %d > %d\n", size, sc->sc_blocksize); 1147 return; 1148 } else if (size < sc->sc_blocksize) { 1149 DPRINTF(("gus: deinterleave %d < %d\n", size, sc->sc_blocksize)); 1150 } 1151 1152 /* 1153 * size is in bytes. 1154 */ 1155 if (sc->sc_precision == 16) { 1156 u_short *dei = sc->sc_deintr_buf; 1157 u_short *sbuf = buf; 1158 size >>= 1; /* bytecnt to shortcnt */ 1159 /* copy 2nd of each pair of samples to the staging area, while 1160 compacting the 1st of each pair into the original area. */ 1161 for (i = 0; i < size/2-1; i++) { 1162 dei[i] = sbuf[i*2+1]; 1163 sbuf[i+1] = sbuf[i*2+2]; 1164 } 1165 /* 1166 * this has copied one less sample than half of the 1167 * buffer. The first sample of the 1st stream was 1168 * already in place and didn't need copying. 1169 * Therefore, we've moved all of the 1st stream's 1170 * samples into place. We have one sample from 2nd 1171 * stream in the last slot of original area, not 1172 * copied to the staging area (But we don't need to!). 1173 * Copy the remainder of the original stream into place. 1174 */ 1175 memcpy(&sbuf[size/2], dei, i * sizeof(short)); 1176 } else { 1177 u_char *dei = sc->sc_deintr_buf; 1178 u_char *sbuf = buf; 1179 for (i = 0; i < size/2-1; i++) { 1180 dei[i] = sbuf[i*2+1]; 1181 sbuf[i+1] = sbuf[i*2+2]; 1182 } 1183 memcpy(&sbuf[size/2], dei, i); 1184 } 1185} 1186 1187/* 1188 * Actually output a buffer to the DSP chip 1189 */ 1190 1191int 1192gusmax_dma_output(void *addr, void *buf, int size, 1193 void (*intr)(void *), void *arg) 1194{ 1195 struct ad1848_isa_softc *ac; 1196 1197 ac = addr; 1198 return gus_dma_output(ac->sc_ad1848.parent, buf, size, intr, arg); 1199} 1200 1201/* 1202 * called at splgus() from interrupt handler. 1203 */ 1204void 1205stereo_dmaintr(void *arg) 1206{ 1207 struct gus_softc *sc; 1208 struct stereo_dma_intr *sa; 1209 1210 DMAPRINTF(("stereo_dmaintr")); 1211 sc = arg; 1212 sa = &sc->sc_stereo; 1213 1214 /* 1215 * Put other half in its place, then call the real interrupt routine :) 1216 */ 1217 1218 sc->sc_dmaoutintr = sa->intr; 1219 sc->sc_outarg = sa->arg; 1220 1221#ifdef GUSPLAYDEBUG 1222 if (gusstats) { 1223 microtime(&dmarecords[dmarecord_index].tv); 1224 dmarecords[dmarecord_index].gusaddr = sa->dmabuf; 1225 dmarecords[dmarecord_index].bsdaddr = sa->buffer; 1226 dmarecords[dmarecord_index].count = sa->size; 1227 dmarecords[dmarecord_index].channel = 1; 1228 dmarecords[dmarecord_index].direction = 1; 1229 dmarecord_index = (dmarecord_index + 1) % NDMARECS; 1230 } 1231#endif 1232 1233 gusdmaout(sc, sa->flags, sa->dmabuf, (caddr_t) sa->buffer, sa->size); 1234 1235 sa->flags = 0; 1236 sa->dmabuf = 0; 1237 sa->buffer = 0; 1238 sa->size = 0; 1239 sa->intr = 0; 1240 sa->arg = 0; 1241} 1242 1243/* 1244 * Start up DMA output to the card. 1245 * Called at splgus/splaudio already, either from intr handler or from 1246 * generic audio code. 1247 */ 1248int 1249gus_dma_output(void *addr, void *buf, int size, 1250 void (*intr)(void *), void *arg) 1251{ 1252 struct gus_softc *sc; 1253 u_char *buffer; 1254 u_long boarddma; 1255 int flags; 1256 1257 DMAPRINTF(("gus_dma_output %d @ %p\n", size, buf)); 1258 sc = addr; 1259 buffer = buf; 1260 1261 if (size != sc->sc_blocksize) { 1262 DPRINTF(("gus_dma_output reqsize %d not sc_blocksize %d\n", 1263 size, sc->sc_blocksize)); 1264 return EINVAL; 1265 } 1266 1267 flags = GUSMASK_DMA_WRITE; 1268 if (sc->sc_precision == 16) 1269 flags |= GUSMASK_DMA_DATA_SIZE; 1270 if (sc->sc_encoding == AUDIO_ENCODING_ULAW || 1271 sc->sc_encoding == AUDIO_ENCODING_ALAW || 1272 sc->sc_encoding == AUDIO_ENCODING_ULINEAR_BE || 1273 sc->sc_encoding == AUDIO_ENCODING_ULINEAR_LE) 1274 flags |= GUSMASK_DMA_INVBIT; 1275 1276 if (sc->sc_channels == 2) { 1277 if (sc->sc_precision == 16) { 1278 if (size & 3) { 1279 DPRINTF(("gus_dma_output: unpaired 16bit samples")); 1280 size &= 3; 1281 } 1282 } else if (size & 1) { 1283 DPRINTF(("gus_dma_output: unpaired samples")); 1284 size &= 1; 1285 } 1286 if (size == 0) 1287 return 0; 1288 1289 gus_deinterleave(sc, (void *)buffer, size); 1290 1291 size >>= 1; 1292 1293 boarddma = size * sc->sc_dmabuf + GUS_MEM_OFFSET; 1294 1295 sc->sc_stereo.intr = intr; 1296 sc->sc_stereo.arg = arg; 1297 sc->sc_stereo.size = size; 1298 sc->sc_stereo.dmabuf = boarddma + GUS_LEFT_RIGHT_OFFSET; 1299 sc->sc_stereo.buffer = buffer + size; 1300 sc->sc_stereo.flags = flags; 1301 if (gus_dostereo) { 1302 intr = stereo_dmaintr; 1303 arg = sc; 1304 } 1305 } else 1306 boarddma = size * sc->sc_dmabuf + GUS_MEM_OFFSET; 1307 1308 1309 sc->sc_flags |= GUS_LOCKED; 1310 sc->sc_dmaoutintr = intr; 1311 sc->sc_outarg = arg; 1312 1313#ifdef GUSPLAYDEBUG 1314 if (gusstats) { 1315 microtime(&dmarecords[dmarecord_index].tv); 1316 dmarecords[dmarecord_index].gusaddr = boarddma; 1317 dmarecords[dmarecord_index].bsdaddr = buffer; 1318 dmarecords[dmarecord_index].count = size; 1319 dmarecords[dmarecord_index].channel = 0; 1320 dmarecords[dmarecord_index].direction = 1; 1321 dmarecord_index = (dmarecord_index + 1) % NDMARECS; 1322 } 1323#endif 1324 1325 gusdmaout(sc, flags, boarddma, (caddr_t) buffer, size); 1326 1327 return 0; 1328} 1329 1330void 1331gusmax_close(void *addr) 1332{ 1333 struct ad1848_isa_softc *ac; 1334 struct gus_softc *sc; 1335 1336 ac = addr; 1337 sc = ac->sc_ad1848.parent; 1338#if 0 1339 ac->mute[AD1848_AUX1_CHANNEL] = MUTE_ALL; 1340 ad1848_mute_channel(ac, MUTE_ALL); /* turn off DAC output */ 1341#endif 1342 ad1848_close(&ac->sc_ad1848); 1343 gusclose(sc); 1344} 1345 1346/* 1347 * Close out device stuff. Called at splgus() from generic audio layer. 1348 */ 1349void 1350gusclose(void *addr) 1351{ 1352 struct gus_softc *sc; 1353 1354 sc = addr; 1355 DPRINTF(("gus_close: sc=%p\n", sc)); 1356 1357 1358/* if (sc->sc_flags & GUS_DMAOUT_ACTIVE) */ { 1359 gus_halt_out_dma(sc); 1360 } 1361/* if (sc->sc_flags & GUS_DMAIN_ACTIVE) */ { 1362 gus_halt_in_dma(sc); 1363 } 1364 sc->sc_flags &= ~(GUS_OPEN|GUS_LOCKED|GUS_DMAOUT_ACTIVE|GUS_DMAIN_ACTIVE); 1365 1366 if (sc->sc_deintr_buf) { 1367 FREE(sc->sc_deintr_buf, M_DEVBUF); 1368 sc->sc_deintr_buf = NULL; 1369 } 1370 /* turn off speaker, etc. */ 1371 1372 /* make sure the voices shut up: */ 1373 gus_stop_voice(sc, GUS_VOICE_LEFT, 1); 1374 gus_stop_voice(sc, GUS_VOICE_RIGHT, 0); 1375} 1376 1377/* 1378 * Service interrupts. Farm them off to helper routines if we are using the 1379 * GUS for simple playback/record 1380 */ 1381 1382#ifdef DIAGNOSTIC 1383int gusintrcnt; 1384int gusdmaintrcnt; 1385int gusvocintrcnt; 1386#endif 1387 1388int 1389gusintr(void *arg) 1390{ 1391 struct gus_softc *sc; 1392 bus_space_tag_t iot; 1393 bus_space_handle_t ioh1; 1394 bus_space_handle_t ioh2; 1395 unsigned char intr; 1396 int retval; 1397 1398 DPRINTF(("gusintr\n")); 1399 sc = arg; 1400 iot = sc->sc_iot; 1401 ioh1 = sc->sc_ioh1; 1402 ioh2 = sc->sc_ioh2; 1403 retval = 0; 1404#ifdef DIAGNOSTIC 1405 gusintrcnt++; 1406#endif 1407 if (HAS_CODEC(sc)) 1408 retval = ad1848_isa_intr(&sc->sc_codec); 1409 if ((intr = bus_space_read_1(iot, ioh1, GUS_IRQ_STATUS)) & GUSMASK_IRQ_DMATC) { 1410 DMAPRINTF(("gusintr DMA flags=%x\n", sc->sc_flags)); 1411#ifdef DIAGNOSTIC 1412 gusdmaintrcnt++; 1413#endif 1414 retval += gus_dmaout_intr(sc); 1415 if (sc->sc_flags & GUS_DMAIN_ACTIVE) { 1416 SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL); 1417 intr = bus_space_read_1(iot, ioh2, GUS_DATA_HIGH); 1418 if (intr & GUSMASK_SAMPLE_DMATC) { 1419 retval += gus_dmain_intr(sc); 1420 } 1421 } 1422 } 1423 if (intr & (GUSMASK_IRQ_VOICE | GUSMASK_IRQ_VOLUME)) { 1424 DMAPRINTF(("gusintr voice flags=%x\n", sc->sc_flags)); 1425#ifdef DIAGNOSTIC 1426 gusvocintrcnt++; 1427#endif 1428 retval += gus_voice_intr(sc); 1429 } 1430 if (retval) 1431 return 1; 1432 return retval; 1433} 1434 1435int gus_bufcnt[GUS_MEM_FOR_BUFFERS / GUS_BUFFER_MULTIPLE]; 1436int gus_restart; /* how many restarts? */ 1437int gus_stops; /* how many times did voice stop? */ 1438int gus_falsestops; /* stopped but not done? */ 1439int gus_continues; 1440 1441struct playcont { 1442 struct timeval tv; 1443 u_int playbuf; 1444 u_int dmabuf; 1445 u_char bufcnt; 1446 u_char vaction; 1447 u_char voccntl; 1448 u_char volcntl; 1449 u_long curaddr; 1450 u_long endaddr; 1451} playstats[NDMARECS]; 1452 1453int playcntr; 1454 1455STATIC void 1456gus_dmaout_timeout(void *arg) 1457{ 1458 struct gus_softc *sc; 1459 bus_space_tag_t iot; 1460 bus_space_handle_t ioh2; 1461 int s; 1462 1463 sc = arg; 1464 iot = sc->sc_iot; 1465 ioh2 = sc->sc_ioh2; 1466 printf("%s: dmaout timeout\n", sc->sc_dev.dv_xname); 1467 /* 1468 * Stop any DMA. 1469 */ 1470 s = splgus(); 1471 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL); 1472 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0); 1473#if 0 1474 /* XXX we will dmadone below? */ 1475 isa_dmaabort(sc->sc_dev.dv_parent, sc->sc_playdrq); 1476#endif 1477 1478 gus_dmaout_dointr(sc); 1479 splx(s); 1480} 1481 1482 1483/* 1484 * Service DMA interrupts. This routine will only get called if we're doing 1485 * a DMA transfer for playback/record requests from the audio layer. 1486 */ 1487 1488STATIC int 1489gus_dmaout_intr(struct gus_softc *sc) 1490{ 1491 bus_space_tag_t iot; 1492 bus_space_handle_t ioh2; 1493 1494 iot = sc->sc_iot; 1495 ioh2 = sc->sc_ioh2; 1496 /* 1497 * If we got a DMA transfer complete from the GUS DRAM, then deal 1498 * with it. 1499 */ 1500 1501 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL); 1502 if (bus_space_read_1(iot, ioh2, GUS_DATA_HIGH) & GUSMASK_DMA_IRQPEND) { 1503 callout_stop(&sc->sc_dmaout_ch); 1504 gus_dmaout_dointr(sc); 1505 return 1; 1506 } 1507 return 0; 1508} 1509 1510STATIC void 1511gus_dmaout_dointr(struct gus_softc *sc) 1512{ 1513 bus_space_tag_t iot; 1514 bus_space_handle_t ioh2; 1515 1516 iot = sc->sc_iot; 1517 ioh2 = sc->sc_ioh2; 1518 /* sc->sc_dmaoutcnt - 1 because DMA controller counts from zero?. */ 1519 isa_dmadone(sc->sc_ic, sc->sc_playdrq); 1520 sc->sc_flags &= ~GUS_DMAOUT_ACTIVE; /* pending DMA is done */ 1521 DMAPRINTF(("gus_dmaout_dointr %d @ %p\n", sc->sc_dmaoutcnt, 1522 sc->sc_dmaoutaddr)); 1523 1524 /* 1525 * to prevent clicking, we need to copy last sample 1526 * from last buffer to scratch area just before beginning of 1527 * buffer. However, if we're doing formats that are converted by 1528 * the card during the DMA process, we need to pick up the converted 1529 * byte rather than the one we have in memory. 1530 */ 1531 if (sc->sc_dmabuf == sc->sc_nbufs - 1) { 1532 int i; 1533 switch (sc->sc_encoding) { 1534 case AUDIO_ENCODING_SLINEAR_LE: 1535 case AUDIO_ENCODING_SLINEAR_BE: 1536 if (sc->sc_precision == 8) 1537 goto byte; 1538 /* we have the native format */ 1539 for (i = 1; i <= 2; i++) 1540 guspoke(iot, ioh2, sc->sc_gusaddr - 1541 (sc->sc_nbufs - 1) * sc->sc_chanblocksize - i, 1542 sc->sc_dmaoutaddr[sc->sc_dmaoutcnt-i]); 1543 break; 1544 case AUDIO_ENCODING_ULINEAR_LE: 1545 case AUDIO_ENCODING_ULINEAR_BE: 1546 guspoke(iot, ioh2, sc->sc_gusaddr - 1547 (sc->sc_nbufs - 1) * sc->sc_chanblocksize - 2, 1548 guspeek(iot, ioh2, 1549 sc->sc_gusaddr + sc->sc_chanblocksize - 2)); 1550 case AUDIO_ENCODING_ALAW: 1551 case AUDIO_ENCODING_ULAW: 1552 byte: 1553 /* we need to fetch the translated byte, then stuff it. */ 1554 guspoke(iot, ioh2, sc->sc_gusaddr - 1555 (sc->sc_nbufs - 1) * sc->sc_chanblocksize - 1, 1556 guspeek(iot, ioh2, 1557 sc->sc_gusaddr + sc->sc_chanblocksize - 1)); 1558 break; 1559 } 1560 } 1561 /* 1562 * If this is the first half of stereo, "ignore" this one 1563 * and copy out the second half. 1564 */ 1565 if (sc->sc_dmaoutintr == stereo_dmaintr) { 1566 (*sc->sc_dmaoutintr)(sc->sc_outarg); 1567 return; 1568 } 1569 /* 1570 * If the voice is stopped, then start it. Reset the loop 1571 * and roll bits. Call the audio layer routine, since if 1572 * we're starting a stopped voice, that means that the next 1573 * buffer can be filled 1574 */ 1575 1576 sc->sc_flags &= ~GUS_LOCKED; 1577 if (sc->sc_voc[GUS_VOICE_LEFT].voccntl & 1578 GUSMASK_VOICE_STOPPED) { 1579 if (sc->sc_flags & GUS_PLAYING) { 1580 printf("%s: playing yet stopped?\n", sc->sc_dev.dv_xname); 1581 } 1582 sc->sc_bufcnt++; /* another yet to be played */ 1583 gus_start_playing(sc, sc->sc_dmabuf); 1584 gus_restart++; 1585 } else { 1586 /* 1587 * set the sound action based on which buffer we 1588 * just transferred. If we just transferred buffer 0 1589 * we want the sound to loop when it gets to the nth 1590 * buffer; if we just transferred 1591 * any other buffer, we want the sound to roll over 1592 * at least one more time. The voice interrupt 1593 * handlers will take care of accounting & 1594 * setting control bits if it's not caught up to us 1595 * yet. 1596 */ 1597 if (++sc->sc_bufcnt == 2) { 1598 /* 1599 * XXX 1600 * If we're too slow in reaction here, 1601 * the voice could be just approaching the 1602 * end of its run. It should be set to stop, 1603 * so these adjustments might not DTRT. 1604 */ 1605 if (sc->sc_dmabuf == 0 && 1606 sc->sc_playbuf == sc->sc_nbufs - 1) { 1607 /* player is just at the last buf, we're at the 1608 first. Turn on looping, turn off rolling. */ 1609 sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_LOOP_ENABLE; 1610 sc->sc_voc[GUS_VOICE_LEFT].volcntl &= ~GUSMASK_VOICE_ROLL; 1611 playstats[playcntr].vaction = 3; 1612 } else { 1613 /* player is at previous buf: 1614 turn on rolling, turn off looping */ 1615 sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~GUSMASK_LOOP_ENABLE; 1616 sc->sc_voc[GUS_VOICE_LEFT].volcntl |= GUSMASK_VOICE_ROLL; 1617 playstats[playcntr].vaction = 4; 1618 } 1619#ifdef GUSPLAYDEBUG 1620 if (gusstats) { 1621 microtime(&playstats[playcntr].tv); 1622 playstats[playcntr].endaddr 1623 = sc->sc_voc[GUS_VOICE_LEFT].end_addr; 1624 playstats[playcntr].voccntl 1625 = sc->sc_voc[GUS_VOICE_LEFT].voccntl; 1626 playstats[playcntr].volcntl 1627 = sc->sc_voc[GUS_VOICE_LEFT].volcntl; 1628 playstats[playcntr].playbuf = sc->sc_playbuf; 1629 playstats[playcntr].dmabuf = sc->sc_dmabuf; 1630 playstats[playcntr].bufcnt = sc->sc_bufcnt; 1631 playstats[playcntr].curaddr 1632 = gus_get_curaddr(sc, GUS_VOICE_LEFT); 1633 playcntr = (playcntr + 1) % NDMARECS; 1634 } 1635#endif 1636 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, GUS_VOICE_LEFT); 1637 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL); 1638 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 1639 sc->sc_voc[GUS_VOICE_LEFT].voccntl); 1640 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL); 1641 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 1642 sc->sc_voc[GUS_VOICE_LEFT].volcntl); 1643 } 1644 } 1645 gus_bufcnt[sc->sc_bufcnt-1]++; 1646 /* 1647 * flip to the next DMA buffer 1648 */ 1649 1650 sc->sc_dmabuf = ++sc->sc_dmabuf % sc->sc_nbufs; 1651 /* 1652 * See comments below about DMA admission control strategy. 1653 * We can call the upper level here if we have an 1654 * idle buffer (not currently playing) to DMA into. 1655 */ 1656 if (sc->sc_dmaoutintr && sc->sc_bufcnt < sc->sc_nbufs) { 1657 /* clean out to prevent double calls */ 1658 void (*pfunc)(void *); 1659 void *arg; 1660 1661 pfunc = sc->sc_dmaoutintr; 1662 arg = sc->sc_outarg; 1663 sc->sc_outarg = 0; 1664 sc->sc_dmaoutintr = 0; 1665 (*pfunc)(arg); 1666 } 1667} 1668 1669/* 1670 * Service voice interrupts 1671 */ 1672 1673STATIC int 1674gus_voice_intr(struct gus_softc *sc) 1675{ 1676 bus_space_tag_t iot; 1677 bus_space_handle_t ioh2; 1678 int ignore, voice, rval; 1679 unsigned char intr, status; 1680 1681 iot = sc->sc_iot; 1682 ioh2 = sc->sc_ioh2; 1683 ignore = 0; 1684 rval = 0; 1685 /* 1686 * The point of this may not be obvious at first. A voice can 1687 * interrupt more than once; according to the GUS SDK we are supposed 1688 * to ignore multiple interrupts for the same voice. 1689 */ 1690 1691 while (1) { 1692 SELECT_GUS_REG(iot, ioh2, GUSREG_IRQ_STATUS); 1693 intr = bus_space_read_1(iot, ioh2, GUS_DATA_HIGH); 1694 1695 if ((intr & (GUSMASK_WIRQ_VOLUME | GUSMASK_WIRQ_VOICE)) 1696 == (GUSMASK_WIRQ_VOLUME | GUSMASK_WIRQ_VOICE)) 1697 /* 1698 * No more interrupts, time to return 1699 */ 1700 return rval; 1701 1702 if ((intr & GUSMASK_WIRQ_VOICE) == 0) { 1703 1704 /* 1705 * We've got a voice interrupt. Ignore previous 1706 * interrupts by the same voice. 1707 */ 1708 1709 rval = 1; 1710 voice = intr & GUSMASK_WIRQ_VOICEMASK; 1711 1712 if ((1 << voice) & ignore) 1713 break; 1714 1715 ignore |= 1 << voice; 1716 1717 /* 1718 * If the voice is stopped, then force it to stop 1719 * (this stops it from continuously generating IRQs) 1720 */ 1721 1722 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL+0x80); 1723 status = bus_space_read_1(iot, ioh2, GUS_DATA_HIGH); 1724 if (status & GUSMASK_VOICE_STOPPED) { 1725 if (voice != GUS_VOICE_LEFT) { 1726 DMAPRINTF(("%s: spurious voice %d stop?\n", 1727 sc->sc_dev.dv_xname, voice)); 1728 gus_stop_voice(sc, voice, 0); 1729 continue; 1730 } 1731 gus_stop_voice(sc, voice, 1); 1732 /* also kill right voice */ 1733 gus_stop_voice(sc, GUS_VOICE_RIGHT, 0); 1734 sc->sc_bufcnt--; /* it finished a buffer */ 1735 if (sc->sc_bufcnt > 0) { 1736 /* 1737 * probably a race to get here: the 1738 * voice stopped while the DMA code was 1739 * just trying to get the next buffer 1740 * in place. Start the voice again. 1741 */ 1742 printf("%s: stopped voice not drained? (%x)\n", 1743 sc->sc_dev.dv_xname, sc->sc_bufcnt); 1744 gus_falsestops++; 1745 1746 sc->sc_playbuf = ++sc->sc_playbuf % sc->sc_nbufs; 1747 gus_start_playing(sc, sc->sc_playbuf); 1748 } else if (sc->sc_bufcnt < 0) { 1749 panic("%s: negative bufcnt in stopped voice", 1750 sc->sc_dev.dv_xname); 1751 } else { 1752 sc->sc_playbuf = -1; /* none are active */ 1753 gus_stops++; 1754 } 1755 /* fall through to callback and admit another 1756 buffer.... */ 1757 } else if (sc->sc_bufcnt != 0) { 1758 /* 1759 * This should always be taken if the voice 1760 * is not stopped. 1761 */ 1762 gus_continues++; 1763 if (gus_continue_playing(sc, voice)) { 1764 /* 1765 * we shouldn't have continued--active 1766 * DMA is in the way in the ring, for 1767 * some as-yet undebugged reason. 1768 */ 1769 gus_stop_voice(sc, GUS_VOICE_LEFT, 1); 1770 /* also kill right voice */ 1771 gus_stop_voice(sc, GUS_VOICE_RIGHT, 0); 1772 sc->sc_playbuf = -1; 1773 gus_stops++; 1774 } 1775 } 1776 /* 1777 * call the upper level to send on down another 1778 * block. We do admission rate control as follows: 1779 * 1780 * When starting up output (in the first N 1781 * blocks), call the upper layer after the DMA is 1782 * complete (see above in gus_dmaout_intr()). 1783 * 1784 * When output is already in progress and we have 1785 * no more GUS buffers to use for DMA, the DMA 1786 * output routines do not call the upper layer. 1787 * Instead, we call the DMA completion routine 1788 * here, after the voice interrupts indicating 1789 * that it's finished with a buffer. 1790 * 1791 * However, don't call anything here if the DMA 1792 * output flag is set, (which shouldn't happen) 1793 * because we'll squish somebody else's DMA if 1794 * that's the case. When DMA is done, it will 1795 * call back if there is a spare buffer. 1796 */ 1797 if (sc->sc_dmaoutintr && !(sc->sc_flags & GUS_LOCKED)) { 1798 if (sc->sc_dmaoutintr == stereo_dmaintr) 1799 printf("gusdmaout botch?\n"); 1800 else { 1801 /* clean out to avoid double calls */ 1802 void (*pfunc)(void *); 1803 void *arg; 1804 1805 pfunc = sc->sc_dmaoutintr; 1806 arg = sc->sc_outarg; 1807 sc->sc_outarg = 0; 1808 sc->sc_dmaoutintr = 0; 1809 (*pfunc)(arg); 1810 } 1811 } 1812 } 1813 1814 /* 1815 * Ignore other interrupts for now 1816 */ 1817 } 1818 return 0; 1819} 1820 1821/* 1822 * Start the voices playing, with buffer BUFNO. 1823 */ 1824STATIC void 1825gus_start_playing(struct gus_softc *sc, int bufno) 1826{ 1827 bus_space_tag_t iot; 1828 bus_space_handle_t ioh2; 1829 1830 iot = sc->sc_iot; 1831 ioh2 = sc->sc_ioh2; 1832 /* 1833 * Loop or roll if we have buffers ready. 1834 */ 1835 1836 if (sc->sc_bufcnt == 1) { 1837 sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~(GUSMASK_LOOP_ENABLE); 1838 sc->sc_voc[GUS_VOICE_LEFT].volcntl &= ~(GUSMASK_VOICE_ROLL); 1839 } else { 1840 if (bufno == sc->sc_nbufs - 1) { 1841 sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_LOOP_ENABLE; 1842 sc->sc_voc[GUS_VOICE_LEFT].volcntl &= ~(GUSMASK_VOICE_ROLL); 1843 } else { 1844 sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~GUSMASK_LOOP_ENABLE; 1845 sc->sc_voc[GUS_VOICE_LEFT].volcntl |= GUSMASK_VOICE_ROLL; 1846 } 1847 } 1848 1849 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, GUS_VOICE_LEFT); 1850 1851 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL); 1852 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_LEFT].voccntl); 1853 1854 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL); 1855 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_LEFT].volcntl); 1856 1857 sc->sc_voc[GUS_VOICE_LEFT].current_addr = 1858 GUS_MEM_OFFSET + sc->sc_chanblocksize * bufno; 1859 sc->sc_voc[GUS_VOICE_LEFT].end_addr = 1860 sc->sc_voc[GUS_VOICE_LEFT].current_addr + sc->sc_chanblocksize - 1; 1861 sc->sc_voc[GUS_VOICE_RIGHT].current_addr = 1862 sc->sc_voc[GUS_VOICE_LEFT].current_addr + 1863 (gus_dostereo && sc->sc_channels == 2 ? GUS_LEFT_RIGHT_OFFSET : 0); 1864 /* 1865 * set up right channel to just loop forever, no interrupts, 1866 * starting at the buffer we just filled. We'll feed it data 1867 * at the same time as left channel. 1868 */ 1869 sc->sc_voc[GUS_VOICE_RIGHT].voccntl |= GUSMASK_LOOP_ENABLE; 1870 sc->sc_voc[GUS_VOICE_RIGHT].volcntl &= ~(GUSMASK_VOICE_ROLL); 1871 1872#ifdef GUSPLAYDEBUG 1873 if (gusstats) { 1874 microtime(&playstats[playcntr].tv); 1875 playstats[playcntr].curaddr = sc->sc_voc[GUS_VOICE_LEFT].current_addr; 1876 1877 playstats[playcntr].voccntl = sc->sc_voc[GUS_VOICE_LEFT].voccntl; 1878 playstats[playcntr].volcntl = sc->sc_voc[GUS_VOICE_LEFT].volcntl; 1879 playstats[playcntr].endaddr = sc->sc_voc[GUS_VOICE_LEFT].end_addr; 1880 playstats[playcntr].playbuf = bufno; 1881 playstats[playcntr].dmabuf = sc->sc_dmabuf; 1882 playstats[playcntr].bufcnt = sc->sc_bufcnt; 1883 playstats[playcntr].vaction = 5; 1884 playcntr = (playcntr + 1) % NDMARECS; 1885 } 1886#endif 1887 1888 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, GUS_VOICE_RIGHT); 1889 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL); 1890 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_RIGHT].voccntl); 1891 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL); 1892 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_RIGHT].volcntl); 1893 1894 gus_start_voice(sc, GUS_VOICE_RIGHT, 0); 1895 gus_start_voice(sc, GUS_VOICE_LEFT, 1); 1896 if (sc->sc_playbuf == -1) 1897 /* mark start of playing */ 1898 sc->sc_playbuf = bufno; 1899} 1900 1901STATIC int 1902gus_continue_playing(struct gus_softc *sc, int voice) 1903{ 1904 bus_space_tag_t iot; 1905 bus_space_handle_t ioh2; 1906 1907 /* 1908 * stop this voice from interrupting while we work. 1909 */ 1910 iot = sc->sc_iot; 1911 ioh2 = sc->sc_ioh2; 1912 1913 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL); 1914 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 1915 sc->sc_voc[voice].voccntl & ~(GUSMASK_VOICE_IRQ)); 1916 1917 /* 1918 * update playbuf to point to the buffer the hardware just started 1919 * playing 1920 */ 1921 sc->sc_playbuf = ++sc->sc_playbuf % sc->sc_nbufs; 1922 1923 /* 1924 * account for buffer just finished 1925 */ 1926 if (--sc->sc_bufcnt == 0) { 1927 DPRINTF(("gus: bufcnt 0 on continuing voice?\n")); 1928 } 1929 if (sc->sc_playbuf == sc->sc_dmabuf && (sc->sc_flags & GUS_LOCKED)) { 1930 printf("%s: continue into active dmabuf?\n", sc->sc_dev.dv_xname); 1931 return 1; 1932 } 1933 1934 /* 1935 * Select the end of the buffer based on the currently active 1936 * buffer, [plus extra contiguous buffers (if ready)]. 1937 */ 1938 1939 /* 1940 * set endpoint at end of buffer we just started playing. 1941 * 1942 * The total gets -1 because end addrs are one less than you might 1943 * think (the end_addr is the address of the last sample to play) 1944 */ 1945 gus_set_endaddr(sc, voice, GUS_MEM_OFFSET + 1946 sc->sc_chanblocksize * (sc->sc_playbuf + 1) - 1); 1947 1948 if (sc->sc_bufcnt < 2) { 1949 /* 1950 * Clear out the loop and roll flags, and rotate the currently 1951 * playing buffer. That way, if we don't manage to get more 1952 * data before this buffer finishes, we'll just stop. 1953 */ 1954 sc->sc_voc[voice].voccntl &= ~GUSMASK_LOOP_ENABLE; 1955 sc->sc_voc[voice].volcntl &= ~GUSMASK_VOICE_ROLL; 1956 playstats[playcntr].vaction = 0; 1957 } else { 1958 /* 1959 * We have some buffers to play. set LOOP if we're on the 1960 * last buffer in the ring, otherwise set ROLL. 1961 */ 1962 if (sc->sc_playbuf == sc->sc_nbufs - 1) { 1963 sc->sc_voc[voice].voccntl |= GUSMASK_LOOP_ENABLE; 1964 sc->sc_voc[voice].volcntl &= ~GUSMASK_VOICE_ROLL; 1965 playstats[playcntr].vaction = 1; 1966 } else { 1967 sc->sc_voc[voice].voccntl &= ~GUSMASK_LOOP_ENABLE; 1968 sc->sc_voc[voice].volcntl |= GUSMASK_VOICE_ROLL; 1969 playstats[playcntr].vaction = 2; 1970 } 1971 } 1972#ifdef GUSPLAYDEBUG 1973 if (gusstats) { 1974 microtime(&playstats[playcntr].tv); 1975 playstats[playcntr].curaddr = gus_get_curaddr(sc, voice); 1976 1977 playstats[playcntr].voccntl = sc->sc_voc[voice].voccntl; 1978 playstats[playcntr].volcntl = sc->sc_voc[voice].volcntl; 1979 playstats[playcntr].endaddr = sc->sc_voc[voice].end_addr; 1980 playstats[playcntr].playbuf = sc->sc_playbuf; 1981 playstats[playcntr].dmabuf = sc->sc_dmabuf; 1982 playstats[playcntr].bufcnt = sc->sc_bufcnt; 1983 playcntr = (playcntr + 1) % NDMARECS; 1984 } 1985#endif 1986 1987 /* 1988 * (re-)set voice parameters. This will reenable interrupts from this 1989 * voice. 1990 */ 1991 1992 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL); 1993 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl); 1994 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL); 1995 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].volcntl); 1996 return 0; 1997} 1998 1999/* 2000 * Send/receive data into GUS's DRAM using DMA. Called at splgus() 2001 */ 2002STATIC void 2003gusdmaout(struct gus_softc *sc, int flags, 2004 u_long gusaddr, caddr_t buffaddr, int length) 2005{ 2006 unsigned char c; 2007 bus_space_tag_t iot; 2008 bus_space_handle_t ioh2; 2009 2010 DMAPRINTF(("gusdmaout flags=%x scflags=%x\n", flags, sc->sc_flags)); 2011 c = (unsigned char) flags; 2012 iot = sc->sc_iot; 2013 ioh2 = sc->sc_ioh2; 2014 2015 sc->sc_gusaddr = gusaddr; 2016 2017 /* 2018 * If we're using a 16 bit DMA channel, we have to jump through some 2019 * extra hoops; this includes translating the DRAM address a bit 2020 */ 2021 2022 if (sc->sc_playdrq >= 4) { 2023 c |= GUSMASK_DMA_WIDTH; 2024 gusaddr = convert_to_16bit(gusaddr); 2025 } 2026 2027 /* 2028 * Add flag bits that we always set - fast DMA, enable IRQ 2029 */ 2030 2031 c |= GUSMASK_DMA_ENABLE | GUSMASK_DMA_R0 | GUSMASK_DMA_IRQ; 2032 2033 /* 2034 * Make sure the GUS _isn't_ setup for DMA 2035 */ 2036 2037 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL); 2038 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0); 2039 2040 /* 2041 * Tell the PC DMA controller to start doing DMA 2042 */ 2043 2044 sc->sc_dmaoutaddr = (u_char *) buffaddr; 2045 sc->sc_dmaoutcnt = length; 2046 isa_dmastart(sc->sc_ic, sc->sc_playdrq, buffaddr, length, 2047 NULL, DMAMODE_WRITE, BUS_DMA_NOWAIT); 2048 2049 /* 2050 * Set up DMA address - use the upper 16 bits ONLY 2051 */ 2052 2053 sc->sc_flags |= GUS_DMAOUT_ACTIVE; 2054 2055 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_START); 2056 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, (int) (gusaddr >> 4)); 2057 2058 /* 2059 * Tell the GUS to start doing DMA 2060 */ 2061 2062 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL); 2063 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, c); 2064 2065 /* 2066 * XXX If we don't finish in one second, give up... 2067 */ 2068 callout_reset(&sc->sc_dmaout_ch, hz, gus_dmaout_timeout, sc); 2069} 2070 2071/* 2072 * Start a voice playing on the GUS. Called from interrupt handler at 2073 * splgus(). 2074 */ 2075 2076STATIC void 2077gus_start_voice(struct gus_softc *sc, int voice, int intrs) 2078{ 2079 bus_space_tag_t iot; 2080 bus_space_handle_t ioh2; 2081 u_long start; 2082 u_long current; 2083 u_long end; 2084 2085 iot = sc->sc_iot; 2086 ioh2 = sc->sc_ioh2; 2087 /* 2088 * Pick all the values for the voice out of the gus_voice struct 2089 * and use those to program the voice 2090 */ 2091 2092 start = sc->sc_voc[voice].start_addr; 2093 current = sc->sc_voc[voice].current_addr; 2094 end = sc->sc_voc[voice].end_addr; 2095 2096 /* 2097 * If we're using 16 bit data, mangle the addresses a bit 2098 */ 2099 2100 if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16) { 2101 /* -1 on start so that we get onto sample boundary--other 2102 * code always sets it for 1-byte rollover protection */ 2103 start = convert_to_16bit(start-1); 2104 current = convert_to_16bit(current); 2105 end = convert_to_16bit(end); 2106 } 2107 2108 /* 2109 * Select the voice we want to use, and program the data addresses 2110 */ 2111 2112 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice); 2113 2114 SELECT_GUS_REG(iot, ioh2, GUSREG_START_ADDR_HIGH); 2115 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(start)); 2116 SELECT_GUS_REG(iot, ioh2, GUSREG_START_ADDR_LOW); 2117 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(start)); 2118 2119 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH); 2120 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(current)); 2121 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW); 2122 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(current)); 2123 2124 SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_HIGH); 2125 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(end)); 2126 SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_LOW); 2127 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(end)); 2128 2129 /* 2130 * (maybe) enable interrupts, disable voice stopping 2131 */ 2132 2133 if (intrs) { 2134 sc->sc_flags |= GUS_PLAYING; /* playing is about to start */ 2135 sc->sc_voc[voice].voccntl |= GUSMASK_VOICE_IRQ; 2136 DMAPRINTF(("gus voice playing=%x\n", sc->sc_flags)); 2137 } else 2138 sc->sc_voc[voice].voccntl &= ~GUSMASK_VOICE_IRQ; 2139 sc->sc_voc[voice].voccntl &= ~(GUSMASK_VOICE_STOPPED | 2140 GUSMASK_STOP_VOICE); 2141 2142 /* 2143 * Tell the GUS about it. Note that we're doing volume ramping here 2144 * from 0 up to the set volume to help reduce clicks. 2145 */ 2146 2147 SELECT_GUS_REG(iot, ioh2, GUSREG_START_VOLUME); 2148 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00); 2149 SELECT_GUS_REG(iot, ioh2, GUSREG_END_VOLUME); 2150 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 2151 sc->sc_voc[voice].current_volume >> 4); 2152 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME); 2153 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x00); 2154 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_RATE); 2155 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 63); 2156 2157 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL); 2158 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl); 2159 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL); 2160 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00); 2161 delay(50); 2162 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL); 2163 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl); 2164 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL); 2165 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00); 2166 2167} 2168 2169/* 2170 * Stop a given voice. called at splgus() 2171 */ 2172STATIC void 2173gus_stop_voice(struct gus_softc *sc, int voice, int intrs_too) 2174{ 2175 bus_space_tag_t iot; 2176 bus_space_handle_t ioh2; 2177 2178 iot = sc->sc_iot; 2179 ioh2 = sc->sc_ioh2; 2180 sc->sc_voc[voice].voccntl |= GUSMASK_VOICE_STOPPED | 2181 GUSMASK_STOP_VOICE; 2182 if (intrs_too) { 2183 sc->sc_voc[voice].voccntl &= ~(GUSMASK_VOICE_IRQ); 2184 /* no more DMA to do */ 2185 sc->sc_flags &= ~GUS_PLAYING; 2186 } 2187 DMAPRINTF(("gusintr voice notplaying=%x\n", sc->sc_flags)); 2188 2189 guspoke(iot, ioh2, 0L, 0); 2190 2191 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice); 2192 2193 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME); 2194 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000); 2195 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL); 2196 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl); 2197 delay(100); 2198 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME); 2199 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000); 2200 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL); 2201 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl); 2202 2203 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH); 2204 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000); 2205 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW); 2206 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000); 2207 2208} 2209 2210 2211/* 2212 * Set the volume of a given voice. Called at splgus(). 2213 */ 2214STATIC void 2215gus_set_volume(struct gus_softc *sc, int voice, int volume) 2216{ 2217 bus_space_tag_t iot; 2218 bus_space_handle_t ioh2; 2219 unsigned int gusvol; 2220 2221 iot = sc->sc_iot; 2222 ioh2 = sc->sc_ioh2; 2223 gusvol = gus_log_volumes[volume < 512 ? volume : 511]; 2224 2225 sc->sc_voc[voice].current_volume = gusvol; 2226 2227 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice); 2228 2229 SELECT_GUS_REG(iot, ioh2, GUSREG_START_VOLUME); 2230 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (unsigned char) (gusvol >> 4)); 2231 2232 SELECT_GUS_REG(iot, ioh2, GUSREG_END_VOLUME); 2233 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (unsigned char) (gusvol >> 4)); 2234 2235 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME); 2236 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, gusvol << 4); 2237 delay(500); 2238 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, gusvol << 4); 2239 2240} 2241 2242/* 2243 * Interface to the audio layer. 2244 */ 2245 2246int 2247gusmax_set_params(void *addr, int setmode, int usemode, audio_params_t *p, 2248 audio_params_t *r, stream_filter_list_t *pfil, 2249 stream_filter_list_t *rfil) 2250{ 2251 struct ad1848_isa_softc *ac; 2252 struct gus_softc *sc; 2253 int error; 2254 2255 ac = addr; 2256 sc = ac->sc_ad1848.parent; 2257 error = ad1848_set_params(ac, setmode, usemode, p, r, pfil, rfil); 2258 if (error) 2259 return error; 2260 /* 2261 * ad1848_set_params() sets a filter for 2262 * SLINEAR_LE 8, SLINEAR_BE 16, ULINEAR_LE 16, ULINEAR_BE 16. 2263 * gus_set_params() sets a filter for 2264 * ULAW, ALAW, ULINEAR_BE (16), SLINEAR_BE (16) 2265 */ 2266 error = gus_set_params(sc, setmode, usemode, p, r, pfil, rfil); 2267 return error; 2268} 2269 2270int 2271gus_set_params( 2272 void *addr, 2273 int setmode, int usemode, 2274 audio_params_t *p, audio_params_t *r, 2275 stream_filter_list_t *pfil, stream_filter_list_t *rfil) 2276{ 2277 audio_params_t hw; 2278 struct gus_softc *sc; 2279 int s; 2280 2281 sc = addr; 2282 switch (p->encoding) { 2283 case AUDIO_ENCODING_ULAW: 2284 case AUDIO_ENCODING_ALAW: 2285 case AUDIO_ENCODING_SLINEAR_LE: 2286 case AUDIO_ENCODING_ULINEAR_LE: 2287 case AUDIO_ENCODING_SLINEAR_BE: 2288 case AUDIO_ENCODING_ULINEAR_BE: 2289 break; 2290 default: 2291 return EINVAL; 2292 } 2293 2294 s = splaudio(); 2295 2296 if (p->precision == 8) { 2297 sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~GUSMASK_DATA_SIZE16; 2298 sc->sc_voc[GUS_VOICE_RIGHT].voccntl &= ~GUSMASK_DATA_SIZE16; 2299 } else { 2300 sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_DATA_SIZE16; 2301 sc->sc_voc[GUS_VOICE_RIGHT].voccntl |= GUSMASK_DATA_SIZE16; 2302 } 2303 2304 sc->sc_encoding = p->encoding; 2305 sc->sc_precision = p->precision; 2306 sc->sc_channels = p->channels; 2307 2308 splx(s); 2309 2310 if (p->sample_rate > gus_max_frequency[sc->sc_voices - GUS_MIN_VOICES]) 2311 p->sample_rate = gus_max_frequency[sc->sc_voices - GUS_MIN_VOICES]; 2312 if (setmode & AUMODE_RECORD) 2313 sc->sc_irate = p->sample_rate; 2314 if (setmode & AUMODE_PLAY) 2315 sc->sc_orate = p->sample_rate; 2316 2317 hw = *p; 2318 /* clear req_size before setting a filter to avoid confliction 2319 * in gusmax_set_params() */ 2320 switch (p->encoding) { 2321 case AUDIO_ENCODING_ULAW: 2322 hw.encoding = AUDIO_ENCODING_ULINEAR_LE; 2323 pfil->req_size = rfil->req_size = 0; 2324 pfil->append(pfil, mulaw_to_linear8, &hw); 2325 rfil->append(rfil, linear8_to_mulaw, &hw); 2326 break; 2327 case AUDIO_ENCODING_ALAW: 2328 hw.encoding = AUDIO_ENCODING_ULINEAR_LE; 2329 pfil->req_size = rfil->req_size = 0; 2330 pfil->append(pfil, alaw_to_linear8, &hw); 2331 rfil->append(rfil, linear8_to_alaw, &hw); 2332 break; 2333 case AUDIO_ENCODING_ULINEAR_BE: 2334 hw.encoding = AUDIO_ENCODING_ULINEAR_LE; 2335 pfil->req_size = rfil->req_size = 0; 2336 pfil->append(pfil, swap_bytes, &hw); 2337 rfil->append(rfil, swap_bytes, &hw); 2338 break; 2339 case AUDIO_ENCODING_SLINEAR_BE: 2340 hw.encoding = AUDIO_ENCODING_SLINEAR_LE; 2341 pfil->req_size = rfil->req_size = 0; 2342 pfil->append(pfil, swap_bytes, &hw); 2343 rfil->append(rfil, swap_bytes, &hw); 2344 break; 2345 } 2346 2347 return 0; 2348} 2349 2350/* 2351 * Interface to the audio layer - set the blocksize to the correct number 2352 * of units 2353 */ 2354 2355int 2356gusmax_round_blocksize(void * addr, int blocksize, 2357 int mode, const audio_params_t *param) 2358{ 2359 struct ad1848_isa_softc *ac; 2360 struct gus_softc *sc; 2361 2362 ac = addr; 2363 sc = ac->sc_ad1848.parent; 2364/* blocksize = ad1848_round_blocksize(ac, blocksize, mode, param);*/ 2365 return gus_round_blocksize(sc, blocksize, mode, param); 2366} 2367 2368int 2369gus_round_blocksize(void * addr, int blocksize, 2370 int mode, const audio_params_t *param) 2371{ 2372 struct gus_softc *sc; 2373 2374 DPRINTF(("gus_round_blocksize called\n")); 2375 sc = addr; 2376 2377 if ((sc->sc_encoding == AUDIO_ENCODING_ULAW || 2378 sc->sc_encoding == AUDIO_ENCODING_ALAW) && blocksize > 32768) 2379 blocksize = 32768; 2380 else if (blocksize > 65536) 2381 blocksize = 65536; 2382 2383 if ((blocksize % GUS_BUFFER_MULTIPLE) != 0) 2384 blocksize = (blocksize / GUS_BUFFER_MULTIPLE + 1) * 2385 GUS_BUFFER_MULTIPLE; 2386 2387 /* set up temporary buffer to hold the deinterleave, if necessary 2388 for stereo output */ 2389 if (sc->sc_deintr_buf) { 2390 FREE(sc->sc_deintr_buf, M_DEVBUF); 2391 sc->sc_deintr_buf = NULL; 2392 } 2393 MALLOC(sc->sc_deintr_buf, void *, blocksize>>1, M_DEVBUF, M_WAITOK); 2394 2395 sc->sc_blocksize = blocksize; 2396 /* multi-buffering not quite working yet. */ 2397 sc->sc_nbufs = /*GUS_MEM_FOR_BUFFERS / blocksize*/ 2; 2398 2399 gus_set_chan_addrs(sc); 2400 2401 return blocksize; 2402} 2403 2404int 2405gus_get_out_gain(caddr_t addr) 2406{ 2407 struct gus_softc *sc; 2408 2409 DPRINTF(("gus_get_out_gain called\n")); 2410 sc = (struct gus_softc *) addr; 2411 return sc->sc_ogain / 2; 2412} 2413 2414STATIC inline void 2415gus_set_voices(struct gus_softc *sc, int voices) 2416{ 2417 bus_space_tag_t iot; 2418 bus_space_handle_t ioh2; 2419 2420 iot = sc->sc_iot; 2421 ioh2 = sc->sc_ioh2; 2422 /* 2423 * Select the active number of voices 2424 */ 2425 SELECT_GUS_REG(iot, ioh2, GUSREG_ACTIVE_VOICES); 2426 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (voices-1) | 0xc0); 2427 2428 sc->sc_voices = voices; 2429} 2430 2431/* 2432 * Actually set the settings of various values on the card 2433 */ 2434int 2435gusmax_commit_settings(void * addr) 2436{ 2437 struct ad1848_isa_softc *ac; 2438 struct gus_softc *sc; 2439 int error; 2440 2441 ac = addr; 2442 sc = ac->sc_ad1848.parent; 2443 error = ad1848_commit_settings(ac); 2444 if (error) 2445 return error; 2446 return gus_commit_settings(sc); 2447} 2448 2449/* 2450 * Commit the settings. Called at normal IPL. 2451 */ 2452int 2453gus_commit_settings(void *addr) 2454{ 2455 struct gus_softc *sc; 2456 int s; 2457 2458 sc = addr; 2459 DPRINTF(("gus_commit_settings called (gain = %d)\n",sc->sc_ogain)); 2460 2461 2462 s = splgus(); 2463 2464 gus_set_recrate(sc, sc->sc_irate); 2465 gus_set_volume(sc, GUS_VOICE_LEFT, sc->sc_ogain); 2466 gus_set_volume(sc, GUS_VOICE_RIGHT, sc->sc_ogain); 2467 gus_set_samprate(sc, GUS_VOICE_LEFT, sc->sc_orate); 2468 gus_set_samprate(sc, GUS_VOICE_RIGHT, sc->sc_orate); 2469 splx(s); 2470 gus_set_chan_addrs(sc); 2471 2472 return 0; 2473} 2474 2475STATIC void 2476gus_set_chan_addrs(struct gus_softc *sc) 2477{ 2478 2479 /* 2480 * We use sc_nbufs * blocksize bytes of storage in the on-board GUS 2481 * ram. 2482 * For mono, each of the sc_nbufs buffers is DMA'd to in one chunk, 2483 * and both left & right channels play the same buffer. 2484 * 2485 * For stereo, each channel gets a contiguous half of the memory, 2486 * and each has sc_nbufs buffers of size blocksize/2. 2487 * Stereo data are deinterleaved in main memory before the DMA out 2488 * routines are called to queue the output. 2489 * 2490 * The blocksize per channel is kept in sc_chanblocksize. 2491 */ 2492 if (sc->sc_channels == 2) 2493 sc->sc_chanblocksize = sc->sc_blocksize/2; 2494 else 2495 sc->sc_chanblocksize = sc->sc_blocksize; 2496 2497 sc->sc_voc[GUS_VOICE_LEFT].start_addr = GUS_MEM_OFFSET - 1; 2498 sc->sc_voc[GUS_VOICE_RIGHT].start_addr = 2499 (gus_dostereo && sc->sc_channels == 2 ? GUS_LEFT_RIGHT_OFFSET : 0) 2500 + GUS_MEM_OFFSET - 1; 2501 sc->sc_voc[GUS_VOICE_RIGHT].current_addr = 2502 sc->sc_voc[GUS_VOICE_RIGHT].start_addr + 1; 2503 sc->sc_voc[GUS_VOICE_RIGHT].end_addr = 2504 sc->sc_voc[GUS_VOICE_RIGHT].start_addr + 2505 sc->sc_nbufs * sc->sc_chanblocksize; 2506 2507} 2508 2509/* 2510 * Set the sample rate of the given voice. Called at splgus(). 2511 */ 2512STATIC void 2513gus_set_samprate(struct gus_softc *sc, int voice, int freq) 2514{ 2515 bus_space_tag_t iot; 2516 bus_space_handle_t ioh2; 2517 unsigned int fc; 2518 u_long temp, f; 2519 2520 iot = sc->sc_iot; 2521 ioh2 = sc->sc_ioh2; 2522 f = (u_long) freq; 2523 /* 2524 * calculate fc based on the number of active voices; 2525 * we need to use longs to preserve enough bits 2526 */ 2527 2528 temp = (u_long) gus_max_frequency[sc->sc_voices-GUS_MIN_VOICES]; 2529 2530 fc = (unsigned int)(((f << 9L) + (temp >> 1L)) / temp); 2531 fc <<= 1; 2532 2533 /* 2534 * Program the voice frequency, and set it in the voice data record 2535 */ 2536 2537 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice); 2538 SELECT_GUS_REG(iot, ioh2, GUSREG_FREQ_CONTROL); 2539 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, fc); 2540 2541 sc->sc_voc[voice].rate = freq; 2542 2543} 2544 2545/* 2546 * Set the sample rate of the recording frequency. Formula is from the GUS 2547 * SDK. Called at splgus(). 2548 */ 2549STATIC void 2550gus_set_recrate(struct gus_softc *sc, u_long rate) 2551{ 2552 bus_space_tag_t iot; 2553 bus_space_handle_t ioh2; 2554 u_char realrate; 2555 2556 DPRINTF(("gus_set_recrate %lu\n", rate)); 2557 iot = sc->sc_iot; 2558 ioh2 = sc->sc_ioh2; 2559 2560#if 0 2561 realrate = 9878400/(16*(rate+2)); /* formula from GUS docs */ 2562#endif 2563 realrate = (9878400 >> 4)/rate - 2; /* formula from code, sigh. */ 2564 2565 SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_FREQ); 2566 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, realrate); 2567} 2568 2569/* 2570 * Interface to the audio layer - turn the output on or off. Note that some 2571 * of these bits are flipped in the register 2572 */ 2573 2574int 2575gusmax_speaker_ctl(void *addr, int newstate) 2576{ 2577 struct ad1848_isa_softc *sc; 2578 2579 sc = addr; 2580 return gus_speaker_ctl(sc->sc_ad1848.parent, newstate); 2581} 2582 2583int 2584gus_speaker_ctl(void *addr, int newstate) 2585{ 2586 struct gus_softc *sc; 2587 bus_space_tag_t iot; 2588 bus_space_handle_t ioh1; 2589 2590 sc = (struct gus_softc *) addr; 2591 iot = sc->sc_iot; 2592 ioh1 = sc->sc_ioh1; 2593 /* Line out bit is flipped: 0 enables, 1 disables */ 2594 if ((newstate == SPKR_ON) && 2595 (sc->sc_mixcontrol & GUSMASK_LINE_OUT)) { 2596 sc->sc_mixcontrol &= ~GUSMASK_LINE_OUT; 2597 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol); 2598 } 2599 if ((newstate == SPKR_OFF) && 2600 (sc->sc_mixcontrol & GUSMASK_LINE_OUT) == 0) { 2601 sc->sc_mixcontrol |= GUSMASK_LINE_OUT; 2602 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol); 2603 } 2604 2605 return 0; 2606} 2607 2608STATIC int 2609gus_linein_ctl(void *addr, int newstate) 2610{ 2611 struct gus_softc *sc; 2612 bus_space_tag_t iot; 2613 bus_space_handle_t ioh1; 2614 2615 sc = (struct gus_softc *) addr; 2616 iot = sc->sc_iot; 2617 ioh1 = sc->sc_ioh1; 2618 /* Line in bit is flipped: 0 enables, 1 disables */ 2619 if ((newstate == SPKR_ON) && 2620 (sc->sc_mixcontrol & GUSMASK_LINE_IN)) { 2621 sc->sc_mixcontrol &= ~GUSMASK_LINE_IN; 2622 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol); 2623 } 2624 if ((newstate == SPKR_OFF) && 2625 (sc->sc_mixcontrol & GUSMASK_LINE_IN) == 0) { 2626 sc->sc_mixcontrol |= GUSMASK_LINE_IN; 2627 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol); 2628 } 2629 2630 return 0; 2631} 2632 2633STATIC int 2634gus_mic_ctl(void *addr, int newstate) 2635{ 2636 struct gus_softc *sc; 2637 bus_space_tag_t iot; 2638 bus_space_handle_t ioh1; 2639 2640 sc = (struct gus_softc *) addr; 2641 iot = sc->sc_iot; 2642 ioh1 = sc->sc_ioh1; 2643 /* Mic bit is normal: 1 enables, 0 disables */ 2644 if ((newstate == SPKR_ON) && 2645 (sc->sc_mixcontrol & GUSMASK_MIC_IN) == 0) { 2646 sc->sc_mixcontrol |= GUSMASK_MIC_IN; 2647 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol); 2648 } 2649 if ((newstate == SPKR_OFF) && 2650 (sc->sc_mixcontrol & GUSMASK_MIC_IN)) { 2651 sc->sc_mixcontrol &= ~GUSMASK_MIC_IN; 2652 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol); 2653 } 2654 2655 return 0; 2656} 2657 2658/* 2659 * Set the end address of a give voice. Called at splgus() 2660 */ 2661STATIC void 2662gus_set_endaddr(struct gus_softc *sc, int voice, u_long addr) 2663{ 2664 bus_space_tag_t iot; 2665 bus_space_handle_t ioh2; 2666 2667 iot = sc->sc_iot; 2668 ioh2 = sc->sc_ioh2; 2669 sc->sc_voc[voice].end_addr = addr; 2670 2671 if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16) 2672 addr = convert_to_16bit(addr); 2673 2674 SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_HIGH); 2675 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(addr)); 2676 SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_LOW); 2677 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(addr)); 2678 2679} 2680 2681#ifdef GUSPLAYDEBUG 2682/* 2683 * Set current address. called at splgus() 2684 */ 2685STATIC void 2686gus_set_curaddr(struct gus_softc *sc, int voice, u_long addr) 2687{ 2688 bus_space_tag_t iot; 2689 bus_space_handle_t ioh2; 2690 2691 iot = sc->sc_iot; 2692 ioh2 = sc->sc_ioh2; 2693 sc->sc_voc[voice].current_addr = addr; 2694 2695 if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16) 2696 addr = convert_to_16bit(addr); 2697 2698 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice); 2699 2700 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH); 2701 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(addr)); 2702 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW); 2703 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(addr)); 2704 2705} 2706 2707/* 2708 * Get current GUS playback address. Called at splgus(). 2709 */ 2710STATIC u_long 2711gus_get_curaddr(struct gus_softc *sc, int voice) 2712{ 2713 bus_space_tag_t iot; 2714 bus_space_handle_t ioh2; 2715 u_long addr; 2716 2717 iot = sc->sc_iot; 2718 ioh2 = sc->sc_ioh2; 2719 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice); 2720 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH|GUSREG_READ); 2721 addr = (bus_space_read_2(iot, ioh2, GUS_DATA_LOW) & 0x1fff) << 7; 2722 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW|GUSREG_READ); 2723 addr |= (bus_space_read_2(iot, ioh2, GUS_DATA_LOW) >> 9L) & 0x7f; 2724 2725 if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16) 2726 addr = (addr & 0xc0000) | ((addr & 0x1ffff) << 1); /* undo 16-bit change */ 2727 DPRINTF(("gus voice %d curaddr %ld end_addr %ld\n", 2728 voice, addr, sc->sc_voc[voice].end_addr)); 2729 /* XXX sanity check the address? */ 2730 2731 return addr; 2732} 2733#endif 2734 2735/* 2736 * Convert an address value to a "16 bit" value - why this is necessary I 2737 * have NO idea 2738 */ 2739 2740STATIC u_long 2741convert_to_16bit(u_long address) 2742{ 2743 u_long old_address; 2744 2745 old_address = address; 2746 address >>= 1; 2747 address &= 0x0001ffffL; 2748 address |= (old_address & 0x000c0000L); 2749 2750 return address; 2751} 2752 2753/* 2754 * Write a value into the GUS's DRAM 2755 */ 2756STATIC void 2757guspoke(bus_space_tag_t iot, bus_space_handle_t ioh2, 2758 long address, unsigned char value) 2759{ 2760 2761 /* 2762 * Select the DRAM address 2763 */ 2764 2765 SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_LOW); 2766 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, (unsigned int) (address & 0xffff)); 2767 SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_HIGH); 2768 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (unsigned char) ((address >> 16) & 0xff)); 2769 2770 /* 2771 * Actually write the data 2772 */ 2773 2774 bus_space_write_1(iot, ioh2, GUS_DRAM_DATA, value); 2775} 2776 2777/* 2778 * Read a value from the GUS's DRAM 2779 */ 2780STATIC unsigned char 2781guspeek(bus_space_tag_t iot, bus_space_handle_t ioh2, u_long address) 2782{ 2783 2784 /* 2785 * Select the DRAM address 2786 */ 2787 2788 SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_LOW); 2789 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, (unsigned int) (address & 0xffff)); 2790 SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_HIGH); 2791 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (unsigned char) ((address >> 16) & 0xff)); 2792 2793 /* 2794 * Read in the data from the board 2795 */ 2796 2797 return (unsigned char) bus_space_read_1(iot, ioh2, GUS_DRAM_DATA); 2798} 2799 2800/* 2801 * Reset the Gravis UltraSound card, completely 2802 */ 2803STATIC void 2804gusreset(struct gus_softc *sc, int voices) 2805{ 2806 bus_space_tag_t iot; 2807 bus_space_handle_t ioh1; 2808 bus_space_handle_t ioh2; 2809 bus_space_handle_t ioh4; 2810 int i,s; 2811 2812 iot = sc->sc_iot; 2813 ioh1 = sc->sc_ioh1; 2814 ioh2 = sc->sc_ioh2; 2815 ioh4 = sc->sc_ioh4; 2816 s = splgus(); 2817 2818 /* 2819 * Reset the GF1 chip 2820 */ 2821 2822 SELECT_GUS_REG(iot, ioh2, GUSREG_RESET); 2823 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00); 2824 2825 delay(500); 2826 2827 /* 2828 * Release reset 2829 */ 2830 2831 SELECT_GUS_REG(iot, ioh2, GUSREG_RESET); 2832 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, GUSMASK_MASTER_RESET); 2833 2834 delay(500); 2835 2836 /* 2837 * Reset MIDI port as well 2838 */ 2839 2840 bus_space_write_1(iot, ioh4, GUS_MIDI_CONTROL, MIDI_RESET); 2841 2842 delay(500); 2843 2844 bus_space_write_1(iot, ioh4, GUS_MIDI_CONTROL, 0x00); 2845 2846 /* 2847 * Clear interrupts 2848 */ 2849 2850 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL); 2851 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00); 2852 SELECT_GUS_REG(iot, ioh2, GUSREG_TIMER_CONTROL); 2853 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00); 2854 SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL); 2855 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00); 2856 2857 gus_set_voices(sc, voices); 2858 2859 bus_space_read_1(iot, ioh1, GUS_IRQ_STATUS); 2860 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL); 2861 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH); 2862 SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL); 2863 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH); 2864 SELECT_GUS_REG(iot, ioh2, GUSREG_IRQ_STATUS); 2865 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH); 2866 2867 /* 2868 * Reset voice specific information 2869 */ 2870 2871 for(i = 0; i < voices; i++) { 2872 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) i); 2873 2874 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL); 2875 2876 sc->sc_voc[i].voccntl = GUSMASK_VOICE_STOPPED | 2877 GUSMASK_STOP_VOICE; 2878 2879 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[i].voccntl); 2880 2881 sc->sc_voc[i].volcntl = GUSMASK_VOLUME_STOPPED | 2882 GUSMASK_STOP_VOLUME; 2883 2884 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL); 2885 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[i].volcntl); 2886 2887 delay(100); 2888 2889 gus_set_samprate(sc, i, 8000); 2890 SELECT_GUS_REG(iot, ioh2, GUSREG_START_ADDR_HIGH); 2891 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000); 2892 SELECT_GUS_REG(iot, ioh2, GUSREG_START_ADDR_LOW); 2893 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000); 2894 SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_HIGH); 2895 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000); 2896 SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_LOW); 2897 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000); 2898 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_RATE); 2899 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x01); 2900 SELECT_GUS_REG(iot, ioh2, GUSREG_START_VOLUME); 2901 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x10); 2902 SELECT_GUS_REG(iot, ioh2, GUSREG_END_VOLUME); 2903 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0xe0); 2904 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME); 2905 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000); 2906 2907 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH); 2908 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000); 2909 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW); 2910 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000); 2911 SELECT_GUS_REG(iot, ioh2, GUSREG_PAN_POS); 2912 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x07); 2913 } 2914 2915 /* 2916 * Clear out any pending IRQs 2917 */ 2918 2919 bus_space_read_1(iot, ioh1, GUS_IRQ_STATUS); 2920 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL); 2921 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH); 2922 SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL); 2923 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH); 2924 SELECT_GUS_REG(iot, ioh2, GUSREG_IRQ_STATUS); 2925 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH); 2926 2927 SELECT_GUS_REG(iot, ioh2, GUSREG_RESET); 2928 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, GUSMASK_MASTER_RESET | GUSMASK_DAC_ENABLE | 2929 GUSMASK_IRQ_ENABLE); 2930 2931 splx(s); 2932} 2933 2934 2935STATIC int 2936gus_init_cs4231(struct gus_softc *sc) 2937{ 2938 bus_space_tag_t iot; 2939 bus_space_handle_t ioh1; 2940 int port; 2941 u_char ctrl; 2942 2943 iot = sc->sc_iot; 2944 ioh1 = sc->sc_ioh1; 2945 port = sc->sc_iobase; 2946 ctrl = (port & 0xf0) >> 4; /* set port address middle nibble */ 2947 /* 2948 * The codec is a bit weird--swapped DMA channels. 2949 */ 2950 ctrl |= GUS_MAX_CODEC_ENABLE; 2951 if (sc->sc_playdrq >= 4) 2952 ctrl |= GUS_MAX_RECCHAN16; 2953 if (sc->sc_recdrq >= 4) 2954 ctrl |= GUS_MAX_PLAYCHAN16; 2955 2956 bus_space_write_1(iot, ioh1, GUS_MAX_CTRL, ctrl); 2957 2958 sc->sc_codec.sc_ad1848.sc_iot = sc->sc_iot; 2959 sc->sc_codec.sc_iobase = port+GUS_MAX_CODEC_BASE; 2960 2961 if (ad1848_isa_mapprobe(&sc->sc_codec, sc->sc_codec.sc_iobase) == 0) { 2962 sc->sc_flags &= ~GUS_CODEC_INSTALLED; 2963 return 0; 2964 } else { 2965 struct ad1848_volume vol = {AUDIO_MAX_GAIN, AUDIO_MAX_GAIN}; 2966 sc->sc_flags |= GUS_CODEC_INSTALLED; 2967 sc->sc_codec.sc_ad1848.parent = sc; 2968 sc->sc_codec.sc_playdrq = sc->sc_recdrq; 2969 sc->sc_codec.sc_play_maxsize = sc->sc_req_maxsize; 2970 sc->sc_codec.sc_recdrq = sc->sc_playdrq; 2971 sc->sc_codec.sc_rec_maxsize = sc->sc_play_maxsize; 2972 /* enable line in and mic in the GUS mixer; the codec chip 2973 will do the real mixing for them. */ 2974 sc->sc_mixcontrol &= ~GUSMASK_LINE_IN; /* 0 enables. */ 2975 sc->sc_mixcontrol |= GUSMASK_MIC_IN; /* 1 enables. */ 2976 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol); 2977 2978 ad1848_isa_attach(&sc->sc_codec); 2979 /* turn on pre-MUX microphone gain. */ 2980 ad1848_set_mic_gain(&sc->sc_codec.sc_ad1848, &vol); 2981 2982 return 1; 2983 } 2984} 2985 2986 2987/* 2988 * Return info about the audio device, for the AUDIO_GETINFO ioctl 2989 */ 2990int 2991gus_getdev(void * addr, struct audio_device *dev) 2992{ 2993 2994 *dev = gus_device; 2995 return 0; 2996} 2997 2998/* 2999 * stubs (XXX) 3000 */ 3001 3002int 3003gus_set_in_gain(caddr_t addr, u_int gain, u_char balance) 3004{ 3005 3006 DPRINTF(("gus_set_in_gain called\n")); 3007 return 0; 3008} 3009 3010int 3011gus_get_in_gain(caddr_t addr) 3012{ 3013 3014 DPRINTF(("gus_get_in_gain called\n")); 3015 return 0; 3016} 3017 3018int 3019gusmax_dma_input(void *addr, void *buf, int size, 3020 void (*callback)(void *), void *arg) 3021{ 3022 struct ad1848_isa_softc *sc; 3023 3024 sc = addr; 3025 return gus_dma_input(sc->sc_ad1848.parent, buf, size, callback, arg); 3026} 3027 3028/* 3029 * Start sampling the input source into the requested DMA buffer. 3030 * Called at splgus(), either from top-half or from interrupt handler. 3031 */ 3032int 3033gus_dma_input(void *addr, void *buf, int size, 3034 void (*callback)(void *), void *arg) 3035{ 3036 struct gus_softc *sc; 3037 bus_space_tag_t iot; 3038 bus_space_handle_t ioh2; 3039 u_char dmac; 3040 3041 DMAPRINTF(("gus_dma_input called\n")); 3042 sc = addr; 3043 iot = sc->sc_iot; 3044 ioh2 = sc->sc_ioh2; 3045 3046 /* 3047 * Sample SIZE bytes of data from the card, into buffer at BUF. 3048 */ 3049 3050 if (sc->sc_precision == 16) 3051 return EINVAL; /* XXX */ 3052 3053 /* set DMA modes */ 3054 dmac = GUSMASK_SAMPLE_IRQ|GUSMASK_SAMPLE_START; 3055 if (sc->sc_recdrq >= 4) 3056 dmac |= GUSMASK_SAMPLE_DATA16; 3057 if (sc->sc_encoding == AUDIO_ENCODING_ULAW || 3058 sc->sc_encoding == AUDIO_ENCODING_ALAW || 3059 sc->sc_encoding == AUDIO_ENCODING_ULINEAR_LE || 3060 sc->sc_encoding == AUDIO_ENCODING_ULINEAR_BE) 3061 dmac |= GUSMASK_SAMPLE_INVBIT; 3062 if (sc->sc_channels == 2) 3063 dmac |= GUSMASK_SAMPLE_STEREO; 3064 isa_dmastart(sc->sc_ic, sc->sc_recdrq, buf, size, 3065 NULL, DMAMODE_READ, BUS_DMA_NOWAIT); 3066 3067 DMAPRINTF(("gus_dma_input isa_dmastarted\n")); 3068 sc->sc_flags |= GUS_DMAIN_ACTIVE; 3069 sc->sc_dmainintr = callback; 3070 sc->sc_inarg = arg; 3071 sc->sc_dmaincnt = size; 3072 sc->sc_dmainaddr = buf; 3073 3074 SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL); 3075 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, dmac); /* Go! */ 3076 3077 3078 DMAPRINTF(("gus_dma_input returning\n")); 3079 3080 return 0; 3081} 3082 3083STATIC int 3084gus_dmain_intr(struct gus_softc *sc) 3085{ 3086 void (*callback)(void *); 3087 void *arg; 3088 3089 DMAPRINTF(("gus_dmain_intr called\n")); 3090 if (sc->sc_dmainintr) { 3091 isa_dmadone(sc->sc_ic, sc->sc_recdrq); 3092 callback = sc->sc_dmainintr; 3093 arg = sc->sc_inarg; 3094 3095 sc->sc_dmainaddr = 0; 3096 sc->sc_dmaincnt = 0; 3097 sc->sc_dmainintr = 0; 3098 sc->sc_inarg = 0; 3099 3100 sc->sc_flags &= ~GUS_DMAIN_ACTIVE; 3101 DMAPRINTF(("calling dmain_intr callback %p(%p)\n", callback, arg)); 3102 (*callback)(arg); 3103 return 1; 3104 } else { 3105 DMAPRINTF(("gus_dmain_intr false?\n")); 3106 return 0; /* XXX ??? */ 3107 } 3108} 3109 3110int 3111gusmax_halt_out_dma(void *addr) 3112{ 3113 struct ad1848_isa_softc *sc; 3114 3115 sc = addr; 3116 return gus_halt_out_dma(sc->sc_ad1848.parent); 3117} 3118 3119 3120int 3121gusmax_halt_in_dma(void *addr) 3122{ 3123 struct ad1848_isa_softc *sc; 3124 3125 sc = addr; 3126 return gus_halt_in_dma(sc->sc_ad1848.parent); 3127} 3128 3129/* 3130 * Stop any DMA output. Called at splgus(). 3131 */ 3132int 3133gus_halt_out_dma(void *addr) 3134{ 3135 struct gus_softc *sc; 3136 bus_space_tag_t iot; 3137 bus_space_handle_t ioh2; 3138 3139 DMAPRINTF(("gus_halt_out_dma called\n")); 3140 sc = addr; 3141 iot = sc->sc_iot; 3142 ioh2 = sc->sc_ioh2; 3143 /* 3144 * Make sure the GUS _isn't_ setup for DMA 3145 */ 3146 3147 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL); 3148 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0); 3149 3150 callout_stop(&sc->sc_dmaout_ch); 3151 isa_dmaabort(sc->sc_ic, sc->sc_playdrq); 3152 sc->sc_flags &= ~(GUS_DMAOUT_ACTIVE|GUS_LOCKED); 3153 sc->sc_dmaoutintr = 0; 3154 sc->sc_outarg = 0; 3155 sc->sc_dmaoutaddr = 0; 3156 sc->sc_dmaoutcnt = 0; 3157 sc->sc_dmabuf = 0; 3158 sc->sc_bufcnt = 0; 3159 sc->sc_playbuf = -1; 3160 /* also stop playing */ 3161 gus_stop_voice(sc, GUS_VOICE_LEFT, 1); 3162 gus_stop_voice(sc, GUS_VOICE_RIGHT, 0); 3163 3164 return 0; 3165} 3166 3167/* 3168 * Stop any DMA output. Called at splgus(). 3169 */ 3170int 3171gus_halt_in_dma(void *addr) 3172{ 3173 struct gus_softc *sc; 3174 bus_space_tag_t iot; 3175 bus_space_handle_t ioh2; 3176 3177 DMAPRINTF(("gus_halt_in_dma called\n")); 3178 sc = addr; 3179 iot = sc->sc_iot; 3180 ioh2 = sc->sc_ioh2; 3181 3182 /* 3183 * Make sure the GUS _isn't_ setup for DMA 3184 */ 3185 3186 SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL); 3187 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 3188 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH) 3189 & ~(GUSMASK_SAMPLE_START|GUSMASK_SAMPLE_IRQ)); 3190 3191 isa_dmaabort(sc->sc_ic, sc->sc_recdrq); 3192 sc->sc_flags &= ~GUS_DMAIN_ACTIVE; 3193 sc->sc_dmainintr = 0; 3194 sc->sc_inarg = 0; 3195 sc->sc_dmainaddr = 0; 3196 sc->sc_dmaincnt = 0; 3197 3198 return 0; 3199} 3200 3201 3202static ad1848_devmap_t gusmapping[] = { 3203 { GUSMAX_DAC_LVL, AD1848_KIND_LVL, AD1848_AUX1_CHANNEL }, 3204 { GUSMAX_LINE_IN_LVL, AD1848_KIND_LVL, AD1848_LINE_CHANNEL }, 3205 { GUSMAX_MONO_LVL, AD1848_KIND_LVL, AD1848_MONO_CHANNEL }, 3206 { GUSMAX_CD_LVL, AD1848_KIND_LVL, AD1848_AUX2_CHANNEL }, 3207 { GUSMAX_MONITOR_LVL, AD1848_KIND_LVL, AD1848_MONITOR_CHANNEL }, 3208 { GUSMAX_OUT_LVL, AD1848_KIND_LVL, AD1848_DAC_CHANNEL }, 3209 { GUSMAX_DAC_MUTE, AD1848_KIND_MUTE, AD1848_AUX1_CHANNEL }, 3210 { GUSMAX_LINE_IN_MUTE, AD1848_KIND_MUTE, AD1848_LINE_CHANNEL }, 3211 { GUSMAX_MONO_MUTE, AD1848_KIND_MUTE, AD1848_MONO_CHANNEL }, 3212 { GUSMAX_CD_MUTE, AD1848_KIND_MUTE, AD1848_AUX2_CHANNEL }, 3213 { GUSMAX_MONITOR_MUTE, AD1848_KIND_MUTE, AD1848_MONITOR_CHANNEL }, 3214 { GUSMAX_REC_LVL, AD1848_KIND_RECORDGAIN, -1 }, 3215 { GUSMAX_RECORD_SOURCE, AD1848_KIND_RECORDSOURCE, -1 } 3216}; 3217 3218static int nummap = sizeof(gusmapping) / sizeof(gusmapping[0]); 3219 3220STATIC int 3221gusmax_mixer_get_port(void *addr, mixer_ctrl_t *cp) 3222{ 3223 struct ad1848_isa_softc *ac; 3224 struct gus_softc *sc; 3225 struct ad1848_volume vol; 3226 int error; 3227 3228 ac = addr; 3229 sc = ac->sc_ad1848.parent; 3230 error = ad1848_mixer_get_port(&ac->sc_ad1848, gusmapping, nummap, cp); 3231 if (error != ENXIO) 3232 return error; 3233 3234 error = EINVAL; 3235 3236 switch (cp->dev) { 3237 case GUSMAX_SPEAKER_LVL: /* fake speaker for mute naming */ 3238 if (cp->type == AUDIO_MIXER_VALUE) { 3239 if (sc->sc_mixcontrol & GUSMASK_LINE_OUT) 3240 vol.left = vol.right = AUDIO_MAX_GAIN; 3241 else 3242 vol.left = vol.right = AUDIO_MIN_GAIN; 3243 error = 0; 3244 ad1848_from_vol(cp, &vol); 3245 } 3246 break; 3247 3248 case GUSMAX_SPEAKER_MUTE: 3249 if (cp->type == AUDIO_MIXER_ENUM) { 3250 cp->un.ord = sc->sc_mixcontrol & GUSMASK_LINE_OUT ? 1 : 0; 3251 error = 0; 3252 } 3253 break; 3254 default: 3255 error = ENXIO; 3256 break; 3257 } 3258 3259 return error; 3260} 3261 3262STATIC int 3263gus_mixer_get_port(void *addr, mixer_ctrl_t *cp) 3264{ 3265 struct gus_softc *sc; 3266 struct ics2101_softc *ic; 3267 struct ad1848_volume vol; 3268 int error; 3269 3270 DPRINTF(("gus_mixer_get_port: dev=%d type=%d\n", cp->dev, cp->type)); 3271 sc = addr; 3272 ic = &sc->sc_mixer; 3273 error = EINVAL; 3274 3275 if (!HAS_MIXER(sc) && cp->dev > GUSICS_MASTER_MUTE) 3276 return ENXIO; 3277 3278 switch (cp->dev) { 3279 3280 case GUSICS_MIC_IN_MUTE: /* Microphone */ 3281 if (cp->type == AUDIO_MIXER_ENUM) { 3282 if (HAS_MIXER(sc)) 3283 cp->un.ord = ic->sc_mute[GUSMIX_CHAN_MIC][ICSMIX_LEFT]; 3284 else 3285 cp->un.ord = 3286 sc->sc_mixcontrol & GUSMASK_MIC_IN ? 0 : 1; 3287 error = 0; 3288 } 3289 break; 3290 3291 case GUSICS_LINE_IN_MUTE: 3292 if (cp->type == AUDIO_MIXER_ENUM) { 3293 if (HAS_MIXER(sc)) 3294 cp->un.ord = ic->sc_mute[GUSMIX_CHAN_LINE][ICSMIX_LEFT]; 3295 else 3296 cp->un.ord = 3297 sc->sc_mixcontrol & GUSMASK_LINE_IN ? 1 : 0; 3298 error = 0; 3299 } 3300 break; 3301 3302 case GUSICS_MASTER_MUTE: 3303 if (cp->type == AUDIO_MIXER_ENUM) { 3304 if (HAS_MIXER(sc)) 3305 cp->un.ord = ic->sc_mute[GUSMIX_CHAN_MASTER][ICSMIX_LEFT]; 3306 else 3307 cp->un.ord = 3308 sc->sc_mixcontrol & GUSMASK_LINE_OUT ? 1 : 0; 3309 error = 0; 3310 } 3311 break; 3312 3313 case GUSICS_DAC_MUTE: 3314 if (cp->type == AUDIO_MIXER_ENUM) { 3315 cp->un.ord = ic->sc_mute[GUSMIX_CHAN_DAC][ICSMIX_LEFT]; 3316 error = 0; 3317 } 3318 break; 3319 3320 case GUSICS_CD_MUTE: 3321 if (cp->type == AUDIO_MIXER_ENUM) { 3322 cp->un.ord = ic->sc_mute[GUSMIX_CHAN_CD][ICSMIX_LEFT]; 3323 error = 0; 3324 } 3325 break; 3326 3327 case GUSICS_MASTER_LVL: 3328 if (cp->type == AUDIO_MIXER_VALUE) { 3329 vol.left = ic->sc_setting[GUSMIX_CHAN_MASTER][ICSMIX_LEFT]; 3330 vol.right = ic->sc_setting[GUSMIX_CHAN_MASTER][ICSMIX_RIGHT]; 3331 if (ad1848_from_vol(cp, &vol)) 3332 error = 0; 3333 } 3334 break; 3335 3336 case GUSICS_MIC_IN_LVL: /* Microphone */ 3337 if (cp->type == AUDIO_MIXER_VALUE) { 3338 vol.left = ic->sc_setting[GUSMIX_CHAN_MIC][ICSMIX_LEFT]; 3339 vol.right = ic->sc_setting[GUSMIX_CHAN_MIC][ICSMIX_RIGHT]; 3340 if (ad1848_from_vol(cp, &vol)) 3341 error = 0; 3342 } 3343 break; 3344 3345 case GUSICS_LINE_IN_LVL: /* line in */ 3346 if (cp->type == AUDIO_MIXER_VALUE) { 3347 vol.left = ic->sc_setting[GUSMIX_CHAN_LINE][ICSMIX_LEFT]; 3348 vol.right = ic->sc_setting[GUSMIX_CHAN_LINE][ICSMIX_RIGHT]; 3349 if (ad1848_from_vol(cp, &vol)) 3350 error = 0; 3351 } 3352 break; 3353 3354 3355 case GUSICS_CD_LVL: 3356 if (cp->type == AUDIO_MIXER_VALUE) { 3357 vol.left = ic->sc_setting[GUSMIX_CHAN_CD][ICSMIX_LEFT]; 3358 vol.right = ic->sc_setting[GUSMIX_CHAN_CD][ICSMIX_RIGHT]; 3359 if (ad1848_from_vol(cp, &vol)) 3360 error = 0; 3361 } 3362 break; 3363 3364 case GUSICS_DAC_LVL: /* dac out */ 3365 if (cp->type == AUDIO_MIXER_VALUE) { 3366 vol.left = ic->sc_setting[GUSMIX_CHAN_DAC][ICSMIX_LEFT]; 3367 vol.right = ic->sc_setting[GUSMIX_CHAN_DAC][ICSMIX_RIGHT]; 3368 if (ad1848_from_vol(cp, &vol)) 3369 error = 0; 3370 } 3371 break; 3372 3373 3374 case GUSICS_RECORD_SOURCE: 3375 if (cp->type == AUDIO_MIXER_ENUM) { 3376 /* Can't set anything else useful, sigh. */ 3377 cp->un.ord = 0; 3378 } 3379 break; 3380 3381 default: 3382 return ENXIO; 3383 /*NOTREACHED*/ 3384 } 3385 return error; 3386} 3387 3388STATIC void 3389gusics_master_mute(struct ics2101_softc *ic, int mute) 3390{ 3391 3392 ics2101_mix_mute(ic, GUSMIX_CHAN_MASTER, ICSMIX_LEFT, mute); 3393 ics2101_mix_mute(ic, GUSMIX_CHAN_MASTER, ICSMIX_RIGHT, mute); 3394} 3395 3396STATIC void 3397gusics_mic_mute(struct ics2101_softc *ic, int mute) 3398{ 3399 3400 ics2101_mix_mute(ic, GUSMIX_CHAN_MIC, ICSMIX_LEFT, mute); 3401 ics2101_mix_mute(ic, GUSMIX_CHAN_MIC, ICSMIX_RIGHT, mute); 3402} 3403 3404STATIC void 3405gusics_linein_mute(struct ics2101_softc *ic, int mute) 3406{ 3407 3408 ics2101_mix_mute(ic, GUSMIX_CHAN_LINE, ICSMIX_LEFT, mute); 3409 ics2101_mix_mute(ic, GUSMIX_CHAN_LINE, ICSMIX_RIGHT, mute); 3410} 3411 3412STATIC void 3413gusics_cd_mute(struct ics2101_softc *ic, int mute) 3414{ 3415 3416 ics2101_mix_mute(ic, GUSMIX_CHAN_CD, ICSMIX_LEFT, mute); 3417 ics2101_mix_mute(ic, GUSMIX_CHAN_CD, ICSMIX_RIGHT, mute); 3418} 3419 3420STATIC void 3421gusics_dac_mute(struct ics2101_softc *ic, int mute) 3422{ 3423 3424 ics2101_mix_mute(ic, GUSMIX_CHAN_DAC, ICSMIX_LEFT, mute); 3425 ics2101_mix_mute(ic, GUSMIX_CHAN_DAC, ICSMIX_RIGHT, mute); 3426} 3427 3428STATIC int 3429gusmax_mixer_set_port(void *addr, mixer_ctrl_t *cp) 3430{ 3431 struct ad1848_isa_softc *ac; 3432 struct gus_softc *sc; 3433 struct ad1848_volume vol; 3434 int error; 3435 3436 ac = addr; 3437 sc = ac->sc_ad1848.parent; 3438 error = ad1848_mixer_set_port(&ac->sc_ad1848, gusmapping, nummap, cp); 3439 if (error != ENXIO) 3440 return error; 3441 3442 DPRINTF(("gusmax_mixer_set_port: dev=%d type=%d\n", cp->dev, cp->type)); 3443 3444 switch (cp->dev) { 3445 case GUSMAX_SPEAKER_LVL: 3446 if (cp->type == AUDIO_MIXER_VALUE && 3447 cp->un.value.num_channels == 1) { 3448 if (ad1848_to_vol(cp, &vol)) { 3449 gus_speaker_ctl(sc, vol.left > AUDIO_MIN_GAIN ? 3450 SPKR_ON : SPKR_OFF); 3451 error = 0; 3452 } 3453 } 3454 break; 3455 3456 case GUSMAX_SPEAKER_MUTE: 3457 if (cp->type == AUDIO_MIXER_ENUM) { 3458 gus_speaker_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON); 3459 error = 0; 3460 } 3461 break; 3462 3463 default: 3464 return ENXIO; 3465 /*NOTREACHED*/ 3466 } 3467 return error; 3468} 3469 3470STATIC int 3471gus_mixer_set_port(void *addr, mixer_ctrl_t *cp) 3472{ 3473 struct gus_softc *sc; 3474 struct ics2101_softc *ic; 3475 struct ad1848_volume vol; 3476 int error; 3477 3478 DPRINTF(("gus_mixer_set_port: dev=%d type=%d\n", cp->dev, cp->type)); 3479 sc = addr; 3480 ic = &sc->sc_mixer; 3481 error = EINVAL; 3482 3483 if (!HAS_MIXER(sc) && cp->dev > GUSICS_MASTER_MUTE) 3484 return ENXIO; 3485 3486 switch (cp->dev) { 3487 3488 case GUSICS_MIC_IN_MUTE: /* Microphone */ 3489 if (cp->type == AUDIO_MIXER_ENUM) { 3490 DPRINTF(("mic mute %d\n", cp->un.ord)); 3491 if (HAS_MIXER(sc)) { 3492 gusics_mic_mute(ic, cp->un.ord); 3493 } 3494 gus_mic_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON); 3495 error = 0; 3496 } 3497 break; 3498 3499 case GUSICS_LINE_IN_MUTE: 3500 if (cp->type == AUDIO_MIXER_ENUM) { 3501 DPRINTF(("linein mute %d\n", cp->un.ord)); 3502 if (HAS_MIXER(sc)) { 3503 gusics_linein_mute(ic, cp->un.ord); 3504 } 3505 gus_linein_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON); 3506 error = 0; 3507 } 3508 break; 3509 3510 case GUSICS_MASTER_MUTE: 3511 if (cp->type == AUDIO_MIXER_ENUM) { 3512 DPRINTF(("master mute %d\n", cp->un.ord)); 3513 if (HAS_MIXER(sc)) { 3514 gusics_master_mute(ic, cp->un.ord); 3515 } 3516 gus_speaker_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON); 3517 error = 0; 3518 } 3519 break; 3520 3521 case GUSICS_DAC_MUTE: 3522 if (cp->type == AUDIO_MIXER_ENUM) { 3523 gusics_dac_mute(ic, cp->un.ord); 3524 error = 0; 3525 } 3526 break; 3527 3528 case GUSICS_CD_MUTE: 3529 if (cp->type == AUDIO_MIXER_ENUM) { 3530 gusics_cd_mute(ic, cp->un.ord); 3531 error = 0; 3532 } 3533 break; 3534 3535 case GUSICS_MASTER_LVL: 3536 if (cp->type == AUDIO_MIXER_VALUE) { 3537 if (ad1848_to_vol(cp, &vol)) { 3538 ics2101_mix_attenuate(ic, 3539 GUSMIX_CHAN_MASTER, 3540 ICSMIX_LEFT, 3541 vol.left); 3542 ics2101_mix_attenuate(ic, 3543 GUSMIX_CHAN_MASTER, 3544 ICSMIX_RIGHT, 3545 vol.right); 3546 error = 0; 3547 } 3548 } 3549 break; 3550 3551 case GUSICS_MIC_IN_LVL: /* Microphone */ 3552 if (cp->type == AUDIO_MIXER_VALUE) { 3553 if (ad1848_to_vol(cp, &vol)) { 3554 ics2101_mix_attenuate(ic, 3555 GUSMIX_CHAN_MIC, 3556 ICSMIX_LEFT, 3557 vol.left); 3558 ics2101_mix_attenuate(ic, 3559 GUSMIX_CHAN_MIC, 3560 ICSMIX_RIGHT, 3561 vol.right); 3562 error = 0; 3563 } 3564 } 3565 break; 3566 3567 case GUSICS_LINE_IN_LVL: /* line in */ 3568 if (cp->type == AUDIO_MIXER_VALUE) { 3569 if (ad1848_to_vol(cp, &vol)) { 3570 ics2101_mix_attenuate(ic, 3571 GUSMIX_CHAN_LINE, 3572 ICSMIX_LEFT, 3573 vol.left); 3574 ics2101_mix_attenuate(ic, 3575 GUSMIX_CHAN_LINE, 3576 ICSMIX_RIGHT, 3577 vol.right); 3578 error = 0; 3579 } 3580 } 3581 break; 3582 3583 3584 case GUSICS_CD_LVL: 3585 if (cp->type == AUDIO_MIXER_VALUE) { 3586 if (ad1848_to_vol(cp, &vol)) { 3587 ics2101_mix_attenuate(ic, 3588 GUSMIX_CHAN_CD, 3589 ICSMIX_LEFT, 3590 vol.left); 3591 ics2101_mix_attenuate(ic, 3592 GUSMIX_CHAN_CD, 3593 ICSMIX_RIGHT, 3594 vol.right); 3595 error = 0; 3596 } 3597 } 3598 break; 3599 3600 case GUSICS_DAC_LVL: /* dac out */ 3601 if (cp->type == AUDIO_MIXER_VALUE) { 3602 if (ad1848_to_vol(cp, &vol)) { 3603 ics2101_mix_attenuate(ic, 3604 GUSMIX_CHAN_DAC, 3605 ICSMIX_LEFT, 3606 vol.left); 3607 ics2101_mix_attenuate(ic, 3608 GUSMIX_CHAN_DAC, 3609 ICSMIX_RIGHT, 3610 vol.right); 3611 error = 0; 3612 } 3613 } 3614 break; 3615 3616 3617 case GUSICS_RECORD_SOURCE: 3618 if (cp->type == AUDIO_MIXER_ENUM && cp->un.ord == 0) { 3619 /* Can't set anything else useful, sigh. */ 3620 error = 0; 3621 } 3622 break; 3623 3624 default: 3625 return ENXIO; 3626 /*NOTREACHED*/ 3627 } 3628 return error; 3629} 3630 3631STATIC int 3632gus_get_props(void *addr) 3633{ 3634 struct gus_softc *sc; 3635 3636 sc = addr; 3637 return AUDIO_PROP_MMAP | 3638 (sc->sc_recdrq == sc->sc_playdrq ? 0 : AUDIO_PROP_FULLDUPLEX); 3639} 3640 3641STATIC int 3642gusmax_get_props(void *addr) 3643{ 3644 struct ad1848_isa_softc *ac; 3645 3646 ac = addr; 3647 return gus_get_props(ac->sc_ad1848.parent); 3648} 3649 3650STATIC int 3651gusmax_mixer_query_devinfo(void *addr, mixer_devinfo_t *dip) 3652{ 3653 3654 DPRINTF(("gusmax_query_devinfo: index=%d\n", dip->index)); 3655 3656 switch(dip->index) { 3657#if 0 3658 case GUSMAX_MIC_IN_LVL: /* Microphone */ 3659 dip->type = AUDIO_MIXER_VALUE; 3660 dip->mixer_class = GUSMAX_INPUT_CLASS; 3661 dip->prev = AUDIO_MIXER_LAST; 3662 dip->next = GUSMAX_MIC_IN_MUTE; 3663 strcpy(dip->label.name, AudioNmicrophone); 3664 dip->un.v.num_channels = 2; 3665 strcpy(dip->un.v.units.name, AudioNvolume); 3666 break; 3667#endif 3668 3669 case GUSMAX_MONO_LVL: /* mono/microphone mixer */ 3670 dip->type = AUDIO_MIXER_VALUE; 3671 dip->mixer_class = GUSMAX_INPUT_CLASS; 3672 dip->prev = AUDIO_MIXER_LAST; 3673 dip->next = GUSMAX_MONO_MUTE; 3674 strcpy(dip->label.name, AudioNmicrophone); 3675 dip->un.v.num_channels = 1; 3676 strcpy(dip->un.v.units.name, AudioNvolume); 3677 break; 3678 3679 case GUSMAX_DAC_LVL: /* dacout */ 3680 dip->type = AUDIO_MIXER_VALUE; 3681 dip->mixer_class = GUSMAX_INPUT_CLASS; 3682 dip->prev = AUDIO_MIXER_LAST; 3683 dip->next = GUSMAX_DAC_MUTE; 3684 strcpy(dip->label.name, AudioNdac); 3685 dip->un.v.num_channels = 2; 3686 strcpy(dip->un.v.units.name, AudioNvolume); 3687 break; 3688 3689 case GUSMAX_LINE_IN_LVL: /* line */ 3690 dip->type = AUDIO_MIXER_VALUE; 3691 dip->mixer_class = GUSMAX_INPUT_CLASS; 3692 dip->prev = AUDIO_MIXER_LAST; 3693 dip->next = GUSMAX_LINE_IN_MUTE; 3694 strcpy(dip->label.name, AudioNline); 3695 dip->un.v.num_channels = 2; 3696 strcpy(dip->un.v.units.name, AudioNvolume); 3697 break; 3698 3699 case GUSMAX_CD_LVL: /* cd */ 3700 dip->type = AUDIO_MIXER_VALUE; 3701 dip->mixer_class = GUSMAX_INPUT_CLASS; 3702 dip->prev = AUDIO_MIXER_LAST; 3703 dip->next = GUSMAX_CD_MUTE; 3704 strcpy(dip->label.name, AudioNcd); 3705 dip->un.v.num_channels = 2; 3706 strcpy(dip->un.v.units.name, AudioNvolume); 3707 break; 3708 3709 3710 case GUSMAX_MONITOR_LVL: /* monitor level */ 3711 dip->type = AUDIO_MIXER_VALUE; 3712 dip->mixer_class = GUSMAX_MONITOR_CLASS; 3713 dip->next = GUSMAX_MONITOR_MUTE; 3714 dip->prev = AUDIO_MIXER_LAST; 3715 strcpy(dip->label.name, AudioNmonitor); 3716 dip->un.v.num_channels = 1; 3717 strcpy(dip->un.v.units.name, AudioNvolume); 3718 break; 3719 3720 case GUSMAX_OUT_LVL: /* cs4231 output volume: not useful? */ 3721 dip->type = AUDIO_MIXER_VALUE; 3722 dip->mixer_class = GUSMAX_MONITOR_CLASS; 3723 dip->prev = dip->next = AUDIO_MIXER_LAST; 3724 strcpy(dip->label.name, AudioNoutput); 3725 dip->un.v.num_channels = 2; 3726 strcpy(dip->un.v.units.name, AudioNvolume); 3727 break; 3728 3729 case GUSMAX_SPEAKER_LVL: /* fake speaker volume */ 3730 dip->type = AUDIO_MIXER_VALUE; 3731 dip->mixer_class = GUSMAX_MONITOR_CLASS; 3732 dip->prev = AUDIO_MIXER_LAST; 3733 dip->next = GUSMAX_SPEAKER_MUTE; 3734 strcpy(dip->label.name, AudioNmaster); 3735 dip->un.v.num_channels = 2; 3736 strcpy(dip->un.v.units.name, AudioNvolume); 3737 break; 3738 3739 case GUSMAX_LINE_IN_MUTE: 3740 dip->mixer_class = GUSMAX_INPUT_CLASS; 3741 dip->type = AUDIO_MIXER_ENUM; 3742 dip->prev = GUSMAX_LINE_IN_LVL; 3743 dip->next = AUDIO_MIXER_LAST; 3744 goto mute; 3745 3746 case GUSMAX_DAC_MUTE: 3747 dip->mixer_class = GUSMAX_INPUT_CLASS; 3748 dip->type = AUDIO_MIXER_ENUM; 3749 dip->prev = GUSMAX_DAC_LVL; 3750 dip->next = AUDIO_MIXER_LAST; 3751 goto mute; 3752 3753 case GUSMAX_CD_MUTE: 3754 dip->mixer_class = GUSMAX_INPUT_CLASS; 3755 dip->type = AUDIO_MIXER_ENUM; 3756 dip->prev = GUSMAX_CD_LVL; 3757 dip->next = AUDIO_MIXER_LAST; 3758 goto mute; 3759 3760 case GUSMAX_MONO_MUTE: 3761 dip->mixer_class = GUSMAX_INPUT_CLASS; 3762 dip->type = AUDIO_MIXER_ENUM; 3763 dip->prev = GUSMAX_MONO_LVL; 3764 dip->next = AUDIO_MIXER_LAST; 3765 goto mute; 3766 3767 case GUSMAX_MONITOR_MUTE: 3768 dip->mixer_class = GUSMAX_OUTPUT_CLASS; 3769 dip->type = AUDIO_MIXER_ENUM; 3770 dip->prev = GUSMAX_MONITOR_LVL; 3771 dip->next = AUDIO_MIXER_LAST; 3772 goto mute; 3773 3774 case GUSMAX_SPEAKER_MUTE: 3775 dip->mixer_class = GUSMAX_OUTPUT_CLASS; 3776 dip->type = AUDIO_MIXER_ENUM; 3777 dip->prev = GUSMAX_SPEAKER_LVL; 3778 dip->next = AUDIO_MIXER_LAST; 3779 mute: 3780 strcpy(dip->label.name, AudioNmute); 3781 dip->un.e.num_mem = 2; 3782 strcpy(dip->un.e.member[0].label.name, AudioNoff); 3783 dip->un.e.member[0].ord = 0; 3784 strcpy(dip->un.e.member[1].label.name, AudioNon); 3785 dip->un.e.member[1].ord = 1; 3786 break; 3787 3788 case GUSMAX_REC_LVL: /* record level */ 3789 dip->type = AUDIO_MIXER_VALUE; 3790 dip->mixer_class = GUSMAX_RECORD_CLASS; 3791 dip->prev = AUDIO_MIXER_LAST; 3792 dip->next = GUSMAX_RECORD_SOURCE; 3793 strcpy(dip->label.name, AudioNrecord); 3794 dip->un.v.num_channels = 2; 3795 strcpy(dip->un.v.units.name, AudioNvolume); 3796 break; 3797 3798 case GUSMAX_RECORD_SOURCE: 3799 dip->mixer_class = GUSMAX_RECORD_CLASS; 3800 dip->type = AUDIO_MIXER_ENUM; 3801 dip->prev = GUSMAX_REC_LVL; 3802 dip->next = AUDIO_MIXER_LAST; 3803 strcpy(dip->label.name, AudioNsource); 3804 dip->un.e.num_mem = 4; 3805 strcpy(dip->un.e.member[0].label.name, AudioNoutput); 3806 dip->un.e.member[0].ord = DAC_IN_PORT; 3807 strcpy(dip->un.e.member[1].label.name, AudioNmicrophone); 3808 dip->un.e.member[1].ord = MIC_IN_PORT; 3809 strcpy(dip->un.e.member[2].label.name, AudioNdac); 3810 dip->un.e.member[2].ord = AUX1_IN_PORT; 3811 strcpy(dip->un.e.member[3].label.name, AudioNline); 3812 dip->un.e.member[3].ord = LINE_IN_PORT; 3813 break; 3814 3815 case GUSMAX_INPUT_CLASS: /* input class descriptor */ 3816 dip->type = AUDIO_MIXER_CLASS; 3817 dip->mixer_class = GUSMAX_INPUT_CLASS; 3818 dip->next = dip->prev = AUDIO_MIXER_LAST; 3819 strcpy(dip->label.name, AudioCinputs); 3820 break; 3821 3822 case GUSMAX_OUTPUT_CLASS: /* output class descriptor */ 3823 dip->type = AUDIO_MIXER_CLASS; 3824 dip->mixer_class = GUSMAX_OUTPUT_CLASS; 3825 dip->next = dip->prev = AUDIO_MIXER_LAST; 3826 strcpy(dip->label.name, AudioCoutputs); 3827 break; 3828 3829 case GUSMAX_MONITOR_CLASS: /* monitor class descriptor */ 3830 dip->type = AUDIO_MIXER_CLASS; 3831 dip->mixer_class = GUSMAX_MONITOR_CLASS; 3832 dip->next = dip->prev = AUDIO_MIXER_LAST; 3833 strcpy(dip->label.name, AudioCmonitor); 3834 break; 3835 3836 case GUSMAX_RECORD_CLASS: /* record source class */ 3837 dip->type = AUDIO_MIXER_CLASS; 3838 dip->mixer_class = GUSMAX_RECORD_CLASS; 3839 dip->next = dip->prev = AUDIO_MIXER_LAST; 3840 strcpy(dip->label.name, AudioCrecord); 3841 break; 3842 3843 default: 3844 return ENXIO; 3845 /*NOTREACHED*/ 3846 } 3847 DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name)); 3848 return 0; 3849} 3850 3851STATIC int 3852gus_mixer_query_devinfo(void *addr, mixer_devinfo_t *dip) 3853{ 3854 struct gus_softc *sc; 3855 3856 DPRINTF(("gusmax_query_devinfo: index=%d\n", dip->index)); 3857 sc = addr; 3858 if (!HAS_MIXER(sc) && dip->index > GUSICS_MASTER_MUTE) 3859 return ENXIO; 3860 3861 switch(dip->index) { 3862 3863 case GUSICS_MIC_IN_LVL: /* Microphone */ 3864 dip->type = AUDIO_MIXER_VALUE; 3865 dip->mixer_class = GUSICS_INPUT_CLASS; 3866 dip->prev = AUDIO_MIXER_LAST; 3867 dip->next = GUSICS_MIC_IN_MUTE; 3868 strcpy(dip->label.name, AudioNmicrophone); 3869 dip->un.v.num_channels = 2; 3870 strcpy(dip->un.v.units.name, AudioNvolume); 3871 break; 3872 3873 case GUSICS_LINE_IN_LVL: /* line */ 3874 dip->type = AUDIO_MIXER_VALUE; 3875 dip->mixer_class = GUSICS_INPUT_CLASS; 3876 dip->prev = AUDIO_MIXER_LAST; 3877 dip->next = GUSICS_LINE_IN_MUTE; 3878 strcpy(dip->label.name, AudioNline); 3879 dip->un.v.num_channels = 2; 3880 strcpy(dip->un.v.units.name, AudioNvolume); 3881 break; 3882 3883 case GUSICS_CD_LVL: /* cd */ 3884 dip->type = AUDIO_MIXER_VALUE; 3885 dip->mixer_class = GUSICS_INPUT_CLASS; 3886 dip->prev = AUDIO_MIXER_LAST; 3887 dip->next = GUSICS_CD_MUTE; 3888 strcpy(dip->label.name, AudioNcd); 3889 dip->un.v.num_channels = 2; 3890 strcpy(dip->un.v.units.name, AudioNvolume); 3891 break; 3892 3893 case GUSICS_DAC_LVL: /* dacout */ 3894 dip->type = AUDIO_MIXER_VALUE; 3895 dip->mixer_class = GUSICS_INPUT_CLASS; 3896 dip->prev = AUDIO_MIXER_LAST; 3897 dip->next = GUSICS_DAC_MUTE; 3898 strcpy(dip->label.name, AudioNdac); 3899 dip->un.v.num_channels = 2; 3900 strcpy(dip->un.v.units.name, AudioNvolume); 3901 break; 3902 3903 case GUSICS_MASTER_LVL: /* master output */ 3904 dip->type = AUDIO_MIXER_VALUE; 3905 dip->mixer_class = GUSICS_OUTPUT_CLASS; 3906 dip->prev = AUDIO_MIXER_LAST; 3907 dip->next = GUSICS_MASTER_MUTE; 3908 strcpy(dip->label.name, AudioNmaster); 3909 dip->un.v.num_channels = 2; 3910 strcpy(dip->un.v.units.name, AudioNvolume); 3911 break; 3912 3913 3914 case GUSICS_LINE_IN_MUTE: 3915 dip->mixer_class = GUSICS_INPUT_CLASS; 3916 dip->type = AUDIO_MIXER_ENUM; 3917 dip->prev = GUSICS_LINE_IN_LVL; 3918 dip->next = AUDIO_MIXER_LAST; 3919 goto mute; 3920 3921 case GUSICS_DAC_MUTE: 3922 dip->mixer_class = GUSICS_INPUT_CLASS; 3923 dip->type = AUDIO_MIXER_ENUM; 3924 dip->prev = GUSICS_DAC_LVL; 3925 dip->next = AUDIO_MIXER_LAST; 3926 goto mute; 3927 3928 case GUSICS_CD_MUTE: 3929 dip->mixer_class = GUSICS_INPUT_CLASS; 3930 dip->type = AUDIO_MIXER_ENUM; 3931 dip->prev = GUSICS_CD_LVL; 3932 dip->next = AUDIO_MIXER_LAST; 3933 goto mute; 3934 3935 case GUSICS_MIC_IN_MUTE: 3936 dip->mixer_class = GUSICS_INPUT_CLASS; 3937 dip->type = AUDIO_MIXER_ENUM; 3938 dip->prev = GUSICS_MIC_IN_LVL; 3939 dip->next = AUDIO_MIXER_LAST; 3940 goto mute; 3941 3942 case GUSICS_MASTER_MUTE: 3943 dip->mixer_class = GUSICS_OUTPUT_CLASS; 3944 dip->type = AUDIO_MIXER_ENUM; 3945 dip->prev = GUSICS_MASTER_LVL; 3946 dip->next = AUDIO_MIXER_LAST; 3947mute: 3948 strcpy(dip->label.name, AudioNmute); 3949 dip->un.e.num_mem = 2; 3950 strcpy(dip->un.e.member[0].label.name, AudioNoff); 3951 dip->un.e.member[0].ord = 0; 3952 strcpy(dip->un.e.member[1].label.name, AudioNon); 3953 dip->un.e.member[1].ord = 1; 3954 break; 3955 3956 case GUSICS_RECORD_SOURCE: 3957 dip->mixer_class = GUSICS_RECORD_CLASS; 3958 dip->type = AUDIO_MIXER_ENUM; 3959 dip->prev = dip->next = AUDIO_MIXER_LAST; 3960 strcpy(dip->label.name, AudioNsource); 3961 dip->un.e.num_mem = 1; 3962 strcpy(dip->un.e.member[0].label.name, AudioNoutput); 3963 dip->un.e.member[0].ord = GUSICS_MASTER_LVL; 3964 break; 3965 3966 case GUSICS_INPUT_CLASS: 3967 dip->type = AUDIO_MIXER_CLASS; 3968 dip->mixer_class = GUSICS_INPUT_CLASS; 3969 dip->next = dip->prev = AUDIO_MIXER_LAST; 3970 strcpy(dip->label.name, AudioCinputs); 3971 break; 3972 3973 case GUSICS_OUTPUT_CLASS: 3974 dip->type = AUDIO_MIXER_CLASS; 3975 dip->mixer_class = GUSICS_OUTPUT_CLASS; 3976 dip->next = dip->prev = AUDIO_MIXER_LAST; 3977 strcpy(dip->label.name, AudioCoutputs); 3978 break; 3979 3980 case GUSICS_RECORD_CLASS: 3981 dip->type = AUDIO_MIXER_CLASS; 3982 dip->mixer_class = GUSICS_RECORD_CLASS; 3983 dip->next = dip->prev = AUDIO_MIXER_LAST; 3984 strcpy(dip->label.name, AudioCrecord); 3985 break; 3986 3987 default: 3988 return ENXIO; 3989 /*NOTREACHED*/ 3990 } 3991 DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name)); 3992 return 0; 3993} 3994 3995STATIC int 3996gus_query_encoding(void *addr, struct audio_encoding *fp) 3997{ 3998 3999 switch (fp->index) { 4000 case 0: 4001 strcpy(fp->name, AudioEmulaw); 4002 fp->encoding = AUDIO_ENCODING_ULAW; 4003 fp->precision = 8; 4004 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 4005 break; 4006 case 1: 4007 strcpy(fp->name, AudioEslinear); 4008 fp->encoding = AUDIO_ENCODING_SLINEAR; 4009 fp->precision = 8; 4010 fp->flags = 0; 4011 break; 4012 case 2: 4013 strcpy(fp->name, AudioEslinear_le); 4014 fp->encoding = AUDIO_ENCODING_SLINEAR_LE; 4015 fp->precision = 16; 4016 fp->flags = 0; 4017 break; 4018 case 3: 4019 strcpy(fp->name, AudioEulinear); 4020 fp->encoding = AUDIO_ENCODING_ULINEAR; 4021 fp->precision = 8; 4022 fp->flags = 0; 4023 break; 4024 case 4: 4025 strcpy(fp->name, AudioEulinear_le); 4026 fp->encoding = AUDIO_ENCODING_ULINEAR_LE; 4027 fp->precision = 16; 4028 fp->flags = 0; 4029 break; 4030 case 5: 4031 strcpy(fp->name, AudioEslinear_be); 4032 fp->encoding = AUDIO_ENCODING_SLINEAR_BE; 4033 fp->precision = 16; 4034 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 4035 break; 4036 case 6: 4037 strcpy(fp->name, AudioEulinear_be); 4038 fp->encoding = AUDIO_ENCODING_ULINEAR_BE; 4039 fp->precision = 16; 4040 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 4041 break; 4042 case 7: 4043 strcpy(fp->name, AudioEalaw); 4044 fp->encoding = AUDIO_ENCODING_ALAW; 4045 fp->precision = 8; 4046 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 4047 break; 4048 4049 default: 4050 return EINVAL; 4051 /*NOTREACHED*/ 4052 } 4053 return 0; 4054} 4055 4056/* 4057 * Setup the ICS mixer in "transparent" mode: reset everything to a sensible 4058 * level. Levels as suggested by GUS SDK code. 4059 */ 4060STATIC void 4061gus_init_ics2101(struct gus_softc *sc) 4062{ 4063 struct ics2101_softc *ic; 4064 4065 ic = &sc->sc_mixer; 4066 sc->sc_mixer.sc_iot = sc->sc_iot; 4067 sc->sc_mixer.sc_selio = GUS_MIXER_SELECT; 4068 sc->sc_mixer.sc_selio_ioh = sc->sc_ioh3; 4069 sc->sc_mixer.sc_dataio = GUS_MIXER_DATA; 4070 sc->sc_mixer.sc_dataio_ioh = sc->sc_ioh2; 4071 sc->sc_mixer.sc_flags = (sc->sc_revision == 5) ? ICS_FLIP : 0; 4072 4073 ics2101_mix_attenuate(ic, 4074 GUSMIX_CHAN_MIC, 4075 ICSMIX_LEFT, 4076 ICSMIX_MIN_ATTN); 4077 ics2101_mix_attenuate(ic, 4078 GUSMIX_CHAN_MIC, 4079 ICSMIX_RIGHT, 4080 ICSMIX_MIN_ATTN); 4081 /* 4082 * Start with microphone muted by the mixer... 4083 */ 4084 gusics_mic_mute(ic, 1); 4085 4086 /* ... and enabled by the GUS master mix control */ 4087 gus_mic_ctl(sc, SPKR_ON); 4088 4089 ics2101_mix_attenuate(ic, 4090 GUSMIX_CHAN_LINE, 4091 ICSMIX_LEFT, 4092 ICSMIX_MIN_ATTN); 4093 ics2101_mix_attenuate(ic, 4094 GUSMIX_CHAN_LINE, 4095 ICSMIX_RIGHT, 4096 ICSMIX_MIN_ATTN); 4097 4098 ics2101_mix_attenuate(ic, 4099 GUSMIX_CHAN_CD, 4100 ICSMIX_LEFT, 4101 ICSMIX_MIN_ATTN); 4102 ics2101_mix_attenuate(ic, 4103 GUSMIX_CHAN_CD, 4104 ICSMIX_RIGHT, 4105 ICSMIX_MIN_ATTN); 4106 4107 ics2101_mix_attenuate(ic, 4108 GUSMIX_CHAN_DAC, 4109 ICSMIX_LEFT, 4110 ICSMIX_MIN_ATTN); 4111 ics2101_mix_attenuate(ic, 4112 GUSMIX_CHAN_DAC, 4113 ICSMIX_RIGHT, 4114 ICSMIX_MIN_ATTN); 4115 4116 ics2101_mix_attenuate(ic, 4117 ICSMIX_CHAN_4, 4118 ICSMIX_LEFT, 4119 ICSMIX_MAX_ATTN); 4120 ics2101_mix_attenuate(ic, 4121 ICSMIX_CHAN_4, 4122 ICSMIX_RIGHT, 4123 ICSMIX_MAX_ATTN); 4124 4125 ics2101_mix_attenuate(ic, 4126 GUSMIX_CHAN_MASTER, 4127 ICSMIX_LEFT, 4128 ICSMIX_MIN_ATTN); 4129 ics2101_mix_attenuate(ic, 4130 GUSMIX_CHAN_MASTER, 4131 ICSMIX_RIGHT, 4132 ICSMIX_MIN_ATTN); 4133 /* unmute other stuff: */ 4134 gusics_cd_mute(ic, 0); 4135 gusics_dac_mute(ic, 0); 4136 gusics_linein_mute(ic, 0); 4137 return; 4138} 4139 4140 4141#endif /* NGUS */ 4142