1 /* $OpenBSD: gusvar.h,v 1.10 2016/09/19 06:46:44 ratchov Exp $ */ 2 /* $NetBSD: gus.c,v 1.51 1998/01/25 23:48:06 mycroft Exp $ */ 3 4 /*- 5 * Copyright (c) 1996 The NetBSD Foundation, Inc. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to The NetBSD Foundation 9 * by Ken Hornstein and John Kohl. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 /* 34 * 35 * TODO: 36 * . figure out why mixer activity while sound is playing causes problems 37 * (phantom interrupts?) 38 * . figure out a better deinterleave strategy that avoids sucking up 39 * CPU, memory and cache bandwidth. (Maybe a special encoding? 40 * Maybe use the double-speed sampling/hardware deinterleave trick 41 * from the GUS SDK?) A 486/33 isn't quite fast enough to keep 42 * up with 44.1kHz 16-bit stereo output without some drop-outs. 43 * . use CS4231 for 16-bit sampling, for a-law and mu-law playback. 44 * . actually test full-duplex sampling(recording) and playback. 45 */ 46 47 /* 48 * Gravis UltraSound driver 49 * 50 * For more detailed information, see the GUS developers' kit 51 * available on the net at: 52 * 53 * ftp://freedom.nmsu.edu/pub/ultrasound/gravis/util/ 54 * gusdkXXX.zip (developers' kit--get rev 2.22 or later) 55 * See ultrawrd.doc inside--it's MS Word (ick), but it's the bible 56 * 57 */ 58 59 /* 60 * The GUS Max has a slightly strange set of connections between the CS4231 61 * and the GF1 and the DMA interconnects. It's set up so that the CS4231 can 62 * be playing while the GF1 is loading patches from the system. 63 * 64 * Here's a recreation of the DMA interconnect diagram: 65 * 66 * GF1 67 * +---------+ digital 68 * | | record ASIC 69 * | |--------------+ 70 * | | | +--------+ 71 * | | play (dram) | +----+ | | 72 * | |--------------(------|-\ | | +-+ | 73 * +---------+ | | >-|----|---|C|--|------ dma chan 1 74 * | +---|-/ | | +-+ | 75 * | | +----+ | | | 76 * | | +----+ | | | 77 * +---------+ +-+ +--(---|-\ | | | | 78 * | | play |8| | | >-|----|----+---|------ dma chan 2 79 * | ---C----|--------|/|------(---|-/ | | | 80 * | ^ |record |1| | +----+ | | 81 * | | | /----|6|------+ +--------+ 82 * | ---+----|--/ +-+ 83 * +---------+ 84 * CS4231 8-to-16 bit bus conversion, if needed 85 * 86 * 87 * "C" is an optional combiner. 88 * 89 */ 90 91 /* 92 * Software state of a single "voice" on the GUS 93 */ 94 struct gus_voice { 95 96 /* 97 * Various control bits 98 */ 99 100 unsigned char voccntl; /* State of voice control register */ 101 unsigned char volcntl; /* State of volume control register */ 102 unsigned char pan_pos; /* Position of volume panning (4 bits) */ 103 int rate; /* Sample rate of voice being played back */ 104 105 /* 106 * Address of the voice data into the GUS's DRAM. 20 bits each 107 */ 108 109 u_long start_addr; /* Starting address of voice data loop area */ 110 u_long end_addr; /* Ending address of voice data loop */ 111 u_long current_addr; /* Beginning address of voice data 112 (start playing here) */ 113 114 /* 115 * linear volume values for the GUS's volume ramp. 0-511 (9 bits). 116 * These values must be translated into the logarithmic values using 117 * gus_log_volumes[] 118 */ 119 120 int start_volume; /* Starting position of volume ramp */ 121 int current_volume; /* Current position of volume on volume ramp */ 122 int end_volume; /* Ending position of volume on volume ramp */ 123 }; 124 125 /* 126 * Software state of GUS 127 */ 128 struct gus_softc { 129 struct device sc_dev; /* base device */ 130 struct device *sc_isa; /* pointer to ISA parent */ 131 void *sc_ih; /* interrupt vector */ 132 struct timeout sc_dma_tmo; 133 bus_space_tag_t sc_iot; /* tag */ 134 bus_space_handle_t sc_ioh1; /* handle */ 135 bus_space_handle_t sc_ioh2; /* handle */ 136 bus_space_handle_t sc_ioh3; /* ICS2101 handle */ 137 bus_space_handle_t sc_ioh4; /* MIDI handle */ 138 139 int sc_iobase; /* I/O base address */ 140 int sc_irq; /* IRQ used */ 141 int sc_drq; /* DMA channel for play */ 142 int sc_recdrq; /* DMA channel for recording */ 143 144 int sc_flags; /* Various flags about the GUS */ 145 #define GUS_MIXER_INSTALLED 0x01 /* An ICS mixer is installed */ 146 #define GUS_LOCKED 0x02 /* GUS is busy doing multi-phase DMA */ 147 #define GUS_CODEC_INSTALLED 0x04 /* CS4231 installed/MAX */ 148 #define GUS_PLAYING 0x08 /* GUS is playing a voice */ 149 #define GUS_DMAOUT_ACTIVE 0x10 /* GUS is busy doing audio DMA */ 150 #define GUS_DMAIN_ACTIVE 0x20 /* GUS is busy sampling */ 151 #define GUS_OPEN 0x100 /* GUS is open */ 152 int sc_dsize; /* Size of GUS DRAM */ 153 int sc_voices; /* Number of active voices */ 154 u_char sc_revision; /* Board revision of GUS */ 155 u_char sc_mixcontrol; /* Value of GUS_MIX_CONTROL register */ 156 157 u_long sc_orate; /* Output sampling rate */ 158 u_long sc_irate; /* Input sampling rate */ 159 160 int sc_encoding; /* Current data encoding type */ 161 int sc_precision; /* # of bits of precision */ 162 int sc_channels; /* Number of active channels */ 163 int sc_blocksize; /* Current blocksize */ 164 int sc_chanblocksize; /* Current blocksize for each in-use 165 channel */ 166 short sc_nbufs; /* how many on-GUS bufs per-channel */ 167 short sc_bufcnt; /* how many need to be played */ 168 void *sc_deintr_buf; /* deinterleave buffer for stereo */ 169 170 int sc_ogain; /* Output gain control */ 171 u_char sc_out_port; /* Current out port (generic only) */ 172 u_char sc_in_port; /* keep track of it when no codec */ 173 174 void (*sc_dmaoutintr)(void *); /* DMA completion intr handler */ 175 void *sc_outarg; /* argument for sc_dmaoutintr() */ 176 u_char *sc_dmaoutaddr; /* for isadma_done */ 177 u_long sc_gusaddr; /* where did we just put it? */ 178 int sc_dmaoutcnt; /* for isadma_done */ 179 180 void (*sc_dmainintr)(void *); /* DMA completion intr handler */ 181 void *sc_inarg; /* argument for sc_dmaoutintr() */ 182 u_char *sc_dmainaddr; /* for isadma_done */ 183 int sc_dmaincnt; /* for isadma_done */ 184 185 struct stereo_dma_intr { 186 void (*intr)(void *); 187 void *arg; 188 u_char *buffer; 189 u_long dmabuf; 190 int size; 191 int flags; 192 } sc_stereo; 193 194 /* 195 * State information for linear audio layer 196 */ 197 198 int sc_dmabuf; /* Which ring buffer we're DMA'ing to */ 199 int sc_playbuf; /* Which ring buffer we're playing */ 200 201 /* 202 * Voice information array. All voice-specific information is stored 203 * here 204 */ 205 206 struct gus_voice sc_voc[32]; /* Voice data for each voice */ 207 union { 208 struct ics2101_softc sc_mixer_u; 209 struct ad1848_softc sc_codec_u; 210 } u; 211 #define sc_mixer u.sc_mixer_u 212 #define sc_codec u.sc_codec_u 213 }; 214 215 struct ics2101_volume { 216 u_char left; 217 u_char right; 218 }; 219 220 #define HAS_CODEC(sc) ((sc)->sc_flags & GUS_CODEC_INSTALLED) 221 #define HAS_MIXER(sc) ((sc)->sc_flags & GUS_MIXER_INSTALLED) 222 223 /* 224 * Mixer devices for ICS2101 225 */ 226 /* MIC IN mute, line in mute, line out mute are first since they can be done 227 even if no ICS mixer. */ 228 #define GUSICS_MIC_IN_MUTE 0 229 #define GUSICS_LINE_IN_MUTE 1 230 #define GUSICS_MASTER_MUTE 2 231 #define GUSICS_CD_MUTE 3 232 #define GUSICS_DAC_MUTE 4 233 #define GUSICS_MIC_IN_LVL 5 234 #define GUSICS_LINE_IN_LVL 6 235 #define GUSICS_CD_LVL 7 236 #define GUSICS_DAC_LVL 8 237 #define GUSICS_MASTER_LVL 9 238 239 #define GUSICS_RECORD_SOURCE 10 240 241 /* Classes */ 242 #define GUSICS_INPUT_CLASS 11 243 #define GUSICS_OUTPUT_CLASS 12 244 #define GUSICS_RECORD_CLASS 13 245 246 /* 247 * Mixer & MUX devices for CS4231 248 */ 249 #define GUSMAX_MONO_LVL 0 /* mic input to MUX; 250 also mono mixer input */ 251 #define GUSMAX_DAC_LVL 1 /* input to MUX; also mixer input */ 252 #define GUSMAX_LINE_IN_LVL 2 /* input to MUX; also mixer input */ 253 #define GUSMAX_CD_LVL 3 /* mixer input only */ 254 #define GUSMAX_MONITOR_LVL 4 /* digital mix (?) */ 255 #define GUSMAX_OUT_LVL 5 /* output level. (?) */ 256 #define GUSMAX_SPEAKER_LVL 6 /* pseudo-device for mute */ 257 #define GUSMAX_LINE_IN_MUTE 7 /* pre-mixer */ 258 #define GUSMAX_DAC_MUTE 8 /* pre-mixer */ 259 #define GUSMAX_CD_MUTE 9 /* pre-mixer */ 260 #define GUSMAX_MONO_MUTE 10 /* pre-mixer--microphone/mono */ 261 #define GUSMAX_MONITOR_MUTE 11 /* post-mixer level/mute */ 262 #define GUSMAX_SPEAKER_MUTE 12 /* speaker mute */ 263 264 #define GUSMAX_REC_LVL 13 /* post-MUX gain */ 265 266 #define GUSMAX_RECORD_SOURCE 14 267 268 /* Classes */ 269 #define GUSMAX_INPUT_CLASS 15 270 #define GUSMAX_RECORD_CLASS 16 271 #define GUSMAX_MONITOR_CLASS 17 272 #define GUSMAX_OUTPUT_CLASS 18 273 274 #ifdef AUDIO_DEBUG 275 #define GUSPLAYDEBUG /*XXX*/ 276 #define DPRINTF(x) if (gusdebug) printf x 277 #define DMAPRINTF(x) if (gusdmadebug) printf x 278 extern int gusdebug; 279 extern int gusdmadebug; 280 #else 281 #define DPRINTF(x) 282 #define DMAPRINTF(x) 283 #endif 284 extern int gus_dostereo; 285 286 #define NDMARECS 2048 287 #ifdef GUSPLAYDEBUG 288 extern int gusstats; 289 struct dma_record { 290 struct timeval tv; 291 u_long gusaddr; 292 caddr_t bsdaddr; 293 u_short count; 294 u_char channel; 295 u_char direction; 296 }; 297 298 extern struct dma_record dmarecords[NDMARECS]; 299 300 extern int dmarecord_index; 301 #endif 302 303 /* 304 * local routines 305 */ 306 307 int gusopen(void *, int); 308 void gusclose(void *); 309 void gusmax_close(void *); 310 int gusintr(void *); 311 int gus_set_in_gain(caddr_t, u_int, u_char); 312 int gus_get_in_gain(caddr_t); 313 int gus_set_out_gain(caddr_t, u_int, u_char); 314 int gus_get_out_gain(caddr_t); 315 int gus_set_params(void *, int, int, struct audio_params *, struct audio_params *); 316 int gusmax_set_params(void *, int, int, struct audio_params *, struct audio_params *); 317 int gus_round_blocksize(void *, int); 318 int gus_commit_settings(void *); 319 int gus_dma_output(void *, void *, int, void (*)(void *), void *); 320 int gus_dma_input(void *, void *, int, void (*)(void *), void *); 321 int gus_halt_out_dma(void *); 322 int gus_halt_in_dma(void *); 323 int gus_speaker_ctl(void *, int); 324 int gusmaxopen(void *, int); 325 int gusmax_round_blocksize(void *, int); 326 int gusmax_commit_settings(void *); 327 int gusmax_dma_output(void *, void *, int, void (*)(void *), void *); 328 int gusmax_dma_input(void *, void *, int, void (*)(void *), void *); 329 int gusmax_halt_out_dma(void *); 330 int gusmax_halt_in_dma(void *); 331 int gusmax_speaker_ctl(void *, int); 332 333 void gus_deinterleave(struct gus_softc *, void *, int); 334 335 int gus_mic_ctl(void *, int); 336 int gus_linein_ctl(void *, int); 337 int gus_test_iobase(bus_space_tag_t, int); 338 void guspoke(bus_space_tag_t, bus_space_handle_t, long, u_char); 339 void gusdmaout(struct gus_softc *, int, u_long, caddr_t, int); 340 int gus_init_cs4231(struct gus_softc *); 341 void gus_init_ics2101(struct gus_softc *); 342 343 void gus_set_chan_addrs(struct gus_softc *); 344 void gusreset(struct gus_softc *, int); 345 void gus_set_voices(struct gus_softc *, int); 346 void gus_set_volume(struct gus_softc *, int, int); 347 void gus_set_samprate(struct gus_softc *, int, int); 348 void gus_set_recrate(struct gus_softc *, u_long); 349 void gus_start_voice(struct gus_softc *, int, int); 350 void gus_stop_voice(struct gus_softc *, int, int); 351 void gus_set_endaddr(struct gus_softc *, int, u_long); 352 #ifdef GUSPLAYDEBUG 353 void gus_set_curaddr(struct gus_softc *, int, u_long); 354 u_long gus_get_curaddr(struct gus_softc *, int); 355 #endif 356 int gus_dmaout_intr(struct gus_softc *); 357 void gus_dmaout_dointr(struct gus_softc *); 358 void gus_dmaout_timeout(void *); 359 int gus_dmain_intr(struct gus_softc *); 360 int gus_voice_intr(struct gus_softc *); 361 void gus_start_playing(struct gus_softc *, int); 362 int gus_continue_playing(struct gus_softc *, int); 363 u_char guspeek(bus_space_tag_t, bus_space_handle_t, u_long); 364 u_long convert_to_16bit(u_long); 365 int gus_mixer_set_port(void *, mixer_ctrl_t *); 366 int gus_mixer_get_port(void *, mixer_ctrl_t *); 367 int gusmax_mixer_set_port(void *, mixer_ctrl_t *); 368 int gusmax_mixer_get_port(void *, mixer_ctrl_t *); 369 int gus_mixer_query_devinfo(void *, mixer_devinfo_t *); 370 int gusmax_mixer_query_devinfo(void *, mixer_devinfo_t *); 371 void *gus_malloc(void *, int, size_t, int, int); 372 void gus_free(void *, void *, int); 373 size_t gus_round(void *, int, size_t); 374 int gus_get_props(void *); 375 int gusmax_get_props(void *); 376 377 void gusics_master_mute(struct ics2101_softc *, int); 378 void gusics_dac_mute(struct ics2101_softc *, int); 379 void gusics_mic_mute(struct ics2101_softc *, int); 380 void gusics_linein_mute(struct ics2101_softc *, int); 381 void gusics_cd_mute(struct ics2101_softc *, int); 382 383 void stereo_dmaintr(void *); 384 385 extern const int gus_irq_map[]; 386 extern const int gus_drq_map[]; 387 extern const int gus_base_addrs[]; 388 extern const int gus_addrs; 389 390 #define SELECT_GUS_REG(iot,ioh1,x) bus_space_write_1(iot,ioh1,GUS_REG_SELECT,x) 391 #define ADDR_HIGH(x) (unsigned int) ((x >> 7L) & 0x1fffL) 392 #define ADDR_LOW(x) (unsigned int) ((x & 0x7fL) << 9L) 393 394 #define GUS_MIN_VOICES 14 /* Minimum possible number of voices */ 395 #define GUS_MAX_VOICES 32 /* Maximum possible number of voices */ 396 #define GUS_VOICE_LEFT 0 /* Voice used for left (and mono) playback */ 397 #define GUS_VOICE_RIGHT 1 /* Voice used for right playback */ 398 #define GUS_MEM_OFFSET 32 /* Offset into GUS memory to begin of buffer */ 399 #define GUS_BUFFER_MULTIPLE 1024 /* Audio buffers are multiples of this */ 400 #define GUS_MEM_FOR_BUFFERS 131072 /* use this many bytes on-GUS */ 401 #define GUS_LEFT_RIGHT_OFFSET (sc->sc_nbufs * sc->sc_chanblocksize + GUS_MEM_OFFSET) 402 403 #define GUS_PREC_BYTES (sc->sc_precision >> 3) /* precision to bytes */ 404 405 /* splgus() must be splaudio() */ 406 407 #define splgus splaudio 408 409 extern struct audio_hw_if gus_hw_if; 410 411 #define FLIP_REV 5 /* This rev has flipped mixer chans */ 412 413 void gus_subattach(struct gus_softc *, struct isa_attach_args *); 414