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