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