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