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