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