FreeBSD/Linux Kernel Cross Reference
sys/dev/isa/gusvar.h
1 /* $OpenBSD: gusvar.h,v 1.13 2022/11/02 10:41:34 kn 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
332 void gus_deinterleave(struct gus_softc *, void *, int);
333
334 int gus_mic_ctl(void *, int);
335 int gus_linein_ctl(void *, int);
336 int gus_test_iobase(bus_space_tag_t, int);
337 void guspoke(bus_space_tag_t, bus_space_handle_t, long, u_char);
338 void gusdmaout(struct gus_softc *, int, u_long, caddr_t, int);
339 int gus_init_cs4231(struct gus_softc *);
340 void gus_init_ics2101(struct gus_softc *);
341
342 void gus_set_chan_addrs(struct gus_softc *);
343 void gusreset(struct gus_softc *, int);
344 void gus_set_voices(struct gus_softc *, int);
345 void gus_set_volume(struct gus_softc *, int, int);
346 void gus_set_samprate(struct gus_softc *, int, int);
347 void gus_set_recrate(struct gus_softc *, u_long);
348 void gus_start_voice(struct gus_softc *, int, int);
349 void gus_stop_voice(struct gus_softc *, int, int);
350 void gus_set_endaddr(struct gus_softc *, int, u_long);
351 #ifdef GUSPLAYDEBUG
352 void gus_set_curaddr(struct gus_softc *, int, u_long);
353 u_long gus_get_curaddr(struct gus_softc *, int);
354 #endif
355 int gus_dmaout_intr(struct gus_softc *);
356 void gus_dmaout_dointr(struct gus_softc *);
357 void gus_dmaout_timeout(void *);
358 int gus_dmain_intr(struct gus_softc *);
359 int gus_voice_intr(struct gus_softc *);
360 void gus_start_playing(struct gus_softc *, int);
361 int gus_continue_playing(struct gus_softc *, int);
362 u_char guspeek(bus_space_tag_t, bus_space_handle_t, u_long);
363 u_long convert_to_16bit(u_long);
364 int gus_mixer_set_port(void *, mixer_ctrl_t *);
365 int gus_mixer_get_port(void *, mixer_ctrl_t *);
366 int gusmax_mixer_set_port(void *, mixer_ctrl_t *);
367 int gusmax_mixer_get_port(void *, mixer_ctrl_t *);
368 int gus_mixer_query_devinfo(void *, mixer_devinfo_t *);
369 int gusmax_mixer_query_devinfo(void *, mixer_devinfo_t *);
370 void *gus_malloc(void *, int, size_t, int, int);
371 void gus_free(void *, void *, int);
372 size_t gus_round(void *, int, size_t);
373
374 void gusics_master_mute(struct ics2101_softc *, int);
375 void gusics_dac_mute(struct ics2101_softc *, int);
376 void gusics_mic_mute(struct ics2101_softc *, int);
377 void gusics_linein_mute(struct ics2101_softc *, int);
378 void gusics_cd_mute(struct ics2101_softc *, int);
379
380 void stereo_dmaintr(void *);
381
382 extern const int gus_irq_map[];
383 extern const int gus_drq_map[];
384 extern const int gus_base_addrs[];
385 extern const int gus_addrs;
386
387 #define SELECT_GUS_REG(iot,ioh1,x) bus_space_write_1(iot,ioh1,GUS_REG_SELECT,x)
388 #define ADDR_HIGH(x) (unsigned int) ((x >> 7L) & 0x1fffL)
389 #define ADDR_LOW(x) (unsigned int) ((x & 0x7fL) << 9L)
390
391 #define GUS_MIN_VOICES 14 /* Minimum possible number of voices */
392 #define GUS_MAX_VOICES 32 /* Maximum possible number of voices */
393 #define GUS_VOICE_LEFT 0 /* Voice used for left (and mono) playback */
394 #define GUS_VOICE_RIGHT 1 /* Voice used for right playback */
395 #define GUS_MEM_OFFSET 32 /* Offset into GUS memory to begin of buffer */
396 #define GUS_BUFFER_MULTIPLE 1024 /* Audio buffers are multiples of this */
397 #define GUS_MEM_FOR_BUFFERS 131072 /* use this many bytes on-GUS */
398 #define GUS_LEFT_RIGHT_OFFSET (sc->sc_nbufs * sc->sc_chanblocksize + GUS_MEM_OFFSET)
399
400 #define GUS_PREC_BYTES (sc->sc_precision >> 3) /* precision to bytes */
401
402 /* splgus() must be splaudio() */
403
404 #define splgus splaudio
405
406 extern const struct audio_hw_if gus_hw_if;
407
408 #define FLIP_REV 5 /* This rev has flipped mixer chans */
409
410 void gus_subattach(struct gus_softc *, struct isa_attach_args *);
Cache object: 71b0dbad0e67760b7a4934162845c46e
|