xref: /openbsd-src/sys/dev/isa/gus.c (revision a0747c9f67a4ae71ccb71e62a28d1ea19e06a63c)
1 /*	$OpenBSD: gus.c,v 1.48 2021/03/07 06:17:03 jsg 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  * http://www.gravis.com/Public/sdk/GUSDK222.ZIP
54  *
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 #include <sys/param.h>
92 #include <sys/systm.h>
93 #include <sys/errno.h>
94 #include <sys/ioctl.h>
95 #include <sys/syslog.h>
96 #include <sys/device.h>
97 #include <sys/buf.h>
98 #include <sys/fcntl.h>
99 #include <sys/malloc.h>
100 #include <sys/kernel.h>
101 #include <sys/timeout.h>
102 
103 #include <machine/cpu.h>
104 #include <machine/intr.h>
105 #include <machine/bus.h>
106 #include <machine/cpufunc.h>
107 #include <sys/audioio.h>
108 #include <dev/audio_if.h>
109 
110 #include <dev/isa/isavar.h>
111 #include <dev/isa/isadmavar.h>
112 
113 #include <dev/ic/ics2101reg.h>
114 #include <dev/ic/cs4231reg.h>
115 #include <dev/ic/ad1848reg.h>
116 #include <dev/isa/ics2101var.h>
117 #include <dev/isa/ad1848var.h>
118 #include <dev/isa/cs4231var.h>
119 #include "gusreg.h"
120 #include "gusvar.h"
121 
122 #ifdef AUDIO_DEBUG
123 #define GUSPLAYDEBUG	/*XXX*/
124 #define DPRINTF(x)	if (gusdebug) printf x
125 #define DMAPRINTF(x)	if (gusdmadebug) printf x
126 int	gusdebug = 0;
127 int	gusdmadebug = 0;
128 #else
129 #define DPRINTF(x)
130 #define DMAPRINTF(x)
131 #endif
132 int	gus_dostereo = 1;
133 
134 #define NDMARECS 2048
135 #ifdef GUSPLAYDEBUG
136 int	gusstats = 0;
137 
138 struct dma_record dmarecords[NDMARECS];
139 
140 int dmarecord_index = 0;
141 #endif
142 
143 struct cfdriver gus_cd = {
144 	NULL, "gus", DV_DULL
145 };
146 
147 /*
148  * A mapping from IRQ/DRQ values to the values used in the GUS's internal
149  * registers.  A zero means that the referenced IRQ/DRQ is invalid
150  */
151 const int gus_irq_map[] = {
152 	IRQUNK, IRQUNK, 1, 3, IRQUNK, 2, IRQUNK, 4, IRQUNK, 1, IRQUNK, 5, 6,
153 	IRQUNK, IRQUNK, 7
154 };
155 const int gus_drq_map[] = {
156 	DRQUNK, 1, DRQUNK, 2, DRQUNK, 3, 4, 5
157 };
158 
159 /*
160  * A list of valid base addresses for the GUS
161  */
162 
163 const int gus_base_addrs[] = {
164 	0x210, 0x220, 0x230, 0x240, 0x250, 0x260
165 };
166 const int gus_addrs = sizeof(gus_base_addrs) / sizeof(gus_base_addrs[0]);
167 
168 /*
169  * Maximum frequency values of the GUS based on the number of currently active
170  * voices.  Since the GUS samples a voice every 1.6 us, the maximum frequency
171  * is dependent on the number of active voices.  Yes, it is pretty weird.
172  */
173 
174 static const int gus_max_frequency[] = {
175 		44100,		/* 14 voices */
176 		41160,		/* 15 voices */
177 		38587,		/* 16 voices */
178 		36317,		/* 17 voices */
179 		34300,		/* 18 voices */
180 		32494,		/* 19 voices */
181 		30870,		/* 20 voices */
182 		29400,		/* 21 voices */
183 		28063,		/* 22 voices */
184 		26843,		/* 23 voices */
185 		25725,		/* 24 voices */
186 		24696,		/* 25 voices */
187 		23746,		/* 26 voices */
188 		22866,		/* 27 voices */
189 		22050,		/* 28 voices */
190 		21289,		/* 29 voices */
191 		20580,		/* 30 voices */
192 		19916,		/* 31 voices */
193 		19293		/* 32 voices */
194 };
195 /*
196  * A mapping of linear volume levels to the logarithmic volume values used
197  * by the GF1 chip on the GUS.  From GUS SDK vol1.c.
198  */
199 
200 static const unsigned short gus_log_volumes[512] = {
201  0x0000,
202  0x0700, 0x07ff, 0x0880, 0x08ff, 0x0940, 0x0980, 0x09c0, 0x09ff, 0x0a20,
203  0x0a40, 0x0a60, 0x0a80, 0x0aa0, 0x0ac0, 0x0ae0, 0x0aff, 0x0b10, 0x0b20,
204  0x0b30, 0x0b40, 0x0b50, 0x0b60, 0x0b70, 0x0b80, 0x0b90, 0x0ba0, 0x0bb0,
205  0x0bc0, 0x0bd0, 0x0be0, 0x0bf0, 0x0bff, 0x0c08, 0x0c10, 0x0c18, 0x0c20,
206  0x0c28, 0x0c30, 0x0c38, 0x0c40, 0x0c48, 0x0c50, 0x0c58, 0x0c60, 0x0c68,
207  0x0c70, 0x0c78, 0x0c80, 0x0c88, 0x0c90, 0x0c98, 0x0ca0, 0x0ca8, 0x0cb0,
208  0x0cb8, 0x0cc0, 0x0cc8, 0x0cd0, 0x0cd8, 0x0ce0, 0x0ce8, 0x0cf0, 0x0cf8,
209  0x0cff, 0x0d04, 0x0d08, 0x0d0c, 0x0d10, 0x0d14, 0x0d18, 0x0d1c, 0x0d20,
210  0x0d24, 0x0d28, 0x0d2c, 0x0d30, 0x0d34, 0x0d38, 0x0d3c, 0x0d40, 0x0d44,
211  0x0d48, 0x0d4c, 0x0d50, 0x0d54, 0x0d58, 0x0d5c, 0x0d60, 0x0d64, 0x0d68,
212  0x0d6c, 0x0d70, 0x0d74, 0x0d78, 0x0d7c, 0x0d80, 0x0d84, 0x0d88, 0x0d8c,
213  0x0d90, 0x0d94, 0x0d98, 0x0d9c, 0x0da0, 0x0da4, 0x0da8, 0x0dac, 0x0db0,
214  0x0db4, 0x0db8, 0x0dbc, 0x0dc0, 0x0dc4, 0x0dc8, 0x0dcc, 0x0dd0, 0x0dd4,
215  0x0dd8, 0x0ddc, 0x0de0, 0x0de4, 0x0de8, 0x0dec, 0x0df0, 0x0df4, 0x0df8,
216  0x0dfc, 0x0dff, 0x0e02, 0x0e04, 0x0e06, 0x0e08, 0x0e0a, 0x0e0c, 0x0e0e,
217  0x0e10, 0x0e12, 0x0e14, 0x0e16, 0x0e18, 0x0e1a, 0x0e1c, 0x0e1e, 0x0e20,
218  0x0e22, 0x0e24, 0x0e26, 0x0e28, 0x0e2a, 0x0e2c, 0x0e2e, 0x0e30, 0x0e32,
219  0x0e34, 0x0e36, 0x0e38, 0x0e3a, 0x0e3c, 0x0e3e, 0x0e40, 0x0e42, 0x0e44,
220  0x0e46, 0x0e48, 0x0e4a, 0x0e4c, 0x0e4e, 0x0e50, 0x0e52, 0x0e54, 0x0e56,
221  0x0e58, 0x0e5a, 0x0e5c, 0x0e5e, 0x0e60, 0x0e62, 0x0e64, 0x0e66, 0x0e68,
222  0x0e6a, 0x0e6c, 0x0e6e, 0x0e70, 0x0e72, 0x0e74, 0x0e76, 0x0e78, 0x0e7a,
223  0x0e7c, 0x0e7e, 0x0e80, 0x0e82, 0x0e84, 0x0e86, 0x0e88, 0x0e8a, 0x0e8c,
224  0x0e8e, 0x0e90, 0x0e92, 0x0e94, 0x0e96, 0x0e98, 0x0e9a, 0x0e9c, 0x0e9e,
225  0x0ea0, 0x0ea2, 0x0ea4, 0x0ea6, 0x0ea8, 0x0eaa, 0x0eac, 0x0eae, 0x0eb0,
226  0x0eb2, 0x0eb4, 0x0eb6, 0x0eb8, 0x0eba, 0x0ebc, 0x0ebe, 0x0ec0, 0x0ec2,
227  0x0ec4, 0x0ec6, 0x0ec8, 0x0eca, 0x0ecc, 0x0ece, 0x0ed0, 0x0ed2, 0x0ed4,
228  0x0ed6, 0x0ed8, 0x0eda, 0x0edc, 0x0ede, 0x0ee0, 0x0ee2, 0x0ee4, 0x0ee6,
229  0x0ee8, 0x0eea, 0x0eec, 0x0eee, 0x0ef0, 0x0ef2, 0x0ef4, 0x0ef6, 0x0ef8,
230  0x0efa, 0x0efc, 0x0efe, 0x0eff, 0x0f01, 0x0f02, 0x0f03, 0x0f04, 0x0f05,
231  0x0f06, 0x0f07, 0x0f08, 0x0f09, 0x0f0a, 0x0f0b, 0x0f0c, 0x0f0d, 0x0f0e,
232  0x0f0f, 0x0f10, 0x0f11, 0x0f12, 0x0f13, 0x0f14, 0x0f15, 0x0f16, 0x0f17,
233  0x0f18, 0x0f19, 0x0f1a, 0x0f1b, 0x0f1c, 0x0f1d, 0x0f1e, 0x0f1f, 0x0f20,
234  0x0f21, 0x0f22, 0x0f23, 0x0f24, 0x0f25, 0x0f26, 0x0f27, 0x0f28, 0x0f29,
235  0x0f2a, 0x0f2b, 0x0f2c, 0x0f2d, 0x0f2e, 0x0f2f, 0x0f30, 0x0f31, 0x0f32,
236  0x0f33, 0x0f34, 0x0f35, 0x0f36, 0x0f37, 0x0f38, 0x0f39, 0x0f3a, 0x0f3b,
237  0x0f3c, 0x0f3d, 0x0f3e, 0x0f3f, 0x0f40, 0x0f41, 0x0f42, 0x0f43, 0x0f44,
238  0x0f45, 0x0f46, 0x0f47, 0x0f48, 0x0f49, 0x0f4a, 0x0f4b, 0x0f4c, 0x0f4d,
239  0x0f4e, 0x0f4f, 0x0f50, 0x0f51, 0x0f52, 0x0f53, 0x0f54, 0x0f55, 0x0f56,
240  0x0f57, 0x0f58, 0x0f59, 0x0f5a, 0x0f5b, 0x0f5c, 0x0f5d, 0x0f5e, 0x0f5f,
241  0x0f60, 0x0f61, 0x0f62, 0x0f63, 0x0f64, 0x0f65, 0x0f66, 0x0f67, 0x0f68,
242  0x0f69, 0x0f6a, 0x0f6b, 0x0f6c, 0x0f6d, 0x0f6e, 0x0f6f, 0x0f70, 0x0f71,
243  0x0f72, 0x0f73, 0x0f74, 0x0f75, 0x0f76, 0x0f77, 0x0f78, 0x0f79, 0x0f7a,
244  0x0f7b, 0x0f7c, 0x0f7d, 0x0f7e, 0x0f7f, 0x0f80, 0x0f81, 0x0f82, 0x0f83,
245  0x0f84, 0x0f85, 0x0f86, 0x0f87, 0x0f88, 0x0f89, 0x0f8a, 0x0f8b, 0x0f8c,
246  0x0f8d, 0x0f8e, 0x0f8f, 0x0f90, 0x0f91, 0x0f92, 0x0f93, 0x0f94, 0x0f95,
247  0x0f96, 0x0f97, 0x0f98, 0x0f99, 0x0f9a, 0x0f9b, 0x0f9c, 0x0f9d, 0x0f9e,
248  0x0f9f, 0x0fa0, 0x0fa1, 0x0fa2, 0x0fa3, 0x0fa4, 0x0fa5, 0x0fa6, 0x0fa7,
249  0x0fa8, 0x0fa9, 0x0faa, 0x0fab, 0x0fac, 0x0fad, 0x0fae, 0x0faf, 0x0fb0,
250  0x0fb1, 0x0fb2, 0x0fb3, 0x0fb4, 0x0fb5, 0x0fb6, 0x0fb7, 0x0fb8, 0x0fb9,
251  0x0fba, 0x0fbb, 0x0fbc, 0x0fbd, 0x0fbe, 0x0fbf, 0x0fc0, 0x0fc1, 0x0fc2,
252  0x0fc3, 0x0fc4, 0x0fc5, 0x0fc6, 0x0fc7, 0x0fc8, 0x0fc9, 0x0fca, 0x0fcb,
253  0x0fcc, 0x0fcd, 0x0fce, 0x0fcf, 0x0fd0, 0x0fd1, 0x0fd2, 0x0fd3, 0x0fd4,
254  0x0fd5, 0x0fd6, 0x0fd7, 0x0fd8, 0x0fd9, 0x0fda, 0x0fdb, 0x0fdc, 0x0fdd,
255  0x0fde, 0x0fdf, 0x0fe0, 0x0fe1, 0x0fe2, 0x0fe3, 0x0fe4, 0x0fe5, 0x0fe6,
256  0x0fe7, 0x0fe8, 0x0fe9, 0x0fea, 0x0feb, 0x0fec, 0x0fed, 0x0fee, 0x0fef,
257  0x0ff0, 0x0ff1, 0x0ff2, 0x0ff3, 0x0ff4, 0x0ff5, 0x0ff6, 0x0ff7, 0x0ff8,
258  0x0ff9, 0x0ffa, 0x0ffb, 0x0ffc, 0x0ffd, 0x0ffe, 0x0fff};
259 
260 /*
261  * Interface to higher level audio driver
262  */
263 struct audio_hw_if gus_hw_if = {
264 	gusopen,
265 	gusclose,
266 	gus_set_params,
267 
268 	gus_round_blocksize,
269 
270 	gus_commit_settings,
271 
272 	NULL,
273 	NULL,
274 
275 	gus_dma_output,
276 	gus_dma_input,
277 	gus_halt_out_dma,
278 	gus_halt_in_dma,
279 	gus_speaker_ctl,
280 
281 	NULL,
282 	gus_mixer_set_port,
283 	gus_mixer_get_port,
284 	gus_mixer_query_devinfo,
285 	gus_malloc,
286 	gus_free,
287 	gus_round,
288 	gus_get_props,
289 
290 	NULL,
291 	NULL
292 };
293 
294 static struct audio_hw_if gusmax_hw_if = {
295 	gusmaxopen,
296 	gusmax_close,
297 	gusmax_set_params,
298 
299 	gusmax_round_blocksize,
300 
301 	gusmax_commit_settings,
302 
303 	NULL,
304 	NULL,
305 
306 	gusmax_dma_output,
307 	gusmax_dma_input,
308 	gusmax_halt_out_dma,
309 	gusmax_halt_in_dma,
310 
311 	gusmax_speaker_ctl,
312 
313 	NULL,
314 	gusmax_mixer_set_port,
315 	gusmax_mixer_get_port,
316 	gusmax_mixer_query_devinfo,
317 	ad1848_malloc,
318 	ad1848_free,
319 	ad1848_round,
320 	gusmax_get_props,
321 
322 	NULL,
323 	NULL
324 };
325 
326 int
327 gusopen(void *addr, int flags)
328 {
329 	struct gus_softc *sc = addr;
330 
331 	DPRINTF(("gusopen() called\n"));
332 
333 	if (sc->sc_flags & GUS_OPEN)
334 		return EBUSY;
335 
336 	/*
337 	 * Some initialization
338 	 */
339 
340 	sc->sc_flags |= GUS_OPEN;
341 	sc->sc_dmabuf = 0;
342 	sc->sc_playbuf = -1;
343 	sc->sc_bufcnt = 0;
344 	sc->sc_voc[GUS_VOICE_LEFT].start_addr = GUS_MEM_OFFSET - 1;
345 	sc->sc_voc[GUS_VOICE_LEFT].current_addr = GUS_MEM_OFFSET;
346 
347 	if (HAS_CODEC(sc)) {
348 		ad1848_open(&sc->sc_codec, flags);
349 		sc->sc_codec.mute[AD1848_AUX1_CHANNEL] = 0;
350 		ad1848_mute_channel(&sc->sc_codec, AD1848_AUX1_CHANNEL, 0); /* turn on DAC output */
351 		if (flags & FREAD) {
352 			sc->sc_codec.mute[AD1848_MONO_CHANNEL] = 0;
353 			ad1848_mute_channel(&sc->sc_codec, AD1848_MONO_CHANNEL, 0);
354 		}
355 	} else if (flags & FREAD) {
356 		/* enable/unmute the microphone */
357 		if (HAS_MIXER(sc)) {
358 			gusics_mic_mute(&sc->sc_mixer, 0);
359 		} else
360 			gus_mic_ctl(sc, SPKR_ON);
361 	}
362 	if (sc->sc_nbufs == 0)
363 	    gus_round_blocksize(sc, GUS_BUFFER_MULTIPLE); /* default blksiz */
364 	return 0;
365 }
366 
367 int
368 gusmaxopen(void *addr, int flags)
369 {
370 	struct ad1848_softc *ac = addr;
371 	return gusopen(ac->parent, flags);
372 }
373 
374 void
375 gus_deinterleave(struct gus_softc *sc, void *buf, int size)
376 {
377 	/* deinterleave the stereo data.  We can use sc->sc_deintr_buf
378 	   for scratch space. */
379 	int i;
380 
381 	if (size > sc->sc_blocksize) {
382 		printf("gus: deinterleave %d > %d\n", size, sc->sc_blocksize);
383 		return;
384 	} else if (size < sc->sc_blocksize) {
385 		DPRINTF(("gus: deinterleave %d < %d\n", size, sc->sc_blocksize));
386 	}
387 
388 	/*
389 	 * size is in bytes.
390 	 */
391 	if (sc->sc_precision == 16) {
392 		u_short *dei = sc->sc_deintr_buf;
393 		u_short *sbuf = buf;
394 		size >>= 1;		/* bytecnt to shortcnt */
395 		/* copy 2nd of each pair of samples to the staging area, while
396 		   compacting the 1st of each pair into the original area. */
397 		for (i = 0; i < size/2-1; i++)  {
398 			dei[i] = sbuf[i*2+1];
399 			sbuf[i+1] = sbuf[i*2+2];
400 		}
401 		/*
402 		 * this has copied one less sample than half of the
403 		 * buffer.  The first sample of the 1st stream was
404 		 * already in place and didn't need copying.
405 		 * Therefore, we've moved all of the 1st stream's
406 		 * samples into place.  We have one sample from 2nd
407 		 * stream in the last slot of original area, not
408 		 * copied to the staging area (But we don't need to!).
409 		 * Copy the remainder of the original stream into place.
410 		 */
411 		bcopy(dei, &sbuf[size/2], i * sizeof(short));
412 	} else {
413 		u_char *dei = sc->sc_deintr_buf;
414 		u_char *sbuf = buf;
415 		for (i = 0; i < size/2-1; i++)  {
416 			dei[i] = sbuf[i*2+1];
417 			sbuf[i+1] = sbuf[i*2+2];
418 		}
419 		bcopy(dei, &sbuf[size/2], i);
420 	}
421 }
422 
423 /*
424  * Actually output a buffer to the DSP chip
425  */
426 
427 int
428 gusmax_dma_output(void *addr, void *buf, int size, void (*intr)(void *),
429     void *arg)
430 {
431 	struct ad1848_softc *ac = addr;
432 	return gus_dma_output(ac->parent, buf, size, intr, arg);
433 }
434 
435 /*
436  * called at splaudio() from interrupt handler.
437  */
438 void
439 stereo_dmaintr(void *arg)
440 {
441     struct gus_softc *sc = arg;
442     struct stereo_dma_intr *sa = &sc->sc_stereo;
443 
444     DMAPRINTF(("stereo_dmaintr"));
445 
446     /*
447      * Put other half in its place, then call the real interrupt routine :)
448      */
449 
450     sc->sc_dmaoutintr = sa->intr;
451     sc->sc_outarg = sa->arg;
452 
453 #ifdef GUSPLAYDEBUG
454     if (gusstats) {
455       microtime(&dmarecords[dmarecord_index].tv);
456       dmarecords[dmarecord_index].gusaddr = sa->dmabuf;
457       dmarecords[dmarecord_index].bsdaddr = sa->buffer;
458       dmarecords[dmarecord_index].count = sa->size;
459       dmarecords[dmarecord_index].channel = 1;
460       dmarecords[dmarecord_index++].direction = 1;
461       dmarecord_index = dmarecord_index % NDMARECS;
462     }
463 #endif
464 
465     gusdmaout(sc, sa->flags, sa->dmabuf, (caddr_t) sa->buffer, sa->size);
466 
467     sa->flags = 0;
468     sa->dmabuf = 0;
469     sa->buffer = 0;
470     sa->size = 0;
471     sa->intr = 0;
472     sa->arg = 0;
473 }
474 
475 /*
476  * Start up DMA output to the card.
477  * Called at splaudio(), either from intr handler or from
478  * generic audio code.
479  */
480 int
481 gus_dma_output(void *addr, void *buf, int size, void (*intr)(void *), void *arg)
482 {
483 	struct gus_softc *sc = addr;
484 	u_char *buffer = buf;
485 	u_long boarddma;
486 	int flags;
487 
488 	DMAPRINTF(("gus_dma_output %d @ %p\n", size, buf));
489 	if (size != sc->sc_blocksize) {
490 	    DPRINTF(("gus_dma_output reqsize %d not sc_blocksize %d\n",
491 		     size, sc->sc_blocksize));
492 	    return EINVAL;
493 	}
494 
495 	flags = GUSMASK_DMA_WRITE;
496 	if (sc->sc_precision == 16)
497 	    flags |= GUSMASK_DMA_DATA_SIZE;
498 	if (sc->sc_encoding == AUDIO_ENCODING_ULAW ||
499 	    sc->sc_encoding == AUDIO_ENCODING_ALAW ||
500 	    sc->sc_encoding == AUDIO_ENCODING_ULINEAR_BE ||
501 	    sc->sc_encoding == AUDIO_ENCODING_ULINEAR_LE)
502 	    flags |= GUSMASK_DMA_INVBIT;
503 
504 	if (sc->sc_channels == 2) {
505 		if (sc->sc_precision == 16) {
506 			if (size & 3) {
507 				DPRINTF(("gus_dma_output: unpaired 16bit samples"));
508 				size &= 3;
509 			}
510 		} else if (size & 1) {
511 			DPRINTF(("gus_dma_output: unpaired samples"));
512 			size &= 1;
513 		}
514 		if (size == 0) {
515 			return 0;
516 		}
517 
518 		gus_deinterleave(sc, (void *)buffer, size);
519 
520 		size >>= 1;
521 
522 		boarddma = size * sc->sc_dmabuf + GUS_MEM_OFFSET;
523 
524 		sc->sc_stereo.intr = intr;
525 		sc->sc_stereo.arg = arg;
526 		sc->sc_stereo.size = size;
527 		sc->sc_stereo.dmabuf = boarddma + GUS_LEFT_RIGHT_OFFSET;
528 		sc->sc_stereo.buffer = buffer + size;
529 		sc->sc_stereo.flags = flags;
530 		if (gus_dostereo) {
531 		  intr = stereo_dmaintr;
532 		  arg = sc;
533 		}
534 	} else
535 		boarddma = size * sc->sc_dmabuf + GUS_MEM_OFFSET;
536 
537 
538 	sc->sc_flags |= GUS_LOCKED;
539 	sc->sc_dmaoutintr = intr;
540 	sc->sc_outarg = arg;
541 
542 #ifdef GUSPLAYDEBUG
543 	if (gusstats) {
544 	  microtime(&dmarecords[dmarecord_index].tv);
545 	  dmarecords[dmarecord_index].gusaddr = boarddma;
546 	  dmarecords[dmarecord_index].bsdaddr = buffer;
547 	  dmarecords[dmarecord_index].count = size;
548 	  dmarecords[dmarecord_index].channel = 0;
549 	  dmarecords[dmarecord_index++].direction = 1;
550 	  dmarecord_index = dmarecord_index % NDMARECS;
551 	}
552 #endif
553 
554 	gusdmaout(sc, flags, boarddma, (caddr_t) buffer, size);
555 	return 0;
556 }
557 
558 void
559 gusmax_close(void *addr)
560 {
561 	struct ad1848_softc *ac = addr;
562 	struct gus_softc *sc = ac->parent;
563 #if 0
564 	ac->mute[AD1848_AUX1_CHANNEL] = MUTE_ALL;
565 	ad1848_mute_channel(ac, MUTE_ALL); /* turn off DAC output */
566 #endif
567 	ad1848_close(ac);
568 	gusclose(sc);
569 }
570 
571 /*
572  * Close out device stuff.  Called at splaudio() from generic audio layer.
573  */
574 void
575 gusclose(void *addr)
576 {
577 	struct gus_softc *sc = addr;
578 
579         DPRINTF(("gus_close: sc=%p\n", sc));
580 
581 /*	if (sc->sc_flags & GUS_DMAOUT_ACTIVE) */ {
582 		gus_halt_out_dma(sc);
583 	}
584 /*	if (sc->sc_flags & GUS_DMAIN_ACTIVE) */ {
585 		gus_halt_in_dma(sc);
586 	}
587 	sc->sc_flags &= ~(GUS_OPEN|GUS_LOCKED|GUS_DMAOUT_ACTIVE|GUS_DMAIN_ACTIVE);
588 
589 	if (sc->sc_deintr_buf) {
590 		free(sc->sc_deintr_buf, M_DEVBUF, 0);
591 		sc->sc_deintr_buf = NULL;
592 	}
593 	/* turn off speaker, etc. */
594 
595 	/* make sure the voices shut up: */
596 	gus_stop_voice(sc, GUS_VOICE_LEFT, 1);
597 	gus_stop_voice(sc, GUS_VOICE_RIGHT, 0);
598 }
599 
600 /*
601  * Service interrupts.  Farm them off to helper routines if we are using the
602  * GUS for simple playback/record
603  */
604 
605 #ifdef AUDIO_DEBUG
606 int gusintrcnt;
607 int gusdmaintrcnt;
608 int gusvocintrcnt;
609 #endif
610 
611 int
612 gusintr(void *arg)
613 {
614 	struct gus_softc *sc = arg;
615 	bus_space_tag_t iot = sc->sc_iot;
616 	bus_space_handle_t ioh1 = sc->sc_ioh1;
617 	bus_space_handle_t ioh2 = sc->sc_ioh2;
618 	unsigned char intr;
619 
620 	int retval = 0;
621 
622 	DPRINTF(("gusintr\n"));
623 #ifdef AUDIO_DEBUG
624 	gusintrcnt++;
625 #endif
626 	if (HAS_CODEC(sc))
627 		retval = ad1848_intr(&sc->sc_codec);
628 	mtx_enter(&audio_lock);
629 	if ((intr = bus_space_read_1(iot, ioh1, GUS_IRQ_STATUS)) & GUSMASK_IRQ_DMATC) {
630 		DMAPRINTF(("gusintr dma flags=%x\n", sc->sc_flags));
631 #ifdef AUDIO_DEBUG
632 		gusdmaintrcnt++;
633 #endif
634 		retval += gus_dmaout_intr(sc);
635 		if (sc->sc_flags & GUS_DMAIN_ACTIVE) {
636 		    SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
637 		    intr = bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
638 		    if (intr & GUSMASK_SAMPLE_DMATC) {
639 			retval += gus_dmain_intr(sc);
640 		    }
641 		}
642 	}
643 	if (intr & (GUSMASK_IRQ_VOICE | GUSMASK_IRQ_VOLUME)) {
644 		DMAPRINTF(("gusintr voice flags=%x\n", sc->sc_flags));
645 #ifdef AUDIO_DEBUG
646 		gusvocintrcnt++;
647 #endif
648 		retval += gus_voice_intr(sc);
649 	}
650 	if (retval) {
651 		mtx_leave(&audio_lock);
652 		return 1;
653 	}
654 	mtx_leave(&audio_lock);
655 	return retval;
656 }
657 
658 int gus_bufcnt[GUS_MEM_FOR_BUFFERS / GUS_BUFFER_MULTIPLE];
659 int gus_restart;				/* how many restarts? */
660 int gus_stops;				/* how many times did voice stop? */
661 int gus_falsestops;			/* stopped but not done? */
662 int gus_continues;
663 
664 struct playcont {
665 	struct timeval tv;
666 	u_int playbuf;
667 	u_int dmabuf;
668 	u_char bufcnt;
669 	u_char vaction;
670 	u_char voccntl;
671 	u_char volcntl;
672 	u_long curaddr;
673 	u_long endaddr;
674 } playstats[NDMARECS];
675 
676 int playcntr;
677 
678 void
679 gus_dmaout_timeout(void *arg)
680 {
681 	struct gus_softc *sc = arg;
682 	bus_space_tag_t iot = sc->sc_iot;
683 	bus_space_handle_t ioh2 = sc->sc_ioh2;
684 
685 	printf("%s: dmaout timeout\n", sc->sc_dev.dv_xname);
686 	/*
687 	 * Stop any DMA.
688 	 */
689 
690 	mtx_enter(&audio_lock);
691 	SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
692 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0);
693 
694 #if 0
695 	/* XXX we will dmadone below? */
696 	isa_dmaabort(sc->sc_dev.dv_parent, sc->sc_drq);
697 #endif
698 
699 	gus_dmaout_dointr(sc);
700 	mtx_leave(&audio_lock);
701 }
702 
703 
704 /*
705  * Service DMA interrupts.  This routine will only get called if we're doing
706  * a DMA transfer for playback/record requests from the audio layer.
707  */
708 
709 int
710 gus_dmaout_intr(struct gus_softc *sc)
711 {
712 	bus_space_tag_t iot = sc->sc_iot;
713 	bus_space_handle_t ioh2 = sc->sc_ioh2;
714 
715 	/*
716 	 * If we got a DMA transfer complete from the GUS DRAM, then deal
717 	 * with it.
718 	 */
719 
720 	SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
721 	if (bus_space_read_1(iot, ioh2, GUS_DATA_HIGH) & GUSMASK_DMA_IRQPEND) {
722 	    timeout_del(&sc->sc_dma_tmo);
723 	    gus_dmaout_dointr(sc);
724 	    return 1;
725 	}
726 	return 0;
727 }
728 
729 void
730 gus_dmaout_dointr(struct gus_softc *sc)
731 {
732 	bus_space_tag_t iot = sc->sc_iot;
733 	bus_space_handle_t ioh2 = sc->sc_ioh2;
734 
735 	/* sc->sc_dmaoutcnt - 1 because DMA controller counts from zero?. */
736 	isa_dmadone(sc->sc_dev.dv_parent, sc->sc_drq);
737 	sc->sc_flags &= ~GUS_DMAOUT_ACTIVE;  /* pending DMA is done */
738 	DMAPRINTF(("gus_dmaout_dointr %d @ %p\n", sc->sc_dmaoutcnt,
739 		   sc->sc_dmaoutaddr));
740 
741 	/*
742 	 * to prevent clicking, we need to copy last sample
743 	 * from last buffer to scratch area just before beginning of
744 	 * buffer.  However, if we're doing formats that are converted by
745 	 * the card during the DMA process, we need to pick up the converted
746 	 * byte rather than the one we have in memory.
747 	 */
748 	if (sc->sc_dmabuf == sc->sc_nbufs - 1) {
749 	  int i;
750 	  switch (sc->sc_encoding) {
751 	  case AUDIO_ENCODING_SLINEAR_LE:
752 	  case AUDIO_ENCODING_SLINEAR_BE:
753 	    if (sc->sc_precision == 8)
754 	      goto byte;
755 	    /* we have the native format */
756 	    for (i = 1; i <= 2; i++)
757 	      guspoke(iot, ioh2, sc->sc_gusaddr -
758 		      (sc->sc_nbufs - 1) * sc->sc_chanblocksize - i,
759 		      sc->sc_dmaoutaddr[sc->sc_dmaoutcnt-i]);
760 	    break;
761 	  case AUDIO_ENCODING_ULINEAR_LE:
762 	  case AUDIO_ENCODING_ULINEAR_BE:
763 	    guspoke(iot, ioh2, sc->sc_gusaddr -
764 		    (sc->sc_nbufs - 1) * sc->sc_chanblocksize - 2,
765 		    guspeek(iot, ioh2,
766 			    sc->sc_gusaddr + sc->sc_chanblocksize - 2));
767 	  case AUDIO_ENCODING_ALAW:
768 	  case AUDIO_ENCODING_ULAW:
769 	  byte:
770 	    /* we need to fetch the translated byte, then stuff it. */
771 	    guspoke(iot, ioh2, sc->sc_gusaddr -
772 		    (sc->sc_nbufs - 1) * sc->sc_chanblocksize - 1,
773 		    guspeek(iot, ioh2,
774 			    sc->sc_gusaddr + sc->sc_chanblocksize - 1));
775 	    break;
776 	  }
777 	}
778 	/*
779 	 * If this is the first half of stereo, "ignore" this one
780 	 * and copy out the second half.
781 	 */
782 	if (sc->sc_dmaoutintr == stereo_dmaintr) {
783 	    (*sc->sc_dmaoutintr)(sc->sc_outarg);
784 	    return;
785 	}
786 	/*
787 	 * If the voice is stopped, then start it.  Reset the loop
788 	 * and roll bits.  Call the audio layer routine, since if
789 	 * we're starting a stopped voice, that means that the next
790 	 * buffer can be filled
791 	 */
792 
793 	sc->sc_flags &= ~GUS_LOCKED;
794 	if (sc->sc_voc[GUS_VOICE_LEFT].voccntl &
795 	    GUSMASK_VOICE_STOPPED) {
796 	    if (sc->sc_flags & GUS_PLAYING) {
797 		printf("%s: playing yet stopped?\n", sc->sc_dev.dv_xname);
798 	    }
799 	    sc->sc_bufcnt++; /* another yet to be played */
800 	    gus_start_playing(sc, sc->sc_dmabuf);
801 	    gus_restart++;
802 	} else {
803 	    /*
804 	     * set the sound action based on which buffer we
805 	     * just transferred.  If we just transferred buffer 0
806 	     * we want the sound to loop when it gets to the nth
807 	     * buffer; if we just transferred
808 	     * any other buffer, we want the sound to roll over
809 	     * at least one more time.  The voice interrupt
810 	     * handlers will take care of accounting &
811 	     * setting control bits if it's not caught up to us
812 	     * yet.
813 	     */
814 	    if (++sc->sc_bufcnt == 2) {
815 		/*
816 		 * XXX
817 		 * If we're too slow in reaction here,
818 		 * the voice could be just approaching the
819 		 * end of its run.  It should be set to stop,
820 		 * so these adjustments might not DTRT.
821 		 */
822 		if (sc->sc_dmabuf == 0 &&
823 		    sc->sc_playbuf == sc->sc_nbufs - 1) {
824 		    /* player is just at the last buf, we're at the
825 		       first.  Turn on looping, turn off rolling. */
826 		    sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_LOOP_ENABLE;
827 		    sc->sc_voc[GUS_VOICE_LEFT].volcntl &= ~GUSMASK_VOICE_ROLL;
828 		    playstats[playcntr].vaction = 3;
829 		} else {
830 		    /* player is at previous buf:
831 		       turn on rolling, turn off looping */
832 		    sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~GUSMASK_LOOP_ENABLE;
833 		    sc->sc_voc[GUS_VOICE_LEFT].volcntl |= GUSMASK_VOICE_ROLL;
834 		    playstats[playcntr].vaction = 4;
835 		}
836 #ifdef GUSPLAYDEBUG
837 		if (gusstats) {
838 		  microtime(&playstats[playcntr].tv);
839 		  playstats[playcntr].endaddr = sc->sc_voc[GUS_VOICE_LEFT].end_addr;
840 		  playstats[playcntr].voccntl = sc->sc_voc[GUS_VOICE_LEFT].voccntl;
841 		  playstats[playcntr].volcntl = sc->sc_voc[GUS_VOICE_LEFT].volcntl;
842 		  playstats[playcntr].playbuf = sc->sc_playbuf;
843 		  playstats[playcntr].dmabuf = sc->sc_dmabuf;
844 		  playstats[playcntr].bufcnt = sc->sc_bufcnt;
845 		  playstats[playcntr++].curaddr = gus_get_curaddr(sc, GUS_VOICE_LEFT);
846 		  playcntr = playcntr % NDMARECS;
847 		}
848 #endif
849 		bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, GUS_VOICE_LEFT);
850 		SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
851 		bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_LEFT].voccntl);
852 		SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
853 		bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_LEFT].volcntl);
854 	    }
855 	}
856 	gus_bufcnt[sc->sc_bufcnt-1]++;
857 	/*
858 	 * flip to the next DMA buffer
859 	 */
860 
861 	sc->sc_dmabuf = (sc->sc_dmabuf + 1) % sc->sc_nbufs;
862 	/*
863 	 * See comments below about DMA admission control strategy.
864 	 * We can call the upper level here if we have an
865 	 * idle buffer (not currently playing) to DMA into.
866 	 */
867 	if (sc->sc_dmaoutintr && sc->sc_bufcnt < sc->sc_nbufs) {
868 	    /* clean out to prevent double calls */
869 	    void (*pfunc)(void *) = sc->sc_dmaoutintr;
870 	    void *arg = sc->sc_outarg;
871 
872 	    sc->sc_outarg = 0;
873 	    sc->sc_dmaoutintr = 0;
874 	    (*pfunc)(arg);
875 	}
876 }
877 
878 /*
879  * Service voice interrupts
880  */
881 
882 int
883 gus_voice_intr(struct gus_softc *sc)
884 {
885 	bus_space_tag_t iot = sc->sc_iot;
886 	bus_space_handle_t ioh2 = sc->sc_ioh2;
887 	int ignore = 0, voice, rval = 0;
888 	unsigned char intr, status;
889 
890 	/*
891 	 * The point of this may not be obvious at first.  A voice can
892 	 * interrupt more than once; according to the GUS SDK we are supposed
893 	 * to ignore multiple interrupts for the same voice.
894 	 */
895 
896 	while(1) {
897 		SELECT_GUS_REG(iot, ioh2, GUSREG_IRQ_STATUS);
898 		intr = bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
899 
900 		if ((intr & (GUSMASK_WIRQ_VOLUME | GUSMASK_WIRQ_VOICE))
901 			== (GUSMASK_WIRQ_VOLUME | GUSMASK_WIRQ_VOICE))
902 			/*
903 			 * No more interrupts, time to return
904 			 */
905 			return rval;
906 
907 		if ((intr & GUSMASK_WIRQ_VOICE) == 0) {
908 
909 		    /*
910 		     * We've got a voice interrupt.  Ignore previous
911 		     * interrupts by the same voice.
912 		     */
913 
914 		    rval = 1;
915 		    voice = intr & GUSMASK_WIRQ_VOICEMASK;
916 
917 		    if ((1 << voice) & ignore)
918 			break;
919 
920 		    ignore |= 1 << voice;
921 
922 		    /*
923 		     * If the voice is stopped, then force it to stop
924 		     * (this stops it from continuously generating IRQs)
925 		     */
926 
927 		    SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL+0x80);
928 		    status = bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
929 		    if (status & GUSMASK_VOICE_STOPPED) {
930 			if (voice != GUS_VOICE_LEFT) {
931 			    DMAPRINTF(("%s: spurious voice %d stop?\n",
932 				       sc->sc_dev.dv_xname, voice));
933 			    gus_stop_voice(sc, voice, 0);
934 			    continue;
935 			}
936 			gus_stop_voice(sc, voice, 1);
937 			/* also kill right voice */
938 			gus_stop_voice(sc, GUS_VOICE_RIGHT, 0);
939 			sc->sc_bufcnt--; /* it finished a buffer */
940 			if (sc->sc_bufcnt > 0) {
941 			    /*
942 			     * probably a race to get here: the voice
943 			     * stopped while the DMA code was just trying to
944 			     * get the next buffer in place.
945 			     * Start the voice again.
946 			     */
947 			    printf("%s: stopped voice not drained? (%x)\n",
948 				   sc->sc_dev.dv_xname, sc->sc_bufcnt);
949 			    gus_falsestops++;
950 
951 			    sc->sc_playbuf = (sc->sc_playbuf + 1) % sc->sc_nbufs;
952 			    gus_start_playing(sc, sc->sc_playbuf);
953 			} else if (sc->sc_bufcnt < 0) {
954 			    panic("%s: negative bufcnt in stopped voice",
955 				   sc->sc_dev.dv_xname);
956 			} else {
957 			    sc->sc_playbuf = -1; /* none are active */
958 			    gus_stops++;
959 			}
960 			/* fall through to callback and admit another
961 			   buffer.... */
962 		    } else if (sc->sc_bufcnt != 0) {
963 			/*
964 			 * This should always be taken if the voice
965 			 * is not stopped.
966 			 */
967 			gus_continues++;
968 			if (gus_continue_playing(sc, voice)) {
969 				/*
970 				 * we shouldn't have continued--active DMA
971 				 * is in the way in the ring, for
972 				 * some as-yet undebugged reason.
973 				 */
974 				gus_stop_voice(sc, GUS_VOICE_LEFT, 1);
975 				/* also kill right voice */
976 				gus_stop_voice(sc, GUS_VOICE_RIGHT, 0);
977 				sc->sc_playbuf = -1;
978 				gus_stops++;
979 			}
980 		    }
981 		    /*
982 		     * call the upper level to send on down another
983 		     * block. We do admission rate control as follows:
984 		     *
985 		     * When starting up output (in the first N
986 		     * blocks), call the upper layer after the DMA is
987 		     * complete (see above in gus_dmaout_intr()).
988 		     *
989 		     * When output is already in progress and we have
990 		     * no more GUS buffers to use for DMA, the DMA
991 		     * output routines do not call the upper layer.
992 		     * Instead, we call the DMA completion routine
993 		     * here, after the voice interrupts indicating
994 		     * that it's finished with a buffer.
995 		     *
996 		     * However, don't call anything here if the DMA
997 		     * output flag is set, (which shouldn't happen)
998 		     * because we'll squish somebody else's DMA if
999 		     * that's the case.  When DMA is done, it will
1000 		     * call back if there is a spare buffer.
1001 		     */
1002 		    if (sc->sc_dmaoutintr && !(sc->sc_flags & GUS_LOCKED)) {
1003 			if (sc->sc_dmaoutintr == stereo_dmaintr)
1004 			    printf("gusdmaout botch?\n");
1005 			else {
1006 			    /* clean out to avoid double calls */
1007 			    void (*pfunc)(void *) = sc->sc_dmaoutintr;
1008 			    void *arg = sc->sc_outarg;
1009 
1010 			    sc->sc_outarg = 0;
1011 			    sc->sc_dmaoutintr = 0;
1012 			    (*pfunc)(arg);
1013 			}
1014 		    }
1015 		}
1016 
1017 		/*
1018 		 * Ignore other interrupts for now
1019 		 */
1020 	}
1021 	return 0;
1022 }
1023 
1024 void
1025 gus_start_playing(struct gus_softc *sc, int bufno)
1026 {
1027 	bus_space_tag_t iot = sc->sc_iot;
1028 	bus_space_handle_t ioh2 = sc->sc_ioh2;
1029 	/*
1030 	 * Start the voices playing, with buffer BUFNO.
1031 	 */
1032 
1033 	/*
1034 	 * Loop or roll if we have buffers ready.
1035 	 */
1036 
1037 	if (sc->sc_bufcnt == 1) {
1038 		sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~(GUSMASK_LOOP_ENABLE);
1039 		sc->sc_voc[GUS_VOICE_LEFT].volcntl &= ~(GUSMASK_VOICE_ROLL);
1040 	} else {
1041 		if (bufno == sc->sc_nbufs - 1) {
1042 			sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_LOOP_ENABLE;
1043 			sc->sc_voc[GUS_VOICE_LEFT].volcntl &= ~(GUSMASK_VOICE_ROLL);
1044 		} else {
1045 			sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~GUSMASK_LOOP_ENABLE;
1046 			sc->sc_voc[GUS_VOICE_LEFT].volcntl |= GUSMASK_VOICE_ROLL;
1047 		}
1048 	}
1049 
1050 	bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, GUS_VOICE_LEFT);
1051 
1052 	SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
1053 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_LEFT].voccntl);
1054 
1055 	SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
1056 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_LEFT].volcntl);
1057 
1058 	sc->sc_voc[GUS_VOICE_LEFT].current_addr =
1059 		GUS_MEM_OFFSET + sc->sc_chanblocksize * bufno;
1060 	sc->sc_voc[GUS_VOICE_LEFT].end_addr =
1061 		sc->sc_voc[GUS_VOICE_LEFT].current_addr + sc->sc_chanblocksize - 1;
1062 	sc->sc_voc[GUS_VOICE_RIGHT].current_addr =
1063 		sc->sc_voc[GUS_VOICE_LEFT].current_addr +
1064 		(gus_dostereo && sc->sc_channels == 2 ? GUS_LEFT_RIGHT_OFFSET : 0);
1065 	/*
1066 	 * set up right channel to just loop forever, no interrupts,
1067 	 * starting at the buffer we just filled.  We'll feed it data
1068 	 * at the same time as left channel.
1069 	 */
1070 	sc->sc_voc[GUS_VOICE_RIGHT].voccntl |= GUSMASK_LOOP_ENABLE;
1071 	sc->sc_voc[GUS_VOICE_RIGHT].volcntl &= ~(GUSMASK_VOICE_ROLL);
1072 
1073 #ifdef GUSPLAYDEBUG
1074 	if (gusstats) {
1075 		microtime(&playstats[playcntr].tv);
1076 		playstats[playcntr].curaddr = sc->sc_voc[GUS_VOICE_LEFT].current_addr;
1077 
1078 		playstats[playcntr].voccntl = sc->sc_voc[GUS_VOICE_LEFT].voccntl;
1079 		playstats[playcntr].volcntl = sc->sc_voc[GUS_VOICE_LEFT].volcntl;
1080 		playstats[playcntr].endaddr = sc->sc_voc[GUS_VOICE_LEFT].end_addr;
1081 		playstats[playcntr].playbuf = bufno;
1082 		playstats[playcntr].dmabuf = sc->sc_dmabuf;
1083 		playstats[playcntr].bufcnt = sc->sc_bufcnt;
1084 		playstats[playcntr++].vaction = 5;
1085 		playcntr = playcntr % NDMARECS;
1086 	}
1087 #endif
1088 
1089 	bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, GUS_VOICE_RIGHT);
1090 	SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
1091 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_RIGHT].voccntl);
1092 	SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
1093 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_RIGHT].volcntl);
1094 
1095 	gus_start_voice(sc, GUS_VOICE_RIGHT, 0);
1096 	gus_start_voice(sc, GUS_VOICE_LEFT, 1);
1097 	if (sc->sc_playbuf == -1)
1098 		/* mark start of playing */
1099 		sc->sc_playbuf = bufno;
1100 }
1101 
1102 int
1103 gus_continue_playing(struct gus_softc *sc, int voice)
1104 {
1105 	bus_space_tag_t iot = sc->sc_iot;
1106 	bus_space_handle_t ioh2 = sc->sc_ioh2;
1107 
1108 	/*
1109 	 * stop this voice from interrupting while we work.
1110 	 */
1111 
1112 	SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
1113 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl & ~(GUSMASK_VOICE_IRQ));
1114 
1115 	/*
1116 	 * update playbuf to point to the buffer the hardware just started
1117 	 * playing
1118 	 */
1119 	sc->sc_playbuf = (sc->sc_playbuf + 1) % sc->sc_nbufs;
1120 
1121 	/*
1122 	 * account for buffer just finished
1123 	 */
1124 	if (--sc->sc_bufcnt == 0) {
1125 		DPRINTF(("gus: bufcnt 0 on continuing voice?\n"));
1126 	}
1127 	if (sc->sc_playbuf == sc->sc_dmabuf && (sc->sc_flags & GUS_LOCKED)) {
1128 		printf("%s: continue into active dmabuf?\n", sc->sc_dev.dv_xname);
1129 		return 1;
1130 	}
1131 
1132 	/*
1133 	 * Select the end of the buffer based on the currently active
1134 	 * buffer, [plus extra contiguous buffers (if ready)].
1135 	 */
1136 
1137 	/*
1138 	 * set endpoint at end of buffer we just started playing.
1139 	 *
1140 	 * The total gets -1 because end addrs are one less than you might
1141 	 * think (the end_addr is the address of the last sample to play)
1142 	 */
1143 	gus_set_endaddr(sc, voice, GUS_MEM_OFFSET +
1144 			sc->sc_chanblocksize * (sc->sc_playbuf + 1) - 1);
1145 
1146 	if (sc->sc_bufcnt < 2) {
1147 		/*
1148 		 * Clear out the loop and roll flags, and rotate the currently
1149 		 * playing buffer.  That way, if we don't manage to get more
1150 		 * data before this buffer finishes, we'll just stop.
1151 		 */
1152 		sc->sc_voc[voice].voccntl &= ~GUSMASK_LOOP_ENABLE;
1153 		sc->sc_voc[voice].volcntl &= ~GUSMASK_VOICE_ROLL;
1154 		playstats[playcntr].vaction = 0;
1155 	} else {
1156 		/*
1157 		 * We have some buffers to play.  set LOOP if we're on the
1158 		 * last buffer in the ring, otherwise set ROLL.
1159 		 */
1160 		if (sc->sc_playbuf == sc->sc_nbufs - 1) {
1161 			sc->sc_voc[voice].voccntl |= GUSMASK_LOOP_ENABLE;
1162 			sc->sc_voc[voice].volcntl &= ~GUSMASK_VOICE_ROLL;
1163 			playstats[playcntr].vaction = 1;
1164 		} else {
1165 			sc->sc_voc[voice].voccntl &= ~GUSMASK_LOOP_ENABLE;
1166 			sc->sc_voc[voice].volcntl |= GUSMASK_VOICE_ROLL;
1167 			playstats[playcntr].vaction = 2;
1168 		}
1169 	}
1170 #ifdef GUSPLAYDEBUG
1171 	if (gusstats) {
1172 		microtime(&playstats[playcntr].tv);
1173 		playstats[playcntr].curaddr = gus_get_curaddr(sc, voice);
1174 
1175 		playstats[playcntr].voccntl = sc->sc_voc[voice].voccntl;
1176 		playstats[playcntr].volcntl = sc->sc_voc[voice].volcntl;
1177 		playstats[playcntr].endaddr = sc->sc_voc[voice].end_addr;
1178 		playstats[playcntr].playbuf = sc->sc_playbuf;
1179 		playstats[playcntr].dmabuf = sc->sc_dmabuf;
1180 		playstats[playcntr++].bufcnt = sc->sc_bufcnt;
1181 		playcntr = playcntr % NDMARECS;
1182 	}
1183 #endif
1184 
1185 	/*
1186 	 * (re-)set voice parameters.  This will reenable interrupts from this
1187 	 * voice.
1188 	 */
1189 
1190 	SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
1191 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
1192 	SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
1193 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].volcntl);
1194 	return 0;
1195 }
1196 
1197 /*
1198  * Send/receive data into GUS's DRAM using DMA.  Called at splaudio()
1199  */
1200 
1201 void
1202 gusdmaout(struct gus_softc *sc, int flags, u_long gusaddr, caddr_t buffaddr,
1203     int length)
1204 {
1205 	unsigned char c = (unsigned char) flags;
1206 	bus_space_tag_t iot = sc->sc_iot;
1207 	bus_space_handle_t ioh2 = sc->sc_ioh2;
1208 
1209 	DMAPRINTF(("gusdmaout flags=%x scflags=%x\n", flags, sc->sc_flags));
1210 
1211 	sc->sc_gusaddr = gusaddr;
1212 
1213 	/*
1214 	 * If we're using a 16 bit DMA channel, we have to jump through some
1215 	 * extra hoops; this includes translating the DRAM address a bit
1216 	 */
1217 
1218 	if (sc->sc_drq >= 4) {
1219 		c |= GUSMASK_DMA_WIDTH;
1220 		gusaddr = convert_to_16bit(gusaddr);
1221 	}
1222 
1223 	/*
1224 	 * Add flag bits that we always set - fast DMA, enable IRQ
1225 	 */
1226 
1227 	c |= GUSMASK_DMA_ENABLE | GUSMASK_DMA_R0 | GUSMASK_DMA_IRQ;
1228 
1229 	/*
1230 	 * Make sure the GUS _isn't_ setup for DMA
1231 	 */
1232 
1233 	SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
1234 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0);
1235 
1236 	/*
1237 	 * Tell the PC DMA controller to start doing DMA
1238 	 */
1239 
1240 	sc->sc_dmaoutaddr = (u_char *) buffaddr;
1241 	sc->sc_dmaoutcnt = length;
1242 	isa_dmastart(sc->sc_dev.dv_parent, sc->sc_drq, buffaddr, length,
1243 	    NULL, DMAMODE_WRITE, BUS_DMA_NOWAIT);
1244 
1245 	/*
1246 	 * Set up DMA address - use the upper 16 bits ONLY
1247 	 */
1248 
1249 	sc->sc_flags |= GUS_DMAOUT_ACTIVE;
1250 
1251 	SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_START);
1252 	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, (int) (gusaddr >> 4));
1253 
1254 	/*
1255 	 * Tell the GUS to start doing DMA
1256 	 */
1257 
1258 	SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
1259 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, c);
1260 
1261 	/*
1262 	 * XXX If we don't finish in one second, give up...
1263 	 */
1264 	timeout_add_sec(&sc->sc_dma_tmo, 1);
1265 }
1266 
1267 /*
1268  * Start a voice playing on the GUS.  Called from interrupt handler at
1269  * splaudio().
1270  */
1271 
1272 void
1273 gus_start_voice(struct gus_softc *sc, int voice, int intrs)
1274 {
1275 	bus_space_tag_t iot = sc->sc_iot;
1276 	bus_space_handle_t ioh2 = sc->sc_ioh2;
1277 	u_long start;
1278 	u_long current;
1279 	u_long end;
1280 
1281 	/*
1282 	 * Pick all the values for the voice out of the gus_voice struct
1283 	 * and use those to program the voice
1284 	 */
1285 
1286 	start = sc->sc_voc[voice].start_addr;
1287 	current = sc->sc_voc[voice].current_addr;
1288 	end = sc->sc_voc[voice].end_addr;
1289 
1290 	/*
1291 	 * If we're using 16 bit data, mangle the addresses a bit
1292 	 */
1293 
1294 	if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16) {
1295 	        /* -1 on start so that we get onto sample boundary--other
1296 		   code always sets it for 1-byte rollover protection */
1297 		start = convert_to_16bit(start-1);
1298 		current = convert_to_16bit(current);
1299 		end = convert_to_16bit(end);
1300 	}
1301 
1302 	/*
1303 	 * Select the voice we want to use, and program the data addresses
1304 	 */
1305 
1306 	bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
1307 
1308 	SELECT_GUS_REG(iot, ioh2, GUSREG_START_ADDR_HIGH);
1309 	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(start));
1310 	SELECT_GUS_REG(iot, ioh2, GUSREG_START_ADDR_LOW);
1311 	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(start));
1312 
1313 	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH);
1314 	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(current));
1315 	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW);
1316 	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(current));
1317 
1318 	SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_HIGH);
1319 	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(end));
1320 	SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_LOW);
1321 	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(end));
1322 
1323 	/*
1324 	 * (maybe) enable interrupts, disable voice stopping
1325 	 */
1326 
1327 	if (intrs) {
1328 		sc->sc_flags |= GUS_PLAYING; /* playing is about to start */
1329 		sc->sc_voc[voice].voccntl |= GUSMASK_VOICE_IRQ;
1330 		DMAPRINTF(("gus voice playing=%x\n", sc->sc_flags));
1331 	} else
1332 		sc->sc_voc[voice].voccntl &= ~GUSMASK_VOICE_IRQ;
1333 	sc->sc_voc[voice].voccntl &= ~(GUSMASK_VOICE_STOPPED |
1334 		GUSMASK_STOP_VOICE);
1335 
1336 	/*
1337 	 * Tell the GUS about it.  Note that we're doing volume ramping here
1338 	 * from 0 up to the set volume to help reduce clicks.
1339 	 */
1340 
1341 	SELECT_GUS_REG(iot, ioh2, GUSREG_START_VOLUME);
1342 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
1343 	SELECT_GUS_REG(iot, ioh2, GUSREG_END_VOLUME);
1344 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].current_volume >> 4);
1345 	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME);
1346 	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x00);
1347 	SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_RATE);
1348 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 63);
1349 
1350 	SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
1351 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
1352 	SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
1353 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
1354 	delay(50);
1355 	SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
1356 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
1357 	SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
1358 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
1359 
1360 }
1361 
1362 /*
1363  * Stop a given voice.  Called at splaudio().
1364  */
1365 
1366 void
1367 gus_stop_voice(struct gus_softc *sc, int voice, int intrs_too)
1368 {
1369 	bus_space_tag_t iot = sc->sc_iot;
1370 	bus_space_handle_t ioh2 = sc->sc_ioh2;
1371 
1372 	sc->sc_voc[voice].voccntl |= GUSMASK_VOICE_STOPPED |
1373 		GUSMASK_STOP_VOICE;
1374 	if (intrs_too) {
1375 	  sc->sc_voc[voice].voccntl &= ~(GUSMASK_VOICE_IRQ);
1376 	  /* no more DMA to do */
1377 	  sc->sc_flags &= ~GUS_PLAYING;
1378 	}
1379 	DMAPRINTF(("gusintr voice notplaying=%x\n", sc->sc_flags));
1380 
1381 	guspoke(iot, ioh2, 0L, 0);
1382 
1383 	bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
1384 
1385 	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME);
1386 	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
1387 	SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
1388 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
1389 	delay(100);
1390 	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME);
1391 	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
1392 	SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
1393 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
1394 
1395 	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH);
1396 	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
1397 	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW);
1398 	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
1399 
1400 }
1401 
1402 
1403 /*
1404  * Set the volume of a given voice.  Called at splaudio().
1405  */
1406 void
1407 gus_set_volume(struct gus_softc *sc, int voice, int volume)
1408 {
1409 	bus_space_tag_t iot = sc->sc_iot;
1410 	bus_space_handle_t ioh2 = sc->sc_ioh2;
1411 	unsigned int gusvol;
1412 
1413 	gusvol = gus_log_volumes[volume < 512 ? volume : 511];
1414 
1415 	sc->sc_voc[voice].current_volume = gusvol;
1416 
1417 	bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
1418 
1419 	SELECT_GUS_REG(iot, ioh2, GUSREG_START_VOLUME);
1420 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (unsigned char) (gusvol >> 4));
1421 
1422 	SELECT_GUS_REG(iot, ioh2, GUSREG_END_VOLUME);
1423 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (unsigned char) (gusvol >> 4));
1424 
1425 	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME);
1426 	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, gusvol << 4);
1427 	delay(500);
1428 	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, gusvol << 4);
1429 
1430 }
1431 
1432 /*
1433  * Interface to the audio layer.
1434  */
1435 
1436 int
1437 gusmax_set_params(void *addr, int setmode, int usemode, struct audio_params *p,
1438     struct audio_params *r)
1439 {
1440 	struct ad1848_softc *ac = addr;
1441 	struct gus_softc *sc = ac->parent;
1442 	int error;
1443 
1444 	error = ad1848_set_params(ac, setmode, usemode, p, r);
1445 	if (error)
1446 		return error;
1447 	error = gus_set_params(sc, setmode, usemode, p, r);
1448 	return error;
1449 }
1450 
1451 int
1452 gus_set_params(void *addr, int setmode, int usemode, struct audio_params *p,
1453     struct audio_params *r)
1454 {
1455 	struct gus_softc *sc = addr;
1456 
1457 	switch (p->encoding) {
1458 	case AUDIO_ENCODING_SLINEAR_LE:
1459 	case AUDIO_ENCODING_ULINEAR_LE:
1460 		break;
1461 	default:
1462 		return (EINVAL);
1463 	}
1464 
1465 	/* XXX: why?! this is called with interrupts disabled */
1466 	mtx_enter(&audio_lock);
1467 
1468 	if (p->precision == 8) {
1469 		sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~GUSMASK_DATA_SIZE16;
1470 		sc->sc_voc[GUS_VOICE_RIGHT].voccntl &= ~GUSMASK_DATA_SIZE16;
1471 	} else {
1472 		sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_DATA_SIZE16;
1473 		sc->sc_voc[GUS_VOICE_RIGHT].voccntl |= GUSMASK_DATA_SIZE16;
1474 	}
1475 
1476 	sc->sc_encoding = p->encoding;
1477 	sc->sc_precision = p->precision;
1478 	sc->sc_channels = p->channels;
1479 
1480 	mtx_leave(&audio_lock);
1481 
1482 	if (p->sample_rate > gus_max_frequency[sc->sc_voices - GUS_MIN_VOICES])
1483 		p->sample_rate = gus_max_frequency[sc->sc_voices - GUS_MIN_VOICES];
1484 	if (setmode & AUMODE_RECORD)
1485 		sc->sc_irate = p->sample_rate;
1486 	if (setmode & AUMODE_PLAY)
1487 		sc->sc_orate = p->sample_rate;
1488 
1489 	p->bps = AUDIO_BPS(p->precision);
1490 	r->bps = AUDIO_BPS(r->precision);
1491 	p->msb = r->msb = 1;
1492 
1493 	return 0;
1494 }
1495 
1496 /*
1497  * Interface to the audio layer - set the blocksize to the correct number
1498  * of units
1499  */
1500 
1501 int
1502 gusmax_round_blocksize(void *addr, int blocksize)
1503 {
1504 	struct ad1848_softc *ac = addr;
1505 	struct gus_softc *sc = ac->parent;
1506 
1507 /*	blocksize = ad1848_round_blocksize(ac, blocksize);*/
1508 	return gus_round_blocksize(sc, blocksize);
1509 }
1510 
1511 int
1512 gus_round_blocksize(void *addr, int blocksize)
1513 {
1514 	struct gus_softc *sc = addr;
1515 
1516 	DPRINTF(("gus_round_blocksize called\n"));
1517 
1518 	if ((sc->sc_encoding == AUDIO_ENCODING_ULAW ||
1519 	     sc->sc_encoding == AUDIO_ENCODING_ALAW) && blocksize > 32768)
1520 		blocksize = 32768;
1521 	else if (blocksize > 65536)
1522 		blocksize = 65536;
1523 
1524 	if ((blocksize % GUS_BUFFER_MULTIPLE) != 0)
1525 		blocksize = (blocksize / GUS_BUFFER_MULTIPLE + 1) *
1526 			GUS_BUFFER_MULTIPLE;
1527 
1528 	/* set up temporary buffer to hold the deinterleave, if necessary
1529 	   for stereo output */
1530 	if (sc->sc_deintr_buf) {
1531 		free(sc->sc_deintr_buf, M_DEVBUF, 0);
1532 		sc->sc_deintr_buf = NULL;
1533 	}
1534 	sc->sc_deintr_buf = malloc(blocksize/2, M_DEVBUF, M_WAITOK);
1535 
1536 	sc->sc_blocksize = blocksize;
1537 	/* multi-buffering not quite working yet. */
1538 	sc->sc_nbufs = /*GUS_MEM_FOR_BUFFERS / blocksize*/ 2;
1539 
1540 	gus_set_chan_addrs(sc);
1541 
1542 	return blocksize;
1543 }
1544 
1545 int
1546 gus_get_out_gain(caddr_t addr)
1547 {
1548 	struct gus_softc *sc = (struct gus_softc *) addr;
1549 
1550 	DPRINTF(("gus_get_out_gain called\n"));
1551 	return sc->sc_ogain / 2;
1552 }
1553 
1554 inline void
1555 gus_set_voices(struct gus_softc *sc, int voices)
1556 {
1557 	bus_space_tag_t iot = sc->sc_iot;
1558 	bus_space_handle_t ioh2 = sc->sc_ioh2;
1559 	/*
1560 	 * Select the active number of voices
1561 	 */
1562 
1563 	SELECT_GUS_REG(iot, ioh2, GUSREG_ACTIVE_VOICES);
1564 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (voices-1) | 0xc0);
1565 
1566 	sc->sc_voices = voices;
1567 }
1568 
1569 /*
1570  * Actually set the settings of various values on the card
1571  */
1572 
1573 int
1574 gusmax_commit_settings(void *addr)
1575 {
1576 	struct ad1848_softc *ac = addr;
1577 	struct gus_softc *sc = ac->parent;
1578 	int error;
1579 
1580 	error = ad1848_commit_settings(ac);
1581 	if (error)
1582 		return error;
1583 	return gus_commit_settings(sc);
1584 }
1585 
1586 /*
1587  * Commit the settings.  Called at normal IPL.
1588  */
1589 int
1590 gus_commit_settings(void *addr)
1591 {
1592 	struct gus_softc *sc = addr;
1593 
1594 	DPRINTF(("gus_commit_settings called (gain = %d)\n",sc->sc_ogain));
1595 
1596 
1597 	/* XXX: why?! this is called with interrupts disabled */
1598 	mtx_enter(&audio_lock);
1599 
1600 	gus_set_recrate(sc, sc->sc_irate);
1601 	gus_set_volume(sc, GUS_VOICE_LEFT, sc->sc_ogain);
1602 	gus_set_volume(sc, GUS_VOICE_RIGHT, sc->sc_ogain);
1603 	gus_set_samprate(sc, GUS_VOICE_LEFT, sc->sc_orate);
1604 	gus_set_samprate(sc, GUS_VOICE_RIGHT, sc->sc_orate);
1605 	mtx_leave(&audio_lock);
1606 	gus_set_chan_addrs(sc);
1607 
1608 	return 0;
1609 }
1610 
1611 void
1612 gus_set_chan_addrs(struct gus_softc *sc)
1613 {
1614 	/*
1615 	 * We use sc_nbufs * blocksize bytes of storage in the on-board GUS
1616 	 * ram.
1617 	 * For mono, each of the sc_nbufs buffers is DMA'd to in one chunk,
1618 	 * and both left & right channels play the same buffer.
1619 	 *
1620 	 * For stereo, each channel gets a contiguous half of the memory,
1621 	 * and each has sc_nbufs buffers of size blocksize/2.
1622 	 * Stereo data are deinterleaved in main memory before the DMA out
1623 	 * routines are called to queue the output.
1624 	 *
1625 	 * The blocksize per channel is kept in sc_chanblocksize.
1626 	 */
1627 	if (sc->sc_channels == 2)
1628 	    sc->sc_chanblocksize = sc->sc_blocksize/2;
1629 	else
1630 	    sc->sc_chanblocksize = sc->sc_blocksize;
1631 
1632 	sc->sc_voc[GUS_VOICE_LEFT].start_addr = GUS_MEM_OFFSET - 1;
1633 	sc->sc_voc[GUS_VOICE_RIGHT].start_addr =
1634 	    (gus_dostereo && sc->sc_channels == 2 ? GUS_LEFT_RIGHT_OFFSET : 0)
1635 	      + GUS_MEM_OFFSET - 1;
1636 	sc->sc_voc[GUS_VOICE_RIGHT].current_addr =
1637 	    sc->sc_voc[GUS_VOICE_RIGHT].start_addr + 1;
1638 	sc->sc_voc[GUS_VOICE_RIGHT].end_addr =
1639 	    sc->sc_voc[GUS_VOICE_RIGHT].start_addr +
1640 	    sc->sc_nbufs * sc->sc_chanblocksize;
1641 
1642 }
1643 
1644 /*
1645  * Set the sample rate of the given voice.  Called at splaudio().
1646  */
1647 
1648 void
1649 gus_set_samprate(struct gus_softc *sc, int voice, int freq)
1650 {
1651 	bus_space_tag_t iot = sc->sc_iot;
1652 	bus_space_handle_t ioh2 = sc->sc_ioh2;
1653 	unsigned int fc;
1654 	u_long temp, f = (u_long) freq;
1655 
1656 	/*
1657 	 * calculate fc based on the number of active voices;
1658 	 * we need to use longs to preserve enough bits
1659 	 */
1660 
1661 	temp = (u_long) gus_max_frequency[sc->sc_voices-GUS_MIN_VOICES];
1662 
1663 	fc = (unsigned int)(((f << 9L) + (temp >> 1L)) / temp);
1664 
1665 	fc <<= 1;
1666 
1667 
1668 	/*
1669 	 * Program the voice frequency, and set it in the voice data record
1670 	 */
1671 
1672 	bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
1673 	SELECT_GUS_REG(iot, ioh2, GUSREG_FREQ_CONTROL);
1674 	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, fc);
1675 
1676 	sc->sc_voc[voice].rate = freq;
1677 
1678 }
1679 
1680 /*
1681  * Set the sample rate of the recording frequency.  Formula is from the GUS
1682  * SDK.  Called at splaudio().
1683  */
1684 
1685 void
1686 gus_set_recrate(struct gus_softc *sc, u_long rate)
1687 {
1688 	bus_space_tag_t iot = sc->sc_iot;
1689 	bus_space_handle_t ioh2 = sc->sc_ioh2;
1690 	u_char realrate;
1691 	DPRINTF(("gus_set_recrate %lu\n", rate));
1692 
1693 #if 0
1694 	realrate = 9878400/(16*(rate+2)); /* formula from GUS docs */
1695 #endif
1696 	realrate = (9878400 >> 4)/rate - 2; /* formula from code, sigh. */
1697 
1698 	SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_FREQ);
1699 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, realrate);
1700 }
1701 
1702 /*
1703  * Interface to the audio layer - turn the output on or off.  Note that some
1704  * of these bits are flipped in the register
1705  */
1706 
1707 int
1708 gusmax_speaker_ctl(void *addr, int newstate)
1709 {
1710 	struct ad1848_softc *sc = addr;
1711 	return gus_speaker_ctl(sc->parent, newstate);
1712 }
1713 
1714 int
1715 gus_speaker_ctl(void *addr, int newstate)
1716 {
1717 	struct gus_softc *sc = (struct gus_softc *) addr;
1718 	bus_space_tag_t iot = sc->sc_iot;
1719 	bus_space_handle_t ioh1 = sc->sc_ioh1;
1720 
1721 	/* Line out bit is flipped: 0 enables, 1 disables */
1722 	if ((newstate == SPKR_ON) &&
1723 	    (sc->sc_mixcontrol & GUSMASK_LINE_OUT)) {
1724 		sc->sc_mixcontrol &= ~GUSMASK_LINE_OUT;
1725 		bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
1726 	}
1727 	if ((newstate == SPKR_OFF) &&
1728 	    (sc->sc_mixcontrol & GUSMASK_LINE_OUT) == 0) {
1729 		sc->sc_mixcontrol |= GUSMASK_LINE_OUT;
1730 		bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
1731 	}
1732 
1733 	return 0;
1734 }
1735 
1736 int
1737 gus_linein_ctl(void *addr, int newstate)
1738 {
1739 	struct gus_softc *sc = (struct gus_softc *) addr;
1740 	bus_space_tag_t iot = sc->sc_iot;
1741 	bus_space_handle_t ioh1 = sc->sc_ioh1;
1742 
1743 	/* Line in bit is flipped: 0 enables, 1 disables */
1744 	if ((newstate == SPKR_ON) &&
1745 	    (sc->sc_mixcontrol & GUSMASK_LINE_IN)) {
1746 		sc->sc_mixcontrol &= ~GUSMASK_LINE_IN;
1747 		bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
1748 	}
1749 	if ((newstate == SPKR_OFF) &&
1750 	    (sc->sc_mixcontrol & GUSMASK_LINE_IN) == 0) {
1751 		sc->sc_mixcontrol |= GUSMASK_LINE_IN;
1752 		bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
1753 	}
1754 
1755 	return 0;
1756 }
1757 
1758 int
1759 gus_mic_ctl(void *addr, int newstate)
1760 {
1761 	struct gus_softc *sc = (struct gus_softc *) addr;
1762 	bus_space_tag_t iot = sc->sc_iot;
1763 	bus_space_handle_t ioh1 = sc->sc_ioh1;
1764 
1765 	/* Mic bit is normal: 1 enables, 0 disables */
1766 	if ((newstate == SPKR_ON) &&
1767 	    (sc->sc_mixcontrol & GUSMASK_MIC_IN) == 0) {
1768 		sc->sc_mixcontrol |= GUSMASK_MIC_IN;
1769 		bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
1770 	}
1771 	if ((newstate == SPKR_OFF) &&
1772 	    (sc->sc_mixcontrol & GUSMASK_MIC_IN)) {
1773 		sc->sc_mixcontrol &= ~GUSMASK_MIC_IN;
1774 		bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
1775 	}
1776 
1777 	return 0;
1778 }
1779 
1780 /*
1781  * Set the end address of a give voice.  Called at splaudio().
1782  */
1783 
1784 void
1785 gus_set_endaddr(struct gus_softc *sc, int voice, u_long addr)
1786 {
1787 	bus_space_tag_t iot = sc->sc_iot;
1788 	bus_space_handle_t ioh2 = sc->sc_ioh2;
1789 
1790 	sc->sc_voc[voice].end_addr = addr;
1791 
1792 	if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16)
1793 		addr = convert_to_16bit(addr);
1794 
1795 	SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_HIGH);
1796 	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(addr));
1797 	SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_LOW);
1798 	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(addr));
1799 
1800 }
1801 
1802 #ifdef GUSPLAYDEBUG
1803 /*
1804  * Set current address.  Called at splaudio().
1805  */
1806 void
1807 gus_set_curaddr(struct gus_softc *sc, int voice, u_long addr)
1808 {
1809 	bus_space_tag_t iot = sc->sc_iot;
1810 	bus_space_handle_t ioh2 = sc->sc_ioh2;
1811 
1812 	sc->sc_voc[voice].current_addr = addr;
1813 
1814 	if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16)
1815 		addr = convert_to_16bit(addr);
1816 
1817 	bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
1818 
1819 	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH);
1820 	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(addr));
1821 	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW);
1822 	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(addr));
1823 
1824 }
1825 
1826 /*
1827  * Get current GUS playback address.  Called at splaudio().
1828  */
1829 u_long
1830 gus_get_curaddr(struct gus_softc *sc, int voice)
1831 {
1832 	bus_space_tag_t iot = sc->sc_iot;
1833 	bus_space_handle_t ioh2 = sc->sc_ioh2;
1834 	u_long addr;
1835 
1836 	bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
1837 	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH|GUSREG_READ);
1838 	addr = (bus_space_read_2(iot, ioh2, GUS_DATA_LOW) & 0x1fff) << 7;
1839 	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW|GUSREG_READ);
1840 	addr |= (bus_space_read_2(iot, ioh2, GUS_DATA_LOW) >> 9L) & 0x7f;
1841 
1842 	if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16)
1843 	    addr = (addr & 0xc0000) | ((addr & 0x1ffff) << 1); /* undo 16-bit change */
1844 	DPRINTF(("gus voice %d curaddr %ld end_addr %ld\n",
1845 		 voice, addr, sc->sc_voc[voice].end_addr));
1846 	/* XXX sanity check the address? */
1847 
1848 	return(addr);
1849 }
1850 #endif
1851 
1852 /*
1853  * Convert an address value to a "16 bit" value - why this is necessary I
1854  * have NO idea
1855  */
1856 
1857 u_long
1858 convert_to_16bit(u_long address)
1859 {
1860 	u_long old_address;
1861 
1862 	old_address = address;
1863 	address >>= 1;
1864 	address &= 0x0001ffffL;
1865 	address |= (old_address & 0x000c0000L);
1866 
1867 	return (address);
1868 }
1869 
1870 /*
1871  * Write a value into the GUS's DRAM
1872  */
1873 
1874 void
1875 guspoke(bus_space_tag_t iot, bus_space_handle_t ioh2, long address,
1876     unsigned char value)
1877 {
1878 
1879 	/*
1880 	 * Select the DRAM address
1881 	 */
1882 
1883 	SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_LOW);
1884 	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, (unsigned int) (address & 0xffff));
1885 	SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_HIGH);
1886 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (unsigned char) ((address >> 16) & 0xff));
1887 
1888 	/*
1889 	 * Actually write the data
1890 	 */
1891 
1892 	bus_space_write_1(iot, ioh2, GUS_DRAM_DATA, value);
1893 }
1894 
1895 /*
1896  * Read a value from the GUS's DRAM
1897  */
1898 
1899 unsigned char
1900 guspeek(bus_space_tag_t iot, bus_space_handle_t ioh2, u_long address)
1901 {
1902 
1903 	/*
1904 	 * Select the DRAM address
1905 	 */
1906 
1907 	SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_LOW);
1908 	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, (unsigned int) (address & 0xffff));
1909 	SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_HIGH);
1910 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (unsigned char) ((address >> 16) & 0xff));
1911 
1912 	/*
1913 	 * Read in the data from the board
1914 	 */
1915 
1916 	return (unsigned char) bus_space_read_1(iot, ioh2, GUS_DRAM_DATA);
1917 }
1918 
1919 /*
1920  * Reset the Gravis UltraSound card, completely
1921  */
1922 
1923 void
1924 gusreset(struct gus_softc *sc, int voices)
1925 {
1926 	bus_space_tag_t iot = sc->sc_iot;
1927 	bus_space_handle_t ioh1 = sc->sc_ioh1;
1928 	bus_space_handle_t ioh2 = sc->sc_ioh2;
1929 	bus_space_handle_t ioh4 = sc->sc_ioh4;
1930 	int i;
1931 
1932 	mtx_enter(&audio_lock);
1933 
1934 	/*
1935 	 * Reset the GF1 chip
1936 	 */
1937 
1938 	SELECT_GUS_REG(iot, ioh2, GUSREG_RESET);
1939 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
1940 
1941 	delay(500);
1942 
1943 	/*
1944 	 * Release reset
1945 	 */
1946 
1947 	SELECT_GUS_REG(iot, ioh2, GUSREG_RESET);
1948 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, GUSMASK_MASTER_RESET);
1949 
1950 	delay(500);
1951 
1952 	/*
1953 	 * Reset MIDI port as well, if applicable
1954 	 */
1955 
1956 	if (ioh4 != (bus_space_handle_t)NULL) {
1957 		bus_space_write_1(iot, ioh4, GUS_MIDI_CONTROL, MIDI_RESET);
1958 
1959 		delay(500);
1960 
1961 		bus_space_write_1(iot, ioh4, GUS_MIDI_CONTROL, 0x00);
1962 	}
1963 
1964 	/*
1965 	 * Clear interrupts
1966 	 */
1967 
1968 	SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
1969 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
1970 	SELECT_GUS_REG(iot, ioh2, GUSREG_TIMER_CONTROL);
1971 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
1972 	SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
1973 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
1974 
1975 	gus_set_voices(sc, voices);
1976 
1977 	bus_space_read_1(iot, ioh1, GUS_IRQ_STATUS);
1978 	SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
1979 	bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
1980 	SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
1981 	bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
1982 	SELECT_GUS_REG(iot, ioh2, GUSREG_IRQ_STATUS);
1983 	bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
1984 
1985 	/*
1986 	 * Reset voice specific information
1987 	 */
1988 
1989 	for(i = 0; i < voices; i++) {
1990 		bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) i);
1991 
1992 		SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
1993 
1994 		sc->sc_voc[i].voccntl = GUSMASK_VOICE_STOPPED |
1995 			GUSMASK_STOP_VOICE;
1996 
1997 		bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[i].voccntl);
1998 
1999 		sc->sc_voc[i].volcntl = GUSMASK_VOLUME_STOPPED |
2000 				GUSMASK_STOP_VOLUME;
2001 
2002 		SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
2003 		bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[i].volcntl);
2004 
2005 		delay(100);
2006 
2007 		gus_set_samprate(sc, i, 8000);
2008 		SELECT_GUS_REG(iot, ioh2, GUSREG_START_ADDR_HIGH);
2009 		bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2010 		SELECT_GUS_REG(iot, ioh2, GUSREG_START_ADDR_LOW);
2011 		bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2012 		SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_HIGH);
2013 		bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2014 		SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_LOW);
2015 		bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2016 		SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_RATE);
2017 		bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x01);
2018 		SELECT_GUS_REG(iot, ioh2, GUSREG_START_VOLUME);
2019 		bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x10);
2020 		SELECT_GUS_REG(iot, ioh2, GUSREG_END_VOLUME);
2021 		bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0xe0);
2022 		SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME);
2023 		bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2024 
2025 		SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH);
2026 		bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2027 		SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW);
2028 		bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2029 		SELECT_GUS_REG(iot, ioh2, GUSREG_PAN_POS);
2030 		bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x07);
2031 	}
2032 
2033 	/*
2034 	 * Clear out any pending IRQs
2035 	 */
2036 
2037 	bus_space_read_1(iot, ioh1, GUS_IRQ_STATUS);
2038 	SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
2039 	bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
2040 	SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
2041 	bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
2042 	SELECT_GUS_REG(iot, ioh2, GUSREG_IRQ_STATUS);
2043 	bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
2044 
2045 	SELECT_GUS_REG(iot, ioh2, GUSREG_RESET);
2046 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, GUSMASK_MASTER_RESET | GUSMASK_DAC_ENABLE |
2047 		GUSMASK_IRQ_ENABLE);
2048 
2049 	mtx_leave(&audio_lock);
2050 }
2051 
2052 
2053 int
2054 gus_init_cs4231(struct gus_softc *sc)
2055 {
2056 	bus_space_tag_t iot = sc->sc_iot;
2057 	bus_space_handle_t ioh1 = sc->sc_ioh1;
2058 	int port = sc->sc_iobase;
2059 	u_char ctrl;
2060 
2061 	ctrl = (port & 0xf0) >> 4;	/* set port address middle nibble */
2062 	/*
2063 	 * The codec is a bit weird--swapped dma channels.
2064 	 */
2065 	ctrl |= GUS_MAX_CODEC_ENABLE;
2066 	if (sc->sc_drq >= 4)
2067 		ctrl |= GUS_MAX_RECCHAN16;
2068 	if (sc->sc_recdrq >= 4)
2069 		ctrl |= GUS_MAX_PLAYCHAN16;
2070 
2071 	bus_space_write_1(iot, ioh1, GUS_MAX_CTRL, ctrl);
2072 
2073 	sc->sc_codec.sc_iot = sc->sc_iot;
2074 	sc->sc_codec.sc_iobase = port+GUS_MAX_CODEC_BASE;
2075 
2076 	if (ad1848_mapprobe(&sc->sc_codec, sc->sc_codec.sc_iobase) == 0) {
2077 		sc->sc_flags &= ~GUS_CODEC_INSTALLED;
2078 		return (0);
2079 	} else {
2080 		struct ad1848_volume vol = {AUDIO_MAX_GAIN, AUDIO_MAX_GAIN};
2081 		sc->sc_flags |= GUS_CODEC_INSTALLED;
2082 		sc->sc_codec.parent = sc;
2083 		sc->sc_codec.sc_drq = sc->sc_recdrq;
2084 		sc->sc_codec.sc_recdrq = sc->sc_drq;
2085 		gus_hw_if = gusmax_hw_if;
2086 		/* enable line in and mic in the GUS mixer; the codec chip
2087 		   will do the real mixing for them. */
2088 		sc->sc_mixcontrol &= ~GUSMASK_LINE_IN; /* 0 enables. */
2089 		sc->sc_mixcontrol |= GUSMASK_MIC_IN; /* 1 enables. */
2090 		bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
2091 
2092 		ad1848_attach(&sc->sc_codec);
2093 		/* turn on pre-MUX microphone gain. */
2094 		ad1848_set_mic_gain(&sc->sc_codec, &vol);
2095 
2096 		return (1);
2097 	}
2098 }
2099 
2100 /*
2101  * stubs (XXX)
2102  */
2103 
2104 int
2105 gus_set_in_gain(caddr_t addr, u_int gain,  u_char balance)
2106 {
2107 	DPRINTF(("gus_set_in_gain called\n"));
2108 	return 0;
2109 }
2110 
2111 int
2112 gus_get_in_gain(caddr_t addr)
2113 {
2114 	DPRINTF(("gus_get_in_gain called\n"));
2115 	return 0;
2116 }
2117 
2118 int
2119 gusmax_dma_input(void *addr, void *buf, int size, void (*callback)(void *),
2120     void *arg)
2121 {
2122 	struct ad1848_softc *sc = addr;
2123 	return gus_dma_input(sc->parent, buf, size, callback, arg);
2124 }
2125 
2126 /*
2127  * Start sampling the input source into the requested DMA buffer.
2128  * Called at splaudio(), either from top-half or from interrupt handler.
2129  */
2130 int
2131 gus_dma_input(void *addr, void *buf, int size, void (*callback)(void *),
2132     void *arg)
2133 {
2134 	struct gus_softc *sc = addr;
2135 	bus_space_tag_t iot = sc->sc_iot;
2136 	bus_space_handle_t ioh2 = sc->sc_ioh2;
2137 	u_char dmac;
2138 	DMAPRINTF(("gus_dma_input called\n"));
2139 
2140 	/*
2141 	 * Sample SIZE bytes of data from the card, into buffer at BUF.
2142 	 */
2143 	if (sc->sc_precision == 16) {
2144 	    return EINVAL;		/* XXX */
2145 	}
2146 
2147 	/* set DMA modes */
2148 	dmac = GUSMASK_SAMPLE_IRQ|GUSMASK_SAMPLE_START;
2149 	if (sc->sc_recdrq >= 4)
2150 		dmac |= GUSMASK_SAMPLE_DATA16;
2151 	if (sc->sc_encoding == AUDIO_ENCODING_ULAW ||
2152 	    sc->sc_encoding == AUDIO_ENCODING_ALAW ||
2153 	    sc->sc_encoding == AUDIO_ENCODING_ULINEAR_LE ||
2154 	    sc->sc_encoding == AUDIO_ENCODING_ULINEAR_BE)
2155 	    dmac |= GUSMASK_SAMPLE_INVBIT;
2156 	if (sc->sc_channels == 2)
2157 	    dmac |= GUSMASK_SAMPLE_STEREO;
2158 	isa_dmastart(sc->sc_dev.dv_parent, sc->sc_recdrq, buf, size,
2159 	    NULL, DMAMODE_READ, BUS_DMA_NOWAIT);
2160 
2161 	DMAPRINTF(("gus_dma_input isadma_started\n"));
2162 	sc->sc_flags |= GUS_DMAIN_ACTIVE;
2163 	sc->sc_dmainintr = callback;
2164 	sc->sc_inarg = arg;
2165 	sc->sc_dmaincnt = size;
2166 	sc->sc_dmainaddr = buf;
2167 
2168 	SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
2169 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, dmac);	/* Go! */
2170 
2171 
2172 	DMAPRINTF(("gus_dma_input returning\n"));
2173 	return 0;
2174 }
2175 
2176 int
2177 gus_dmain_intr(struct gus_softc *sc)
2178 {
2179         void (*callback)(void *);
2180 	void *arg;
2181 
2182 	DMAPRINTF(("gus_dmain_intr called\n"));
2183 	if (sc->sc_dmainintr) {
2184 	    isa_dmadone(sc->sc_dev.dv_parent, sc->sc_recdrq);
2185 	    callback = sc->sc_dmainintr;
2186 	    arg = sc->sc_inarg;
2187 
2188 	    sc->sc_dmainaddr = 0;
2189 	    sc->sc_dmaincnt = 0;
2190 	    sc->sc_dmainintr = 0;
2191 	    sc->sc_inarg = 0;
2192 
2193 	    sc->sc_flags &= ~GUS_DMAIN_ACTIVE;
2194 	    DMAPRINTF(("calling dmain_intr callback %p(%p)\n", callback, arg));
2195 	    (*callback)(arg);
2196 	    return 1;
2197 	} else {
2198 	    DMAPRINTF(("gus_dmain_intr false?\n"));
2199 	    return 0;			/* XXX ??? */
2200 	}
2201 }
2202 
2203 int
2204 gusmax_halt_out_dma(void *addr)
2205 {
2206 	struct ad1848_softc *sc = addr;
2207 	return gus_halt_out_dma(sc->parent);
2208 }
2209 
2210 
2211 int
2212 gusmax_halt_in_dma(void *addr)
2213 {
2214 	struct ad1848_softc *sc = addr;
2215 	return gus_halt_in_dma(sc->parent);
2216 }
2217 
2218 /*
2219  * Stop any DMA output.  Called at splaudio().
2220  */
2221 int
2222 gus_halt_out_dma(void *addr)
2223 {
2224 	struct gus_softc *sc = addr;
2225 	bus_space_tag_t iot = sc->sc_iot;
2226 	bus_space_handle_t ioh2 = sc->sc_ioh2;
2227 
2228 	mtx_enter(&audio_lock);
2229 	DMAPRINTF(("gus_halt_out_dma called\n"));
2230 	/*
2231 	 * Make sure the GUS _isn't_ setup for DMA
2232 	 */
2233 
2234 	SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
2235 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0);
2236 
2237 	timeout_del(&sc->sc_dma_tmo);
2238 	isa_dmaabort(sc->sc_dev.dv_parent, sc->sc_drq);
2239 	sc->sc_flags &= ~(GUS_DMAOUT_ACTIVE|GUS_LOCKED);
2240 	sc->sc_dmaoutintr = 0;
2241 	sc->sc_outarg = 0;
2242 	sc->sc_dmaoutaddr = 0;
2243 	sc->sc_dmaoutcnt = 0;
2244 	sc->sc_dmabuf = 0;
2245 	sc->sc_bufcnt = 0;
2246 	sc->sc_playbuf = -1;
2247 	/* also stop playing */
2248 	gus_stop_voice(sc, GUS_VOICE_LEFT, 1);
2249 	gus_stop_voice(sc, GUS_VOICE_RIGHT, 0);
2250 	mtx_leave(&audio_lock);
2251 	return 0;
2252 }
2253 
2254 /*
2255  * Stop any DMA output.  Called at splaudio().
2256  */
2257 int
2258 gus_halt_in_dma(void *addr)
2259 {
2260 	struct gus_softc *sc = addr;
2261 	bus_space_tag_t iot = sc->sc_iot;
2262 	bus_space_handle_t ioh2 = sc->sc_ioh2;
2263 
2264 	mtx_enter(&audio_lock);
2265 	DMAPRINTF(("gus_halt_in_dma called\n"));
2266 
2267 	/*
2268 	 * Make sure the GUS _isn't_ setup for DMA
2269 	 */
2270 
2271 	SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
2272 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH,
2273 	     bus_space_read_1(iot, ioh2, GUS_DATA_HIGH) & ~(GUSMASK_SAMPLE_START|GUSMASK_SAMPLE_IRQ));
2274 
2275 	isa_dmaabort(sc->sc_dev.dv_parent, sc->sc_recdrq);
2276 	sc->sc_flags &= ~GUS_DMAIN_ACTIVE;
2277 	sc->sc_dmainintr = 0;
2278 	sc->sc_inarg = 0;
2279 	sc->sc_dmainaddr = 0;
2280 	sc->sc_dmaincnt = 0;
2281 	mtx_leave(&audio_lock);
2282 	return 0;
2283 }
2284 
2285 
2286 ad1848_devmap_t gusmapping[] = {
2287   {GUSMAX_DAC_LVL, AD1848_KIND_LVL, AD1848_AUX1_CHANNEL},
2288   {GUSMAX_LINE_IN_LVL, AD1848_KIND_LVL, AD1848_LINE_CHANNEL},
2289   {GUSMAX_MONO_LVL, AD1848_KIND_LVL, AD1848_MONO_CHANNEL},
2290   {GUSMAX_CD_LVL, AD1848_KIND_LVL, AD1848_AUX2_CHANNEL},
2291   {GUSMAX_MONITOR_LVL, AD1848_KIND_LVL, AD1848_MONITOR_CHANNEL},
2292   {GUSMAX_OUT_LVL, AD1848_KIND_LVL, AD1848_DAC_CHANNEL},
2293   {GUSMAX_DAC_MUTE, AD1848_KIND_MUTE, AD1848_AUX1_CHANNEL},
2294   {GUSMAX_LINE_IN_MUTE, AD1848_KIND_MUTE, AD1848_LINE_CHANNEL},
2295   {GUSMAX_MONO_MUTE, AD1848_KIND_MUTE, AD1848_MONO_CHANNEL},
2296   {GUSMAX_CD_MUTE, AD1848_KIND_MUTE, AD1848_AUX2_CHANNEL},
2297   {GUSMAX_MONITOR_MUTE, AD1848_KIND_MUTE, AD1848_MONITOR_CHANNEL},
2298   {GUSMAX_REC_LVL, AD1848_KIND_RECORDGAIN, -1},
2299   {GUSMAX_RECORD_SOURCE, AD1848_KIND_RECORDSOURCE, -1}
2300 };
2301 
2302 int nummap = sizeof(gusmapping) / sizeof(gusmapping[0]);
2303 
2304 int
2305 gusmax_mixer_get_port(void *addr, mixer_ctrl_t *cp)
2306 {
2307 	struct ad1848_softc *ac = addr;
2308 	struct gus_softc *sc = ac->parent;
2309 	struct ad1848_volume vol;
2310 	int error = ad1848_mixer_get_port(ac, gusmapping, nummap, cp);
2311 
2312 	if (error != ENXIO)
2313 	  return (error);
2314 
2315 	error = EINVAL;
2316 
2317 	switch (cp->dev) {
2318 	case GUSMAX_SPEAKER_LVL:	/* fake speaker for mute naming */
2319 		if (cp->type == AUDIO_MIXER_VALUE) {
2320 			if (sc->sc_mixcontrol & GUSMASK_LINE_OUT)
2321 				vol.left = vol.right = AUDIO_MAX_GAIN;
2322 			else
2323 				vol.left = vol.right = AUDIO_MIN_GAIN;
2324 			error = 0;
2325 			ad1848_from_vol(cp, &vol);
2326 		}
2327 		break;
2328 
2329 	case GUSMAX_SPEAKER_MUTE:
2330 		if (cp->type == AUDIO_MIXER_ENUM) {
2331 			cp->un.ord = sc->sc_mixcontrol & GUSMASK_LINE_OUT ? 1 : 0;
2332 			error = 0;
2333 		}
2334 		break;
2335 	default:
2336 		error = ENXIO;
2337 		break;
2338 	}
2339 
2340 	return(error);
2341 }
2342 
2343 int
2344 gus_mixer_get_port(void *addr, mixer_ctrl_t *cp)
2345 {
2346 	struct gus_softc *sc = addr;
2347 	struct ics2101_softc *ic = &sc->sc_mixer;
2348 	struct ad1848_volume vol;
2349 	int error = EINVAL;
2350 
2351 	DPRINTF(("gus_mixer_get_port: dev=%d type=%d\n", cp->dev, cp->type));
2352 
2353 	if (!HAS_MIXER(sc) && cp->dev > GUSICS_MASTER_MUTE)
2354 		return ENXIO;
2355 
2356 	switch (cp->dev) {
2357 
2358 	case GUSICS_MIC_IN_MUTE:	/* Microphone */
2359 		if (cp->type == AUDIO_MIXER_ENUM) {
2360 			if (HAS_MIXER(sc))
2361 				cp->un.ord = ic->sc_mute[GUSMIX_CHAN_MIC][ICSMIX_LEFT];
2362 			else
2363 				cp->un.ord =
2364 				    sc->sc_mixcontrol & GUSMASK_MIC_IN ? 0 : 1;
2365 			error = 0;
2366 		}
2367 		break;
2368 
2369 	case GUSICS_LINE_IN_MUTE:
2370 		if (cp->type == AUDIO_MIXER_ENUM) {
2371 			if (HAS_MIXER(sc))
2372 				cp->un.ord = ic->sc_mute[GUSMIX_CHAN_LINE][ICSMIX_LEFT];
2373 			else
2374 				cp->un.ord =
2375 				    sc->sc_mixcontrol & GUSMASK_LINE_IN ? 1 : 0;
2376 			error = 0;
2377 		}
2378 		break;
2379 
2380 	case GUSICS_MASTER_MUTE:
2381 		if (cp->type == AUDIO_MIXER_ENUM) {
2382 			if (HAS_MIXER(sc))
2383 				cp->un.ord = ic->sc_mute[GUSMIX_CHAN_MASTER][ICSMIX_LEFT];
2384 			else
2385 				cp->un.ord =
2386 				    sc->sc_mixcontrol & GUSMASK_LINE_OUT ? 1 : 0;
2387 			error = 0;
2388 		}
2389 		break;
2390 
2391 	case GUSICS_DAC_MUTE:
2392 		if (cp->type == AUDIO_MIXER_ENUM) {
2393 			cp->un.ord = ic->sc_mute[GUSMIX_CHAN_DAC][ICSMIX_LEFT];
2394 			error = 0;
2395 		}
2396 		break;
2397 
2398 	case GUSICS_CD_MUTE:
2399 		if (cp->type == AUDIO_MIXER_ENUM) {
2400 			cp->un.ord = ic->sc_mute[GUSMIX_CHAN_CD][ICSMIX_LEFT];
2401 			error = 0;
2402 		}
2403 		break;
2404 
2405 	case GUSICS_MASTER_LVL:
2406 		if (cp->type == AUDIO_MIXER_VALUE) {
2407 			vol.left = ic->sc_setting[GUSMIX_CHAN_MASTER][ICSMIX_LEFT];
2408 			vol.right = ic->sc_setting[GUSMIX_CHAN_MASTER][ICSMIX_RIGHT];
2409 			if (ad1848_from_vol(cp, &vol))
2410 				error = 0;
2411 		}
2412 		break;
2413 
2414 	case GUSICS_MIC_IN_LVL:	/* Microphone */
2415 		if (cp->type == AUDIO_MIXER_VALUE) {
2416 			vol.left = ic->sc_setting[GUSMIX_CHAN_MIC][ICSMIX_LEFT];
2417 			vol.right = ic->sc_setting[GUSMIX_CHAN_MIC][ICSMIX_RIGHT];
2418 			if (ad1848_from_vol(cp, &vol))
2419 				error = 0;
2420 		}
2421 		break;
2422 
2423 	case GUSICS_LINE_IN_LVL:	/* line in */
2424 		if (cp->type == AUDIO_MIXER_VALUE) {
2425 			vol.left = ic->sc_setting[GUSMIX_CHAN_LINE][ICSMIX_LEFT];
2426 			vol.right = ic->sc_setting[GUSMIX_CHAN_LINE][ICSMIX_RIGHT];
2427 			if (ad1848_from_vol(cp, &vol))
2428 				error = 0;
2429 		}
2430 		break;
2431 
2432 
2433 	case GUSICS_CD_LVL:
2434 		if (cp->type == AUDIO_MIXER_VALUE) {
2435 			vol.left = ic->sc_setting[GUSMIX_CHAN_CD][ICSMIX_LEFT];
2436 			vol.right = ic->sc_setting[GUSMIX_CHAN_CD][ICSMIX_RIGHT];
2437 			if (ad1848_from_vol(cp, &vol))
2438 				error = 0;
2439 		}
2440 		break;
2441 
2442 	case GUSICS_DAC_LVL:		/* dac out */
2443 		if (cp->type == AUDIO_MIXER_VALUE) {
2444 			vol.left = ic->sc_setting[GUSMIX_CHAN_DAC][ICSMIX_LEFT];
2445 			vol.right = ic->sc_setting[GUSMIX_CHAN_DAC][ICSMIX_RIGHT];
2446 			if (ad1848_from_vol(cp, &vol))
2447 				error = 0;
2448 		}
2449 		break;
2450 
2451 
2452 	case GUSICS_RECORD_SOURCE:
2453 		if (cp->type == AUDIO_MIXER_ENUM) {
2454 			/* Can't set anything else useful, sigh. */
2455 			 cp->un.ord = 0;
2456 		}
2457 		break;
2458 
2459 	default:
2460 		return ENXIO;
2461 	    /*NOTREACHED*/
2462 	}
2463 	return error;
2464 }
2465 
2466 void
2467 gusics_master_mute(struct ics2101_softc *ic, int mute)
2468 {
2469 	ics2101_mix_mute(ic, GUSMIX_CHAN_MASTER, ICSMIX_LEFT, mute);
2470 	ics2101_mix_mute(ic, GUSMIX_CHAN_MASTER, ICSMIX_RIGHT, mute);
2471 }
2472 
2473 void
2474 gusics_mic_mute(struct ics2101_softc *ic, int mute)
2475 {
2476 	ics2101_mix_mute(ic, GUSMIX_CHAN_MIC, ICSMIX_LEFT, mute);
2477 	ics2101_mix_mute(ic, GUSMIX_CHAN_MIC, ICSMIX_RIGHT, mute);
2478 }
2479 
2480 void
2481 gusics_linein_mute(struct ics2101_softc *ic, int mute)
2482 {
2483 	ics2101_mix_mute(ic, GUSMIX_CHAN_LINE, ICSMIX_LEFT, mute);
2484 	ics2101_mix_mute(ic, GUSMIX_CHAN_LINE, ICSMIX_RIGHT, mute);
2485 }
2486 
2487 void
2488 gusics_cd_mute(struct ics2101_softc *ic, int mute)
2489 {
2490 	ics2101_mix_mute(ic, GUSMIX_CHAN_CD, ICSMIX_LEFT, mute);
2491 	ics2101_mix_mute(ic, GUSMIX_CHAN_CD, ICSMIX_RIGHT, mute);
2492 }
2493 
2494 void
2495 gusics_dac_mute(struct ics2101_softc *ic, int mute)
2496 {
2497 	ics2101_mix_mute(ic, GUSMIX_CHAN_DAC, ICSMIX_LEFT, mute);
2498 	ics2101_mix_mute(ic, GUSMIX_CHAN_DAC, ICSMIX_RIGHT, mute);
2499 }
2500 
2501 int
2502 gusmax_mixer_set_port(void *addr, mixer_ctrl_t *cp)
2503 {
2504 	struct ad1848_softc *ac = addr;
2505 	struct gus_softc *sc = ac->parent;
2506 	struct ad1848_volume vol;
2507 	int error = ad1848_mixer_set_port(ac, gusmapping, nummap, cp);
2508 
2509 	if (error != ENXIO)
2510 	  return (error);
2511 
2512 	DPRINTF(("gusmax_mixer_set_port: dev=%d type=%d\n", cp->dev, cp->type));
2513 
2514 	switch (cp->dev) {
2515 	case GUSMAX_SPEAKER_LVL:
2516 		if (cp->type == AUDIO_MIXER_VALUE &&
2517 		    cp->un.value.num_channels == 1) {
2518 			if (ad1848_to_vol(cp, &vol)) {
2519 				gus_speaker_ctl(sc, vol.left > AUDIO_MIN_GAIN ?
2520 						SPKR_ON : SPKR_OFF);
2521 				error = 0;
2522 			}
2523 		}
2524 		break;
2525 
2526 	case GUSMAX_SPEAKER_MUTE:
2527 		if (cp->type == AUDIO_MIXER_ENUM) {
2528 			gus_speaker_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON);
2529 			error = 0;
2530 		}
2531 		break;
2532 
2533 	default:
2534 		return ENXIO;
2535 	    /*NOTREACHED*/
2536     }
2537     return error;
2538 }
2539 
2540 int
2541 gus_mixer_set_port(void *addr, mixer_ctrl_t *cp)
2542 {
2543 	struct gus_softc *sc = addr;
2544 	struct ics2101_softc *ic = &sc->sc_mixer;
2545 	struct ad1848_volume vol;
2546 	int error = EINVAL;
2547 
2548 	DPRINTF(("gus_mixer_set_port: dev=%d type=%d\n", cp->dev, cp->type));
2549 
2550 	if (!HAS_MIXER(sc) && cp->dev > GUSICS_MASTER_MUTE)
2551 		return ENXIO;
2552 
2553 	switch (cp->dev) {
2554 
2555 	case GUSICS_MIC_IN_MUTE:	/* Microphone */
2556 		if (cp->type == AUDIO_MIXER_ENUM) {
2557 			DPRINTF(("mic mute %d\n", cp->un.ord));
2558 			if (HAS_MIXER(sc)) {
2559 				gusics_mic_mute(ic, cp->un.ord);
2560 			}
2561 			gus_mic_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON);
2562 			error = 0;
2563 		}
2564 		break;
2565 
2566 	case GUSICS_LINE_IN_MUTE:
2567 		if (cp->type == AUDIO_MIXER_ENUM) {
2568 			DPRINTF(("linein mute %d\n", cp->un.ord));
2569 			if (HAS_MIXER(sc)) {
2570 				gusics_linein_mute(ic, cp->un.ord);
2571 			}
2572 			gus_linein_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON);
2573 			error = 0;
2574 		}
2575 		break;
2576 
2577 	case GUSICS_MASTER_MUTE:
2578 		if (cp->type == AUDIO_MIXER_ENUM) {
2579 			DPRINTF(("master mute %d\n", cp->un.ord));
2580 			if (HAS_MIXER(sc)) {
2581 				gusics_master_mute(ic, cp->un.ord);
2582 			}
2583 			gus_speaker_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON);
2584 			error = 0;
2585 		}
2586 		break;
2587 
2588 	case GUSICS_DAC_MUTE:
2589 		if (cp->type == AUDIO_MIXER_ENUM) {
2590 			gusics_dac_mute(ic, cp->un.ord);
2591 			error = 0;
2592 		}
2593 		break;
2594 
2595 	case GUSICS_CD_MUTE:
2596 		if (cp->type == AUDIO_MIXER_ENUM) {
2597 			gusics_cd_mute(ic, cp->un.ord);
2598 			error = 0;
2599 		}
2600 		break;
2601 
2602 	case GUSICS_MASTER_LVL:
2603 		if (cp->type == AUDIO_MIXER_VALUE) {
2604 			if (ad1848_to_vol(cp, &vol)) {
2605 				ics2101_mix_attenuate(ic,
2606 						      GUSMIX_CHAN_MASTER,
2607 						      ICSMIX_LEFT,
2608 						      vol.left);
2609 				ics2101_mix_attenuate(ic,
2610 						      GUSMIX_CHAN_MASTER,
2611 						      ICSMIX_RIGHT,
2612 						      vol.right);
2613 				error = 0;
2614 			}
2615 		}
2616 		break;
2617 
2618 	case GUSICS_MIC_IN_LVL:	/* Microphone */
2619 		if (cp->type == AUDIO_MIXER_VALUE) {
2620 			if (ad1848_to_vol(cp, &vol)) {
2621 				ics2101_mix_attenuate(ic,
2622 						      GUSMIX_CHAN_MIC,
2623 						      ICSMIX_LEFT,
2624 						      vol.left);
2625 				ics2101_mix_attenuate(ic,
2626 						      GUSMIX_CHAN_MIC,
2627 						      ICSMIX_RIGHT,
2628 						      vol.right);
2629 				error = 0;
2630 			}
2631 		}
2632 		break;
2633 
2634 	case GUSICS_LINE_IN_LVL:	/* line in */
2635 		if (cp->type == AUDIO_MIXER_VALUE) {
2636 			if (ad1848_to_vol(cp, &vol)) {
2637 				ics2101_mix_attenuate(ic,
2638 						      GUSMIX_CHAN_LINE,
2639 						      ICSMIX_LEFT,
2640 						      vol.left);
2641 				ics2101_mix_attenuate(ic,
2642 						      GUSMIX_CHAN_LINE,
2643 						      ICSMIX_RIGHT,
2644 						      vol.right);
2645 				error = 0;
2646 			}
2647 		}
2648 		break;
2649 
2650 
2651 	case GUSICS_CD_LVL:
2652 		if (cp->type == AUDIO_MIXER_VALUE) {
2653 			if (ad1848_to_vol(cp, &vol)) {
2654 				ics2101_mix_attenuate(ic,
2655 						      GUSMIX_CHAN_CD,
2656 						      ICSMIX_LEFT,
2657 						      vol.left);
2658 				ics2101_mix_attenuate(ic,
2659 						      GUSMIX_CHAN_CD,
2660 						      ICSMIX_RIGHT,
2661 						      vol.right);
2662 				error = 0;
2663 			}
2664 		}
2665 		break;
2666 
2667 	case GUSICS_DAC_LVL:		/* dac out */
2668 		if (cp->type == AUDIO_MIXER_VALUE) {
2669 			if (ad1848_to_vol(cp, &vol)) {
2670 				ics2101_mix_attenuate(ic,
2671 						      GUSMIX_CHAN_DAC,
2672 						      ICSMIX_LEFT,
2673 						      vol.left);
2674 				ics2101_mix_attenuate(ic,
2675 						      GUSMIX_CHAN_DAC,
2676 						      ICSMIX_RIGHT,
2677 						      vol.right);
2678 				error = 0;
2679 			}
2680 		}
2681 		break;
2682 
2683 
2684 	case GUSICS_RECORD_SOURCE:
2685 		if (cp->type == AUDIO_MIXER_ENUM && cp->un.ord == 0) {
2686 			/* Can't set anything else useful, sigh. */
2687 			error = 0;
2688 		}
2689 		break;
2690 
2691 	default:
2692 		return ENXIO;
2693 	    /*NOTREACHED*/
2694 	}
2695 	return error;
2696 }
2697 
2698 int
2699 gus_get_props(void *addr)
2700 {
2701 	struct gus_softc *sc = addr;
2702 	return AUDIO_PROP_MMAP |
2703 		(sc->sc_recdrq == sc->sc_drq ? 0 : AUDIO_PROP_FULLDUPLEX);
2704 }
2705 
2706 int
2707 gusmax_get_props(void *addr)
2708 {
2709 	struct ad1848_softc *ac = addr;
2710 	return gus_get_props(ac->parent);
2711 }
2712 
2713 int
2714 gusmax_mixer_query_devinfo(void *addr, mixer_devinfo_t *dip)
2715 {
2716 	DPRINTF(("gusmax_query_devinfo: index=%d\n", dip->index));
2717 
2718 	switch(dip->index) {
2719 #if 0
2720     case GUSMAX_MIC_IN_LVL:	/* Microphone */
2721 	dip->type = AUDIO_MIXER_VALUE;
2722 	dip->mixer_class = GUSMAX_INPUT_CLASS;
2723 	dip->prev = AUDIO_MIXER_LAST;
2724 	dip->next = GUSMAX_MIC_IN_MUTE;
2725 	strlcpy(dip->label.name, AudioNmicrophone, sizeof dip->label.name);
2726 	dip->un.v.num_channels = 2;
2727 	strlcpy(dip->un.v.units.name, AudioNvolume,
2728 	    sizeof dip->un.v.units.name);
2729 	break;
2730 #endif
2731 
2732     case GUSMAX_MONO_LVL:	/* mono/microphone mixer */
2733 	dip->type = AUDIO_MIXER_VALUE;
2734 	dip->mixer_class = GUSMAX_INPUT_CLASS;
2735 	dip->prev = AUDIO_MIXER_LAST;
2736 	dip->next = GUSMAX_MONO_MUTE;
2737 	strlcpy(dip->label.name, AudioNmicrophone, sizeof dip->label.name);
2738 	dip->un.v.num_channels = 1;
2739 	strlcpy(dip->un.v.units.name, AudioNvolume,
2740 	    sizeof dip->un.v.units.name);
2741 	break;
2742 
2743     case GUSMAX_DAC_LVL:		/*  dacout */
2744 	dip->type = AUDIO_MIXER_VALUE;
2745 	dip->mixer_class = GUSMAX_INPUT_CLASS;
2746 	dip->prev = AUDIO_MIXER_LAST;
2747 	dip->next = GUSMAX_DAC_MUTE;
2748 	strlcpy(dip->label.name, AudioNdac, sizeof dip->label.name);
2749 	dip->un.v.num_channels = 2;
2750 	strlcpy(dip->un.v.units.name, AudioNvolume,
2751 	    sizeof dip->un.v.units.name);
2752 	break;
2753 
2754     case GUSMAX_LINE_IN_LVL:	/* line */
2755 	dip->type = AUDIO_MIXER_VALUE;
2756 	dip->mixer_class = GUSMAX_INPUT_CLASS;
2757 	dip->prev = AUDIO_MIXER_LAST;
2758 	dip->next = GUSMAX_LINE_IN_MUTE;
2759 	strlcpy(dip->label.name, AudioNline, sizeof dip->label.name);
2760 	dip->un.v.num_channels = 2;
2761 	strlcpy(dip->un.v.units.name, AudioNvolume,
2762 	    sizeof dip->un.v.units.name);
2763 	break;
2764 
2765     case GUSMAX_CD_LVL:		/* cd */
2766 	dip->type = AUDIO_MIXER_VALUE;
2767 	dip->mixer_class = GUSMAX_INPUT_CLASS;
2768 	dip->prev = AUDIO_MIXER_LAST;
2769 	dip->next = GUSMAX_CD_MUTE;
2770 	strlcpy(dip->label.name, AudioNcd, sizeof dip->label.name);
2771 	dip->un.v.num_channels = 2;
2772 	strlcpy(dip->un.v.units.name, AudioNvolume,
2773 	    sizeof dip->un.v.units.name);
2774 	break;
2775 
2776 
2777     case GUSMAX_MONITOR_LVL:	/* monitor level */
2778 	dip->type = AUDIO_MIXER_VALUE;
2779 	dip->mixer_class = GUSMAX_MONITOR_CLASS;
2780 	dip->next = GUSMAX_MONITOR_MUTE;
2781 	dip->prev = AUDIO_MIXER_LAST;
2782 	strlcpy(dip->label.name, AudioNmonitor, sizeof dip->label.name);
2783 	dip->un.v.num_channels = 1;
2784 	strlcpy(dip->un.v.units.name, AudioNvolume,
2785 	    sizeof dip->un.v.units.name);
2786 	break;
2787 
2788     case GUSMAX_OUT_LVL:		/* cs4231 output volume: not useful? */
2789 	dip->type = AUDIO_MIXER_VALUE;
2790 	dip->mixer_class = GUSMAX_MONITOR_CLASS;
2791 	dip->prev = dip->next = AUDIO_MIXER_LAST;
2792 	strlcpy(dip->label.name, AudioNoutput, sizeof dip->label.name);
2793 	dip->un.v.num_channels = 2;
2794 	strlcpy(dip->un.v.units.name, AudioNvolume,
2795 	    sizeof dip->un.v.units.name);
2796 	break;
2797 
2798     case GUSMAX_SPEAKER_LVL:		/* fake speaker volume */
2799 	dip->type = AUDIO_MIXER_VALUE;
2800 	dip->mixer_class = GUSMAX_MONITOR_CLASS;
2801 	dip->prev = AUDIO_MIXER_LAST;
2802 	dip->next = GUSMAX_SPEAKER_MUTE;
2803 	strlcpy(dip->label.name, AudioNmaster, sizeof dip->label.name);
2804 	dip->un.v.num_channels = 2;
2805 	strlcpy(dip->un.v.units.name, AudioNvolume,
2806 	    sizeof dip->un.v.units.name);
2807 	break;
2808 
2809     case GUSMAX_LINE_IN_MUTE:
2810 	dip->mixer_class = GUSMAX_INPUT_CLASS;
2811 	dip->type = AUDIO_MIXER_ENUM;
2812 	dip->prev = GUSMAX_LINE_IN_LVL;
2813 	dip->next = AUDIO_MIXER_LAST;
2814 	goto mute;
2815 
2816     case GUSMAX_DAC_MUTE:
2817 	dip->mixer_class = GUSMAX_INPUT_CLASS;
2818 	dip->type = AUDIO_MIXER_ENUM;
2819 	dip->prev = GUSMAX_DAC_LVL;
2820 	dip->next = AUDIO_MIXER_LAST;
2821 	goto mute;
2822 
2823     case GUSMAX_CD_MUTE:
2824 	dip->mixer_class = GUSMAX_INPUT_CLASS;
2825 	dip->type = AUDIO_MIXER_ENUM;
2826 	dip->prev = GUSMAX_CD_LVL;
2827 	dip->next = AUDIO_MIXER_LAST;
2828 	goto mute;
2829 
2830     case GUSMAX_MONO_MUTE:
2831 	dip->mixer_class = GUSMAX_INPUT_CLASS;
2832 	dip->type = AUDIO_MIXER_ENUM;
2833 	dip->prev = GUSMAX_MONO_LVL;
2834 	dip->next = AUDIO_MIXER_LAST;
2835 	goto mute;
2836 
2837     case GUSMAX_MONITOR_MUTE:
2838 	dip->mixer_class = GUSMAX_OUTPUT_CLASS;
2839 	dip->type = AUDIO_MIXER_ENUM;
2840 	dip->prev = GUSMAX_MONITOR_LVL;
2841 	dip->next = AUDIO_MIXER_LAST;
2842 	goto mute;
2843 
2844     case GUSMAX_SPEAKER_MUTE:
2845 	dip->mixer_class = GUSMAX_OUTPUT_CLASS;
2846 	dip->type = AUDIO_MIXER_ENUM;
2847 	dip->prev = GUSMAX_SPEAKER_LVL;
2848 	dip->next = AUDIO_MIXER_LAST;
2849     mute:
2850 	strlcpy(dip->label.name, AudioNmute, sizeof dip->label.name);
2851 	dip->un.e.num_mem = 2;
2852 	strlcpy(dip->un.e.member[0].label.name, AudioNoff,
2853 	    sizeof dip->un.e.member[0].label.name);
2854 	dip->un.e.member[0].ord = 0;
2855 	strlcpy(dip->un.e.member[1].label.name, AudioNon,
2856 	    sizeof dip->un.e.member[1].label.name);
2857 	dip->un.e.member[1].ord = 1;
2858 	break;
2859 
2860     case GUSMAX_REC_LVL:	/* record level */
2861 	dip->type = AUDIO_MIXER_VALUE;
2862 	dip->mixer_class = GUSMAX_RECORD_CLASS;
2863 	dip->prev = AUDIO_MIXER_LAST;
2864 	dip->next = GUSMAX_RECORD_SOURCE;
2865 	strlcpy(dip->label.name, AudioNrecord, sizeof dip->label.name);
2866 	dip->un.v.num_channels = 2;
2867 	strlcpy(dip->un.v.units.name, AudioNvolume, sizeof dip->un.v.units.name);
2868 	break;
2869 
2870     case GUSMAX_RECORD_SOURCE:
2871 	dip->mixer_class = GUSMAX_RECORD_CLASS;
2872 	dip->type = AUDIO_MIXER_ENUM;
2873 	dip->prev = GUSMAX_REC_LVL;
2874 	dip->next = AUDIO_MIXER_LAST;
2875 	strlcpy(dip->label.name, AudioNsource, sizeof dip->label.name);
2876 	dip->un.e.num_mem = 4;
2877 	strlcpy(dip->un.e.member[0].label.name, AudioNoutput,
2878 	    sizeof dip->un.e.member[0].label.name);
2879 	dip->un.e.member[0].ord = DAC_IN_PORT;
2880 	strlcpy(dip->un.e.member[1].label.name, AudioNmicrophone,
2881 	    sizeof dip->un.e.member[1].label.name);
2882 	dip->un.e.member[1].ord = MIC_IN_PORT;
2883 	strlcpy(dip->un.e.member[2].label.name, AudioNdac,
2884 	    sizeof dip->un.e.member[2].label.name);
2885 	dip->un.e.member[2].ord = AUX1_IN_PORT;
2886 	strlcpy(dip->un.e.member[3].label.name, AudioNline,
2887 	    sizeof dip->un.e.member[3].label.name);
2888 	dip->un.e.member[3].ord = LINE_IN_PORT;
2889 	break;
2890 
2891     case GUSMAX_INPUT_CLASS:			/* input class descriptor */
2892 	dip->type = AUDIO_MIXER_CLASS;
2893 	dip->mixer_class = GUSMAX_INPUT_CLASS;
2894 	dip->next = dip->prev = AUDIO_MIXER_LAST;
2895 	strlcpy(dip->label.name, AudioCinputs, sizeof dip->label.name);
2896 	break;
2897 
2898     case GUSMAX_OUTPUT_CLASS:			/* output class descriptor */
2899 	dip->type = AUDIO_MIXER_CLASS;
2900 	dip->mixer_class = GUSMAX_OUTPUT_CLASS;
2901 	dip->next = dip->prev = AUDIO_MIXER_LAST;
2902 	strlcpy(dip->label.name, AudioCoutputs, sizeof dip->label.name);
2903 	break;
2904 
2905     case GUSMAX_MONITOR_CLASS:			/* monitor class descriptor */
2906 	dip->type = AUDIO_MIXER_CLASS;
2907 	dip->mixer_class = GUSMAX_MONITOR_CLASS;
2908 	dip->next = dip->prev = AUDIO_MIXER_LAST;
2909 	strlcpy(dip->label.name, AudioCmonitor, sizeof dip->label.name);
2910 	break;
2911 
2912     case GUSMAX_RECORD_CLASS:			/* record source class */
2913 	dip->type = AUDIO_MIXER_CLASS;
2914 	dip->mixer_class = GUSMAX_RECORD_CLASS;
2915 	dip->next = dip->prev = AUDIO_MIXER_LAST;
2916 	strlcpy(dip->label.name, AudioCrecord, sizeof dip->label.name);
2917 	break;
2918 
2919     default:
2920 	return ENXIO;
2921 	/*NOTREACHED*/
2922     }
2923     DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name));
2924 	return 0;
2925 }
2926 
2927 int
2928 gus_mixer_query_devinfo(void *addr, mixer_devinfo_t *dip)
2929 {
2930 	struct gus_softc *sc = addr;
2931 
2932 	DPRINTF(("gusmax_query_devinfo: index=%d\n", dip->index));
2933 
2934 	if (!HAS_MIXER(sc) && dip->index > GUSICS_MASTER_MUTE)
2935 		return ENXIO;
2936 
2937 	switch(dip->index) {
2938 
2939 	case GUSICS_MIC_IN_LVL:	/* Microphone */
2940 		dip->type = AUDIO_MIXER_VALUE;
2941 		dip->mixer_class = GUSICS_INPUT_CLASS;
2942 		dip->prev = AUDIO_MIXER_LAST;
2943 		dip->next = GUSICS_MIC_IN_MUTE;
2944 		strlcpy(dip->label.name, AudioNmicrophone,
2945 		    sizeof dip->label.name);
2946 		dip->un.v.num_channels = 2;
2947 		strlcpy(dip->un.v.units.name, AudioNvolume,
2948 		    sizeof dip->un.v.units.name);
2949 		break;
2950 
2951 	case GUSICS_LINE_IN_LVL:	/* line */
2952 		dip->type = AUDIO_MIXER_VALUE;
2953 		dip->mixer_class = GUSICS_INPUT_CLASS;
2954 		dip->prev = AUDIO_MIXER_LAST;
2955 		dip->next = GUSICS_LINE_IN_MUTE;
2956 		strlcpy(dip->label.name, AudioNline, sizeof dip->label.name);
2957 		dip->un.v.num_channels = 2;
2958 		strlcpy(dip->un.v.units.name, AudioNvolume,
2959 		    sizeof dip->un.v.units.name);
2960 		break;
2961 
2962 	case GUSICS_CD_LVL:		/* cd */
2963 		dip->type = AUDIO_MIXER_VALUE;
2964 		dip->mixer_class = GUSICS_INPUT_CLASS;
2965 		dip->prev = AUDIO_MIXER_LAST;
2966 		dip->next = GUSICS_CD_MUTE;
2967 		strlcpy(dip->label.name, AudioNcd, sizeof dip->label.name);
2968 		dip->un.v.num_channels = 2;
2969 		strlcpy(dip->un.v.units.name, AudioNvolume,
2970 		    sizeof dip->un.v.units.name);
2971 		break;
2972 
2973 	case GUSICS_DAC_LVL:		/*  dacout */
2974 		dip->type = AUDIO_MIXER_VALUE;
2975 		dip->mixer_class = GUSICS_INPUT_CLASS;
2976 		dip->prev = AUDIO_MIXER_LAST;
2977 		dip->next = GUSICS_DAC_MUTE;
2978 		strlcpy(dip->label.name, AudioNdac, sizeof dip->label.name);
2979 		dip->un.v.num_channels = 2;
2980 		strlcpy(dip->un.v.units.name, AudioNvolume,
2981 		    sizeof dip->un.v.units.name);
2982 		break;
2983 
2984 	case GUSICS_MASTER_LVL:		/*  master output */
2985 		dip->type = AUDIO_MIXER_VALUE;
2986 		dip->mixer_class = GUSICS_OUTPUT_CLASS;
2987 		dip->prev = AUDIO_MIXER_LAST;
2988 		dip->next = GUSICS_MASTER_MUTE;
2989 		strlcpy(dip->label.name, AudioNmaster, sizeof dip->label.name);
2990 		dip->un.v.num_channels = 2;
2991 		strlcpy(dip->un.v.units.name, AudioNvolume,
2992 		    sizeof dip->un.v.units.name);
2993 		break;
2994 
2995 
2996 	case GUSICS_LINE_IN_MUTE:
2997 		dip->mixer_class = GUSICS_INPUT_CLASS;
2998 		dip->type = AUDIO_MIXER_ENUM;
2999 		dip->prev = GUSICS_LINE_IN_LVL;
3000 		dip->next = AUDIO_MIXER_LAST;
3001 		goto mute;
3002 
3003 	case GUSICS_DAC_MUTE:
3004 		dip->mixer_class = GUSICS_INPUT_CLASS;
3005 		dip->type = AUDIO_MIXER_ENUM;
3006 		dip->prev = GUSICS_DAC_LVL;
3007 		dip->next = AUDIO_MIXER_LAST;
3008 		goto mute;
3009 
3010 	case GUSICS_CD_MUTE:
3011 		dip->mixer_class = GUSICS_INPUT_CLASS;
3012 		dip->type = AUDIO_MIXER_ENUM;
3013 		dip->prev = GUSICS_CD_LVL;
3014 		dip->next = AUDIO_MIXER_LAST;
3015 		goto mute;
3016 
3017 	case GUSICS_MIC_IN_MUTE:
3018 		dip->mixer_class = GUSICS_INPUT_CLASS;
3019 		dip->type = AUDIO_MIXER_ENUM;
3020 		dip->prev = GUSICS_MIC_IN_LVL;
3021 		dip->next = AUDIO_MIXER_LAST;
3022 		goto mute;
3023 
3024 	case GUSICS_MASTER_MUTE:
3025 		dip->mixer_class = GUSICS_OUTPUT_CLASS;
3026 		dip->type = AUDIO_MIXER_ENUM;
3027 		dip->prev = GUSICS_MASTER_LVL;
3028 		dip->next = AUDIO_MIXER_LAST;
3029 mute:
3030 		strlcpy(dip->label.name, AudioNmute, sizeof dip->label.name);
3031 		dip->un.e.num_mem = 2;
3032 		strlcpy(dip->un.e.member[0].label.name, AudioNoff,
3033 		    sizeof dip->un.e.member[0].label.name);
3034 		dip->un.e.member[0].ord = 0;
3035 		strlcpy(dip->un.e.member[1].label.name, AudioNon,
3036 		    sizeof dip->un.e.member[1].label.name);
3037 		dip->un.e.member[1].ord = 1;
3038 		break;
3039 
3040 	case GUSICS_RECORD_SOURCE:
3041 		dip->mixer_class = GUSICS_RECORD_CLASS;
3042 		dip->type = AUDIO_MIXER_ENUM;
3043 		dip->prev = dip->next = AUDIO_MIXER_LAST;
3044 		strlcpy(dip->label.name, AudioNsource, sizeof dip->label.name);
3045 		dip->un.e.num_mem = 1;
3046 		strlcpy(dip->un.e.member[0].label.name, AudioNoutput,
3047 		    sizeof dip->un.e.member[0].label.name);
3048 		dip->un.e.member[0].ord = GUSICS_MASTER_LVL;
3049 		break;
3050 
3051 	case GUSICS_INPUT_CLASS:
3052 		dip->type = AUDIO_MIXER_CLASS;
3053 		dip->mixer_class = GUSICS_INPUT_CLASS;
3054 		dip->next = dip->prev = AUDIO_MIXER_LAST;
3055 		strlcpy(dip->label.name, AudioCinputs, sizeof dip->label.name);
3056 		break;
3057 
3058 	case GUSICS_OUTPUT_CLASS:
3059 		dip->type = AUDIO_MIXER_CLASS;
3060 		dip->mixer_class = GUSICS_OUTPUT_CLASS;
3061 		dip->next = dip->prev = AUDIO_MIXER_LAST;
3062 		strlcpy(dip->label.name, AudioCoutputs, sizeof dip->label.name);
3063 		break;
3064 
3065 	case GUSICS_RECORD_CLASS:
3066 		dip->type = AUDIO_MIXER_CLASS;
3067 		dip->mixer_class = GUSICS_RECORD_CLASS;
3068 		dip->next = dip->prev = AUDIO_MIXER_LAST;
3069 		strlcpy(dip->label.name, AudioCrecord, sizeof dip->label.name);
3070 		break;
3071 
3072 	default:
3073 		return ENXIO;
3074 	/*NOTREACHED*/
3075 	}
3076 	DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name));
3077 	return 0;
3078 }
3079 
3080 void *
3081 gus_malloc(void *addr, int direction, size_t size, int pool, int flags)
3082 {
3083 	struct gus_softc *sc = addr;
3084 	int drq;
3085 
3086 	if (direction == AUMODE_PLAY)
3087 		drq = sc->sc_drq;
3088 	else
3089 		drq = sc->sc_recdrq;
3090 
3091 	return isa_malloc(sc->sc_isa, drq, size, pool, flags);
3092 }
3093 
3094 void
3095 gus_free(void *addr, void *ptr, int pool)
3096 {
3097 	isa_free(ptr, pool);
3098 }
3099 
3100 size_t
3101 gus_round(void *addr, int direction, size_t size)
3102 {
3103 	if (size > MAX_ISADMA)
3104 		size = MAX_ISADMA;
3105 	return size;
3106 }
3107 
3108 /*
3109  * Setup the ICS mixer in "transparent" mode: reset everything to a sensible
3110  * level.  Levels as suggested by GUS SDK code.
3111  */
3112 
3113 void
3114 gus_init_ics2101(struct gus_softc *sc)
3115 {
3116 	struct ics2101_softc *ic = &sc->sc_mixer;
3117 	sc->sc_mixer.sc_iot = sc->sc_iot;
3118 	sc->sc_mixer.sc_selio = GUS_MIXER_SELECT;
3119 	sc->sc_mixer.sc_selio_ioh = sc->sc_ioh3;
3120 	sc->sc_mixer.sc_dataio = GUS_MIXER_DATA;
3121 	sc->sc_mixer.sc_dataio_ioh = sc->sc_ioh2;
3122 	sc->sc_mixer.sc_flags = (sc->sc_revision == 5) ? ICS_FLIP : 0;
3123 
3124 	ics2101_mix_attenuate(ic,
3125 			      GUSMIX_CHAN_MIC,
3126 			      ICSMIX_LEFT,
3127 			      ICSMIX_MIN_ATTN);
3128 	ics2101_mix_attenuate(ic,
3129 			      GUSMIX_CHAN_MIC,
3130 			      ICSMIX_RIGHT,
3131 			      ICSMIX_MIN_ATTN);
3132 	/*
3133 	 * Start with microphone muted by the mixer...
3134 	 */
3135 	gusics_mic_mute(ic, 1);
3136 
3137 	/* ... and enabled by the GUS master mix control */
3138 	gus_mic_ctl(sc, SPKR_ON);
3139 
3140 	ics2101_mix_attenuate(ic,
3141 			      GUSMIX_CHAN_LINE,
3142 			      ICSMIX_LEFT,
3143 			      ICSMIX_MIN_ATTN);
3144 	ics2101_mix_attenuate(ic,
3145 			      GUSMIX_CHAN_LINE,
3146 			      ICSMIX_RIGHT,
3147 			      ICSMIX_MIN_ATTN);
3148 
3149 	ics2101_mix_attenuate(ic,
3150 			      GUSMIX_CHAN_CD,
3151 			      ICSMIX_LEFT,
3152 			      ICSMIX_MIN_ATTN);
3153 	ics2101_mix_attenuate(ic,
3154 			      GUSMIX_CHAN_CD,
3155 			      ICSMIX_RIGHT,
3156 			      ICSMIX_MIN_ATTN);
3157 
3158 	ics2101_mix_attenuate(ic,
3159 			      GUSMIX_CHAN_DAC,
3160 			      ICSMIX_LEFT,
3161 			      ICSMIX_MIN_ATTN);
3162 	ics2101_mix_attenuate(ic,
3163 			      GUSMIX_CHAN_DAC,
3164 			      ICSMIX_RIGHT,
3165 			      ICSMIX_MIN_ATTN);
3166 
3167 	ics2101_mix_attenuate(ic,
3168 			      ICSMIX_CHAN_4,
3169 			      ICSMIX_LEFT,
3170 			      ICSMIX_MAX_ATTN);
3171 	ics2101_mix_attenuate(ic,
3172 			      ICSMIX_CHAN_4,
3173 			      ICSMIX_RIGHT,
3174 			      ICSMIX_MAX_ATTN);
3175 
3176 	ics2101_mix_attenuate(ic,
3177 			      GUSMIX_CHAN_MASTER,
3178 			      ICSMIX_LEFT,
3179 			      ICSMIX_MIN_ATTN);
3180 	ics2101_mix_attenuate(ic,
3181 			      GUSMIX_CHAN_MASTER,
3182 			      ICSMIX_RIGHT,
3183 			      ICSMIX_MIN_ATTN);
3184 	/* unmute other stuff: */
3185 	gusics_cd_mute(ic, 0);
3186 	gusics_dac_mute(ic, 0);
3187 	gusics_linein_mute(ic, 0);
3188 	return;
3189 }
3190 
3191 
3192 
3193 void
3194 gus_subattach(struct gus_softc *sc, struct isa_attach_args *ia)
3195 {
3196 	int		i;
3197 	bus_space_tag_t iot;
3198 	unsigned char	c,d,m;
3199 	u_long		s;
3200 
3201 	iot = sc->sc_iot;
3202 
3203 	/*
3204 	 * Figure out our board rev, and see if we need to initialize the
3205 	 * mixer
3206 	 */
3207 
3208 	c = bus_space_read_1(iot, sc->sc_ioh3, GUS_BOARD_REV);
3209 	if (c != 0xff)
3210 		sc->sc_revision = c;
3211 	else
3212 		sc->sc_revision = 0;
3213 
3214 	SELECT_GUS_REG(iot, sc->sc_ioh2, GUSREG_RESET);
3215 	bus_space_write_1(iot, sc->sc_ioh2, GUS_DATA_HIGH, 0x00);
3216 
3217 	gusreset(sc, GUS_MAX_VOICES); /* initialize all voices */
3218 	gusreset(sc, GUS_MIN_VOICES); /* then set to just the ones we use */
3219 
3220 	/*
3221 	 * Setup the IRQ and DRQ lines in software, using values from
3222 	 * config file
3223 	 */
3224 
3225 	m = GUSMASK_LINE_IN|GUSMASK_LINE_OUT;		/* disable all */
3226 
3227 	c = ((unsigned char) gus_irq_map[ia->ia_irq]) | GUSMASK_BOTH_RQ;
3228 
3229 	if (sc->sc_recdrq == sc->sc_drq)
3230 		d = (unsigned char) (gus_drq_map[sc->sc_drq] |
3231 				GUSMASK_BOTH_RQ);
3232 	else
3233 		d = (unsigned char) (gus_drq_map[sc->sc_drq] |
3234 				gus_drq_map[sc->sc_recdrq] << 3);
3235 
3236 	/*
3237 	 * Program the IRQ and DMA channels on the GUS.  Note that we hardwire
3238 	 * the GUS to only use one IRQ channel, but we give the user the
3239 	 * option of using two DMA channels (the other one given by the drq2
3240 	 * option in the config file).  Two DMA channels are needed for full-
3241 	 * duplex operation.
3242 	 *
3243 	 * The order of these operations is very magical.
3244 	 */
3245 
3246 	s = intr_disable();		/* XXX needed? */
3247 
3248 	bus_space_write_1(iot, sc->sc_ioh1, GUS_REG_CONTROL, GUS_REG_IRQCTL);
3249 	bus_space_write_1(iot, sc->sc_ioh1, GUS_MIX_CONTROL, m);
3250 	bus_space_write_1(iot, sc->sc_ioh1, GUS_IRQCTL_CONTROL, 0x00);
3251 	bus_space_write_1(iot, sc->sc_ioh1, 0x0f, 0x00);
3252 
3253 	bus_space_write_1(iot, sc->sc_ioh1, GUS_MIX_CONTROL, m);
3254 
3255 	/* magic reset? */
3256 	bus_space_write_1(iot, sc->sc_ioh1, GUS_DMA_CONTROL, d | 0x80);
3257 
3258 	bus_space_write_1(iot, sc->sc_ioh1, GUS_MIX_CONTROL,
3259 	    m | GUSMASK_CONTROL_SEL);
3260 	bus_space_write_1(iot, sc->sc_ioh1, GUS_IRQ_CONTROL, c);
3261 
3262 	bus_space_write_1(iot, sc->sc_ioh1, GUS_MIX_CONTROL, m);
3263 	bus_space_write_1(iot, sc->sc_ioh1, GUS_DMA_CONTROL, d);
3264 
3265 	bus_space_write_1(iot, sc->sc_ioh1, GUS_MIX_CONTROL,
3266 	    m | GUSMASK_CONTROL_SEL);
3267 	bus_space_write_1(iot, sc->sc_ioh1, GUS_IRQ_CONTROL, c);
3268 
3269 	bus_space_write_1(iot, sc->sc_ioh2, GUS_VOICE_SELECT, 0x00);
3270 
3271 	/* enable line in, line out.  leave mic disabled. */
3272 	bus_space_write_1(iot, sc->sc_ioh1, GUS_MIX_CONTROL,
3273 	     (m | GUSMASK_LATCHES) & ~(GUSMASK_LINE_OUT|GUSMASK_LINE_IN));
3274 	bus_space_write_1(iot, sc->sc_ioh2, GUS_VOICE_SELECT, 0x00);
3275 
3276 	intr_restore(s);
3277 
3278 	sc->sc_mixcontrol =
3279 		(m | GUSMASK_LATCHES) & ~(GUSMASK_LINE_OUT|GUSMASK_LINE_IN);
3280 
3281 	sc->sc_codec.sc_isa = sc->sc_isa;
3282 
3283 	if (sc->sc_revision >= 5 && sc->sc_revision <= 9) {
3284 		sc->sc_flags |= GUS_MIXER_INSTALLED;
3285 		gus_init_ics2101(sc);
3286 	}
3287 	if (sc->sc_revision < 10 || !gus_init_cs4231(sc)) {
3288 		/* Not using the CS4231, so create our DMA maps. */
3289 		if (sc->sc_drq != -1) {
3290 			if (isa_dmamap_create(sc->sc_isa, sc->sc_drq,
3291 			    MAX_ISADMA, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) {
3292 				printf("%s: can't create map for drq %d\n",
3293 				       sc->sc_dev.dv_xname, sc->sc_drq);
3294 				return;
3295 			}
3296 		}
3297 		if (sc->sc_recdrq != -1 && sc->sc_recdrq != sc->sc_drq) {
3298 			if (isa_dmamap_create(sc->sc_isa, sc->sc_recdrq,
3299 			    MAX_ISADMA, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) {
3300 				printf("%s: can't create map for drq %d\n",
3301 				       sc->sc_dev.dv_xname, sc->sc_recdrq);
3302 				return;
3303 			}
3304 		}
3305 	}
3306 
3307 	timeout_set(&sc->sc_dma_tmo, gus_dmaout_timeout, sc);
3308 
3309 	SELECT_GUS_REG(iot, sc->sc_ioh2, GUSREG_RESET);
3310 	/*
3311 	 * Check to see how much memory we have on this card; see if any
3312 	 * "mirroring" occurs.  We're assuming at least 256K already exists
3313 	 * on the card; otherwise the initial probe would have failed
3314 	 */
3315 
3316 	guspoke(iot, sc->sc_ioh2, 0L, 0x00);
3317 	for(i = 1; i < 1024; i++) {
3318 		u_long loc;
3319 
3320 		/*
3321 		 * See if we've run into mirroring yet
3322 		 */
3323 
3324 		if (guspeek(iot, sc->sc_ioh2, 0L) != 0)
3325 			break;
3326 
3327 		loc = i << 10;
3328 
3329 		guspoke(iot, sc->sc_ioh2, loc, 0xaa);
3330 		if (guspeek(iot, sc->sc_ioh2, loc) != 0xaa)
3331 			break;
3332 	}
3333 
3334 	sc->sc_dsize = i;
3335 	/*
3336 	 * The "official" (3.x) version number cannot easily be obtained.
3337 	 * The revision register does not correspond to the minor number
3338 	 * of the board version. Simply use the revision register as
3339 	 * identification.
3340 	 */
3341 	printf(": ver %d", sc->sc_revision);
3342 	if (sc->sc_revision >= 10)
3343 		printf(", MAX");
3344 	else {
3345 		if (HAS_MIXER(sc))
3346 			printf(", ICS2101 mixer");
3347 		if (HAS_CODEC(sc))
3348 			printf(", %s codec/mixer", sc->sc_codec.chip_name);
3349 	}
3350 	printf(", %dKB DRAM, ", sc->sc_dsize);
3351 	if (sc->sc_recdrq == sc->sc_drq) {
3352 		printf("half-duplex");
3353 	} else {
3354 		printf("full-duplex, record drq %d", sc->sc_recdrq);
3355 	}
3356 
3357 	printf("\n");
3358 
3359 	/*
3360 	 * Setup a default interrupt handler
3361 	 */
3362 
3363 	sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq,
3364 	    IST_EDGE, IPL_AUDIO | IPL_MPSAFE,
3365 	    gusintr, sc /* sc->sc_gusdsp */, sc->sc_dev.dv_xname);
3366 
3367 	/*
3368 	 * Set some default values
3369 	 * XXX others start with 8kHz mono mulaw
3370 	 */
3371 
3372 	sc->sc_irate = sc->sc_orate = 44100;
3373 	sc->sc_encoding = AUDIO_ENCODING_SLINEAR_LE;
3374 	sc->sc_precision = 16;
3375 	sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_DATA_SIZE16;
3376 	sc->sc_voc[GUS_VOICE_RIGHT].voccntl |= GUSMASK_DATA_SIZE16;
3377 	sc->sc_channels = 1;
3378 	sc->sc_ogain = 340;
3379 	gus_commit_settings(sc);
3380 
3381 	/*
3382 	 * We always put the left channel full left & right channel
3383 	 * full right.
3384 	 * For mono playback, we set up both voices playing the same buffer.
3385 	 */
3386 	bus_space_write_1(iot, sc->sc_ioh2, GUS_VOICE_SELECT,
3387 	    (u_char)GUS_VOICE_LEFT);
3388 	SELECT_GUS_REG(iot, sc->sc_ioh2, GUSREG_PAN_POS);
3389 	bus_space_write_1(iot, sc->sc_ioh2, GUS_DATA_HIGH, GUS_PAN_FULL_LEFT);
3390 
3391 	bus_space_write_1(iot, sc->sc_ioh2, GUS_VOICE_SELECT,
3392 	    (u_char)GUS_VOICE_RIGHT);
3393 	SELECT_GUS_REG(iot, sc->sc_ioh2, GUSREG_PAN_POS);
3394 	bus_space_write_1(iot, sc->sc_ioh2, GUS_DATA_HIGH, GUS_PAN_FULL_RIGHT);
3395 
3396 	/*
3397 	 * Attach to the generic audio layer
3398 	 */
3399 
3400 	audio_attach_mi(&gus_hw_if, HAS_CODEC(sc) ? (void *)&sc->sc_codec :
3401 	    (void *)sc, &sc->sc_dev);
3402 }
3403 
3404 /*
3405  * Test to see if a particular I/O base is valid for the GUS.  Return true
3406  * if it is.
3407  */
3408 
3409 int
3410 gus_test_iobase (bus_space_tag_t iot, int iobase)
3411 {
3412 	bus_space_handle_t ioh1, ioh2, ioh3, ioh4;
3413 	u_char s1, s2;
3414 	int rv = 0;
3415 
3416 	/* Map i/o space */
3417 	if (bus_space_map(iot, iobase, GUS_NPORT1, 0, &ioh1))
3418 		return 0;
3419 	if (bus_space_map(iot, iobase+GUS_IOH2_OFFSET, GUS_NPORT2, 0, &ioh2))
3420 		goto bad1;
3421 
3422 	/* XXX Maybe we shouldn't fail on mapping this, but just assume
3423 	 * the card is of revision 0? */
3424 	if (bus_space_map(iot, iobase+GUS_IOH3_OFFSET, GUS_NPORT3, 0, &ioh3))
3425 		goto bad2;
3426 
3427 	if (bus_space_map(iot, iobase+GUS_IOH4_OFFSET, GUS_NPORT4, 0, &ioh4))
3428 		goto bad3;
3429 
3430 	/*
3431 	 * Reset GUS to an initial state before we do anything.
3432 	 */
3433 
3434 	mtx_enter(&audio_lock);
3435 	delay(500);
3436 
3437 	SELECT_GUS_REG(iot, ioh2, GUSREG_RESET);
3438 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
3439 
3440 	delay(500);
3441 
3442 	SELECT_GUS_REG(iot, ioh2, GUSREG_RESET);
3443 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, GUSMASK_MASTER_RESET);
3444 
3445 	delay(500);
3446 
3447 	mtx_leave(&audio_lock);
3448 
3449 	/*
3450 	 * See if we can write to the board's memory
3451 	 */
3452 
3453 	s1 = guspeek(iot, ioh2, 0L);
3454 	s2 = guspeek(iot, ioh2, 1L);
3455 
3456 	guspoke(iot, ioh2, 0L, 0xaa);
3457 	guspoke(iot, ioh2, 1L, 0x55);
3458 
3459 	if (guspeek(iot, ioh2, 0L) != 0xaa)
3460 		goto bad;
3461 
3462 	guspoke(iot, ioh2, 0L, s1);
3463 	guspoke(iot, ioh2, 1L, s2);
3464 
3465 	rv = 1;
3466 
3467 bad:
3468 	bus_space_unmap(iot, ioh4, GUS_NPORT4);
3469 bad3:
3470 	bus_space_unmap(iot, ioh3, GUS_NPORT3);
3471 bad2:
3472 	bus_space_unmap(iot, ioh2, GUS_NPORT2);
3473 bad1:
3474 	bus_space_unmap(iot, ioh1, GUS_NPORT1);
3475 	return rv;
3476 }
3477