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