xref: /openbsd/sys/dev/isa/gus.c (revision 4cfece93)
1 /*	$OpenBSD: gus.c,v 1.47 2018/07/30 14:19:12 kettenis 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(addr, blocksize)
1513 	void * addr;
1514 	int blocksize;
1515 {
1516 	struct gus_softc *sc = addr;
1517 
1518 	DPRINTF(("gus_round_blocksize called\n"));
1519 
1520 	if ((sc->sc_encoding == AUDIO_ENCODING_ULAW ||
1521 	     sc->sc_encoding == AUDIO_ENCODING_ALAW) && blocksize > 32768)
1522 		blocksize = 32768;
1523 	else if (blocksize > 65536)
1524 		blocksize = 65536;
1525 
1526 	if ((blocksize % GUS_BUFFER_MULTIPLE) != 0)
1527 		blocksize = (blocksize / GUS_BUFFER_MULTIPLE + 1) *
1528 			GUS_BUFFER_MULTIPLE;
1529 
1530 	/* set up temporary buffer to hold the deinterleave, if necessary
1531 	   for stereo output */
1532 	if (sc->sc_deintr_buf) {
1533 		free(sc->sc_deintr_buf, M_DEVBUF, 0);
1534 		sc->sc_deintr_buf = NULL;
1535 	}
1536 	sc->sc_deintr_buf = malloc(blocksize/2, M_DEVBUF, M_WAITOK);
1537 
1538 	sc->sc_blocksize = blocksize;
1539 	/* multi-buffering not quite working yet. */
1540 	sc->sc_nbufs = /*GUS_MEM_FOR_BUFFERS / blocksize*/ 2;
1541 
1542 	gus_set_chan_addrs(sc);
1543 
1544 	return blocksize;
1545 }
1546 
1547 int
1548 gus_get_out_gain(caddr_t addr)
1549 {
1550 	struct gus_softc *sc = (struct gus_softc *) addr;
1551 
1552 	DPRINTF(("gus_get_out_gain called\n"));
1553 	return sc->sc_ogain / 2;
1554 }
1555 
1556 inline void
1557 gus_set_voices(struct gus_softc *sc, int voices)
1558 {
1559 	bus_space_tag_t iot = sc->sc_iot;
1560 	bus_space_handle_t ioh2 = sc->sc_ioh2;
1561 	/*
1562 	 * Select the active number of voices
1563 	 */
1564 
1565 	SELECT_GUS_REG(iot, ioh2, GUSREG_ACTIVE_VOICES);
1566 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (voices-1) | 0xc0);
1567 
1568 	sc->sc_voices = voices;
1569 }
1570 
1571 /*
1572  * Actually set the settings of various values on the card
1573  */
1574 
1575 int
1576 gusmax_commit_settings(void *addr)
1577 {
1578 	struct ad1848_softc *ac = addr;
1579 	struct gus_softc *sc = ac->parent;
1580 	int error;
1581 
1582 	error = ad1848_commit_settings(ac);
1583 	if (error)
1584 		return error;
1585 	return gus_commit_settings(sc);
1586 }
1587 
1588 /*
1589  * Commit the settings.  Called at normal IPL.
1590  */
1591 int
1592 gus_commit_settings(void *addr)
1593 {
1594 	struct gus_softc *sc = addr;
1595 
1596 	DPRINTF(("gus_commit_settings called (gain = %d)\n",sc->sc_ogain));
1597 
1598 
1599 	/* XXX: why?! this is called with interrupts disabled */
1600 	mtx_enter(&audio_lock);
1601 
1602 	gus_set_recrate(sc, sc->sc_irate);
1603 	gus_set_volume(sc, GUS_VOICE_LEFT, sc->sc_ogain);
1604 	gus_set_volume(sc, GUS_VOICE_RIGHT, sc->sc_ogain);
1605 	gus_set_samprate(sc, GUS_VOICE_LEFT, sc->sc_orate);
1606 	gus_set_samprate(sc, GUS_VOICE_RIGHT, sc->sc_orate);
1607 	mtx_leave(&audio_lock);
1608 	gus_set_chan_addrs(sc);
1609 
1610 	return 0;
1611 }
1612 
1613 void
1614 gus_set_chan_addrs(struct gus_softc *sc)
1615 {
1616 	/*
1617 	 * We use sc_nbufs * blocksize bytes of storage in the on-board GUS
1618 	 * ram.
1619 	 * For mono, each of the sc_nbufs buffers is DMA'd to in one chunk,
1620 	 * and both left & right channels play the same buffer.
1621 	 *
1622 	 * For stereo, each channel gets a contiguous half of the memory,
1623 	 * and each has sc_nbufs buffers of size blocksize/2.
1624 	 * Stereo data are deinterleaved in main memory before the DMA out
1625 	 * routines are called to queue the output.
1626 	 *
1627 	 * The blocksize per channel is kept in sc_chanblocksize.
1628 	 */
1629 	if (sc->sc_channels == 2)
1630 	    sc->sc_chanblocksize = sc->sc_blocksize/2;
1631 	else
1632 	    sc->sc_chanblocksize = sc->sc_blocksize;
1633 
1634 	sc->sc_voc[GUS_VOICE_LEFT].start_addr = GUS_MEM_OFFSET - 1;
1635 	sc->sc_voc[GUS_VOICE_RIGHT].start_addr =
1636 	    (gus_dostereo && sc->sc_channels == 2 ? GUS_LEFT_RIGHT_OFFSET : 0)
1637 	      + GUS_MEM_OFFSET - 1;
1638 	sc->sc_voc[GUS_VOICE_RIGHT].current_addr =
1639 	    sc->sc_voc[GUS_VOICE_RIGHT].start_addr + 1;
1640 	sc->sc_voc[GUS_VOICE_RIGHT].end_addr =
1641 	    sc->sc_voc[GUS_VOICE_RIGHT].start_addr +
1642 	    sc->sc_nbufs * sc->sc_chanblocksize;
1643 
1644 }
1645 
1646 /*
1647  * Set the sample rate of the given voice.  Called at splaudio().
1648  */
1649 
1650 void
1651 gus_set_samprate(struct gus_softc *sc, int voice, int freq)
1652 {
1653 	bus_space_tag_t iot = sc->sc_iot;
1654 	bus_space_handle_t ioh2 = sc->sc_ioh2;
1655 	unsigned int fc;
1656 	u_long temp, f = (u_long) freq;
1657 
1658 	/*
1659 	 * calculate fc based on the number of active voices;
1660 	 * we need to use longs to preserve enough bits
1661 	 */
1662 
1663 	temp = (u_long) gus_max_frequency[sc->sc_voices-GUS_MIN_VOICES];
1664 
1665 	fc = (unsigned int)(((f << 9L) + (temp >> 1L)) / temp);
1666 
1667 	fc <<= 1;
1668 
1669 
1670 	/*
1671 	 * Program the voice frequency, and set it in the voice data record
1672 	 */
1673 
1674 	bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
1675 	SELECT_GUS_REG(iot, ioh2, GUSREG_FREQ_CONTROL);
1676 	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, fc);
1677 
1678 	sc->sc_voc[voice].rate = freq;
1679 
1680 }
1681 
1682 /*
1683  * Set the sample rate of the recording frequency.  Formula is from the GUS
1684  * SDK.  Called at splaudio().
1685  */
1686 
1687 void
1688 gus_set_recrate(struct gus_softc *sc, u_long rate)
1689 {
1690 	bus_space_tag_t iot = sc->sc_iot;
1691 	bus_space_handle_t ioh2 = sc->sc_ioh2;
1692 	u_char realrate;
1693 	DPRINTF(("gus_set_recrate %lu\n", rate));
1694 
1695 #if 0
1696 	realrate = 9878400/(16*(rate+2)); /* formula from GUS docs */
1697 #endif
1698 	realrate = (9878400 >> 4)/rate - 2; /* formula from code, sigh. */
1699 
1700 	SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_FREQ);
1701 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, realrate);
1702 }
1703 
1704 /*
1705  * Interface to the audio layer - turn the output on or off.  Note that some
1706  * of these bits are flipped in the register
1707  */
1708 
1709 int
1710 gusmax_speaker_ctl(void *addr, int newstate)
1711 {
1712 	struct ad1848_softc *sc = addr;
1713 	return gus_speaker_ctl(sc->parent, newstate);
1714 }
1715 
1716 int
1717 gus_speaker_ctl(void *addr, int newstate)
1718 {
1719 	struct gus_softc *sc = (struct gus_softc *) addr;
1720 	bus_space_tag_t iot = sc->sc_iot;
1721 	bus_space_handle_t ioh1 = sc->sc_ioh1;
1722 
1723 	/* Line out bit is flipped: 0 enables, 1 disables */
1724 	if ((newstate == SPKR_ON) &&
1725 	    (sc->sc_mixcontrol & GUSMASK_LINE_OUT)) {
1726 		sc->sc_mixcontrol &= ~GUSMASK_LINE_OUT;
1727 		bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
1728 	}
1729 	if ((newstate == SPKR_OFF) &&
1730 	    (sc->sc_mixcontrol & GUSMASK_LINE_OUT) == 0) {
1731 		sc->sc_mixcontrol |= GUSMASK_LINE_OUT;
1732 		bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
1733 	}
1734 
1735 	return 0;
1736 }
1737 
1738 int
1739 gus_linein_ctl(void *addr, int newstate)
1740 {
1741 	struct gus_softc *sc = (struct gus_softc *) addr;
1742 	bus_space_tag_t iot = sc->sc_iot;
1743 	bus_space_handle_t ioh1 = sc->sc_ioh1;
1744 
1745 	/* Line in bit is flipped: 0 enables, 1 disables */
1746 	if ((newstate == SPKR_ON) &&
1747 	    (sc->sc_mixcontrol & GUSMASK_LINE_IN)) {
1748 		sc->sc_mixcontrol &= ~GUSMASK_LINE_IN;
1749 		bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
1750 	}
1751 	if ((newstate == SPKR_OFF) &&
1752 	    (sc->sc_mixcontrol & GUSMASK_LINE_IN) == 0) {
1753 		sc->sc_mixcontrol |= GUSMASK_LINE_IN;
1754 		bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
1755 	}
1756 
1757 	return 0;
1758 }
1759 
1760 int
1761 gus_mic_ctl(void *addr, int newstate)
1762 {
1763 	struct gus_softc *sc = (struct gus_softc *) addr;
1764 	bus_space_tag_t iot = sc->sc_iot;
1765 	bus_space_handle_t ioh1 = sc->sc_ioh1;
1766 
1767 	/* Mic bit is normal: 1 enables, 0 disables */
1768 	if ((newstate == SPKR_ON) &&
1769 	    (sc->sc_mixcontrol & GUSMASK_MIC_IN) == 0) {
1770 		sc->sc_mixcontrol |= GUSMASK_MIC_IN;
1771 		bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
1772 	}
1773 	if ((newstate == SPKR_OFF) &&
1774 	    (sc->sc_mixcontrol & GUSMASK_MIC_IN)) {
1775 		sc->sc_mixcontrol &= ~GUSMASK_MIC_IN;
1776 		bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
1777 	}
1778 
1779 	return 0;
1780 }
1781 
1782 /*
1783  * Set the end address of a give voice.  Called at splaudio().
1784  */
1785 
1786 void
1787 gus_set_endaddr(struct gus_softc *sc, int voice, u_long addr)
1788 {
1789 	bus_space_tag_t iot = sc->sc_iot;
1790 	bus_space_handle_t ioh2 = sc->sc_ioh2;
1791 
1792 	sc->sc_voc[voice].end_addr = addr;
1793 
1794 	if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16)
1795 		addr = convert_to_16bit(addr);
1796 
1797 	SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_HIGH);
1798 	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(addr));
1799 	SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_LOW);
1800 	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(addr));
1801 
1802 }
1803 
1804 #ifdef GUSPLAYDEBUG
1805 /*
1806  * Set current address.  Called at splaudio().
1807  */
1808 void
1809 gus_set_curaddr(struct gus_softc *sc, int voice, u_long addr)
1810 {
1811 	bus_space_tag_t iot = sc->sc_iot;
1812 	bus_space_handle_t ioh2 = sc->sc_ioh2;
1813 
1814 	sc->sc_voc[voice].current_addr = addr;
1815 
1816 	if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16)
1817 		addr = convert_to_16bit(addr);
1818 
1819 	bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
1820 
1821 	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH);
1822 	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(addr));
1823 	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW);
1824 	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(addr));
1825 
1826 }
1827 
1828 /*
1829  * Get current GUS playback address.  Called at splaudio().
1830  */
1831 u_long
1832 gus_get_curaddr(struct gus_softc *sc, int voice)
1833 {
1834 	bus_space_tag_t iot = sc->sc_iot;
1835 	bus_space_handle_t ioh2 = sc->sc_ioh2;
1836 	u_long addr;
1837 
1838 	bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
1839 	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH|GUSREG_READ);
1840 	addr = (bus_space_read_2(iot, ioh2, GUS_DATA_LOW) & 0x1fff) << 7;
1841 	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW|GUSREG_READ);
1842 	addr |= (bus_space_read_2(iot, ioh2, GUS_DATA_LOW) >> 9L) & 0x7f;
1843 
1844 	if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16)
1845 	    addr = (addr & 0xc0000) | ((addr & 0x1ffff) << 1); /* undo 16-bit change */
1846 	DPRINTF(("gus voice %d curaddr %ld end_addr %ld\n",
1847 		 voice, addr, sc->sc_voc[voice].end_addr));
1848 	/* XXX sanity check the address? */
1849 
1850 	return(addr);
1851 }
1852 #endif
1853 
1854 /*
1855  * Convert an address value to a "16 bit" value - why this is necessary I
1856  * have NO idea
1857  */
1858 
1859 u_long
1860 convert_to_16bit(u_long address)
1861 {
1862 	u_long old_address;
1863 
1864 	old_address = address;
1865 	address >>= 1;
1866 	address &= 0x0001ffffL;
1867 	address |= (old_address & 0x000c0000L);
1868 
1869 	return (address);
1870 }
1871 
1872 /*
1873  * Write a value into the GUS's DRAM
1874  */
1875 
1876 void
1877 guspoke(bus_space_tag_t iot, bus_space_handle_t ioh2, long address,
1878     unsigned char value)
1879 {
1880 
1881 	/*
1882 	 * Select the DRAM address
1883 	 */
1884 
1885 	SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_LOW);
1886 	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, (unsigned int) (address & 0xffff));
1887 	SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_HIGH);
1888 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (unsigned char) ((address >> 16) & 0xff));
1889 
1890 	/*
1891 	 * Actually write the data
1892 	 */
1893 
1894 	bus_space_write_1(iot, ioh2, GUS_DRAM_DATA, value);
1895 }
1896 
1897 /*
1898  * Read a value from the GUS's DRAM
1899  */
1900 
1901 unsigned char
1902 guspeek(bus_space_tag_t iot, bus_space_handle_t ioh2, u_long address)
1903 {
1904 
1905 	/*
1906 	 * Select the DRAM address
1907 	 */
1908 
1909 	SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_LOW);
1910 	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, (unsigned int) (address & 0xffff));
1911 	SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_HIGH);
1912 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (unsigned char) ((address >> 16) & 0xff));
1913 
1914 	/*
1915 	 * Read in the data from the board
1916 	 */
1917 
1918 	return (unsigned char) bus_space_read_1(iot, ioh2, GUS_DRAM_DATA);
1919 }
1920 
1921 /*
1922  * Reset the Gravis UltraSound card, completely
1923  */
1924 
1925 void
1926 gusreset(struct gus_softc *sc, int voices)
1927 {
1928 	bus_space_tag_t iot = sc->sc_iot;
1929 	bus_space_handle_t ioh1 = sc->sc_ioh1;
1930 	bus_space_handle_t ioh2 = sc->sc_ioh2;
1931 	bus_space_handle_t ioh4 = sc->sc_ioh4;
1932 	int i;
1933 
1934 	mtx_enter(&audio_lock);
1935 
1936 	/*
1937 	 * Reset the GF1 chip
1938 	 */
1939 
1940 	SELECT_GUS_REG(iot, ioh2, GUSREG_RESET);
1941 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
1942 
1943 	delay(500);
1944 
1945 	/*
1946 	 * Release reset
1947 	 */
1948 
1949 	SELECT_GUS_REG(iot, ioh2, GUSREG_RESET);
1950 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, GUSMASK_MASTER_RESET);
1951 
1952 	delay(500);
1953 
1954 	/*
1955 	 * Reset MIDI port as well, if applicable
1956 	 */
1957 
1958 	if (ioh4 != (bus_space_handle_t)NULL) {
1959 		bus_space_write_1(iot, ioh4, GUS_MIDI_CONTROL, MIDI_RESET);
1960 
1961 		delay(500);
1962 
1963 		bus_space_write_1(iot, ioh4, GUS_MIDI_CONTROL, 0x00);
1964 	}
1965 
1966 	/*
1967 	 * Clear interrupts
1968 	 */
1969 
1970 	SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
1971 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
1972 	SELECT_GUS_REG(iot, ioh2, GUSREG_TIMER_CONTROL);
1973 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
1974 	SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
1975 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
1976 
1977 	gus_set_voices(sc, voices);
1978 
1979 	bus_space_read_1(iot, ioh1, GUS_IRQ_STATUS);
1980 	SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
1981 	bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
1982 	SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
1983 	bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
1984 	SELECT_GUS_REG(iot, ioh2, GUSREG_IRQ_STATUS);
1985 	bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
1986 
1987 	/*
1988 	 * Reset voice specific information
1989 	 */
1990 
1991 	for(i = 0; i < voices; i++) {
1992 		bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) i);
1993 
1994 		SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
1995 
1996 		sc->sc_voc[i].voccntl = GUSMASK_VOICE_STOPPED |
1997 			GUSMASK_STOP_VOICE;
1998 
1999 		bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[i].voccntl);
2000 
2001 		sc->sc_voc[i].volcntl = GUSMASK_VOLUME_STOPPED |
2002 				GUSMASK_STOP_VOLUME;
2003 
2004 		SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
2005 		bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[i].volcntl);
2006 
2007 		delay(100);
2008 
2009 		gus_set_samprate(sc, i, 8000);
2010 		SELECT_GUS_REG(iot, ioh2, GUSREG_START_ADDR_HIGH);
2011 		bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2012 		SELECT_GUS_REG(iot, ioh2, GUSREG_START_ADDR_LOW);
2013 		bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2014 		SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_HIGH);
2015 		bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2016 		SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_LOW);
2017 		bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2018 		SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_RATE);
2019 		bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x01);
2020 		SELECT_GUS_REG(iot, ioh2, GUSREG_START_VOLUME);
2021 		bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x10);
2022 		SELECT_GUS_REG(iot, ioh2, GUSREG_END_VOLUME);
2023 		bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0xe0);
2024 		SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME);
2025 		bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2026 
2027 		SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH);
2028 		bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2029 		SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW);
2030 		bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2031 		SELECT_GUS_REG(iot, ioh2, GUSREG_PAN_POS);
2032 		bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x07);
2033 	}
2034 
2035 	/*
2036 	 * Clear out any pending IRQs
2037 	 */
2038 
2039 	bus_space_read_1(iot, ioh1, GUS_IRQ_STATUS);
2040 	SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
2041 	bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
2042 	SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
2043 	bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
2044 	SELECT_GUS_REG(iot, ioh2, GUSREG_IRQ_STATUS);
2045 	bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
2046 
2047 	SELECT_GUS_REG(iot, ioh2, GUSREG_RESET);
2048 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, GUSMASK_MASTER_RESET | GUSMASK_DAC_ENABLE |
2049 		GUSMASK_IRQ_ENABLE);
2050 
2051 	mtx_leave(&audio_lock);
2052 }
2053 
2054 
2055 int
2056 gus_init_cs4231(struct gus_softc *sc)
2057 {
2058 	bus_space_tag_t iot = sc->sc_iot;
2059 	bus_space_handle_t ioh1 = sc->sc_ioh1;
2060 	int port = sc->sc_iobase;
2061 	u_char ctrl;
2062 
2063 	ctrl = (port & 0xf0) >> 4;	/* set port address middle nibble */
2064 	/*
2065 	 * The codec is a bit weird--swapped dma channels.
2066 	 */
2067 	ctrl |= GUS_MAX_CODEC_ENABLE;
2068 	if (sc->sc_drq >= 4)
2069 		ctrl |= GUS_MAX_RECCHAN16;
2070 	if (sc->sc_recdrq >= 4)
2071 		ctrl |= GUS_MAX_PLAYCHAN16;
2072 
2073 	bus_space_write_1(iot, ioh1, GUS_MAX_CTRL, ctrl);
2074 
2075 	sc->sc_codec.sc_iot = sc->sc_iot;
2076 	sc->sc_codec.sc_iobase = port+GUS_MAX_CODEC_BASE;
2077 
2078 	if (ad1848_mapprobe(&sc->sc_codec, sc->sc_codec.sc_iobase) == 0) {
2079 		sc->sc_flags &= ~GUS_CODEC_INSTALLED;
2080 		return (0);
2081 	} else {
2082 		struct ad1848_volume vol = {AUDIO_MAX_GAIN, AUDIO_MAX_GAIN};
2083 		sc->sc_flags |= GUS_CODEC_INSTALLED;
2084 		sc->sc_codec.parent = sc;
2085 		sc->sc_codec.sc_drq = sc->sc_recdrq;
2086 		sc->sc_codec.sc_recdrq = sc->sc_drq;
2087 		gus_hw_if = gusmax_hw_if;
2088 		/* enable line in and mic in the GUS mixer; the codec chip
2089 		   will do the real mixing for them. */
2090 		sc->sc_mixcontrol &= ~GUSMASK_LINE_IN; /* 0 enables. */
2091 		sc->sc_mixcontrol |= GUSMASK_MIC_IN; /* 1 enables. */
2092 		bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
2093 
2094 		ad1848_attach(&sc->sc_codec);
2095 		/* turn on pre-MUX microphone gain. */
2096 		ad1848_set_mic_gain(&sc->sc_codec, &vol);
2097 
2098 		return (1);
2099 	}
2100 }
2101 
2102 /*
2103  * stubs (XXX)
2104  */
2105 
2106 int
2107 gus_set_in_gain(caddr_t addr, u_int gain,  u_char balance)
2108 {
2109 	DPRINTF(("gus_set_in_gain called\n"));
2110 	return 0;
2111 }
2112 
2113 int
2114 gus_get_in_gain(caddr_t addr)
2115 {
2116 	DPRINTF(("gus_get_in_gain called\n"));
2117 	return 0;
2118 }
2119 
2120 int
2121 gusmax_dma_input(void *addr, void *buf, int size, void (*callback)(void *),
2122     void *arg)
2123 {
2124 	struct ad1848_softc *sc = addr;
2125 	return gus_dma_input(sc->parent, buf, size, callback, arg);
2126 }
2127 
2128 /*
2129  * Start sampling the input source into the requested DMA buffer.
2130  * Called at splaudio(), either from top-half or from interrupt handler.
2131  */
2132 int
2133 gus_dma_input(void *addr, void *buf, int size, void (*callback)(void *),
2134     void *arg)
2135 {
2136 	struct gus_softc *sc = addr;
2137 	bus_space_tag_t iot = sc->sc_iot;
2138 	bus_space_handle_t ioh2 = sc->sc_ioh2;
2139 	u_char dmac;
2140 	DMAPRINTF(("gus_dma_input called\n"));
2141 
2142 	/*
2143 	 * Sample SIZE bytes of data from the card, into buffer at BUF.
2144 	 */
2145 	if (sc->sc_precision == 16) {
2146 	    return EINVAL;		/* XXX */
2147 	}
2148 
2149 	/* set DMA modes */
2150 	dmac = GUSMASK_SAMPLE_IRQ|GUSMASK_SAMPLE_START;
2151 	if (sc->sc_recdrq >= 4)
2152 		dmac |= GUSMASK_SAMPLE_DATA16;
2153 	if (sc->sc_encoding == AUDIO_ENCODING_ULAW ||
2154 	    sc->sc_encoding == AUDIO_ENCODING_ALAW ||
2155 	    sc->sc_encoding == AUDIO_ENCODING_ULINEAR_LE ||
2156 	    sc->sc_encoding == AUDIO_ENCODING_ULINEAR_BE)
2157 	    dmac |= GUSMASK_SAMPLE_INVBIT;
2158 	if (sc->sc_channels == 2)
2159 	    dmac |= GUSMASK_SAMPLE_STEREO;
2160 	isa_dmastart(sc->sc_dev.dv_parent, sc->sc_recdrq, buf, size,
2161 	    NULL, DMAMODE_READ, BUS_DMA_NOWAIT);
2162 
2163 	DMAPRINTF(("gus_dma_input isadma_started\n"));
2164 	sc->sc_flags |= GUS_DMAIN_ACTIVE;
2165 	sc->sc_dmainintr = callback;
2166 	sc->sc_inarg = arg;
2167 	sc->sc_dmaincnt = size;
2168 	sc->sc_dmainaddr = buf;
2169 
2170 	SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
2171 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, dmac);	/* Go! */
2172 
2173 
2174 	DMAPRINTF(("gus_dma_input returning\n"));
2175 	return 0;
2176 }
2177 
2178 int
2179 gus_dmain_intr(struct gus_softc *sc)
2180 {
2181         void (*callback)(void *);
2182 	void *arg;
2183 
2184 	DMAPRINTF(("gus_dmain_intr called\n"));
2185 	if (sc->sc_dmainintr) {
2186 	    isa_dmadone(sc->sc_dev.dv_parent, sc->sc_recdrq);
2187 	    callback = sc->sc_dmainintr;
2188 	    arg = sc->sc_inarg;
2189 
2190 	    sc->sc_dmainaddr = 0;
2191 	    sc->sc_dmaincnt = 0;
2192 	    sc->sc_dmainintr = 0;
2193 	    sc->sc_inarg = 0;
2194 
2195 	    sc->sc_flags &= ~GUS_DMAIN_ACTIVE;
2196 	    DMAPRINTF(("calling dmain_intr callback %p(%p)\n", callback, arg));
2197 	    (*callback)(arg);
2198 	    return 1;
2199 	} else {
2200 	    DMAPRINTF(("gus_dmain_intr false?\n"));
2201 	    return 0;			/* XXX ??? */
2202 	}
2203 }
2204 
2205 int
2206 gusmax_halt_out_dma(void *addr)
2207 {
2208 	struct ad1848_softc *sc = addr;
2209 	return gus_halt_out_dma(sc->parent);
2210 }
2211 
2212 
2213 int
2214 gusmax_halt_in_dma(void *addr)
2215 {
2216 	struct ad1848_softc *sc = addr;
2217 	return gus_halt_in_dma(sc->parent);
2218 }
2219 
2220 /*
2221  * Stop any DMA output.  Called at splaudio().
2222  */
2223 int
2224 gus_halt_out_dma(void *addr)
2225 {
2226 	struct gus_softc *sc = addr;
2227 	bus_space_tag_t iot = sc->sc_iot;
2228 	bus_space_handle_t ioh2 = sc->sc_ioh2;
2229 
2230 	mtx_enter(&audio_lock);
2231 	DMAPRINTF(("gus_halt_out_dma called\n"));
2232 	/*
2233 	 * Make sure the GUS _isn't_ setup for DMA
2234 	 */
2235 
2236 	SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
2237 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0);
2238 
2239 	timeout_del(&sc->sc_dma_tmo);
2240 	isa_dmaabort(sc->sc_dev.dv_parent, sc->sc_drq);
2241 	sc->sc_flags &= ~(GUS_DMAOUT_ACTIVE|GUS_LOCKED);
2242 	sc->sc_dmaoutintr = 0;
2243 	sc->sc_outarg = 0;
2244 	sc->sc_dmaoutaddr = 0;
2245 	sc->sc_dmaoutcnt = 0;
2246 	sc->sc_dmabuf = 0;
2247 	sc->sc_bufcnt = 0;
2248 	sc->sc_playbuf = -1;
2249 	/* also stop playing */
2250 	gus_stop_voice(sc, GUS_VOICE_LEFT, 1);
2251 	gus_stop_voice(sc, GUS_VOICE_RIGHT, 0);
2252 	mtx_leave(&audio_lock);
2253 	return 0;
2254 }
2255 
2256 /*
2257  * Stop any DMA output.  Called at splaudio().
2258  */
2259 int
2260 gus_halt_in_dma(void *addr)
2261 {
2262 	struct gus_softc *sc = addr;
2263 	bus_space_tag_t iot = sc->sc_iot;
2264 	bus_space_handle_t ioh2 = sc->sc_ioh2;
2265 
2266 	mtx_enter(&audio_lock);
2267 	DMAPRINTF(("gus_halt_in_dma called\n"));
2268 
2269 	/*
2270 	 * Make sure the GUS _isn't_ setup for DMA
2271 	 */
2272 
2273 	SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
2274 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH,
2275 	     bus_space_read_1(iot, ioh2, GUS_DATA_HIGH) & ~(GUSMASK_SAMPLE_START|GUSMASK_SAMPLE_IRQ));
2276 
2277 	isa_dmaabort(sc->sc_dev.dv_parent, sc->sc_recdrq);
2278 	sc->sc_flags &= ~GUS_DMAIN_ACTIVE;
2279 	sc->sc_dmainintr = 0;
2280 	sc->sc_inarg = 0;
2281 	sc->sc_dmainaddr = 0;
2282 	sc->sc_dmaincnt = 0;
2283 	mtx_leave(&audio_lock);
2284 	return 0;
2285 }
2286 
2287 
2288 ad1848_devmap_t gusmapping[] = {
2289   {GUSMAX_DAC_LVL, AD1848_KIND_LVL, AD1848_AUX1_CHANNEL},
2290   {GUSMAX_LINE_IN_LVL, AD1848_KIND_LVL, AD1848_LINE_CHANNEL},
2291   {GUSMAX_MONO_LVL, AD1848_KIND_LVL, AD1848_MONO_CHANNEL},
2292   {GUSMAX_CD_LVL, AD1848_KIND_LVL, AD1848_AUX2_CHANNEL},
2293   {GUSMAX_MONITOR_LVL, AD1848_KIND_LVL, AD1848_MONITOR_CHANNEL},
2294   {GUSMAX_OUT_LVL, AD1848_KIND_LVL, AD1848_DAC_CHANNEL},
2295   {GUSMAX_DAC_MUTE, AD1848_KIND_MUTE, AD1848_AUX1_CHANNEL},
2296   {GUSMAX_LINE_IN_MUTE, AD1848_KIND_MUTE, AD1848_LINE_CHANNEL},
2297   {GUSMAX_MONO_MUTE, AD1848_KIND_MUTE, AD1848_MONO_CHANNEL},
2298   {GUSMAX_CD_MUTE, AD1848_KIND_MUTE, AD1848_AUX2_CHANNEL},
2299   {GUSMAX_MONITOR_MUTE, AD1848_KIND_MUTE, AD1848_MONITOR_CHANNEL},
2300   {GUSMAX_REC_LVL, AD1848_KIND_RECORDGAIN, -1},
2301   {GUSMAX_RECORD_SOURCE, AD1848_KIND_RECORDSOURCE, -1}
2302 };
2303 
2304 int nummap = sizeof(gusmapping) / sizeof(gusmapping[0]);
2305 
2306 int
2307 gusmax_mixer_get_port(void *addr, mixer_ctrl_t *cp)
2308 {
2309 	struct ad1848_softc *ac = addr;
2310 	struct gus_softc *sc = ac->parent;
2311 	struct ad1848_volume vol;
2312 	int error = ad1848_mixer_get_port(ac, gusmapping, nummap, cp);
2313 
2314 	if (error != ENXIO)
2315 	  return (error);
2316 
2317 	error = EINVAL;
2318 
2319 	switch (cp->dev) {
2320 	case GUSMAX_SPEAKER_LVL:	/* fake speaker for mute naming */
2321 		if (cp->type == AUDIO_MIXER_VALUE) {
2322 			if (sc->sc_mixcontrol & GUSMASK_LINE_OUT)
2323 				vol.left = vol.right = AUDIO_MAX_GAIN;
2324 			else
2325 				vol.left = vol.right = AUDIO_MIN_GAIN;
2326 			error = 0;
2327 			ad1848_from_vol(cp, &vol);
2328 		}
2329 		break;
2330 
2331 	case GUSMAX_SPEAKER_MUTE:
2332 		if (cp->type == AUDIO_MIXER_ENUM) {
2333 			cp->un.ord = sc->sc_mixcontrol & GUSMASK_LINE_OUT ? 1 : 0;
2334 			error = 0;
2335 		}
2336 		break;
2337 	default:
2338 		error = ENXIO;
2339 		break;
2340 	}
2341 
2342 	return(error);
2343 }
2344 
2345 int
2346 gus_mixer_get_port(void *addr, mixer_ctrl_t *cp)
2347 {
2348 	struct gus_softc *sc = addr;
2349 	struct ics2101_softc *ic = &sc->sc_mixer;
2350 	struct ad1848_volume vol;
2351 	int error = EINVAL;
2352 
2353 	DPRINTF(("gus_mixer_get_port: dev=%d type=%d\n", cp->dev, cp->type));
2354 
2355 	if (!HAS_MIXER(sc) && cp->dev > GUSICS_MASTER_MUTE)
2356 		return ENXIO;
2357 
2358 	switch (cp->dev) {
2359 
2360 	case GUSICS_MIC_IN_MUTE:	/* Microphone */
2361 		if (cp->type == AUDIO_MIXER_ENUM) {
2362 			if (HAS_MIXER(sc))
2363 				cp->un.ord = ic->sc_mute[GUSMIX_CHAN_MIC][ICSMIX_LEFT];
2364 			else
2365 				cp->un.ord =
2366 				    sc->sc_mixcontrol & GUSMASK_MIC_IN ? 0 : 1;
2367 			error = 0;
2368 		}
2369 		break;
2370 
2371 	case GUSICS_LINE_IN_MUTE:
2372 		if (cp->type == AUDIO_MIXER_ENUM) {
2373 			if (HAS_MIXER(sc))
2374 				cp->un.ord = ic->sc_mute[GUSMIX_CHAN_LINE][ICSMIX_LEFT];
2375 			else
2376 				cp->un.ord =
2377 				    sc->sc_mixcontrol & GUSMASK_LINE_IN ? 1 : 0;
2378 			error = 0;
2379 		}
2380 		break;
2381 
2382 	case GUSICS_MASTER_MUTE:
2383 		if (cp->type == AUDIO_MIXER_ENUM) {
2384 			if (HAS_MIXER(sc))
2385 				cp->un.ord = ic->sc_mute[GUSMIX_CHAN_MASTER][ICSMIX_LEFT];
2386 			else
2387 				cp->un.ord =
2388 				    sc->sc_mixcontrol & GUSMASK_LINE_OUT ? 1 : 0;
2389 			error = 0;
2390 		}
2391 		break;
2392 
2393 	case GUSICS_DAC_MUTE:
2394 		if (cp->type == AUDIO_MIXER_ENUM) {
2395 			cp->un.ord = ic->sc_mute[GUSMIX_CHAN_DAC][ICSMIX_LEFT];
2396 			error = 0;
2397 		}
2398 		break;
2399 
2400 	case GUSICS_CD_MUTE:
2401 		if (cp->type == AUDIO_MIXER_ENUM) {
2402 			cp->un.ord = ic->sc_mute[GUSMIX_CHAN_CD][ICSMIX_LEFT];
2403 			error = 0;
2404 		}
2405 		break;
2406 
2407 	case GUSICS_MASTER_LVL:
2408 		if (cp->type == AUDIO_MIXER_VALUE) {
2409 			vol.left = ic->sc_setting[GUSMIX_CHAN_MASTER][ICSMIX_LEFT];
2410 			vol.right = ic->sc_setting[GUSMIX_CHAN_MASTER][ICSMIX_RIGHT];
2411 			if (ad1848_from_vol(cp, &vol))
2412 				error = 0;
2413 		}
2414 		break;
2415 
2416 	case GUSICS_MIC_IN_LVL:	/* Microphone */
2417 		if (cp->type == AUDIO_MIXER_VALUE) {
2418 			vol.left = ic->sc_setting[GUSMIX_CHAN_MIC][ICSMIX_LEFT];
2419 			vol.right = ic->sc_setting[GUSMIX_CHAN_MIC][ICSMIX_RIGHT];
2420 			if (ad1848_from_vol(cp, &vol))
2421 				error = 0;
2422 		}
2423 		break;
2424 
2425 	case GUSICS_LINE_IN_LVL:	/* line in */
2426 		if (cp->type == AUDIO_MIXER_VALUE) {
2427 			vol.left = ic->sc_setting[GUSMIX_CHAN_LINE][ICSMIX_LEFT];
2428 			vol.right = ic->sc_setting[GUSMIX_CHAN_LINE][ICSMIX_RIGHT];
2429 			if (ad1848_from_vol(cp, &vol))
2430 				error = 0;
2431 		}
2432 		break;
2433 
2434 
2435 	case GUSICS_CD_LVL:
2436 		if (cp->type == AUDIO_MIXER_VALUE) {
2437 			vol.left = ic->sc_setting[GUSMIX_CHAN_CD][ICSMIX_LEFT];
2438 			vol.right = ic->sc_setting[GUSMIX_CHAN_CD][ICSMIX_RIGHT];
2439 			if (ad1848_from_vol(cp, &vol))
2440 				error = 0;
2441 		}
2442 		break;
2443 
2444 	case GUSICS_DAC_LVL:		/* dac out */
2445 		if (cp->type == AUDIO_MIXER_VALUE) {
2446 			vol.left = ic->sc_setting[GUSMIX_CHAN_DAC][ICSMIX_LEFT];
2447 			vol.right = ic->sc_setting[GUSMIX_CHAN_DAC][ICSMIX_RIGHT];
2448 			if (ad1848_from_vol(cp, &vol))
2449 				error = 0;
2450 		}
2451 		break;
2452 
2453 
2454 	case GUSICS_RECORD_SOURCE:
2455 		if (cp->type == AUDIO_MIXER_ENUM) {
2456 			/* Can't set anything else useful, sigh. */
2457 			 cp->un.ord = 0;
2458 		}
2459 		break;
2460 
2461 	default:
2462 		return ENXIO;
2463 	    /*NOTREACHED*/
2464 	}
2465 	return error;
2466 }
2467 
2468 void
2469 gusics_master_mute(struct ics2101_softc *ic, int mute)
2470 {
2471 	ics2101_mix_mute(ic, GUSMIX_CHAN_MASTER, ICSMIX_LEFT, mute);
2472 	ics2101_mix_mute(ic, GUSMIX_CHAN_MASTER, ICSMIX_RIGHT, mute);
2473 }
2474 
2475 void
2476 gusics_mic_mute(struct ics2101_softc *ic, int mute)
2477 {
2478 	ics2101_mix_mute(ic, GUSMIX_CHAN_MIC, ICSMIX_LEFT, mute);
2479 	ics2101_mix_mute(ic, GUSMIX_CHAN_MIC, ICSMIX_RIGHT, mute);
2480 }
2481 
2482 void
2483 gusics_linein_mute(struct ics2101_softc *ic, int mute)
2484 {
2485 	ics2101_mix_mute(ic, GUSMIX_CHAN_LINE, ICSMIX_LEFT, mute);
2486 	ics2101_mix_mute(ic, GUSMIX_CHAN_LINE, ICSMIX_RIGHT, mute);
2487 }
2488 
2489 void
2490 gusics_cd_mute(struct ics2101_softc *ic, int mute)
2491 {
2492 	ics2101_mix_mute(ic, GUSMIX_CHAN_CD, ICSMIX_LEFT, mute);
2493 	ics2101_mix_mute(ic, GUSMIX_CHAN_CD, ICSMIX_RIGHT, mute);
2494 }
2495 
2496 void
2497 gusics_dac_mute(struct ics2101_softc *ic, int mute)
2498 {
2499 	ics2101_mix_mute(ic, GUSMIX_CHAN_DAC, ICSMIX_LEFT, mute);
2500 	ics2101_mix_mute(ic, GUSMIX_CHAN_DAC, ICSMIX_RIGHT, mute);
2501 }
2502 
2503 int
2504 gusmax_mixer_set_port(void *addr, mixer_ctrl_t *cp)
2505 {
2506 	struct ad1848_softc *ac = addr;
2507 	struct gus_softc *sc = ac->parent;
2508 	struct ad1848_volume vol;
2509 	int error = ad1848_mixer_set_port(ac, gusmapping, nummap, cp);
2510 
2511 	if (error != ENXIO)
2512 	  return (error);
2513 
2514 	DPRINTF(("gusmax_mixer_set_port: dev=%d type=%d\n", cp->dev, cp->type));
2515 
2516 	switch (cp->dev) {
2517 	case GUSMAX_SPEAKER_LVL:
2518 		if (cp->type == AUDIO_MIXER_VALUE &&
2519 		    cp->un.value.num_channels == 1) {
2520 			if (ad1848_to_vol(cp, &vol)) {
2521 				gus_speaker_ctl(sc, vol.left > AUDIO_MIN_GAIN ?
2522 						SPKR_ON : SPKR_OFF);
2523 				error = 0;
2524 			}
2525 		}
2526 		break;
2527 
2528 	case GUSMAX_SPEAKER_MUTE:
2529 		if (cp->type == AUDIO_MIXER_ENUM) {
2530 			gus_speaker_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON);
2531 			error = 0;
2532 		}
2533 		break;
2534 
2535 	default:
2536 		return ENXIO;
2537 	    /*NOTREACHED*/
2538     }
2539     return error;
2540 }
2541 
2542 int
2543 gus_mixer_set_port(void *addr, mixer_ctrl_t *cp)
2544 {
2545 	struct gus_softc *sc = addr;
2546 	struct ics2101_softc *ic = &sc->sc_mixer;
2547 	struct ad1848_volume vol;
2548 	int error = EINVAL;
2549 
2550 	DPRINTF(("gus_mixer_set_port: dev=%d type=%d\n", cp->dev, cp->type));
2551 
2552 	if (!HAS_MIXER(sc) && cp->dev > GUSICS_MASTER_MUTE)
2553 		return ENXIO;
2554 
2555 	switch (cp->dev) {
2556 
2557 	case GUSICS_MIC_IN_MUTE:	/* Microphone */
2558 		if (cp->type == AUDIO_MIXER_ENUM) {
2559 			DPRINTF(("mic mute %d\n", cp->un.ord));
2560 			if (HAS_MIXER(sc)) {
2561 				gusics_mic_mute(ic, cp->un.ord);
2562 			}
2563 			gus_mic_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON);
2564 			error = 0;
2565 		}
2566 		break;
2567 
2568 	case GUSICS_LINE_IN_MUTE:
2569 		if (cp->type == AUDIO_MIXER_ENUM) {
2570 			DPRINTF(("linein mute %d\n", cp->un.ord));
2571 			if (HAS_MIXER(sc)) {
2572 				gusics_linein_mute(ic, cp->un.ord);
2573 			}
2574 			gus_linein_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON);
2575 			error = 0;
2576 		}
2577 		break;
2578 
2579 	case GUSICS_MASTER_MUTE:
2580 		if (cp->type == AUDIO_MIXER_ENUM) {
2581 			DPRINTF(("master mute %d\n", cp->un.ord));
2582 			if (HAS_MIXER(sc)) {
2583 				gusics_master_mute(ic, cp->un.ord);
2584 			}
2585 			gus_speaker_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON);
2586 			error = 0;
2587 		}
2588 		break;
2589 
2590 	case GUSICS_DAC_MUTE:
2591 		if (cp->type == AUDIO_MIXER_ENUM) {
2592 			gusics_dac_mute(ic, cp->un.ord);
2593 			error = 0;
2594 		}
2595 		break;
2596 
2597 	case GUSICS_CD_MUTE:
2598 		if (cp->type == AUDIO_MIXER_ENUM) {
2599 			gusics_cd_mute(ic, cp->un.ord);
2600 			error = 0;
2601 		}
2602 		break;
2603 
2604 	case GUSICS_MASTER_LVL:
2605 		if (cp->type == AUDIO_MIXER_VALUE) {
2606 			if (ad1848_to_vol(cp, &vol)) {
2607 				ics2101_mix_attenuate(ic,
2608 						      GUSMIX_CHAN_MASTER,
2609 						      ICSMIX_LEFT,
2610 						      vol.left);
2611 				ics2101_mix_attenuate(ic,
2612 						      GUSMIX_CHAN_MASTER,
2613 						      ICSMIX_RIGHT,
2614 						      vol.right);
2615 				error = 0;
2616 			}
2617 		}
2618 		break;
2619 
2620 	case GUSICS_MIC_IN_LVL:	/* Microphone */
2621 		if (cp->type == AUDIO_MIXER_VALUE) {
2622 			if (ad1848_to_vol(cp, &vol)) {
2623 				ics2101_mix_attenuate(ic,
2624 						      GUSMIX_CHAN_MIC,
2625 						      ICSMIX_LEFT,
2626 						      vol.left);
2627 				ics2101_mix_attenuate(ic,
2628 						      GUSMIX_CHAN_MIC,
2629 						      ICSMIX_RIGHT,
2630 						      vol.right);
2631 				error = 0;
2632 			}
2633 		}
2634 		break;
2635 
2636 	case GUSICS_LINE_IN_LVL:	/* line in */
2637 		if (cp->type == AUDIO_MIXER_VALUE) {
2638 			if (ad1848_to_vol(cp, &vol)) {
2639 				ics2101_mix_attenuate(ic,
2640 						      GUSMIX_CHAN_LINE,
2641 						      ICSMIX_LEFT,
2642 						      vol.left);
2643 				ics2101_mix_attenuate(ic,
2644 						      GUSMIX_CHAN_LINE,
2645 						      ICSMIX_RIGHT,
2646 						      vol.right);
2647 				error = 0;
2648 			}
2649 		}
2650 		break;
2651 
2652 
2653 	case GUSICS_CD_LVL:
2654 		if (cp->type == AUDIO_MIXER_VALUE) {
2655 			if (ad1848_to_vol(cp, &vol)) {
2656 				ics2101_mix_attenuate(ic,
2657 						      GUSMIX_CHAN_CD,
2658 						      ICSMIX_LEFT,
2659 						      vol.left);
2660 				ics2101_mix_attenuate(ic,
2661 						      GUSMIX_CHAN_CD,
2662 						      ICSMIX_RIGHT,
2663 						      vol.right);
2664 				error = 0;
2665 			}
2666 		}
2667 		break;
2668 
2669 	case GUSICS_DAC_LVL:		/* dac out */
2670 		if (cp->type == AUDIO_MIXER_VALUE) {
2671 			if (ad1848_to_vol(cp, &vol)) {
2672 				ics2101_mix_attenuate(ic,
2673 						      GUSMIX_CHAN_DAC,
2674 						      ICSMIX_LEFT,
2675 						      vol.left);
2676 				ics2101_mix_attenuate(ic,
2677 						      GUSMIX_CHAN_DAC,
2678 						      ICSMIX_RIGHT,
2679 						      vol.right);
2680 				error = 0;
2681 			}
2682 		}
2683 		break;
2684 
2685 
2686 	case GUSICS_RECORD_SOURCE:
2687 		if (cp->type == AUDIO_MIXER_ENUM && cp->un.ord == 0) {
2688 			/* Can't set anything else useful, sigh. */
2689 			error = 0;
2690 		}
2691 		break;
2692 
2693 	default:
2694 		return ENXIO;
2695 	    /*NOTREACHED*/
2696 	}
2697 	return error;
2698 }
2699 
2700 int
2701 gus_get_props(void *addr)
2702 {
2703 	struct gus_softc *sc = addr;
2704 	return AUDIO_PROP_MMAP |
2705 		(sc->sc_recdrq == sc->sc_drq ? 0 : AUDIO_PROP_FULLDUPLEX);
2706 }
2707 
2708 int
2709 gusmax_get_props(void *addr)
2710 {
2711 	struct ad1848_softc *ac = addr;
2712 	return gus_get_props(ac->parent);
2713 }
2714 
2715 int
2716 gusmax_mixer_query_devinfo(void *addr, mixer_devinfo_t *dip)
2717 {
2718 	DPRINTF(("gusmax_query_devinfo: index=%d\n", dip->index));
2719 
2720 	switch(dip->index) {
2721 #if 0
2722     case GUSMAX_MIC_IN_LVL:	/* Microphone */
2723 	dip->type = AUDIO_MIXER_VALUE;
2724 	dip->mixer_class = GUSMAX_INPUT_CLASS;
2725 	dip->prev = AUDIO_MIXER_LAST;
2726 	dip->next = GUSMAX_MIC_IN_MUTE;
2727 	strlcpy(dip->label.name, AudioNmicrophone, sizeof dip->label.name);
2728 	dip->un.v.num_channels = 2;
2729 	strlcpy(dip->un.v.units.name, AudioNvolume,
2730 	    sizeof dip->un.v.units.name);
2731 	break;
2732 #endif
2733 
2734     case GUSMAX_MONO_LVL:	/* mono/microphone mixer */
2735 	dip->type = AUDIO_MIXER_VALUE;
2736 	dip->mixer_class = GUSMAX_INPUT_CLASS;
2737 	dip->prev = AUDIO_MIXER_LAST;
2738 	dip->next = GUSMAX_MONO_MUTE;
2739 	strlcpy(dip->label.name, AudioNmicrophone, sizeof dip->label.name);
2740 	dip->un.v.num_channels = 1;
2741 	strlcpy(dip->un.v.units.name, AudioNvolume,
2742 	    sizeof dip->un.v.units.name);
2743 	break;
2744 
2745     case GUSMAX_DAC_LVL:		/*  dacout */
2746 	dip->type = AUDIO_MIXER_VALUE;
2747 	dip->mixer_class = GUSMAX_INPUT_CLASS;
2748 	dip->prev = AUDIO_MIXER_LAST;
2749 	dip->next = GUSMAX_DAC_MUTE;
2750 	strlcpy(dip->label.name, AudioNdac, sizeof dip->label.name);
2751 	dip->un.v.num_channels = 2;
2752 	strlcpy(dip->un.v.units.name, AudioNvolume,
2753 	    sizeof dip->un.v.units.name);
2754 	break;
2755 
2756     case GUSMAX_LINE_IN_LVL:	/* line */
2757 	dip->type = AUDIO_MIXER_VALUE;
2758 	dip->mixer_class = GUSMAX_INPUT_CLASS;
2759 	dip->prev = AUDIO_MIXER_LAST;
2760 	dip->next = GUSMAX_LINE_IN_MUTE;
2761 	strlcpy(dip->label.name, AudioNline, sizeof dip->label.name);
2762 	dip->un.v.num_channels = 2;
2763 	strlcpy(dip->un.v.units.name, AudioNvolume,
2764 	    sizeof dip->un.v.units.name);
2765 	break;
2766 
2767     case GUSMAX_CD_LVL:		/* cd */
2768 	dip->type = AUDIO_MIXER_VALUE;
2769 	dip->mixer_class = GUSMAX_INPUT_CLASS;
2770 	dip->prev = AUDIO_MIXER_LAST;
2771 	dip->next = GUSMAX_CD_MUTE;
2772 	strlcpy(dip->label.name, AudioNcd, sizeof dip->label.name);
2773 	dip->un.v.num_channels = 2;
2774 	strlcpy(dip->un.v.units.name, AudioNvolume,
2775 	    sizeof dip->un.v.units.name);
2776 	break;
2777 
2778 
2779     case GUSMAX_MONITOR_LVL:	/* monitor level */
2780 	dip->type = AUDIO_MIXER_VALUE;
2781 	dip->mixer_class = GUSMAX_MONITOR_CLASS;
2782 	dip->next = GUSMAX_MONITOR_MUTE;
2783 	dip->prev = AUDIO_MIXER_LAST;
2784 	strlcpy(dip->label.name, AudioNmonitor, sizeof dip->label.name);
2785 	dip->un.v.num_channels = 1;
2786 	strlcpy(dip->un.v.units.name, AudioNvolume,
2787 	    sizeof dip->un.v.units.name);
2788 	break;
2789 
2790     case GUSMAX_OUT_LVL:		/* cs4231 output volume: not useful? */
2791 	dip->type = AUDIO_MIXER_VALUE;
2792 	dip->mixer_class = GUSMAX_MONITOR_CLASS;
2793 	dip->prev = dip->next = AUDIO_MIXER_LAST;
2794 	strlcpy(dip->label.name, AudioNoutput, sizeof dip->label.name);
2795 	dip->un.v.num_channels = 2;
2796 	strlcpy(dip->un.v.units.name, AudioNvolume,
2797 	    sizeof dip->un.v.units.name);
2798 	break;
2799 
2800     case GUSMAX_SPEAKER_LVL:		/* fake speaker volume */
2801 	dip->type = AUDIO_MIXER_VALUE;
2802 	dip->mixer_class = GUSMAX_MONITOR_CLASS;
2803 	dip->prev = AUDIO_MIXER_LAST;
2804 	dip->next = GUSMAX_SPEAKER_MUTE;
2805 	strlcpy(dip->label.name, AudioNmaster, sizeof dip->label.name);
2806 	dip->un.v.num_channels = 2;
2807 	strlcpy(dip->un.v.units.name, AudioNvolume,
2808 	    sizeof dip->un.v.units.name);
2809 	break;
2810 
2811     case GUSMAX_LINE_IN_MUTE:
2812 	dip->mixer_class = GUSMAX_INPUT_CLASS;
2813 	dip->type = AUDIO_MIXER_ENUM;
2814 	dip->prev = GUSMAX_LINE_IN_LVL;
2815 	dip->next = AUDIO_MIXER_LAST;
2816 	goto mute;
2817 
2818     case GUSMAX_DAC_MUTE:
2819 	dip->mixer_class = GUSMAX_INPUT_CLASS;
2820 	dip->type = AUDIO_MIXER_ENUM;
2821 	dip->prev = GUSMAX_DAC_LVL;
2822 	dip->next = AUDIO_MIXER_LAST;
2823 	goto mute;
2824 
2825     case GUSMAX_CD_MUTE:
2826 	dip->mixer_class = GUSMAX_INPUT_CLASS;
2827 	dip->type = AUDIO_MIXER_ENUM;
2828 	dip->prev = GUSMAX_CD_LVL;
2829 	dip->next = AUDIO_MIXER_LAST;
2830 	goto mute;
2831 
2832     case GUSMAX_MONO_MUTE:
2833 	dip->mixer_class = GUSMAX_INPUT_CLASS;
2834 	dip->type = AUDIO_MIXER_ENUM;
2835 	dip->prev = GUSMAX_MONO_LVL;
2836 	dip->next = AUDIO_MIXER_LAST;
2837 	goto mute;
2838 
2839     case GUSMAX_MONITOR_MUTE:
2840 	dip->mixer_class = GUSMAX_OUTPUT_CLASS;
2841 	dip->type = AUDIO_MIXER_ENUM;
2842 	dip->prev = GUSMAX_MONITOR_LVL;
2843 	dip->next = AUDIO_MIXER_LAST;
2844 	goto mute;
2845 
2846     case GUSMAX_SPEAKER_MUTE:
2847 	dip->mixer_class = GUSMAX_OUTPUT_CLASS;
2848 	dip->type = AUDIO_MIXER_ENUM;
2849 	dip->prev = GUSMAX_SPEAKER_LVL;
2850 	dip->next = AUDIO_MIXER_LAST;
2851     mute:
2852 	strlcpy(dip->label.name, AudioNmute, sizeof dip->label.name);
2853 	dip->un.e.num_mem = 2;
2854 	strlcpy(dip->un.e.member[0].label.name, AudioNoff,
2855 	    sizeof dip->un.e.member[0].label.name);
2856 	dip->un.e.member[0].ord = 0;
2857 	strlcpy(dip->un.e.member[1].label.name, AudioNon,
2858 	    sizeof dip->un.e.member[1].label.name);
2859 	dip->un.e.member[1].ord = 1;
2860 	break;
2861 
2862     case GUSMAX_REC_LVL:	/* record level */
2863 	dip->type = AUDIO_MIXER_VALUE;
2864 	dip->mixer_class = GUSMAX_RECORD_CLASS;
2865 	dip->prev = AUDIO_MIXER_LAST;
2866 	dip->next = GUSMAX_RECORD_SOURCE;
2867 	strlcpy(dip->label.name, AudioNrecord, sizeof dip->label.name);
2868 	dip->un.v.num_channels = 2;
2869 	strlcpy(dip->un.v.units.name, AudioNvolume, sizeof dip->un.v.units.name);
2870 	break;
2871 
2872     case GUSMAX_RECORD_SOURCE:
2873 	dip->mixer_class = GUSMAX_RECORD_CLASS;
2874 	dip->type = AUDIO_MIXER_ENUM;
2875 	dip->prev = GUSMAX_REC_LVL;
2876 	dip->next = AUDIO_MIXER_LAST;
2877 	strlcpy(dip->label.name, AudioNsource, sizeof dip->label.name);
2878 	dip->un.e.num_mem = 4;
2879 	strlcpy(dip->un.e.member[0].label.name, AudioNoutput,
2880 	    sizeof dip->un.e.member[0].label.name);
2881 	dip->un.e.member[0].ord = DAC_IN_PORT;
2882 	strlcpy(dip->un.e.member[1].label.name, AudioNmicrophone,
2883 	    sizeof dip->un.e.member[1].label.name);
2884 	dip->un.e.member[1].ord = MIC_IN_PORT;
2885 	strlcpy(dip->un.e.member[2].label.name, AudioNdac,
2886 	    sizeof dip->un.e.member[2].label.name);
2887 	dip->un.e.member[2].ord = AUX1_IN_PORT;
2888 	strlcpy(dip->un.e.member[3].label.name, AudioNline,
2889 	    sizeof dip->un.e.member[3].label.name);
2890 	dip->un.e.member[3].ord = LINE_IN_PORT;
2891 	break;
2892 
2893     case GUSMAX_INPUT_CLASS:			/* input class descriptor */
2894 	dip->type = AUDIO_MIXER_CLASS;
2895 	dip->mixer_class = GUSMAX_INPUT_CLASS;
2896 	dip->next = dip->prev = AUDIO_MIXER_LAST;
2897 	strlcpy(dip->label.name, AudioCinputs, sizeof dip->label.name);
2898 	break;
2899 
2900     case GUSMAX_OUTPUT_CLASS:			/* output class descriptor */
2901 	dip->type = AUDIO_MIXER_CLASS;
2902 	dip->mixer_class = GUSMAX_OUTPUT_CLASS;
2903 	dip->next = dip->prev = AUDIO_MIXER_LAST;
2904 	strlcpy(dip->label.name, AudioCoutputs, sizeof dip->label.name);
2905 	break;
2906 
2907     case GUSMAX_MONITOR_CLASS:			/* monitor class descriptor */
2908 	dip->type = AUDIO_MIXER_CLASS;
2909 	dip->mixer_class = GUSMAX_MONITOR_CLASS;
2910 	dip->next = dip->prev = AUDIO_MIXER_LAST;
2911 	strlcpy(dip->label.name, AudioCmonitor, sizeof dip->label.name);
2912 	break;
2913 
2914     case GUSMAX_RECORD_CLASS:			/* record source class */
2915 	dip->type = AUDIO_MIXER_CLASS;
2916 	dip->mixer_class = GUSMAX_RECORD_CLASS;
2917 	dip->next = dip->prev = AUDIO_MIXER_LAST;
2918 	strlcpy(dip->label.name, AudioCrecord, sizeof dip->label.name);
2919 	break;
2920 
2921     default:
2922 	return ENXIO;
2923 	/*NOTREACHED*/
2924     }
2925     DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name));
2926 	return 0;
2927 }
2928 
2929 int
2930 gus_mixer_query_devinfo(void *addr, mixer_devinfo_t *dip)
2931 {
2932 	struct gus_softc *sc = addr;
2933 
2934 	DPRINTF(("gusmax_query_devinfo: index=%d\n", dip->index));
2935 
2936 	if (!HAS_MIXER(sc) && dip->index > GUSICS_MASTER_MUTE)
2937 		return ENXIO;
2938 
2939 	switch(dip->index) {
2940 
2941 	case GUSICS_MIC_IN_LVL:	/* Microphone */
2942 		dip->type = AUDIO_MIXER_VALUE;
2943 		dip->mixer_class = GUSICS_INPUT_CLASS;
2944 		dip->prev = AUDIO_MIXER_LAST;
2945 		dip->next = GUSICS_MIC_IN_MUTE;
2946 		strlcpy(dip->label.name, AudioNmicrophone,
2947 		    sizeof dip->label.name);
2948 		dip->un.v.num_channels = 2;
2949 		strlcpy(dip->un.v.units.name, AudioNvolume,
2950 		    sizeof dip->un.v.units.name);
2951 		break;
2952 
2953 	case GUSICS_LINE_IN_LVL:	/* line */
2954 		dip->type = AUDIO_MIXER_VALUE;
2955 		dip->mixer_class = GUSICS_INPUT_CLASS;
2956 		dip->prev = AUDIO_MIXER_LAST;
2957 		dip->next = GUSICS_LINE_IN_MUTE;
2958 		strlcpy(dip->label.name, AudioNline, sizeof dip->label.name);
2959 		dip->un.v.num_channels = 2;
2960 		strlcpy(dip->un.v.units.name, AudioNvolume,
2961 		    sizeof dip->un.v.units.name);
2962 		break;
2963 
2964 	case GUSICS_CD_LVL:		/* cd */
2965 		dip->type = AUDIO_MIXER_VALUE;
2966 		dip->mixer_class = GUSICS_INPUT_CLASS;
2967 		dip->prev = AUDIO_MIXER_LAST;
2968 		dip->next = GUSICS_CD_MUTE;
2969 		strlcpy(dip->label.name, AudioNcd, sizeof dip->label.name);
2970 		dip->un.v.num_channels = 2;
2971 		strlcpy(dip->un.v.units.name, AudioNvolume,
2972 		    sizeof dip->un.v.units.name);
2973 		break;
2974 
2975 	case GUSICS_DAC_LVL:		/*  dacout */
2976 		dip->type = AUDIO_MIXER_VALUE;
2977 		dip->mixer_class = GUSICS_INPUT_CLASS;
2978 		dip->prev = AUDIO_MIXER_LAST;
2979 		dip->next = GUSICS_DAC_MUTE;
2980 		strlcpy(dip->label.name, AudioNdac, sizeof dip->label.name);
2981 		dip->un.v.num_channels = 2;
2982 		strlcpy(dip->un.v.units.name, AudioNvolume,
2983 		    sizeof dip->un.v.units.name);
2984 		break;
2985 
2986 	case GUSICS_MASTER_LVL:		/*  master output */
2987 		dip->type = AUDIO_MIXER_VALUE;
2988 		dip->mixer_class = GUSICS_OUTPUT_CLASS;
2989 		dip->prev = AUDIO_MIXER_LAST;
2990 		dip->next = GUSICS_MASTER_MUTE;
2991 		strlcpy(dip->label.name, AudioNmaster, sizeof dip->label.name);
2992 		dip->un.v.num_channels = 2;
2993 		strlcpy(dip->un.v.units.name, AudioNvolume,
2994 		    sizeof dip->un.v.units.name);
2995 		break;
2996 
2997 
2998 	case GUSICS_LINE_IN_MUTE:
2999 		dip->mixer_class = GUSICS_INPUT_CLASS;
3000 		dip->type = AUDIO_MIXER_ENUM;
3001 		dip->prev = GUSICS_LINE_IN_LVL;
3002 		dip->next = AUDIO_MIXER_LAST;
3003 		goto mute;
3004 
3005 	case GUSICS_DAC_MUTE:
3006 		dip->mixer_class = GUSICS_INPUT_CLASS;
3007 		dip->type = AUDIO_MIXER_ENUM;
3008 		dip->prev = GUSICS_DAC_LVL;
3009 		dip->next = AUDIO_MIXER_LAST;
3010 		goto mute;
3011 
3012 	case GUSICS_CD_MUTE:
3013 		dip->mixer_class = GUSICS_INPUT_CLASS;
3014 		dip->type = AUDIO_MIXER_ENUM;
3015 		dip->prev = GUSICS_CD_LVL;
3016 		dip->next = AUDIO_MIXER_LAST;
3017 		goto mute;
3018 
3019 	case GUSICS_MIC_IN_MUTE:
3020 		dip->mixer_class = GUSICS_INPUT_CLASS;
3021 		dip->type = AUDIO_MIXER_ENUM;
3022 		dip->prev = GUSICS_MIC_IN_LVL;
3023 		dip->next = AUDIO_MIXER_LAST;
3024 		goto mute;
3025 
3026 	case GUSICS_MASTER_MUTE:
3027 		dip->mixer_class = GUSICS_OUTPUT_CLASS;
3028 		dip->type = AUDIO_MIXER_ENUM;
3029 		dip->prev = GUSICS_MASTER_LVL;
3030 		dip->next = AUDIO_MIXER_LAST;
3031 mute:
3032 		strlcpy(dip->label.name, AudioNmute, sizeof dip->label.name);
3033 		dip->un.e.num_mem = 2;
3034 		strlcpy(dip->un.e.member[0].label.name, AudioNoff,
3035 		    sizeof dip->un.e.member[0].label.name);
3036 		dip->un.e.member[0].ord = 0;
3037 		strlcpy(dip->un.e.member[1].label.name, AudioNon,
3038 		    sizeof dip->un.e.member[1].label.name);
3039 		dip->un.e.member[1].ord = 1;
3040 		break;
3041 
3042 	case GUSICS_RECORD_SOURCE:
3043 		dip->mixer_class = GUSICS_RECORD_CLASS;
3044 		dip->type = AUDIO_MIXER_ENUM;
3045 		dip->prev = dip->next = AUDIO_MIXER_LAST;
3046 		strlcpy(dip->label.name, AudioNsource, sizeof dip->label.name);
3047 		dip->un.e.num_mem = 1;
3048 		strlcpy(dip->un.e.member[0].label.name, AudioNoutput,
3049 		    sizeof dip->un.e.member[0].label.name);
3050 		dip->un.e.member[0].ord = GUSICS_MASTER_LVL;
3051 		break;
3052 
3053 	case GUSICS_INPUT_CLASS:
3054 		dip->type = AUDIO_MIXER_CLASS;
3055 		dip->mixer_class = GUSICS_INPUT_CLASS;
3056 		dip->next = dip->prev = AUDIO_MIXER_LAST;
3057 		strlcpy(dip->label.name, AudioCinputs, sizeof dip->label.name);
3058 		break;
3059 
3060 	case GUSICS_OUTPUT_CLASS:
3061 		dip->type = AUDIO_MIXER_CLASS;
3062 		dip->mixer_class = GUSICS_OUTPUT_CLASS;
3063 		dip->next = dip->prev = AUDIO_MIXER_LAST;
3064 		strlcpy(dip->label.name, AudioCoutputs, sizeof dip->label.name);
3065 		break;
3066 
3067 	case GUSICS_RECORD_CLASS:
3068 		dip->type = AUDIO_MIXER_CLASS;
3069 		dip->mixer_class = GUSICS_RECORD_CLASS;
3070 		dip->next = dip->prev = AUDIO_MIXER_LAST;
3071 		strlcpy(dip->label.name, AudioCrecord, sizeof dip->label.name);
3072 		break;
3073 
3074 	default:
3075 		return ENXIO;
3076 	/*NOTREACHED*/
3077 	}
3078 	DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name));
3079 	return 0;
3080 }
3081 
3082 void *
3083 gus_malloc(void *addr, int direction, size_t size, int pool, int flags)
3084 {
3085 	struct gus_softc *sc = addr;
3086 	int drq;
3087 
3088 	if (direction == AUMODE_PLAY)
3089 		drq = sc->sc_drq;
3090 	else
3091 		drq = sc->sc_recdrq;
3092 
3093 	return isa_malloc(sc->sc_isa, drq, size, pool, flags);
3094 }
3095 
3096 void
3097 gus_free(void *addr, void *ptr, int pool)
3098 {
3099 	isa_free(ptr, pool);
3100 }
3101 
3102 size_t
3103 gus_round(void *addr, int direction, size_t size)
3104 {
3105 	if (size > MAX_ISADMA)
3106 		size = MAX_ISADMA;
3107 	return size;
3108 }
3109 
3110 /*
3111  * Setup the ICS mixer in "transparent" mode: reset everything to a sensible
3112  * level.  Levels as suggested by GUS SDK code.
3113  */
3114 
3115 void
3116 gus_init_ics2101(struct gus_softc *sc)
3117 {
3118 	struct ics2101_softc *ic = &sc->sc_mixer;
3119 	sc->sc_mixer.sc_iot = sc->sc_iot;
3120 	sc->sc_mixer.sc_selio = GUS_MIXER_SELECT;
3121 	sc->sc_mixer.sc_selio_ioh = sc->sc_ioh3;
3122 	sc->sc_mixer.sc_dataio = GUS_MIXER_DATA;
3123 	sc->sc_mixer.sc_dataio_ioh = sc->sc_ioh2;
3124 	sc->sc_mixer.sc_flags = (sc->sc_revision == 5) ? ICS_FLIP : 0;
3125 
3126 	ics2101_mix_attenuate(ic,
3127 			      GUSMIX_CHAN_MIC,
3128 			      ICSMIX_LEFT,
3129 			      ICSMIX_MIN_ATTN);
3130 	ics2101_mix_attenuate(ic,
3131 			      GUSMIX_CHAN_MIC,
3132 			      ICSMIX_RIGHT,
3133 			      ICSMIX_MIN_ATTN);
3134 	/*
3135 	 * Start with microphone muted by the mixer...
3136 	 */
3137 	gusics_mic_mute(ic, 1);
3138 
3139 	/* ... and enabled by the GUS master mix control */
3140 	gus_mic_ctl(sc, SPKR_ON);
3141 
3142 	ics2101_mix_attenuate(ic,
3143 			      GUSMIX_CHAN_LINE,
3144 			      ICSMIX_LEFT,
3145 			      ICSMIX_MIN_ATTN);
3146 	ics2101_mix_attenuate(ic,
3147 			      GUSMIX_CHAN_LINE,
3148 			      ICSMIX_RIGHT,
3149 			      ICSMIX_MIN_ATTN);
3150 
3151 	ics2101_mix_attenuate(ic,
3152 			      GUSMIX_CHAN_CD,
3153 			      ICSMIX_LEFT,
3154 			      ICSMIX_MIN_ATTN);
3155 	ics2101_mix_attenuate(ic,
3156 			      GUSMIX_CHAN_CD,
3157 			      ICSMIX_RIGHT,
3158 			      ICSMIX_MIN_ATTN);
3159 
3160 	ics2101_mix_attenuate(ic,
3161 			      GUSMIX_CHAN_DAC,
3162 			      ICSMIX_LEFT,
3163 			      ICSMIX_MIN_ATTN);
3164 	ics2101_mix_attenuate(ic,
3165 			      GUSMIX_CHAN_DAC,
3166 			      ICSMIX_RIGHT,
3167 			      ICSMIX_MIN_ATTN);
3168 
3169 	ics2101_mix_attenuate(ic,
3170 			      ICSMIX_CHAN_4,
3171 			      ICSMIX_LEFT,
3172 			      ICSMIX_MAX_ATTN);
3173 	ics2101_mix_attenuate(ic,
3174 			      ICSMIX_CHAN_4,
3175 			      ICSMIX_RIGHT,
3176 			      ICSMIX_MAX_ATTN);
3177 
3178 	ics2101_mix_attenuate(ic,
3179 			      GUSMIX_CHAN_MASTER,
3180 			      ICSMIX_LEFT,
3181 			      ICSMIX_MIN_ATTN);
3182 	ics2101_mix_attenuate(ic,
3183 			      GUSMIX_CHAN_MASTER,
3184 			      ICSMIX_RIGHT,
3185 			      ICSMIX_MIN_ATTN);
3186 	/* unmute other stuff: */
3187 	gusics_cd_mute(ic, 0);
3188 	gusics_dac_mute(ic, 0);
3189 	gusics_linein_mute(ic, 0);
3190 	return;
3191 }
3192 
3193 
3194 
3195 void
3196 gus_subattach(struct gus_softc *sc, struct isa_attach_args *ia)
3197 {
3198 	int		i;
3199 	bus_space_tag_t iot;
3200 	unsigned char	c,d,m;
3201 	u_long		s;
3202 
3203 	iot = sc->sc_iot;
3204 
3205 	/*
3206 	 * Figure out our board rev, and see if we need to initialize the
3207 	 * mixer
3208 	 */
3209 
3210 	c = bus_space_read_1(iot, sc->sc_ioh3, GUS_BOARD_REV);
3211 	if (c != 0xff)
3212 		sc->sc_revision = c;
3213 	else
3214 		sc->sc_revision = 0;
3215 
3216 	SELECT_GUS_REG(iot, sc->sc_ioh2, GUSREG_RESET);
3217 	bus_space_write_1(iot, sc->sc_ioh2, GUS_DATA_HIGH, 0x00);
3218 
3219 	gusreset(sc, GUS_MAX_VOICES); /* initialize all voices */
3220 	gusreset(sc, GUS_MIN_VOICES); /* then set to just the ones we use */
3221 
3222 	/*
3223 	 * Setup the IRQ and DRQ lines in software, using values from
3224 	 * config file
3225 	 */
3226 
3227 	m = GUSMASK_LINE_IN|GUSMASK_LINE_OUT;		/* disable all */
3228 
3229 	c = ((unsigned char) gus_irq_map[ia->ia_irq]) | GUSMASK_BOTH_RQ;
3230 
3231 	if (sc->sc_recdrq == sc->sc_drq)
3232 		d = (unsigned char) (gus_drq_map[sc->sc_drq] |
3233 				GUSMASK_BOTH_RQ);
3234 	else
3235 		d = (unsigned char) (gus_drq_map[sc->sc_drq] |
3236 				gus_drq_map[sc->sc_recdrq] << 3);
3237 
3238 	/*
3239 	 * Program the IRQ and DMA channels on the GUS.  Note that we hardwire
3240 	 * the GUS to only use one IRQ channel, but we give the user the
3241 	 * option of using two DMA channels (the other one given by the drq2
3242 	 * option in the config file).  Two DMA channels are needed for full-
3243 	 * duplex operation.
3244 	 *
3245 	 * The order of these operations is very magical.
3246 	 */
3247 
3248 	s = intr_disable();		/* XXX needed? */
3249 
3250 	bus_space_write_1(iot, sc->sc_ioh1, GUS_REG_CONTROL, GUS_REG_IRQCTL);
3251 	bus_space_write_1(iot, sc->sc_ioh1, GUS_MIX_CONTROL, m);
3252 	bus_space_write_1(iot, sc->sc_ioh1, GUS_IRQCTL_CONTROL, 0x00);
3253 	bus_space_write_1(iot, sc->sc_ioh1, 0x0f, 0x00);
3254 
3255 	bus_space_write_1(iot, sc->sc_ioh1, GUS_MIX_CONTROL, m);
3256 
3257 	/* magic reset? */
3258 	bus_space_write_1(iot, sc->sc_ioh1, GUS_DMA_CONTROL, d | 0x80);
3259 
3260 	bus_space_write_1(iot, sc->sc_ioh1, GUS_MIX_CONTROL,
3261 	    m | GUSMASK_CONTROL_SEL);
3262 	bus_space_write_1(iot, sc->sc_ioh1, GUS_IRQ_CONTROL, c);
3263 
3264 	bus_space_write_1(iot, sc->sc_ioh1, GUS_MIX_CONTROL, m);
3265 	bus_space_write_1(iot, sc->sc_ioh1, GUS_DMA_CONTROL, d);
3266 
3267 	bus_space_write_1(iot, sc->sc_ioh1, GUS_MIX_CONTROL,
3268 	    m | GUSMASK_CONTROL_SEL);
3269 	bus_space_write_1(iot, sc->sc_ioh1, GUS_IRQ_CONTROL, c);
3270 
3271 	bus_space_write_1(iot, sc->sc_ioh2, GUS_VOICE_SELECT, 0x00);
3272 
3273 	/* enable line in, line out.  leave mic disabled. */
3274 	bus_space_write_1(iot, sc->sc_ioh1, GUS_MIX_CONTROL,
3275 	     (m | GUSMASK_LATCHES) & ~(GUSMASK_LINE_OUT|GUSMASK_LINE_IN));
3276 	bus_space_write_1(iot, sc->sc_ioh2, GUS_VOICE_SELECT, 0x00);
3277 
3278 	intr_restore(s);
3279 
3280 	sc->sc_mixcontrol =
3281 		(m | GUSMASK_LATCHES) & ~(GUSMASK_LINE_OUT|GUSMASK_LINE_IN);
3282 
3283 	sc->sc_codec.sc_isa = sc->sc_isa;
3284 
3285 	if (sc->sc_revision >= 5 && sc->sc_revision <= 9) {
3286 		sc->sc_flags |= GUS_MIXER_INSTALLED;
3287 		gus_init_ics2101(sc);
3288 	}
3289 	if (sc->sc_revision < 10 || !gus_init_cs4231(sc)) {
3290 		/* Not using the CS4231, so create our DMA maps. */
3291 		if (sc->sc_drq != -1) {
3292 			if (isa_dmamap_create(sc->sc_isa, sc->sc_drq,
3293 			    MAX_ISADMA, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) {
3294 				printf("%s: can't create map for drq %d\n",
3295 				       sc->sc_dev.dv_xname, sc->sc_drq);
3296 				return;
3297 			}
3298 		}
3299 		if (sc->sc_recdrq != -1 && sc->sc_recdrq != sc->sc_drq) {
3300 			if (isa_dmamap_create(sc->sc_isa, sc->sc_recdrq,
3301 			    MAX_ISADMA, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) {
3302 				printf("%s: can't create map for drq %d\n",
3303 				       sc->sc_dev.dv_xname, sc->sc_recdrq);
3304 				return;
3305 			}
3306 		}
3307 	}
3308 
3309 	timeout_set(&sc->sc_dma_tmo, gus_dmaout_timeout, sc);
3310 
3311 	SELECT_GUS_REG(iot, sc->sc_ioh2, GUSREG_RESET);
3312 	/*
3313 	 * Check to see how much memory we have on this card; see if any
3314 	 * "mirroring" occurs.  We're assuming at least 256K already exists
3315 	 * on the card; otherwise the initial probe would have failed
3316 	 */
3317 
3318 	guspoke(iot, sc->sc_ioh2, 0L, 0x00);
3319 	for(i = 1; i < 1024; i++) {
3320 		u_long loc;
3321 
3322 		/*
3323 		 * See if we've run into mirroring yet
3324 		 */
3325 
3326 		if (guspeek(iot, sc->sc_ioh2, 0L) != 0)
3327 			break;
3328 
3329 		loc = i << 10;
3330 
3331 		guspoke(iot, sc->sc_ioh2, loc, 0xaa);
3332 		if (guspeek(iot, sc->sc_ioh2, loc) != 0xaa)
3333 			break;
3334 	}
3335 
3336 	sc->sc_dsize = i;
3337 	/*
3338 	 * The "official" (3.x) version number cannot easily be obtained.
3339 	 * The revision register does not correspond to the minor number
3340 	 * of the board version. Simply use the revision register as
3341 	 * identification.
3342 	 */
3343 	printf(": ver %d", sc->sc_revision);
3344 	if (sc->sc_revision >= 10)
3345 		printf(", MAX");
3346 	else {
3347 		if (HAS_MIXER(sc))
3348 			printf(", ICS2101 mixer");
3349 		if (HAS_CODEC(sc))
3350 			printf(", %s codec/mixer", sc->sc_codec.chip_name);
3351 	}
3352 	printf(", %dKB DRAM, ", sc->sc_dsize);
3353 	if (sc->sc_recdrq == sc->sc_drq) {
3354 		printf("half-duplex");
3355 	} else {
3356 		printf("full-duplex, record drq %d", sc->sc_recdrq);
3357 	}
3358 
3359 	printf("\n");
3360 
3361 	/*
3362 	 * Setup a default interrupt handler
3363 	 */
3364 
3365 	sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq,
3366 	    IST_EDGE, IPL_AUDIO | IPL_MPSAFE,
3367 	    gusintr, sc /* sc->sc_gusdsp */, sc->sc_dev.dv_xname);
3368 
3369 	/*
3370 	 * Set some default values
3371 	 * XXX others start with 8kHz mono mulaw
3372 	 */
3373 
3374 	sc->sc_irate = sc->sc_orate = 44100;
3375 	sc->sc_encoding = AUDIO_ENCODING_SLINEAR_LE;
3376 	sc->sc_precision = 16;
3377 	sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_DATA_SIZE16;
3378 	sc->sc_voc[GUS_VOICE_RIGHT].voccntl |= GUSMASK_DATA_SIZE16;
3379 	sc->sc_channels = 1;
3380 	sc->sc_ogain = 340;
3381 	gus_commit_settings(sc);
3382 
3383 	/*
3384 	 * We always put the left channel full left & right channel
3385 	 * full right.
3386 	 * For mono playback, we set up both voices playing the same buffer.
3387 	 */
3388 	bus_space_write_1(iot, sc->sc_ioh2, GUS_VOICE_SELECT,
3389 	    (u_char)GUS_VOICE_LEFT);
3390 	SELECT_GUS_REG(iot, sc->sc_ioh2, GUSREG_PAN_POS);
3391 	bus_space_write_1(iot, sc->sc_ioh2, GUS_DATA_HIGH, GUS_PAN_FULL_LEFT);
3392 
3393 	bus_space_write_1(iot, sc->sc_ioh2, GUS_VOICE_SELECT,
3394 	    (u_char)GUS_VOICE_RIGHT);
3395 	SELECT_GUS_REG(iot, sc->sc_ioh2, GUSREG_PAN_POS);
3396 	bus_space_write_1(iot, sc->sc_ioh2, GUS_DATA_HIGH, GUS_PAN_FULL_RIGHT);
3397 
3398 	/*
3399 	 * Attach to the generic audio layer
3400 	 */
3401 
3402 	audio_attach_mi(&gus_hw_if, HAS_CODEC(sc) ? (void *)&sc->sc_codec :
3403 	    (void *)sc, &sc->sc_dev);
3404 }
3405 
3406 /*
3407  * Test to see if a particular I/O base is valid for the GUS.  Return true
3408  * if it is.
3409  */
3410 
3411 int
3412 gus_test_iobase (bus_space_tag_t iot, int iobase)
3413 {
3414 	bus_space_handle_t ioh1, ioh2, ioh3, ioh4;
3415 	u_char s1, s2;
3416 	int rv = 0;
3417 
3418 	/* Map i/o space */
3419 	if (bus_space_map(iot, iobase, GUS_NPORT1, 0, &ioh1))
3420 		return 0;
3421 	if (bus_space_map(iot, iobase+GUS_IOH2_OFFSET, GUS_NPORT2, 0, &ioh2))
3422 		goto bad1;
3423 
3424 	/* XXX Maybe we shouldn't fail on mapping this, but just assume
3425 	 * the card is of revision 0? */
3426 	if (bus_space_map(iot, iobase+GUS_IOH3_OFFSET, GUS_NPORT3, 0, &ioh3))
3427 		goto bad2;
3428 
3429 	if (bus_space_map(iot, iobase+GUS_IOH4_OFFSET, GUS_NPORT4, 0, &ioh4))
3430 		goto bad3;
3431 
3432 	/*
3433 	 * Reset GUS to an initial state before we do anything.
3434 	 */
3435 
3436 	mtx_enter(&audio_lock);
3437 	delay(500);
3438 
3439 	SELECT_GUS_REG(iot, ioh2, GUSREG_RESET);
3440 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
3441 
3442 	delay(500);
3443 
3444 	SELECT_GUS_REG(iot, ioh2, GUSREG_RESET);
3445 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, GUSMASK_MASTER_RESET);
3446 
3447 	delay(500);
3448 
3449 	mtx_leave(&audio_lock);
3450 
3451 	/*
3452 	 * See if we can write to the board's memory
3453 	 */
3454 
3455 	s1 = guspeek(iot, ioh2, 0L);
3456 	s2 = guspeek(iot, ioh2, 1L);
3457 
3458 	guspoke(iot, ioh2, 0L, 0xaa);
3459 	guspoke(iot, ioh2, 1L, 0x55);
3460 
3461 	if (guspeek(iot, ioh2, 0L) != 0xaa)
3462 		goto bad;
3463 
3464 	guspoke(iot, ioh2, 0L, s1);
3465 	guspoke(iot, ioh2, 1L, s2);
3466 
3467 	rv = 1;
3468 
3469 bad:
3470 	bus_space_unmap(iot, ioh4, GUS_NPORT4);
3471 bad3:
3472 	bus_space_unmap(iot, ioh3, GUS_NPORT3);
3473 bad2:
3474 	bus_space_unmap(iot, ioh2, GUS_NPORT2);
3475 bad1:
3476 	bus_space_unmap(iot, ioh1, GUS_NPORT1);
3477 	return rv;
3478 }
3479