xref: /openbsd/sys/dev/isa/gusvar.h (revision dda28197)
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