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