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