xref: /openbsd-src/sys/dev/isa/gus.c (revision 2b0358df1d88d06ef4139321dd05bd5e05d91eaf)
1 /*	$OpenBSD: gus.c,v 1.32 2008/10/15 19:12:18 blambert 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 #ifdef DDB
1005 			    printf("%s: negative bufcnt in stopped voice\n",
1006 				   sc->sc_dev.dv_xname);
1007 			    Debugger();
1008 #else
1009 			    panic("%s: negative bufcnt in stopped voice",
1010 				  sc->sc_dev.dv_xname);
1011 #endif
1012 			} else {
1013 			    sc->sc_playbuf = -1; /* none are active */
1014 			    gus_stops++;
1015 			}
1016 			/* fall through to callback and admit another
1017 			   buffer.... */
1018 		    } else if (sc->sc_bufcnt != 0) {
1019 			/*
1020 			 * This should always be taken if the voice
1021 			 * is not stopped.
1022 			 */
1023 			gus_continues++;
1024 			if (gus_continue_playing(sc, voice)) {
1025 				/*
1026 				 * we shouldn't have continued--active DMA
1027 				 * is in the way in the ring, for
1028 				 * some as-yet undebugged reason.
1029 				 */
1030 				gus_stop_voice(sc, GUS_VOICE_LEFT, 1);
1031 				/* also kill right voice */
1032 				gus_stop_voice(sc, GUS_VOICE_RIGHT, 0);
1033 				sc->sc_playbuf = -1;
1034 				gus_stops++;
1035 			}
1036 		    }
1037 		    /*
1038 		     * call the upper level to send on down another
1039 		     * block. We do admission rate control as follows:
1040 		     *
1041 		     * When starting up output (in the first N
1042 		     * blocks), call the upper layer after the DMA is
1043 		     * complete (see above in gus_dmaout_intr()).
1044 		     *
1045 		     * When output is already in progress and we have
1046 		     * no more GUS buffers to use for DMA, the DMA
1047 		     * output routines do not call the upper layer.
1048 		     * Instead, we call the DMA completion routine
1049 		     * here, after the voice interrupts indicating
1050 		     * that it's finished with a buffer.
1051 		     *
1052 		     * However, don't call anything here if the DMA
1053 		     * output flag is set, (which shouldn't happen)
1054 		     * because we'll squish somebody else's DMA if
1055 		     * that's the case.  When DMA is done, it will
1056 		     * call back if there is a spare buffer.
1057 		     */
1058 		    if (sc->sc_dmaoutintr && !(sc->sc_flags & GUS_LOCKED)) {
1059 			if (sc->sc_dmaoutintr == stereo_dmaintr)
1060 			    printf("gusdmaout botch?\n");
1061 			else {
1062 			    /* clean out to avoid double calls */
1063 			    void (*pfunc)(void *) = sc->sc_dmaoutintr;
1064 			    void *arg = sc->sc_outarg;
1065 
1066 			    sc->sc_outarg = 0;
1067 			    sc->sc_dmaoutintr = 0;
1068 			    (*pfunc)(arg);
1069 			}
1070 		    }
1071 		}
1072 
1073 		/*
1074 		 * Ignore other interrupts for now
1075 		 */
1076 	}
1077 	return 0;
1078 }
1079 
1080 void
1081 gus_start_playing(sc, bufno)
1082 	struct gus_softc *sc;
1083 	int bufno;
1084 {
1085 	bus_space_tag_t iot = sc->sc_iot;
1086 	bus_space_handle_t ioh2 = sc->sc_ioh2;
1087 	/*
1088 	 * Start the voices playing, with buffer BUFNO.
1089 	 */
1090 
1091 	/*
1092 	 * Loop or roll if we have buffers ready.
1093 	 */
1094 
1095 	if (sc->sc_bufcnt == 1) {
1096 		sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~(GUSMASK_LOOP_ENABLE);
1097 		sc->sc_voc[GUS_VOICE_LEFT].volcntl &= ~(GUSMASK_VOICE_ROLL);
1098 	} else {
1099 		if (bufno == sc->sc_nbufs - 1) {
1100 			sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_LOOP_ENABLE;
1101 			sc->sc_voc[GUS_VOICE_LEFT].volcntl &= ~(GUSMASK_VOICE_ROLL);
1102 		} else {
1103 			sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~GUSMASK_LOOP_ENABLE;
1104 			sc->sc_voc[GUS_VOICE_LEFT].volcntl |= GUSMASK_VOICE_ROLL;
1105 		}
1106 	}
1107 
1108 	bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, GUS_VOICE_LEFT);
1109 
1110 	SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
1111 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_LEFT].voccntl);
1112 
1113 	SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
1114 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_LEFT].volcntl);
1115 
1116 	sc->sc_voc[GUS_VOICE_LEFT].current_addr =
1117 		GUS_MEM_OFFSET + sc->sc_chanblocksize * bufno;
1118 	sc->sc_voc[GUS_VOICE_LEFT].end_addr =
1119 		sc->sc_voc[GUS_VOICE_LEFT].current_addr + sc->sc_chanblocksize - 1;
1120 	sc->sc_voc[GUS_VOICE_RIGHT].current_addr =
1121 		sc->sc_voc[GUS_VOICE_LEFT].current_addr +
1122 		(gus_dostereo && sc->sc_channels == 2 ? GUS_LEFT_RIGHT_OFFSET : 0);
1123 	/*
1124 	 * set up right channel to just loop forever, no interrupts,
1125 	 * starting at the buffer we just filled.  We'll feed it data
1126 	 * at the same time as left channel.
1127 	 */
1128 	sc->sc_voc[GUS_VOICE_RIGHT].voccntl |= GUSMASK_LOOP_ENABLE;
1129 	sc->sc_voc[GUS_VOICE_RIGHT].volcntl &= ~(GUSMASK_VOICE_ROLL);
1130 
1131 #ifdef GUSPLAYDEBUG
1132 	if (gusstats) {
1133 		microtime(&playstats[playcntr].tv);
1134 		playstats[playcntr].curaddr = sc->sc_voc[GUS_VOICE_LEFT].current_addr;
1135 
1136 		playstats[playcntr].voccntl = sc->sc_voc[GUS_VOICE_LEFT].voccntl;
1137 		playstats[playcntr].volcntl = sc->sc_voc[GUS_VOICE_LEFT].volcntl;
1138 		playstats[playcntr].endaddr = sc->sc_voc[GUS_VOICE_LEFT].end_addr;
1139 		playstats[playcntr].playbuf = bufno;
1140 		playstats[playcntr].dmabuf = sc->sc_dmabuf;
1141 		playstats[playcntr].bufcnt = sc->sc_bufcnt;
1142 		playstats[playcntr++].vaction = 5;
1143 		playcntr = playcntr % NDMARECS;
1144 	}
1145 #endif
1146 
1147 	bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, GUS_VOICE_RIGHT);
1148 	SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
1149 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_RIGHT].voccntl);
1150 	SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
1151 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_RIGHT].volcntl);
1152 
1153 	gus_start_voice(sc, GUS_VOICE_RIGHT, 0);
1154 	gus_start_voice(sc, GUS_VOICE_LEFT, 1);
1155 	if (sc->sc_playbuf == -1)
1156 		/* mark start of playing */
1157 		sc->sc_playbuf = bufno;
1158 }
1159 
1160 int
1161 gus_continue_playing(sc, voice)
1162 	struct gus_softc *sc;
1163 	int voice;
1164 {
1165 	bus_space_tag_t iot = sc->sc_iot;
1166 	bus_space_handle_t ioh2 = sc->sc_ioh2;
1167 
1168 	/*
1169 	 * stop this voice from interrupting while we work.
1170 	 */
1171 
1172 	SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
1173 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl & ~(GUSMASK_VOICE_IRQ));
1174 
1175 	/*
1176 	 * update playbuf to point to the buffer the hardware just started
1177 	 * playing
1178 	 */
1179 	sc->sc_playbuf = ++sc->sc_playbuf % sc->sc_nbufs;
1180 
1181 	/*
1182 	 * account for buffer just finished
1183 	 */
1184 	if (--sc->sc_bufcnt == 0) {
1185 		DPRINTF(("gus: bufcnt 0 on continuing voice?\n"));
1186 	}
1187 	if (sc->sc_playbuf == sc->sc_dmabuf && (sc->sc_flags & GUS_LOCKED)) {
1188 		printf("%s: continue into active dmabuf?\n", sc->sc_dev.dv_xname);
1189 		return 1;
1190 	}
1191 
1192 	/*
1193 	 * Select the end of the buffer based on the currently active
1194 	 * buffer, [plus extra contiguous buffers (if ready)].
1195 	 */
1196 
1197 	/*
1198 	 * set endpoint at end of buffer we just started playing.
1199 	 *
1200 	 * The total gets -1 because end addrs are one less than you might
1201 	 * think (the end_addr is the address of the last sample to play)
1202 	 */
1203 	gus_set_endaddr(sc, voice, GUS_MEM_OFFSET +
1204 			sc->sc_chanblocksize * (sc->sc_playbuf + 1) - 1);
1205 
1206 	if (sc->sc_bufcnt < 2) {
1207 		/*
1208 		 * Clear out the loop and roll flags, and rotate the currently
1209 		 * playing buffer.  That way, if we don't manage to get more
1210 		 * data before this buffer finishes, we'll just stop.
1211 		 */
1212 		sc->sc_voc[voice].voccntl &= ~GUSMASK_LOOP_ENABLE;
1213 		sc->sc_voc[voice].volcntl &= ~GUSMASK_VOICE_ROLL;
1214 		playstats[playcntr].vaction = 0;
1215 	} else {
1216 		/*
1217 		 * We have some buffers to play.  set LOOP if we're on the
1218 		 * last buffer in the ring, otherwise set ROLL.
1219 		 */
1220 		if (sc->sc_playbuf == sc->sc_nbufs - 1) {
1221 			sc->sc_voc[voice].voccntl |= GUSMASK_LOOP_ENABLE;
1222 			sc->sc_voc[voice].volcntl &= ~GUSMASK_VOICE_ROLL;
1223 			playstats[playcntr].vaction = 1;
1224 		} else {
1225 			sc->sc_voc[voice].voccntl &= ~GUSMASK_LOOP_ENABLE;
1226 			sc->sc_voc[voice].volcntl |= GUSMASK_VOICE_ROLL;
1227 			playstats[playcntr].vaction = 2;
1228 		}
1229 	}
1230 #ifdef GUSPLAYDEBUG
1231 	if (gusstats) {
1232 		microtime(&playstats[playcntr].tv);
1233 		playstats[playcntr].curaddr = gus_get_curaddr(sc, voice);
1234 
1235 		playstats[playcntr].voccntl = sc->sc_voc[voice].voccntl;
1236 		playstats[playcntr].volcntl = sc->sc_voc[voice].volcntl;
1237 		playstats[playcntr].endaddr = sc->sc_voc[voice].end_addr;
1238 		playstats[playcntr].playbuf = sc->sc_playbuf;
1239 		playstats[playcntr].dmabuf = sc->sc_dmabuf;
1240 		playstats[playcntr++].bufcnt = sc->sc_bufcnt;
1241 		playcntr = playcntr % NDMARECS;
1242 	}
1243 #endif
1244 
1245 	/*
1246 	 * (re-)set voice parameters.  This will reenable interrupts from this
1247 	 * voice.
1248 	 */
1249 
1250 	SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
1251 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
1252 	SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
1253 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].volcntl);
1254 	return 0;
1255 }
1256 
1257 /*
1258  * Send/receive data into GUS's DRAM using DMA.  Called at splgus()
1259  */
1260 
1261 void
1262 gusdmaout(sc, flags, gusaddr, buffaddr, length)
1263 	struct gus_softc *sc;
1264 	int flags, length;
1265 	u_long gusaddr;
1266 	caddr_t buffaddr;
1267 {
1268 	unsigned char c = (unsigned char) flags;
1269 	bus_space_tag_t iot = sc->sc_iot;
1270 	bus_space_handle_t ioh2 = sc->sc_ioh2;
1271 
1272 	DMAPRINTF(("gusdmaout flags=%x scflags=%x\n", flags, sc->sc_flags));
1273 
1274 	sc->sc_gusaddr = gusaddr;
1275 
1276 	/*
1277 	 * If we're using a 16 bit DMA channel, we have to jump through some
1278 	 * extra hoops; this includes translating the DRAM address a bit
1279 	 */
1280 
1281 	if (sc->sc_drq >= 4) {
1282 		c |= GUSMASK_DMA_WIDTH;
1283 		gusaddr = convert_to_16bit(gusaddr);
1284 	}
1285 
1286 	/*
1287 	 * Add flag bits that we always set - fast DMA, enable IRQ
1288 	 */
1289 
1290 	c |= GUSMASK_DMA_ENABLE | GUSMASK_DMA_R0 | GUSMASK_DMA_IRQ;
1291 
1292 	/*
1293 	 * Make sure the GUS _isn't_ setup for DMA
1294 	 */
1295 
1296 	SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
1297 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0);
1298 
1299 	/*
1300 	 * Tell the PC DMA controller to start doing DMA
1301 	 */
1302 
1303 	sc->sc_dmaoutaddr = (u_char *) buffaddr;
1304 	sc->sc_dmaoutcnt = length;
1305 	isa_dmastart(sc->sc_dev.dv_parent, sc->sc_drq, buffaddr, length,
1306 	    NULL, DMAMODE_WRITE, BUS_DMA_NOWAIT);
1307 
1308 	/*
1309 	 * Set up DMA address - use the upper 16 bits ONLY
1310 	 */
1311 
1312 	sc->sc_flags |= GUS_DMAOUT_ACTIVE;
1313 
1314 	SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_START);
1315 	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, (int) (gusaddr >> 4));
1316 
1317 	/*
1318 	 * Tell the GUS to start doing DMA
1319 	 */
1320 
1321 	SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
1322 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, c);
1323 
1324 	/*
1325 	 * XXX If we don't finish in one second, give up...
1326 	 */
1327 	timeout_add_sec(&sc->sc_dma_tmo, 1);
1328 }
1329 
1330 /*
1331  * Start a voice playing on the GUS.  Called from interrupt handler at
1332  * splgus().
1333  */
1334 
1335 void
1336 gus_start_voice(sc, voice, intrs)
1337 	struct gus_softc *sc;
1338 	int voice;
1339 	int intrs;
1340 {
1341 	bus_space_tag_t iot = sc->sc_iot;
1342 	bus_space_handle_t ioh2 = sc->sc_ioh2;
1343 	u_long start;
1344 	u_long current;
1345 	u_long end;
1346 
1347 	/*
1348 	 * Pick all the values for the voice out of the gus_voice struct
1349 	 * and use those to program the voice
1350 	 */
1351 
1352 	start = sc->sc_voc[voice].start_addr;
1353 	current = sc->sc_voc[voice].current_addr;
1354 	end = sc->sc_voc[voice].end_addr;
1355 
1356 	/*
1357 	 * If we're using 16 bit data, mangle the addresses a bit
1358 	 */
1359 
1360 	if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16) {
1361 	        /* -1 on start so that we get onto sample boundary--other
1362 		   code always sets it for 1-byte rollover protection */
1363 		start = convert_to_16bit(start-1);
1364 		current = convert_to_16bit(current);
1365 		end = convert_to_16bit(end);
1366 	}
1367 
1368 	/*
1369 	 * Select the voice we want to use, and program the data addresses
1370 	 */
1371 
1372 	bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
1373 
1374 	SELECT_GUS_REG(iot, ioh2, GUSREG_START_ADDR_HIGH);
1375 	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(start));
1376 	SELECT_GUS_REG(iot, ioh2, GUSREG_START_ADDR_LOW);
1377 	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(start));
1378 
1379 	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH);
1380 	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(current));
1381 	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW);
1382 	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(current));
1383 
1384 	SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_HIGH);
1385 	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(end));
1386 	SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_LOW);
1387 	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(end));
1388 
1389 	/*
1390 	 * (maybe) enable interrupts, disable voice stopping
1391 	 */
1392 
1393 	if (intrs) {
1394 		sc->sc_flags |= GUS_PLAYING; /* playing is about to start */
1395 		sc->sc_voc[voice].voccntl |= GUSMASK_VOICE_IRQ;
1396 		DMAPRINTF(("gus voice playing=%x\n", sc->sc_flags));
1397 	} else
1398 		sc->sc_voc[voice].voccntl &= ~GUSMASK_VOICE_IRQ;
1399 	sc->sc_voc[voice].voccntl &= ~(GUSMASK_VOICE_STOPPED |
1400 		GUSMASK_STOP_VOICE);
1401 
1402 	/*
1403 	 * Tell the GUS about it.  Note that we're doing volume ramping here
1404 	 * from 0 up to the set volume to help reduce clicks.
1405 	 */
1406 
1407 	SELECT_GUS_REG(iot, ioh2, GUSREG_START_VOLUME);
1408 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
1409 	SELECT_GUS_REG(iot, ioh2, GUSREG_END_VOLUME);
1410 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].current_volume >> 4);
1411 	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME);
1412 	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x00);
1413 	SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_RATE);
1414 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 63);
1415 
1416 	SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
1417 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
1418 	SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
1419 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
1420 	delay(50);
1421 	SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
1422 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
1423 	SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
1424 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
1425 
1426 }
1427 
1428 /*
1429  * Stop a given voice.  called at splgus()
1430  */
1431 
1432 void
1433 gus_stop_voice(sc, voice, intrs_too)
1434 	struct gus_softc *sc;
1435 	int voice;
1436 	int intrs_too;
1437 {
1438 	bus_space_tag_t iot = sc->sc_iot;
1439 	bus_space_handle_t ioh2 = sc->sc_ioh2;
1440 
1441 	sc->sc_voc[voice].voccntl |= GUSMASK_VOICE_STOPPED |
1442 		GUSMASK_STOP_VOICE;
1443 	if (intrs_too) {
1444 	  sc->sc_voc[voice].voccntl &= ~(GUSMASK_VOICE_IRQ);
1445 	  /* no more DMA to do */
1446 	  sc->sc_flags &= ~GUS_PLAYING;
1447 	}
1448 	DMAPRINTF(("gusintr voice notplaying=%x\n", sc->sc_flags));
1449 
1450 	guspoke(iot, ioh2, 0L, 0);
1451 
1452 	bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
1453 
1454 	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME);
1455 	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
1456 	SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
1457 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
1458 	delay(100);
1459 	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME);
1460 	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
1461 	SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
1462 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
1463 
1464 	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH);
1465 	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
1466 	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW);
1467 	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
1468 
1469 }
1470 
1471 
1472 /*
1473  * Set the volume of a given voice.  Called at splgus().
1474  */
1475 void
1476 gus_set_volume(sc, voice, volume)
1477 	struct gus_softc *sc;
1478 	int voice, volume;
1479 {
1480 	bus_space_tag_t iot = sc->sc_iot;
1481 	bus_space_handle_t ioh2 = sc->sc_ioh2;
1482 	unsigned int gusvol;
1483 
1484 	gusvol = gus_log_volumes[volume < 512 ? volume : 511];
1485 
1486 	sc->sc_voc[voice].current_volume = gusvol;
1487 
1488 	bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
1489 
1490 	SELECT_GUS_REG(iot, ioh2, GUSREG_START_VOLUME);
1491 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (unsigned char) (gusvol >> 4));
1492 
1493 	SELECT_GUS_REG(iot, ioh2, GUSREG_END_VOLUME);
1494 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (unsigned char) (gusvol >> 4));
1495 
1496 	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME);
1497 	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, gusvol << 4);
1498 	delay(500);
1499 	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, gusvol << 4);
1500 
1501 }
1502 
1503 /*
1504  * Interface to the audio layer.
1505  */
1506 
1507 int
1508 gusmax_set_params(addr, setmode, usemode, p, r)
1509 	void *addr;
1510 	int setmode, usemode;
1511 	struct audio_params *p, *r;
1512 {
1513 	struct ad1848_softc *ac = addr;
1514 	struct gus_softc *sc = ac->parent;
1515 	int error;
1516 
1517 	error = ad1848_set_params(ac, setmode, usemode, p, r);
1518 	if (error)
1519 		return error;
1520 	error = gus_set_params(sc, setmode, usemode, p, r);
1521 	return error;
1522 }
1523 
1524 int
1525 gus_set_params(addr, setmode, usemode, p, r)
1526 	void *addr;
1527 	int setmode, usemode;
1528 	struct audio_params *p, *r;
1529 {
1530 	struct gus_softc *sc = addr;
1531 	int s;
1532 
1533 	switch (p->encoding) {
1534 	case AUDIO_ENCODING_ULAW:
1535 	case AUDIO_ENCODING_ALAW:
1536 	case AUDIO_ENCODING_SLINEAR_LE:
1537 	case AUDIO_ENCODING_ULINEAR_LE:
1538 	case AUDIO_ENCODING_SLINEAR_BE:
1539 	case AUDIO_ENCODING_ULINEAR_BE:
1540 		break;
1541 	default:
1542 		return (EINVAL);
1543 	}
1544 
1545 	s = splaudio();
1546 
1547 	if (p->precision == 8) {
1548 		sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~GUSMASK_DATA_SIZE16;
1549 		sc->sc_voc[GUS_VOICE_RIGHT].voccntl &= ~GUSMASK_DATA_SIZE16;
1550 	} else {
1551 		sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_DATA_SIZE16;
1552 		sc->sc_voc[GUS_VOICE_RIGHT].voccntl |= GUSMASK_DATA_SIZE16;
1553 	}
1554 
1555 	sc->sc_encoding = p->encoding;
1556 	sc->sc_precision = p->precision;
1557 	sc->sc_channels = p->channels;
1558 
1559 	splx(s);
1560 
1561 	if (p->sample_rate > gus_max_frequency[sc->sc_voices - GUS_MIN_VOICES])
1562 		p->sample_rate = gus_max_frequency[sc->sc_voices - GUS_MIN_VOICES];
1563 	if (setmode & AUMODE_RECORD)
1564 		sc->sc_irate = p->sample_rate;
1565 	if (setmode & AUMODE_PLAY)
1566 		sc->sc_orate = p->sample_rate;
1567 
1568 	switch (p->encoding) {
1569 	case AUDIO_ENCODING_ULAW:
1570 		p->sw_code = mulaw_to_ulinear8;
1571 		r->sw_code = ulinear8_to_mulaw;
1572 		break;
1573 	case AUDIO_ENCODING_ALAW:
1574 		p->sw_code = alaw_to_ulinear8;
1575 		r->sw_code = ulinear8_to_alaw;
1576 		break;
1577 	case AUDIO_ENCODING_ULINEAR_BE:
1578 	case AUDIO_ENCODING_SLINEAR_BE:
1579 		r->sw_code = p->sw_code = swap_bytes;
1580 		break;
1581 	}
1582 
1583 	return 0;
1584 }
1585 
1586 /*
1587  * Interface to the audio layer - set the blocksize to the correct number
1588  * of units
1589  */
1590 
1591 int
1592 gusmax_round_blocksize(addr, blocksize)
1593 	void * addr;
1594 	int blocksize;
1595 {
1596 	struct ad1848_softc *ac = addr;
1597 	struct gus_softc *sc = ac->parent;
1598 
1599 /*	blocksize = ad1848_round_blocksize(ac, blocksize);*/
1600 	return gus_round_blocksize(sc, blocksize);
1601 }
1602 
1603 int
1604 gus_round_blocksize(addr, blocksize)
1605 	void * addr;
1606 	int blocksize;
1607 {
1608 	struct gus_softc *sc = addr;
1609 
1610 	DPRINTF(("gus_round_blocksize called\n"));
1611 
1612 	if ((sc->sc_encoding == AUDIO_ENCODING_ULAW ||
1613 	     sc->sc_encoding == AUDIO_ENCODING_ALAW) && blocksize > 32768)
1614 		blocksize = 32768;
1615 	else if (blocksize > 65536)
1616 		blocksize = 65536;
1617 
1618 	if ((blocksize % GUS_BUFFER_MULTIPLE) != 0)
1619 		blocksize = (blocksize / GUS_BUFFER_MULTIPLE + 1) *
1620 			GUS_BUFFER_MULTIPLE;
1621 
1622 	/* set up temporary buffer to hold the deinterleave, if necessary
1623 	   for stereo output */
1624 	if (sc->sc_deintr_buf) {
1625 		free(sc->sc_deintr_buf, M_DEVBUF);
1626 		sc->sc_deintr_buf = NULL;
1627 	}
1628 	sc->sc_deintr_buf = malloc(blocksize/2, M_DEVBUF, M_WAITOK);
1629 
1630 	sc->sc_blocksize = blocksize;
1631 	/* multi-buffering not quite working yet. */
1632 	sc->sc_nbufs = /*GUS_MEM_FOR_BUFFERS / blocksize*/ 2;
1633 
1634 	gus_set_chan_addrs(sc);
1635 
1636 	return blocksize;
1637 }
1638 
1639 int
1640 gus_get_out_gain(addr)
1641 	caddr_t addr;
1642 {
1643 	struct gus_softc *sc = (struct gus_softc *) addr;
1644 
1645 	DPRINTF(("gus_get_out_gain called\n"));
1646 	return sc->sc_ogain / 2;
1647 }
1648 
1649 inline void gus_set_voices(sc, voices)
1650 struct gus_softc *sc;
1651 int voices;
1652 {
1653 	bus_space_tag_t iot = sc->sc_iot;
1654 	bus_space_handle_t ioh2 = sc->sc_ioh2;
1655 	/*
1656 	 * Select the active number of voices
1657 	 */
1658 
1659 	SELECT_GUS_REG(iot, ioh2, GUSREG_ACTIVE_VOICES);
1660 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (voices-1) | 0xc0);
1661 
1662 	sc->sc_voices = voices;
1663 }
1664 
1665 /*
1666  * Actually set the settings of various values on the card
1667  */
1668 
1669 int
1670 gusmax_commit_settings(addr)
1671 	void * addr;
1672 {
1673 	struct ad1848_softc *ac = addr;
1674 	struct gus_softc *sc = ac->parent;
1675 	int error;
1676 
1677 	error = ad1848_commit_settings(ac);
1678 	if (error)
1679 		return error;
1680 	return gus_commit_settings(sc);
1681 }
1682 
1683 /*
1684  * Commit the settings.  Called at normal IPL.
1685  */
1686 int
1687 gus_commit_settings(addr)
1688 	void * addr;
1689 {
1690 	struct gus_softc *sc = addr;
1691 	int s;
1692 
1693 	DPRINTF(("gus_commit_settings called (gain = %d)\n",sc->sc_ogain));
1694 
1695 
1696 	s = splgus();
1697 
1698 	gus_set_recrate(sc, sc->sc_irate);
1699 	gus_set_volume(sc, GUS_VOICE_LEFT, sc->sc_ogain);
1700 	gus_set_volume(sc, GUS_VOICE_RIGHT, sc->sc_ogain);
1701 	gus_set_samprate(sc, GUS_VOICE_LEFT, sc->sc_orate);
1702 	gus_set_samprate(sc, GUS_VOICE_RIGHT, sc->sc_orate);
1703 	splx(s);
1704 	gus_set_chan_addrs(sc);
1705 
1706 	return 0;
1707 }
1708 
1709 void
1710 gus_set_chan_addrs(sc)
1711 struct gus_softc *sc;
1712 {
1713 	/*
1714 	 * We use sc_nbufs * blocksize bytes of storage in the on-board GUS
1715 	 * ram.
1716 	 * For mono, each of the sc_nbufs buffers is DMA'd to in one chunk,
1717 	 * and both left & right channels play the same buffer.
1718 	 *
1719 	 * For stereo, each channel gets a contiguous half of the memory,
1720 	 * and each has sc_nbufs buffers of size blocksize/2.
1721 	 * Stereo data are deinterleaved in main memory before the DMA out
1722 	 * routines are called to queue the output.
1723 	 *
1724 	 * The blocksize per channel is kept in sc_chanblocksize.
1725 	 */
1726 	if (sc->sc_channels == 2)
1727 	    sc->sc_chanblocksize = sc->sc_blocksize/2;
1728 	else
1729 	    sc->sc_chanblocksize = sc->sc_blocksize;
1730 
1731 	sc->sc_voc[GUS_VOICE_LEFT].start_addr = GUS_MEM_OFFSET - 1;
1732 	sc->sc_voc[GUS_VOICE_RIGHT].start_addr =
1733 	    (gus_dostereo && sc->sc_channels == 2 ? GUS_LEFT_RIGHT_OFFSET : 0)
1734 	      + GUS_MEM_OFFSET - 1;
1735 	sc->sc_voc[GUS_VOICE_RIGHT].current_addr =
1736 	    sc->sc_voc[GUS_VOICE_RIGHT].start_addr + 1;
1737 	sc->sc_voc[GUS_VOICE_RIGHT].end_addr =
1738 	    sc->sc_voc[GUS_VOICE_RIGHT].start_addr +
1739 	    sc->sc_nbufs * sc->sc_chanblocksize;
1740 
1741 }
1742 
1743 /*
1744  * Set the sample rate of the given voice.  Called at splgus().
1745  */
1746 
1747 void
1748 gus_set_samprate(sc, voice, freq)
1749 	struct gus_softc *sc;
1750 	int voice, freq;
1751 {
1752 	bus_space_tag_t iot = sc->sc_iot;
1753 	bus_space_handle_t ioh2 = sc->sc_ioh2;
1754 	unsigned int fc;
1755 	u_long temp, f = (u_long) freq;
1756 
1757 	/*
1758 	 * calculate fc based on the number of active voices;
1759 	 * we need to use longs to preserve enough bits
1760 	 */
1761 
1762 	temp = (u_long) gus_max_frequency[sc->sc_voices-GUS_MIN_VOICES];
1763 
1764 	fc = (unsigned int)(((f << 9L) + (temp >> 1L)) / temp);
1765 
1766 	fc <<= 1;
1767 
1768 
1769 	/*
1770 	 * Program the voice frequency, and set it in the voice data record
1771 	 */
1772 
1773 	bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
1774 	SELECT_GUS_REG(iot, ioh2, GUSREG_FREQ_CONTROL);
1775 	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, fc);
1776 
1777 	sc->sc_voc[voice].rate = freq;
1778 
1779 }
1780 
1781 /*
1782  * Set the sample rate of the recording frequency.  Formula is from the GUS
1783  * SDK.  Called at splgus().
1784  */
1785 
1786 void
1787 gus_set_recrate(sc, rate)
1788 	struct gus_softc *sc;
1789 	u_long rate;
1790 {
1791 	bus_space_tag_t iot = sc->sc_iot;
1792 	bus_space_handle_t ioh2 = sc->sc_ioh2;
1793 	u_char realrate;
1794 	DPRINTF(("gus_set_recrate %lu\n", rate));
1795 
1796 #if 0
1797 	realrate = 9878400/(16*(rate+2)); /* formula from GUS docs */
1798 #endif
1799 	realrate = (9878400 >> 4)/rate - 2; /* formula from code, sigh. */
1800 
1801 	SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_FREQ);
1802 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, realrate);
1803 }
1804 
1805 /*
1806  * Interface to the audio layer - turn the output on or off.  Note that some
1807  * of these bits are flipped in the register
1808  */
1809 
1810 int
1811 gusmax_speaker_ctl(addr, newstate)
1812 	void * addr;
1813 	int newstate;
1814 {
1815 	struct ad1848_softc *sc = addr;
1816 	return gus_speaker_ctl(sc->parent, newstate);
1817 }
1818 
1819 int
1820 gus_speaker_ctl(addr, newstate)
1821 	void * addr;
1822 	int newstate;
1823 {
1824 	struct gus_softc *sc = (struct gus_softc *) addr;
1825 	bus_space_tag_t iot = sc->sc_iot;
1826 	bus_space_handle_t ioh1 = sc->sc_ioh1;
1827 
1828 	/* Line out bit is flipped: 0 enables, 1 disables */
1829 	if ((newstate == SPKR_ON) &&
1830 	    (sc->sc_mixcontrol & GUSMASK_LINE_OUT)) {
1831 		sc->sc_mixcontrol &= ~GUSMASK_LINE_OUT;
1832 		bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
1833 	}
1834 	if ((newstate == SPKR_OFF) &&
1835 	    (sc->sc_mixcontrol & GUSMASK_LINE_OUT) == 0) {
1836 		sc->sc_mixcontrol |= GUSMASK_LINE_OUT;
1837 		bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
1838 	}
1839 
1840 	return 0;
1841 }
1842 
1843 int
1844 gus_linein_ctl(addr, newstate)
1845 	void * addr;
1846 	int newstate;
1847 {
1848 	struct gus_softc *sc = (struct gus_softc *) addr;
1849 	bus_space_tag_t iot = sc->sc_iot;
1850 	bus_space_handle_t ioh1 = sc->sc_ioh1;
1851 
1852 	/* Line in bit is flipped: 0 enables, 1 disables */
1853 	if ((newstate == SPKR_ON) &&
1854 	    (sc->sc_mixcontrol & GUSMASK_LINE_IN)) {
1855 		sc->sc_mixcontrol &= ~GUSMASK_LINE_IN;
1856 		bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
1857 	}
1858 	if ((newstate == SPKR_OFF) &&
1859 	    (sc->sc_mixcontrol & GUSMASK_LINE_IN) == 0) {
1860 		sc->sc_mixcontrol |= GUSMASK_LINE_IN;
1861 		bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
1862 	}
1863 
1864 	return 0;
1865 }
1866 
1867 int
1868 gus_mic_ctl(addr, newstate)
1869 	void * addr;
1870 	int newstate;
1871 {
1872 	struct gus_softc *sc = (struct gus_softc *) addr;
1873 	bus_space_tag_t iot = sc->sc_iot;
1874 	bus_space_handle_t ioh1 = sc->sc_ioh1;
1875 
1876 	/* Mic bit is normal: 1 enables, 0 disables */
1877 	if ((newstate == SPKR_ON) &&
1878 	    (sc->sc_mixcontrol & GUSMASK_MIC_IN) == 0) {
1879 		sc->sc_mixcontrol |= GUSMASK_MIC_IN;
1880 		bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
1881 	}
1882 	if ((newstate == SPKR_OFF) &&
1883 	    (sc->sc_mixcontrol & GUSMASK_MIC_IN)) {
1884 		sc->sc_mixcontrol &= ~GUSMASK_MIC_IN;
1885 		bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
1886 	}
1887 
1888 	return 0;
1889 }
1890 
1891 /*
1892  * Set the end address of a give voice.  Called at splgus()
1893  */
1894 
1895 void
1896 gus_set_endaddr(sc, voice, addr)
1897 	struct gus_softc *sc;
1898 	int voice;
1899 	u_long addr;
1900 {
1901 	bus_space_tag_t iot = sc->sc_iot;
1902 	bus_space_handle_t ioh2 = sc->sc_ioh2;
1903 
1904 	sc->sc_voc[voice].end_addr = addr;
1905 
1906 	if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16)
1907 		addr = convert_to_16bit(addr);
1908 
1909 	SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_HIGH);
1910 	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(addr));
1911 	SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_LOW);
1912 	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(addr));
1913 
1914 }
1915 
1916 #ifdef GUSPLAYDEBUG
1917 /*
1918  * Set current address.  called at splgus()
1919  */
1920 void
1921 gus_set_curaddr(sc, voice, addr)
1922 	struct gus_softc *sc;
1923 	int voice;
1924 	u_long addr;
1925 {
1926 	bus_space_tag_t iot = sc->sc_iot;
1927 	bus_space_handle_t ioh2 = sc->sc_ioh2;
1928 
1929 	sc->sc_voc[voice].current_addr = addr;
1930 
1931 	if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16)
1932 		addr = convert_to_16bit(addr);
1933 
1934 	bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
1935 
1936 	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH);
1937 	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(addr));
1938 	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW);
1939 	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(addr));
1940 
1941 }
1942 
1943 /*
1944  * Get current GUS playback address.  Called at splgus().
1945  */
1946 u_long
1947 gus_get_curaddr(sc, voice)
1948 	struct gus_softc *sc;
1949 	int voice;
1950 {
1951 	bus_space_tag_t iot = sc->sc_iot;
1952 	bus_space_handle_t ioh2 = sc->sc_ioh2;
1953 	u_long addr;
1954 
1955 	bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
1956 	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH|GUSREG_READ);
1957 	addr = (bus_space_read_2(iot, ioh2, GUS_DATA_LOW) & 0x1fff) << 7;
1958 	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW|GUSREG_READ);
1959 	addr |= (bus_space_read_2(iot, ioh2, GUS_DATA_LOW) >> 9L) & 0x7f;
1960 
1961 	if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16)
1962 	    addr = (addr & 0xc0000) | ((addr & 0x1ffff) << 1); /* undo 16-bit change */
1963 	DPRINTF(("gus voice %d curaddr %ld end_addr %ld\n",
1964 		 voice, addr, sc->sc_voc[voice].end_addr));
1965 	/* XXX sanity check the address? */
1966 
1967 	return(addr);
1968 }
1969 #endif
1970 
1971 /*
1972  * Convert an address value to a "16 bit" value - why this is necessary I
1973  * have NO idea
1974  */
1975 
1976 u_long
1977 convert_to_16bit(address)
1978 	u_long address;
1979 {
1980 	u_long old_address;
1981 
1982 	old_address = address;
1983 	address >>= 1;
1984 	address &= 0x0001ffffL;
1985 	address |= (old_address & 0x000c0000L);
1986 
1987 	return (address);
1988 }
1989 
1990 /*
1991  * Write a value into the GUS's DRAM
1992  */
1993 
1994 void
1995 guspoke(iot, ioh2, address, value)
1996 	bus_space_tag_t iot;
1997 	bus_space_handle_t ioh2;
1998 	long address;
1999 	unsigned char value;
2000 {
2001 
2002 	/*
2003 	 * Select the DRAM address
2004 	 */
2005 
2006 	SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_LOW);
2007 	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, (unsigned int) (address & 0xffff));
2008 	SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_HIGH);
2009 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (unsigned char) ((address >> 16) & 0xff));
2010 
2011 	/*
2012 	 * Actually write the data
2013 	 */
2014 
2015 	bus_space_write_1(iot, ioh2, GUS_DRAM_DATA, value);
2016 }
2017 
2018 /*
2019  * Read a value from the GUS's DRAM
2020  */
2021 
2022 unsigned char
2023 guspeek(iot, ioh2, address)
2024 	bus_space_tag_t iot;
2025 	bus_space_handle_t ioh2;
2026 	u_long address;
2027 {
2028 
2029 	/*
2030 	 * Select the DRAM address
2031 	 */
2032 
2033 	SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_LOW);
2034 	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, (unsigned int) (address & 0xffff));
2035 	SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_HIGH);
2036 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (unsigned char) ((address >> 16) & 0xff));
2037 
2038 	/*
2039 	 * Read in the data from the board
2040 	 */
2041 
2042 	return (unsigned char) bus_space_read_1(iot, ioh2, GUS_DRAM_DATA);
2043 }
2044 
2045 /*
2046  * Reset the Gravis UltraSound card, completely
2047  */
2048 
2049 void
2050 gusreset(sc, voices)
2051 	struct gus_softc *sc;
2052 	int voices;
2053 {
2054 	bus_space_tag_t iot = sc->sc_iot;
2055 	bus_space_handle_t ioh1 = sc->sc_ioh1;
2056 	bus_space_handle_t ioh2 = sc->sc_ioh2;
2057 	bus_space_handle_t ioh4 = sc->sc_ioh4;
2058 	int i,s;
2059 
2060 	s = splgus();
2061 
2062 	/*
2063 	 * Reset the GF1 chip
2064 	 */
2065 
2066 	SELECT_GUS_REG(iot, ioh2, GUSREG_RESET);
2067 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
2068 
2069 	delay(500);
2070 
2071 	/*
2072 	 * Release reset
2073 	 */
2074 
2075 	SELECT_GUS_REG(iot, ioh2, GUSREG_RESET);
2076 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, GUSMASK_MASTER_RESET);
2077 
2078 	delay(500);
2079 
2080 	/*
2081 	 * Reset MIDI port as well
2082 	 */
2083 
2084 	bus_space_write_1(iot, ioh4, GUS_MIDI_CONTROL, MIDI_RESET);
2085 
2086 	delay(500);
2087 
2088 	bus_space_write_1(iot, ioh4, GUS_MIDI_CONTROL, 0x00);
2089 
2090 	/*
2091 	 * Clear interrupts
2092 	 */
2093 
2094 	SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
2095 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
2096 	SELECT_GUS_REG(iot, ioh2, GUSREG_TIMER_CONTROL);
2097 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
2098 	SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
2099 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
2100 
2101 	gus_set_voices(sc, voices);
2102 
2103 	bus_space_read_1(iot, ioh1, GUS_IRQ_STATUS);
2104 	SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
2105 	bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
2106 	SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
2107 	bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
2108 	SELECT_GUS_REG(iot, ioh2, GUSREG_IRQ_STATUS);
2109 	bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
2110 
2111 	/*
2112 	 * Reset voice specific information
2113 	 */
2114 
2115 	for(i = 0; i < voices; i++) {
2116 		bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) i);
2117 
2118 		SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
2119 
2120 		sc->sc_voc[i].voccntl = GUSMASK_VOICE_STOPPED |
2121 			GUSMASK_STOP_VOICE;
2122 
2123 		bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[i].voccntl);
2124 
2125 		sc->sc_voc[i].volcntl = GUSMASK_VOLUME_STOPPED |
2126 				GUSMASK_STOP_VOLUME;
2127 
2128 		SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
2129 		bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[i].volcntl);
2130 
2131 		delay(100);
2132 
2133 		gus_set_samprate(sc, i, 8000);
2134 		SELECT_GUS_REG(iot, ioh2, GUSREG_START_ADDR_HIGH);
2135 		bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2136 		SELECT_GUS_REG(iot, ioh2, GUSREG_START_ADDR_LOW);
2137 		bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2138 		SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_HIGH);
2139 		bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2140 		SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_LOW);
2141 		bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2142 		SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_RATE);
2143 		bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x01);
2144 		SELECT_GUS_REG(iot, ioh2, GUSREG_START_VOLUME);
2145 		bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x10);
2146 		SELECT_GUS_REG(iot, ioh2, GUSREG_END_VOLUME);
2147 		bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0xe0);
2148 		SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME);
2149 		bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2150 
2151 		SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH);
2152 		bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2153 		SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW);
2154 		bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2155 		SELECT_GUS_REG(iot, ioh2, GUSREG_PAN_POS);
2156 		bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x07);
2157 	}
2158 
2159 	/*
2160 	 * Clear out any pending IRQs
2161 	 */
2162 
2163 	bus_space_read_1(iot, ioh1, GUS_IRQ_STATUS);
2164 	SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
2165 	bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
2166 	SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
2167 	bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
2168 	SELECT_GUS_REG(iot, ioh2, GUSREG_IRQ_STATUS);
2169 	bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
2170 
2171 	SELECT_GUS_REG(iot, ioh2, GUSREG_RESET);
2172 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, GUSMASK_MASTER_RESET | GUSMASK_DAC_ENABLE |
2173 		GUSMASK_IRQ_ENABLE);
2174 
2175 	splx(s);
2176 }
2177 
2178 
2179 int
2180 gus_init_cs4231(sc)
2181 	struct gus_softc *sc;
2182 {
2183 	bus_space_tag_t iot = sc->sc_iot;
2184 	bus_space_handle_t ioh1 = sc->sc_ioh1;
2185 	int port = sc->sc_iobase;
2186 	u_char ctrl;
2187 
2188 	ctrl = (port & 0xf0) >> 4;	/* set port address middle nibble */
2189 	/*
2190 	 * The codec is a bit weird--swapped dma channels.
2191 	 */
2192 	ctrl |= GUS_MAX_CODEC_ENABLE;
2193 	if (sc->sc_drq >= 4)
2194 		ctrl |= GUS_MAX_RECCHAN16;
2195 	if (sc->sc_recdrq >= 4)
2196 		ctrl |= GUS_MAX_PLAYCHAN16;
2197 
2198 	bus_space_write_1(iot, ioh1, GUS_MAX_CTRL, ctrl);
2199 
2200 	sc->sc_codec.sc_iot = sc->sc_iot;
2201 	sc->sc_codec.sc_iobase = port+GUS_MAX_CODEC_BASE;
2202 
2203 	if (ad1848_mapprobe(&sc->sc_codec, sc->sc_codec.sc_iobase) == 0) {
2204 		sc->sc_flags &= ~GUS_CODEC_INSTALLED;
2205 		return (0);
2206 	} else {
2207 		struct ad1848_volume vol = {AUDIO_MAX_GAIN, AUDIO_MAX_GAIN};
2208 		sc->sc_flags |= GUS_CODEC_INSTALLED;
2209 		sc->sc_codec.parent = sc;
2210 		sc->sc_codec.sc_drq = sc->sc_recdrq;
2211 		sc->sc_codec.sc_recdrq = sc->sc_drq;
2212 		gus_hw_if = gusmax_hw_if;
2213 		/* enable line in and mic in the GUS mixer; the codec chip
2214 		   will do the real mixing for them. */
2215 		sc->sc_mixcontrol &= ~GUSMASK_LINE_IN; /* 0 enables. */
2216 		sc->sc_mixcontrol |= GUSMASK_MIC_IN; /* 1 enables. */
2217 		bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
2218 
2219 		ad1848_attach(&sc->sc_codec);
2220 		/* turn on pre-MUX microphone gain. */
2221 		ad1848_set_mic_gain(&sc->sc_codec, &vol);
2222 
2223 		return (1);
2224 	}
2225 }
2226 
2227 
2228 /*
2229  * Return info about the audio device, for the AUDIO_GETINFO ioctl
2230  */
2231 
2232 int
2233 gus_getdev(addr, dev)
2234 	void * addr;
2235 	struct audio_device *dev;
2236 {
2237 	*dev = gus_device;
2238 	return 0;
2239 }
2240 
2241 /*
2242  * stubs (XXX)
2243  */
2244 
2245 int
2246 gus_set_in_gain(addr, gain, balance)
2247 	caddr_t addr;
2248 	u_int gain;
2249 	u_char balance;
2250 {
2251 	DPRINTF(("gus_set_in_gain called\n"));
2252 	return 0;
2253 }
2254 
2255 int
2256 gus_get_in_gain(addr)
2257 	caddr_t addr;
2258 {
2259 	DPRINTF(("gus_get_in_gain called\n"));
2260 	return 0;
2261 }
2262 
2263 int
2264 gusmax_dma_input(addr, buf, size, callback, arg)
2265 	void * addr;
2266 	void *buf;
2267 	int size;
2268 	void (*callback)(void *);
2269 	void *arg;
2270 {
2271 	struct ad1848_softc *sc = addr;
2272 	return gus_dma_input(sc->parent, buf, size, callback, arg);
2273 }
2274 
2275 /*
2276  * Start sampling the input source into the requested DMA buffer.
2277  * Called at splgus(), either from top-half or from interrupt handler.
2278  */
2279 int
2280 gus_dma_input(addr, buf, size, callback, arg)
2281 	void * addr;
2282 	void *buf;
2283 	int size;
2284 	void (*callback)(void *);
2285 	void *arg;
2286 {
2287 	struct gus_softc *sc = addr;
2288 	bus_space_tag_t iot = sc->sc_iot;
2289 	bus_space_handle_t ioh2 = sc->sc_ioh2;
2290 	u_char dmac;
2291 	DMAPRINTF(("gus_dma_input called\n"));
2292 
2293 	/*
2294 	 * Sample SIZE bytes of data from the card, into buffer at BUF.
2295 	 */
2296 
2297 	if (sc->sc_precision == 16)
2298 	    return EINVAL;		/* XXX */
2299 
2300 	/* set DMA modes */
2301 	dmac = GUSMASK_SAMPLE_IRQ|GUSMASK_SAMPLE_START;
2302 	if (sc->sc_recdrq >= 4)
2303 		dmac |= GUSMASK_SAMPLE_DATA16;
2304 	if (sc->sc_encoding == AUDIO_ENCODING_ULAW ||
2305 	    sc->sc_encoding == AUDIO_ENCODING_ALAW ||
2306 	    sc->sc_encoding == AUDIO_ENCODING_ULINEAR_LE ||
2307 	    sc->sc_encoding == AUDIO_ENCODING_ULINEAR_BE)
2308 	    dmac |= GUSMASK_SAMPLE_INVBIT;
2309 	if (sc->sc_channels == 2)
2310 	    dmac |= GUSMASK_SAMPLE_STEREO;
2311 	isa_dmastart(sc->sc_dev.dv_parent, sc->sc_recdrq, buf, size,
2312 	    NULL, DMAMODE_READ, BUS_DMA_NOWAIT);
2313 
2314 	DMAPRINTF(("gus_dma_input isadma_started\n"));
2315 	sc->sc_flags |= GUS_DMAIN_ACTIVE;
2316 	sc->sc_dmainintr = callback;
2317 	sc->sc_inarg = arg;
2318 	sc->sc_dmaincnt = size;
2319 	sc->sc_dmainaddr = buf;
2320 
2321 	SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
2322 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, dmac);	/* Go! */
2323 
2324 
2325 	DMAPRINTF(("gus_dma_input returning\n"));
2326 
2327 	return 0;
2328 }
2329 
2330 int
2331 gus_dmain_intr(sc)
2332 	struct gus_softc *sc;
2333 {
2334         void (*callback)(void *);
2335 	void *arg;
2336 
2337 	DMAPRINTF(("gus_dmain_intr called\n"));
2338 	if (sc->sc_dmainintr) {
2339 	    isa_dmadone(sc->sc_dev.dv_parent, sc->sc_recdrq);
2340 	    callback = sc->sc_dmainintr;
2341 	    arg = sc->sc_inarg;
2342 
2343 	    sc->sc_dmainaddr = 0;
2344 	    sc->sc_dmaincnt = 0;
2345 	    sc->sc_dmainintr = 0;
2346 	    sc->sc_inarg = 0;
2347 
2348 	    sc->sc_flags &= ~GUS_DMAIN_ACTIVE;
2349 	    DMAPRINTF(("calling dmain_intr callback %p(%p)\n", callback, arg));
2350 	    (*callback)(arg);
2351 	    return 1;
2352 	} else {
2353 	    DMAPRINTF(("gus_dmain_intr false?\n"));
2354 	    return 0;			/* XXX ??? */
2355 	}
2356 }
2357 
2358 int
2359 gusmax_halt_out_dma(addr)
2360 	void * addr;
2361 {
2362 	struct ad1848_softc *sc = addr;
2363 	return gus_halt_out_dma(sc->parent);
2364 }
2365 
2366 
2367 int
2368 gusmax_halt_in_dma(addr)
2369 	void * addr;
2370 {
2371 	struct ad1848_softc *sc = addr;
2372 	return gus_halt_in_dma(sc->parent);
2373 }
2374 
2375 /*
2376  * Stop any DMA output.  Called at splgus().
2377  */
2378 int
2379 gus_halt_out_dma(addr)
2380 	void * addr;
2381 {
2382 	struct gus_softc *sc = addr;
2383 	bus_space_tag_t iot = sc->sc_iot;
2384 	bus_space_handle_t ioh2 = sc->sc_ioh2;
2385 
2386 	DMAPRINTF(("gus_halt_out_dma called\n"));
2387 	/*
2388 	 * Make sure the GUS _isn't_ setup for DMA
2389 	 */
2390 
2391 	SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
2392 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0);
2393 
2394 	timeout_del(&sc->sc_dma_tmo);
2395 	isa_dmaabort(sc->sc_dev.dv_parent, sc->sc_drq);
2396 	sc->sc_flags &= ~(GUS_DMAOUT_ACTIVE|GUS_LOCKED);
2397 	sc->sc_dmaoutintr = 0;
2398 	sc->sc_outarg = 0;
2399 	sc->sc_dmaoutaddr = 0;
2400 	sc->sc_dmaoutcnt = 0;
2401 	sc->sc_dmabuf = 0;
2402 	sc->sc_bufcnt = 0;
2403 	sc->sc_playbuf = -1;
2404 	/* also stop playing */
2405 	gus_stop_voice(sc, GUS_VOICE_LEFT, 1);
2406 	gus_stop_voice(sc, GUS_VOICE_RIGHT, 0);
2407 
2408 	return 0;
2409 }
2410 
2411 /*
2412  * Stop any DMA output.  Called at splgus().
2413  */
2414 int
2415 gus_halt_in_dma(addr)
2416 	void * addr;
2417 {
2418 	struct gus_softc *sc = addr;
2419 	bus_space_tag_t iot = sc->sc_iot;
2420 	bus_space_handle_t ioh2 = sc->sc_ioh2;
2421 	DMAPRINTF(("gus_halt_in_dma called\n"));
2422 
2423 	/*
2424 	 * Make sure the GUS _isn't_ setup for DMA
2425 	 */
2426 
2427 	SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
2428 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH,
2429 	     bus_space_read_1(iot, ioh2, GUS_DATA_HIGH) & ~(GUSMASK_SAMPLE_START|GUSMASK_SAMPLE_IRQ));
2430 
2431 	isa_dmaabort(sc->sc_dev.dv_parent, sc->sc_recdrq);
2432 	sc->sc_flags &= ~GUS_DMAIN_ACTIVE;
2433 	sc->sc_dmainintr = 0;
2434 	sc->sc_inarg = 0;
2435 	sc->sc_dmainaddr = 0;
2436 	sc->sc_dmaincnt = 0;
2437 
2438 	return 0;
2439 }
2440 
2441 
2442 ad1848_devmap_t gusmapping[] = {
2443   {GUSMAX_DAC_LVL, AD1848_KIND_LVL, AD1848_AUX1_CHANNEL},
2444   {GUSMAX_LINE_IN_LVL, AD1848_KIND_LVL, AD1848_LINE_CHANNEL},
2445   {GUSMAX_MONO_LVL, AD1848_KIND_LVL, AD1848_MONO_CHANNEL},
2446   {GUSMAX_CD_LVL, AD1848_KIND_LVL, AD1848_AUX2_CHANNEL},
2447   {GUSMAX_MONITOR_LVL, AD1848_KIND_LVL, AD1848_MONITOR_CHANNEL},
2448   {GUSMAX_OUT_LVL, AD1848_KIND_LVL, AD1848_DAC_CHANNEL},
2449   {GUSMAX_DAC_MUTE, AD1848_KIND_MUTE, AD1848_AUX1_CHANNEL},
2450   {GUSMAX_LINE_IN_MUTE, AD1848_KIND_MUTE, AD1848_LINE_CHANNEL},
2451   {GUSMAX_MONO_MUTE, AD1848_KIND_MUTE, AD1848_MONO_CHANNEL},
2452   {GUSMAX_CD_MUTE, AD1848_KIND_MUTE, AD1848_AUX2_CHANNEL},
2453   {GUSMAX_MONITOR_MUTE, AD1848_KIND_MUTE, AD1848_MONITOR_CHANNEL},
2454   {GUSMAX_REC_LVL, AD1848_KIND_RECORDGAIN, -1},
2455   {GUSMAX_RECORD_SOURCE, AD1848_KIND_RECORDSOURCE, -1}
2456 };
2457 
2458 int nummap = sizeof(gusmapping) / sizeof(gusmapping[0]);
2459 
2460 int
2461 gusmax_mixer_get_port(addr, cp)
2462 	void *addr;
2463 	mixer_ctrl_t *cp;
2464 {
2465 	struct ad1848_softc *ac = addr;
2466 	struct gus_softc *sc = ac->parent;
2467 	struct ad1848_volume vol;
2468 	int error = ad1848_mixer_get_port(ac, gusmapping, nummap, cp);
2469 
2470 	if (error != ENXIO)
2471 	  return (error);
2472 
2473 	error = EINVAL;
2474 
2475 	switch (cp->dev) {
2476 	case GUSMAX_SPEAKER_LVL:	/* fake speaker for mute naming */
2477 		if (cp->type == AUDIO_MIXER_VALUE) {
2478 			if (sc->sc_mixcontrol & GUSMASK_LINE_OUT)
2479 				vol.left = vol.right = AUDIO_MAX_GAIN;
2480 			else
2481 				vol.left = vol.right = AUDIO_MIN_GAIN;
2482 			error = 0;
2483 			ad1848_from_vol(cp, &vol);
2484 		}
2485 		break;
2486 
2487 	case GUSMAX_SPEAKER_MUTE:
2488 		if (cp->type == AUDIO_MIXER_ENUM) {
2489 			cp->un.ord = sc->sc_mixcontrol & GUSMASK_LINE_OUT ? 1 : 0;
2490 			error = 0;
2491 		}
2492 		break;
2493 	default:
2494 		error = ENXIO;
2495 		break;
2496 	}
2497 
2498 	return(error);
2499 }
2500 
2501 int
2502 gus_mixer_get_port(addr, cp)
2503 	void *addr;
2504 	mixer_ctrl_t *cp;
2505 {
2506 	struct gus_softc *sc = addr;
2507 	struct ics2101_softc *ic = &sc->sc_mixer;
2508 	struct ad1848_volume vol;
2509 	int error = EINVAL;
2510 
2511 	DPRINTF(("gus_mixer_get_port: dev=%d type=%d\n", cp->dev, cp->type));
2512 
2513 	if (!HAS_MIXER(sc) && cp->dev > GUSICS_MASTER_MUTE)
2514 		return ENXIO;
2515 
2516 	switch (cp->dev) {
2517 
2518 	case GUSICS_MIC_IN_MUTE:	/* Microphone */
2519 		if (cp->type == AUDIO_MIXER_ENUM) {
2520 			if (HAS_MIXER(sc))
2521 				cp->un.ord = ic->sc_mute[GUSMIX_CHAN_MIC][ICSMIX_LEFT];
2522 			else
2523 				cp->un.ord =
2524 				    sc->sc_mixcontrol & GUSMASK_MIC_IN ? 0 : 1;
2525 			error = 0;
2526 		}
2527 		break;
2528 
2529 	case GUSICS_LINE_IN_MUTE:
2530 		if (cp->type == AUDIO_MIXER_ENUM) {
2531 			if (HAS_MIXER(sc))
2532 				cp->un.ord = ic->sc_mute[GUSMIX_CHAN_LINE][ICSMIX_LEFT];
2533 			else
2534 				cp->un.ord =
2535 				    sc->sc_mixcontrol & GUSMASK_LINE_IN ? 1 : 0;
2536 			error = 0;
2537 		}
2538 		break;
2539 
2540 	case GUSICS_MASTER_MUTE:
2541 		if (cp->type == AUDIO_MIXER_ENUM) {
2542 			if (HAS_MIXER(sc))
2543 				cp->un.ord = ic->sc_mute[GUSMIX_CHAN_MASTER][ICSMIX_LEFT];
2544 			else
2545 				cp->un.ord =
2546 				    sc->sc_mixcontrol & GUSMASK_LINE_OUT ? 1 : 0;
2547 			error = 0;
2548 		}
2549 		break;
2550 
2551 	case GUSICS_DAC_MUTE:
2552 		if (cp->type == AUDIO_MIXER_ENUM) {
2553 			cp->un.ord = ic->sc_mute[GUSMIX_CHAN_DAC][ICSMIX_LEFT];
2554 			error = 0;
2555 		}
2556 		break;
2557 
2558 	case GUSICS_CD_MUTE:
2559 		if (cp->type == AUDIO_MIXER_ENUM) {
2560 			cp->un.ord = ic->sc_mute[GUSMIX_CHAN_CD][ICSMIX_LEFT];
2561 			error = 0;
2562 		}
2563 		break;
2564 
2565 	case GUSICS_MASTER_LVL:
2566 		if (cp->type == AUDIO_MIXER_VALUE) {
2567 			vol.left = ic->sc_setting[GUSMIX_CHAN_MASTER][ICSMIX_LEFT];
2568 			vol.right = ic->sc_setting[GUSMIX_CHAN_MASTER][ICSMIX_RIGHT];
2569 			if (ad1848_from_vol(cp, &vol))
2570 				error = 0;
2571 		}
2572 		break;
2573 
2574 	case GUSICS_MIC_IN_LVL:	/* Microphone */
2575 		if (cp->type == AUDIO_MIXER_VALUE) {
2576 			vol.left = ic->sc_setting[GUSMIX_CHAN_MIC][ICSMIX_LEFT];
2577 			vol.right = ic->sc_setting[GUSMIX_CHAN_MIC][ICSMIX_RIGHT];
2578 			if (ad1848_from_vol(cp, &vol))
2579 				error = 0;
2580 		}
2581 		break;
2582 
2583 	case GUSICS_LINE_IN_LVL:	/* line in */
2584 		if (cp->type == AUDIO_MIXER_VALUE) {
2585 			vol.left = ic->sc_setting[GUSMIX_CHAN_LINE][ICSMIX_LEFT];
2586 			vol.right = ic->sc_setting[GUSMIX_CHAN_LINE][ICSMIX_RIGHT];
2587 			if (ad1848_from_vol(cp, &vol))
2588 				error = 0;
2589 		}
2590 		break;
2591 
2592 
2593 	case GUSICS_CD_LVL:
2594 		if (cp->type == AUDIO_MIXER_VALUE) {
2595 			vol.left = ic->sc_setting[GUSMIX_CHAN_CD][ICSMIX_LEFT];
2596 			vol.right = ic->sc_setting[GUSMIX_CHAN_CD][ICSMIX_RIGHT];
2597 			if (ad1848_from_vol(cp, &vol))
2598 				error = 0;
2599 		}
2600 		break;
2601 
2602 	case GUSICS_DAC_LVL:		/* dac out */
2603 		if (cp->type == AUDIO_MIXER_VALUE) {
2604 			vol.left = ic->sc_setting[GUSMIX_CHAN_DAC][ICSMIX_LEFT];
2605 			vol.right = ic->sc_setting[GUSMIX_CHAN_DAC][ICSMIX_RIGHT];
2606 			if (ad1848_from_vol(cp, &vol))
2607 				error = 0;
2608 		}
2609 		break;
2610 
2611 
2612 	case GUSICS_RECORD_SOURCE:
2613 		if (cp->type == AUDIO_MIXER_ENUM) {
2614 			/* Can't set anything else useful, sigh. */
2615 			 cp->un.ord = 0;
2616 		}
2617 		break;
2618 
2619 	default:
2620 		return ENXIO;
2621 	    /*NOTREACHED*/
2622 	}
2623 	return error;
2624 }
2625 
2626 void
2627 gusics_master_mute(ic, mute)
2628 	struct ics2101_softc *ic;
2629 	int mute;
2630 {
2631 	ics2101_mix_mute(ic, GUSMIX_CHAN_MASTER, ICSMIX_LEFT, mute);
2632 	ics2101_mix_mute(ic, GUSMIX_CHAN_MASTER, ICSMIX_RIGHT, mute);
2633 }
2634 
2635 void
2636 gusics_mic_mute(ic, mute)
2637 	struct ics2101_softc *ic;
2638 	int mute;
2639 {
2640 	ics2101_mix_mute(ic, GUSMIX_CHAN_MIC, ICSMIX_LEFT, mute);
2641 	ics2101_mix_mute(ic, GUSMIX_CHAN_MIC, ICSMIX_RIGHT, mute);
2642 }
2643 
2644 void
2645 gusics_linein_mute(ic, mute)
2646 	struct ics2101_softc *ic;
2647 	int mute;
2648 {
2649 	ics2101_mix_mute(ic, GUSMIX_CHAN_LINE, ICSMIX_LEFT, mute);
2650 	ics2101_mix_mute(ic, GUSMIX_CHAN_LINE, ICSMIX_RIGHT, mute);
2651 }
2652 
2653 void
2654 gusics_cd_mute(ic, mute)
2655 	struct ics2101_softc *ic;
2656 	int mute;
2657 {
2658 	ics2101_mix_mute(ic, GUSMIX_CHAN_CD, ICSMIX_LEFT, mute);
2659 	ics2101_mix_mute(ic, GUSMIX_CHAN_CD, ICSMIX_RIGHT, mute);
2660 }
2661 
2662 void
2663 gusics_dac_mute(ic, mute)
2664 	struct ics2101_softc *ic;
2665 	int mute;
2666 {
2667 	ics2101_mix_mute(ic, GUSMIX_CHAN_DAC, ICSMIX_LEFT, mute);
2668 	ics2101_mix_mute(ic, GUSMIX_CHAN_DAC, ICSMIX_RIGHT, mute);
2669 }
2670 
2671 int
2672 gusmax_mixer_set_port(addr, cp)
2673 	void *addr;
2674 	mixer_ctrl_t *cp;
2675 {
2676 	struct ad1848_softc *ac = addr;
2677 	struct gus_softc *sc = ac->parent;
2678 	struct ad1848_volume vol;
2679 	int error = ad1848_mixer_set_port(ac, gusmapping, nummap, cp);
2680 
2681 	if (error != ENXIO)
2682 	  return (error);
2683 
2684 	DPRINTF(("gusmax_mixer_set_port: dev=%d type=%d\n", cp->dev, cp->type));
2685 
2686 	switch (cp->dev) {
2687 	case GUSMAX_SPEAKER_LVL:
2688 		if (cp->type == AUDIO_MIXER_VALUE &&
2689 		    cp->un.value.num_channels == 1) {
2690 			if (ad1848_to_vol(cp, &vol)) {
2691 				gus_speaker_ctl(sc, vol.left > AUDIO_MIN_GAIN ?
2692 						SPKR_ON : SPKR_OFF);
2693 				error = 0;
2694 			}
2695 		}
2696 		break;
2697 
2698 	case GUSMAX_SPEAKER_MUTE:
2699 		if (cp->type == AUDIO_MIXER_ENUM) {
2700 			gus_speaker_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON);
2701 			error = 0;
2702 		}
2703 		break;
2704 
2705 	default:
2706 		return ENXIO;
2707 	    /*NOTREACHED*/
2708     }
2709     return error;
2710 }
2711 
2712 int
2713 gus_mixer_set_port(addr, cp)
2714 	void *addr;
2715 	mixer_ctrl_t *cp;
2716 {
2717 	struct gus_softc *sc = addr;
2718 	struct ics2101_softc *ic = &sc->sc_mixer;
2719 	struct ad1848_volume vol;
2720 	int error = EINVAL;
2721 
2722 	DPRINTF(("gus_mixer_set_port: dev=%d type=%d\n", cp->dev, cp->type));
2723 
2724 	if (!HAS_MIXER(sc) && cp->dev > GUSICS_MASTER_MUTE)
2725 		return ENXIO;
2726 
2727 	switch (cp->dev) {
2728 
2729 	case GUSICS_MIC_IN_MUTE:	/* Microphone */
2730 		if (cp->type == AUDIO_MIXER_ENUM) {
2731 			DPRINTF(("mic mute %d\n", cp->un.ord));
2732 			if (HAS_MIXER(sc)) {
2733 				gusics_mic_mute(ic, cp->un.ord);
2734 			}
2735 			gus_mic_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON);
2736 			error = 0;
2737 		}
2738 		break;
2739 
2740 	case GUSICS_LINE_IN_MUTE:
2741 		if (cp->type == AUDIO_MIXER_ENUM) {
2742 			DPRINTF(("linein mute %d\n", cp->un.ord));
2743 			if (HAS_MIXER(sc)) {
2744 				gusics_linein_mute(ic, cp->un.ord);
2745 			}
2746 			gus_linein_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON);
2747 			error = 0;
2748 		}
2749 		break;
2750 
2751 	case GUSICS_MASTER_MUTE:
2752 		if (cp->type == AUDIO_MIXER_ENUM) {
2753 			DPRINTF(("master mute %d\n", cp->un.ord));
2754 			if (HAS_MIXER(sc)) {
2755 				gusics_master_mute(ic, cp->un.ord);
2756 			}
2757 			gus_speaker_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON);
2758 			error = 0;
2759 		}
2760 		break;
2761 
2762 	case GUSICS_DAC_MUTE:
2763 		if (cp->type == AUDIO_MIXER_ENUM) {
2764 			gusics_dac_mute(ic, cp->un.ord);
2765 			error = 0;
2766 		}
2767 		break;
2768 
2769 	case GUSICS_CD_MUTE:
2770 		if (cp->type == AUDIO_MIXER_ENUM) {
2771 			gusics_cd_mute(ic, cp->un.ord);
2772 			error = 0;
2773 		}
2774 		break;
2775 
2776 	case GUSICS_MASTER_LVL:
2777 		if (cp->type == AUDIO_MIXER_VALUE) {
2778 			if (ad1848_to_vol(cp, &vol)) {
2779 				ics2101_mix_attenuate(ic,
2780 						      GUSMIX_CHAN_MASTER,
2781 						      ICSMIX_LEFT,
2782 						      vol.left);
2783 				ics2101_mix_attenuate(ic,
2784 						      GUSMIX_CHAN_MASTER,
2785 						      ICSMIX_RIGHT,
2786 						      vol.right);
2787 				error = 0;
2788 			}
2789 		}
2790 		break;
2791 
2792 	case GUSICS_MIC_IN_LVL:	/* Microphone */
2793 		if (cp->type == AUDIO_MIXER_VALUE) {
2794 			if (ad1848_to_vol(cp, &vol)) {
2795 				ics2101_mix_attenuate(ic,
2796 						      GUSMIX_CHAN_MIC,
2797 						      ICSMIX_LEFT,
2798 						      vol.left);
2799 				ics2101_mix_attenuate(ic,
2800 						      GUSMIX_CHAN_MIC,
2801 						      ICSMIX_RIGHT,
2802 						      vol.right);
2803 				error = 0;
2804 			}
2805 		}
2806 		break;
2807 
2808 	case GUSICS_LINE_IN_LVL:	/* line in */
2809 		if (cp->type == AUDIO_MIXER_VALUE) {
2810 			if (ad1848_to_vol(cp, &vol)) {
2811 				ics2101_mix_attenuate(ic,
2812 						      GUSMIX_CHAN_LINE,
2813 						      ICSMIX_LEFT,
2814 						      vol.left);
2815 				ics2101_mix_attenuate(ic,
2816 						      GUSMIX_CHAN_LINE,
2817 						      ICSMIX_RIGHT,
2818 						      vol.right);
2819 				error = 0;
2820 			}
2821 		}
2822 		break;
2823 
2824 
2825 	case GUSICS_CD_LVL:
2826 		if (cp->type == AUDIO_MIXER_VALUE) {
2827 			if (ad1848_to_vol(cp, &vol)) {
2828 				ics2101_mix_attenuate(ic,
2829 						      GUSMIX_CHAN_CD,
2830 						      ICSMIX_LEFT,
2831 						      vol.left);
2832 				ics2101_mix_attenuate(ic,
2833 						      GUSMIX_CHAN_CD,
2834 						      ICSMIX_RIGHT,
2835 						      vol.right);
2836 				error = 0;
2837 			}
2838 		}
2839 		break;
2840 
2841 	case GUSICS_DAC_LVL:		/* dac out */
2842 		if (cp->type == AUDIO_MIXER_VALUE) {
2843 			if (ad1848_to_vol(cp, &vol)) {
2844 				ics2101_mix_attenuate(ic,
2845 						      GUSMIX_CHAN_DAC,
2846 						      ICSMIX_LEFT,
2847 						      vol.left);
2848 				ics2101_mix_attenuate(ic,
2849 						      GUSMIX_CHAN_DAC,
2850 						      ICSMIX_RIGHT,
2851 						      vol.right);
2852 				error = 0;
2853 			}
2854 		}
2855 		break;
2856 
2857 
2858 	case GUSICS_RECORD_SOURCE:
2859 		if (cp->type == AUDIO_MIXER_ENUM && cp->un.ord == 0) {
2860 			/* Can't set anything else useful, sigh. */
2861 			error = 0;
2862 		}
2863 		break;
2864 
2865 	default:
2866 		return ENXIO;
2867 	    /*NOTREACHED*/
2868 	}
2869 	return error;
2870 }
2871 
2872 int
2873 gus_get_props(addr)
2874 	void *addr;
2875 {
2876 	struct gus_softc *sc = addr;
2877 	return AUDIO_PROP_MMAP |
2878 		(sc->sc_recdrq == sc->sc_drq ? 0 : AUDIO_PROP_FULLDUPLEX);
2879 }
2880 
2881 int
2882 gusmax_get_props(addr)
2883 	void *addr;
2884 {
2885 	struct ad1848_softc *ac = addr;
2886 	return gus_get_props(ac->parent);
2887 }
2888 
2889 int
2890 gusmax_mixer_query_devinfo(addr, dip)
2891 	void *addr;
2892 	mixer_devinfo_t *dip;
2893 {
2894 	DPRINTF(("gusmax_query_devinfo: index=%d\n", dip->index));
2895 
2896 	switch(dip->index) {
2897 #if 0
2898     case GUSMAX_MIC_IN_LVL:	/* Microphone */
2899 	dip->type = AUDIO_MIXER_VALUE;
2900 	dip->mixer_class = GUSMAX_INPUT_CLASS;
2901 	dip->prev = AUDIO_MIXER_LAST;
2902 	dip->next = GUSMAX_MIC_IN_MUTE;
2903 	strlcpy(dip->label.name, AudioNmicrophone, sizeof dip->label.name);
2904 	dip->un.v.num_channels = 2;
2905 	strlcpy(dip->un.v.units.name, AudioNvolume,
2906 	    sizeof dip->un.v.units.name);
2907 	break;
2908 #endif
2909 
2910     case GUSMAX_MONO_LVL:	/* mono/microphone mixer */
2911 	dip->type = AUDIO_MIXER_VALUE;
2912 	dip->mixer_class = GUSMAX_INPUT_CLASS;
2913 	dip->prev = AUDIO_MIXER_LAST;
2914 	dip->next = GUSMAX_MONO_MUTE;
2915 	strlcpy(dip->label.name, AudioNmicrophone, sizeof dip->label.name);
2916 	dip->un.v.num_channels = 1;
2917 	strlcpy(dip->un.v.units.name, AudioNvolume,
2918 	    sizeof dip->un.v.units.name);
2919 	break;
2920 
2921     case GUSMAX_DAC_LVL:		/*  dacout */
2922 	dip->type = AUDIO_MIXER_VALUE;
2923 	dip->mixer_class = GUSMAX_INPUT_CLASS;
2924 	dip->prev = AUDIO_MIXER_LAST;
2925 	dip->next = GUSMAX_DAC_MUTE;
2926 	strlcpy(dip->label.name, AudioNdac, sizeof dip->label.name);
2927 	dip->un.v.num_channels = 2;
2928 	strlcpy(dip->un.v.units.name, AudioNvolume,
2929 	    sizeof dip->un.v.units.name);
2930 	break;
2931 
2932     case GUSMAX_LINE_IN_LVL:	/* line */
2933 	dip->type = AUDIO_MIXER_VALUE;
2934 	dip->mixer_class = GUSMAX_INPUT_CLASS;
2935 	dip->prev = AUDIO_MIXER_LAST;
2936 	dip->next = GUSMAX_LINE_IN_MUTE;
2937 	strlcpy(dip->label.name, AudioNline, sizeof dip->label.name);
2938 	dip->un.v.num_channels = 2;
2939 	strlcpy(dip->un.v.units.name, AudioNvolume,
2940 	    sizeof dip->un.v.units.name);
2941 	break;
2942 
2943     case GUSMAX_CD_LVL:		/* cd */
2944 	dip->type = AUDIO_MIXER_VALUE;
2945 	dip->mixer_class = GUSMAX_INPUT_CLASS;
2946 	dip->prev = AUDIO_MIXER_LAST;
2947 	dip->next = GUSMAX_CD_MUTE;
2948 	strlcpy(dip->label.name, AudioNcd, sizeof dip->label.name);
2949 	dip->un.v.num_channels = 2;
2950 	strlcpy(dip->un.v.units.name, AudioNvolume,
2951 	    sizeof dip->un.v.units.name);
2952 	break;
2953 
2954 
2955     case GUSMAX_MONITOR_LVL:	/* monitor level */
2956 	dip->type = AUDIO_MIXER_VALUE;
2957 	dip->mixer_class = GUSMAX_MONITOR_CLASS;
2958 	dip->next = GUSMAX_MONITOR_MUTE;
2959 	dip->prev = AUDIO_MIXER_LAST;
2960 	strlcpy(dip->label.name, AudioNmonitor, sizeof dip->label.name);
2961 	dip->un.v.num_channels = 1;
2962 	strlcpy(dip->un.v.units.name, AudioNvolume,
2963 	    sizeof dip->un.v.units.name);
2964 	break;
2965 
2966     case GUSMAX_OUT_LVL:		/* cs4231 output volume: not useful? */
2967 	dip->type = AUDIO_MIXER_VALUE;
2968 	dip->mixer_class = GUSMAX_MONITOR_CLASS;
2969 	dip->prev = dip->next = AUDIO_MIXER_LAST;
2970 	strlcpy(dip->label.name, AudioNoutput, sizeof dip->label.name);
2971 	dip->un.v.num_channels = 2;
2972 	strlcpy(dip->un.v.units.name, AudioNvolume,
2973 	    sizeof dip->un.v.units.name);
2974 	break;
2975 
2976     case GUSMAX_SPEAKER_LVL:		/* fake speaker volume */
2977 	dip->type = AUDIO_MIXER_VALUE;
2978 	dip->mixer_class = GUSMAX_MONITOR_CLASS;
2979 	dip->prev = AUDIO_MIXER_LAST;
2980 	dip->next = GUSMAX_SPEAKER_MUTE;
2981 	strlcpy(dip->label.name, AudioNmaster, sizeof dip->label.name);
2982 	dip->un.v.num_channels = 2;
2983 	strlcpy(dip->un.v.units.name, AudioNvolume,
2984 	    sizeof dip->un.v.units.name);
2985 	break;
2986 
2987     case GUSMAX_LINE_IN_MUTE:
2988 	dip->mixer_class = GUSMAX_INPUT_CLASS;
2989 	dip->type = AUDIO_MIXER_ENUM;
2990 	dip->prev = GUSMAX_LINE_IN_LVL;
2991 	dip->next = AUDIO_MIXER_LAST;
2992 	goto mute;
2993 
2994     case GUSMAX_DAC_MUTE:
2995 	dip->mixer_class = GUSMAX_INPUT_CLASS;
2996 	dip->type = AUDIO_MIXER_ENUM;
2997 	dip->prev = GUSMAX_DAC_LVL;
2998 	dip->next = AUDIO_MIXER_LAST;
2999 	goto mute;
3000 
3001     case GUSMAX_CD_MUTE:
3002 	dip->mixer_class = GUSMAX_INPUT_CLASS;
3003 	dip->type = AUDIO_MIXER_ENUM;
3004 	dip->prev = GUSMAX_CD_LVL;
3005 	dip->next = AUDIO_MIXER_LAST;
3006 	goto mute;
3007 
3008     case GUSMAX_MONO_MUTE:
3009 	dip->mixer_class = GUSMAX_INPUT_CLASS;
3010 	dip->type = AUDIO_MIXER_ENUM;
3011 	dip->prev = GUSMAX_MONO_LVL;
3012 	dip->next = AUDIO_MIXER_LAST;
3013 	goto mute;
3014 
3015     case GUSMAX_MONITOR_MUTE:
3016 	dip->mixer_class = GUSMAX_OUTPUT_CLASS;
3017 	dip->type = AUDIO_MIXER_ENUM;
3018 	dip->prev = GUSMAX_MONITOR_LVL;
3019 	dip->next = AUDIO_MIXER_LAST;
3020 	goto mute;
3021 
3022     case GUSMAX_SPEAKER_MUTE:
3023 	dip->mixer_class = GUSMAX_OUTPUT_CLASS;
3024 	dip->type = AUDIO_MIXER_ENUM;
3025 	dip->prev = GUSMAX_SPEAKER_LVL;
3026 	dip->next = AUDIO_MIXER_LAST;
3027     mute:
3028 	strlcpy(dip->label.name, AudioNmute, sizeof dip->label.name);
3029 	dip->un.e.num_mem = 2;
3030 	strlcpy(dip->un.e.member[0].label.name, AudioNoff,
3031 	    sizeof dip->un.e.member[0].label.name);
3032 	dip->un.e.member[0].ord = 0;
3033 	strlcpy(dip->un.e.member[1].label.name, AudioNon,
3034 	    sizeof dip->un.e.member[1].label.name);
3035 	dip->un.e.member[1].ord = 1;
3036 	break;
3037 
3038     case GUSMAX_REC_LVL:	/* record level */
3039 	dip->type = AUDIO_MIXER_VALUE;
3040 	dip->mixer_class = GUSMAX_RECORD_CLASS;
3041 	dip->prev = AUDIO_MIXER_LAST;
3042 	dip->next = GUSMAX_RECORD_SOURCE;
3043 	strlcpy(dip->label.name, AudioNrecord, sizeof dip->label.name);
3044 	dip->un.v.num_channels = 2;
3045 	strlcpy(dip->un.v.units.name, AudioNvolume, sizeof dip->un.v.units.name);
3046 	break;
3047 
3048     case GUSMAX_RECORD_SOURCE:
3049 	dip->mixer_class = GUSMAX_RECORD_CLASS;
3050 	dip->type = AUDIO_MIXER_ENUM;
3051 	dip->prev = GUSMAX_REC_LVL;
3052 	dip->next = AUDIO_MIXER_LAST;
3053 	strlcpy(dip->label.name, AudioNsource, sizeof dip->label.name);
3054 	dip->un.e.num_mem = 4;
3055 	strlcpy(dip->un.e.member[0].label.name, AudioNoutput,
3056 	    sizeof dip->un.e.member[0].label.name);
3057 	dip->un.e.member[0].ord = DAC_IN_PORT;
3058 	strlcpy(dip->un.e.member[1].label.name, AudioNmicrophone,
3059 	    sizeof dip->un.e.member[1].label.name);
3060 	dip->un.e.member[1].ord = MIC_IN_PORT;
3061 	strlcpy(dip->un.e.member[2].label.name, AudioNdac,
3062 	    sizeof dip->un.e.member[2].label.name);
3063 	dip->un.e.member[2].ord = AUX1_IN_PORT;
3064 	strlcpy(dip->un.e.member[3].label.name, AudioNline,
3065 	    sizeof dip->un.e.member[3].label.name);
3066 	dip->un.e.member[3].ord = LINE_IN_PORT;
3067 	break;
3068 
3069     case GUSMAX_INPUT_CLASS:			/* input class descriptor */
3070 	dip->type = AUDIO_MIXER_CLASS;
3071 	dip->mixer_class = GUSMAX_INPUT_CLASS;
3072 	dip->next = dip->prev = AUDIO_MIXER_LAST;
3073 	strlcpy(dip->label.name, AudioCinputs, sizeof dip->label.name);
3074 	break;
3075 
3076     case GUSMAX_OUTPUT_CLASS:			/* output class descriptor */
3077 	dip->type = AUDIO_MIXER_CLASS;
3078 	dip->mixer_class = GUSMAX_OUTPUT_CLASS;
3079 	dip->next = dip->prev = AUDIO_MIXER_LAST;
3080 	strlcpy(dip->label.name, AudioCoutputs, sizeof dip->label.name);
3081 	break;
3082 
3083     case GUSMAX_MONITOR_CLASS:			/* monitor class descriptor */
3084 	dip->type = AUDIO_MIXER_CLASS;
3085 	dip->mixer_class = GUSMAX_MONITOR_CLASS;
3086 	dip->next = dip->prev = AUDIO_MIXER_LAST;
3087 	strlcpy(dip->label.name, AudioCmonitor, sizeof dip->label.name);
3088 	break;
3089 
3090     case GUSMAX_RECORD_CLASS:			/* record source class */
3091 	dip->type = AUDIO_MIXER_CLASS;
3092 	dip->mixer_class = GUSMAX_RECORD_CLASS;
3093 	dip->next = dip->prev = AUDIO_MIXER_LAST;
3094 	strlcpy(dip->label.name, AudioCrecord, sizeof dip->label.name);
3095 	break;
3096 
3097     default:
3098 	return ENXIO;
3099 	/*NOTREACHED*/
3100     }
3101     DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name));
3102 	return 0;
3103 }
3104 
3105 int
3106 gus_mixer_query_devinfo(addr, dip)
3107 	void *addr;
3108 	mixer_devinfo_t *dip;
3109 {
3110 	struct gus_softc *sc = addr;
3111 
3112 	DPRINTF(("gusmax_query_devinfo: index=%d\n", dip->index));
3113 
3114 	if (!HAS_MIXER(sc) && dip->index > GUSICS_MASTER_MUTE)
3115 		return ENXIO;
3116 
3117 	switch(dip->index) {
3118 
3119 	case GUSICS_MIC_IN_LVL:	/* Microphone */
3120 		dip->type = AUDIO_MIXER_VALUE;
3121 		dip->mixer_class = GUSICS_INPUT_CLASS;
3122 		dip->prev = AUDIO_MIXER_LAST;
3123 		dip->next = GUSICS_MIC_IN_MUTE;
3124 		strlcpy(dip->label.name, AudioNmicrophone,
3125 		    sizeof dip->label.name);
3126 		dip->un.v.num_channels = 2;
3127 		strlcpy(dip->un.v.units.name, AudioNvolume,
3128 		    sizeof dip->un.v.units.name);
3129 		break;
3130 
3131 	case GUSICS_LINE_IN_LVL:	/* line */
3132 		dip->type = AUDIO_MIXER_VALUE;
3133 		dip->mixer_class = GUSICS_INPUT_CLASS;
3134 		dip->prev = AUDIO_MIXER_LAST;
3135 		dip->next = GUSICS_LINE_IN_MUTE;
3136 		strlcpy(dip->label.name, AudioNline, sizeof dip->label.name);
3137 		dip->un.v.num_channels = 2;
3138 		strlcpy(dip->un.v.units.name, AudioNvolume,
3139 		    sizeof dip->un.v.units.name);
3140 		break;
3141 
3142 	case GUSICS_CD_LVL:		/* cd */
3143 		dip->type = AUDIO_MIXER_VALUE;
3144 		dip->mixer_class = GUSICS_INPUT_CLASS;
3145 		dip->prev = AUDIO_MIXER_LAST;
3146 		dip->next = GUSICS_CD_MUTE;
3147 		strlcpy(dip->label.name, AudioNcd, sizeof dip->label.name);
3148 		dip->un.v.num_channels = 2;
3149 		strlcpy(dip->un.v.units.name, AudioNvolume,
3150 		    sizeof dip->un.v.units.name);
3151 		break;
3152 
3153 	case GUSICS_DAC_LVL:		/*  dacout */
3154 		dip->type = AUDIO_MIXER_VALUE;
3155 		dip->mixer_class = GUSICS_INPUT_CLASS;
3156 		dip->prev = AUDIO_MIXER_LAST;
3157 		dip->next = GUSICS_DAC_MUTE;
3158 		strlcpy(dip->label.name, AudioNdac, sizeof dip->label.name);
3159 		dip->un.v.num_channels = 2;
3160 		strlcpy(dip->un.v.units.name, AudioNvolume,
3161 		    sizeof dip->un.v.units.name);
3162 		break;
3163 
3164 	case GUSICS_MASTER_LVL:		/*  master output */
3165 		dip->type = AUDIO_MIXER_VALUE;
3166 		dip->mixer_class = GUSICS_OUTPUT_CLASS;
3167 		dip->prev = AUDIO_MIXER_LAST;
3168 		dip->next = GUSICS_MASTER_MUTE;
3169 		strlcpy(dip->label.name, AudioNmaster, sizeof dip->label.name);
3170 		dip->un.v.num_channels = 2;
3171 		strlcpy(dip->un.v.units.name, AudioNvolume,
3172 		    sizeof dip->un.v.units.name);
3173 		break;
3174 
3175 
3176 	case GUSICS_LINE_IN_MUTE:
3177 		dip->mixer_class = GUSICS_INPUT_CLASS;
3178 		dip->type = AUDIO_MIXER_ENUM;
3179 		dip->prev = GUSICS_LINE_IN_LVL;
3180 		dip->next = AUDIO_MIXER_LAST;
3181 		goto mute;
3182 
3183 	case GUSICS_DAC_MUTE:
3184 		dip->mixer_class = GUSICS_INPUT_CLASS;
3185 		dip->type = AUDIO_MIXER_ENUM;
3186 		dip->prev = GUSICS_DAC_LVL;
3187 		dip->next = AUDIO_MIXER_LAST;
3188 		goto mute;
3189 
3190 	case GUSICS_CD_MUTE:
3191 		dip->mixer_class = GUSICS_INPUT_CLASS;
3192 		dip->type = AUDIO_MIXER_ENUM;
3193 		dip->prev = GUSICS_CD_LVL;
3194 		dip->next = AUDIO_MIXER_LAST;
3195 		goto mute;
3196 
3197 	case GUSICS_MIC_IN_MUTE:
3198 		dip->mixer_class = GUSICS_INPUT_CLASS;
3199 		dip->type = AUDIO_MIXER_ENUM;
3200 		dip->prev = GUSICS_MIC_IN_LVL;
3201 		dip->next = AUDIO_MIXER_LAST;
3202 		goto mute;
3203 
3204 	case GUSICS_MASTER_MUTE:
3205 		dip->mixer_class = GUSICS_OUTPUT_CLASS;
3206 		dip->type = AUDIO_MIXER_ENUM;
3207 		dip->prev = GUSICS_MASTER_LVL;
3208 		dip->next = AUDIO_MIXER_LAST;
3209 mute:
3210 		strlcpy(dip->label.name, AudioNmute, sizeof dip->label.name);
3211 		dip->un.e.num_mem = 2;
3212 		strlcpy(dip->un.e.member[0].label.name, AudioNoff,
3213 		    sizeof dip->un.e.member[0].label.name);
3214 		dip->un.e.member[0].ord = 0;
3215 		strlcpy(dip->un.e.member[1].label.name, AudioNon,
3216 		    sizeof dip->un.e.member[1].label.name);
3217 		dip->un.e.member[1].ord = 1;
3218 		break;
3219 
3220 	case GUSICS_RECORD_SOURCE:
3221 		dip->mixer_class = GUSICS_RECORD_CLASS;
3222 		dip->type = AUDIO_MIXER_ENUM;
3223 		dip->prev = dip->next = AUDIO_MIXER_LAST;
3224 		strlcpy(dip->label.name, AudioNsource, sizeof dip->label.name);
3225 		dip->un.e.num_mem = 1;
3226 		strlcpy(dip->un.e.member[0].label.name, AudioNoutput,
3227 		    sizeof dip->un.e.member[0].label.name);
3228 		dip->un.e.member[0].ord = GUSICS_MASTER_LVL;
3229 		break;
3230 
3231 	case GUSICS_INPUT_CLASS:
3232 		dip->type = AUDIO_MIXER_CLASS;
3233 		dip->mixer_class = GUSICS_INPUT_CLASS;
3234 		dip->next = dip->prev = AUDIO_MIXER_LAST;
3235 		strlcpy(dip->label.name, AudioCinputs, sizeof dip->label.name);
3236 		break;
3237 
3238 	case GUSICS_OUTPUT_CLASS:
3239 		dip->type = AUDIO_MIXER_CLASS;
3240 		dip->mixer_class = GUSICS_OUTPUT_CLASS;
3241 		dip->next = dip->prev = AUDIO_MIXER_LAST;
3242 		strlcpy(dip->label.name, AudioCoutputs, sizeof dip->label.name);
3243 		break;
3244 
3245 	case GUSICS_RECORD_CLASS:
3246 		dip->type = AUDIO_MIXER_CLASS;
3247 		dip->mixer_class = GUSICS_RECORD_CLASS;
3248 		dip->next = dip->prev = AUDIO_MIXER_LAST;
3249 		strlcpy(dip->label.name, AudioCrecord, sizeof dip->label.name);
3250 		break;
3251 
3252 	default:
3253 		return ENXIO;
3254 	/*NOTREACHED*/
3255 	}
3256 	DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name));
3257 	return 0;
3258 }
3259 
3260 int
3261 gus_query_encoding(addr, fp)
3262 	void *addr;
3263 	struct audio_encoding *fp;
3264 {
3265 	switch (fp->index) {
3266 	case 0:
3267 		strlcpy(fp->name, AudioEmulaw, sizeof fp->name);
3268 		fp->encoding = AUDIO_ENCODING_ULAW;
3269 		fp->precision = 8;
3270 		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
3271 		break;
3272 	case 1:
3273 		strlcpy(fp->name, AudioEslinear, sizeof fp->name);
3274 		fp->encoding = AUDIO_ENCODING_SLINEAR;
3275 		fp->precision = 8;
3276 		fp->flags = 0;
3277 		break;
3278 	case 2:
3279 		strlcpy(fp->name, AudioEslinear_le, sizeof fp->name);
3280 		fp->encoding = AUDIO_ENCODING_SLINEAR_LE;
3281 		fp->precision = 16;
3282 		fp->flags = 0;
3283 		break;
3284 	case 3:
3285 		strlcpy(fp->name, AudioEulinear, sizeof fp->name);
3286 		fp->encoding = AUDIO_ENCODING_ULINEAR;
3287 		fp->precision = 8;
3288 		fp->flags = 0;
3289 		break;
3290 	case 4:
3291 		strlcpy(fp->name, AudioEulinear_le, sizeof fp->name);
3292 		fp->encoding = AUDIO_ENCODING_ULINEAR_LE;
3293 		fp->precision = 16;
3294 		fp->flags = 0;
3295 		break;
3296 	case 5:
3297 		strlcpy(fp->name, AudioEslinear_be, sizeof fp->name);
3298 		fp->encoding = AUDIO_ENCODING_SLINEAR_BE;
3299 		fp->precision = 16;
3300 		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
3301 		break;
3302 	case 6:
3303 		strlcpy(fp->name, AudioEulinear_be, sizeof fp->name);
3304 		fp->encoding = AUDIO_ENCODING_ULINEAR_BE;
3305 		fp->precision = 16;
3306 		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
3307 		break;
3308 	case 7:
3309 		strlcpy(fp->name, AudioEalaw, sizeof fp->name);
3310 		fp->encoding = AUDIO_ENCODING_ALAW;
3311 		fp->precision = 8;
3312 		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
3313 		break;
3314 
3315 	default:
3316 		return(EINVAL);
3317 		/*NOTREACHED*/
3318 	}
3319 	return (0);
3320 }
3321 
3322 /*
3323  * Setup the ICS mixer in "transparent" mode: reset everything to a sensible
3324  * level.  Levels as suggested by GUS SDK code.
3325  */
3326 
3327 void
3328 gus_init_ics2101(sc)
3329 	struct gus_softc *sc;
3330 {
3331 	struct ics2101_softc *ic = &sc->sc_mixer;
3332 	sc->sc_mixer.sc_iot = sc->sc_iot;
3333 	sc->sc_mixer.sc_selio = GUS_MIXER_SELECT;
3334 	sc->sc_mixer.sc_selio_ioh = sc->sc_ioh3;
3335 	sc->sc_mixer.sc_dataio = GUS_MIXER_DATA;
3336 	sc->sc_mixer.sc_dataio_ioh = sc->sc_ioh2;
3337 	sc->sc_mixer.sc_flags = (sc->sc_revision == 5) ? ICS_FLIP : 0;
3338 
3339 	ics2101_mix_attenuate(ic,
3340 			      GUSMIX_CHAN_MIC,
3341 			      ICSMIX_LEFT,
3342 			      ICSMIX_MIN_ATTN);
3343 	ics2101_mix_attenuate(ic,
3344 			      GUSMIX_CHAN_MIC,
3345 			      ICSMIX_RIGHT,
3346 			      ICSMIX_MIN_ATTN);
3347 	/*
3348 	 * Start with microphone muted by the mixer...
3349 	 */
3350 	gusics_mic_mute(ic, 1);
3351 
3352 	/* ... and enabled by the GUS master mix control */
3353 	gus_mic_ctl(sc, SPKR_ON);
3354 
3355 	ics2101_mix_attenuate(ic,
3356 			      GUSMIX_CHAN_LINE,
3357 			      ICSMIX_LEFT,
3358 			      ICSMIX_MIN_ATTN);
3359 	ics2101_mix_attenuate(ic,
3360 			      GUSMIX_CHAN_LINE,
3361 			      ICSMIX_RIGHT,
3362 			      ICSMIX_MIN_ATTN);
3363 
3364 	ics2101_mix_attenuate(ic,
3365 			      GUSMIX_CHAN_CD,
3366 			      ICSMIX_LEFT,
3367 			      ICSMIX_MIN_ATTN);
3368 	ics2101_mix_attenuate(ic,
3369 			      GUSMIX_CHAN_CD,
3370 			      ICSMIX_RIGHT,
3371 			      ICSMIX_MIN_ATTN);
3372 
3373 	ics2101_mix_attenuate(ic,
3374 			      GUSMIX_CHAN_DAC,
3375 			      ICSMIX_LEFT,
3376 			      ICSMIX_MIN_ATTN);
3377 	ics2101_mix_attenuate(ic,
3378 			      GUSMIX_CHAN_DAC,
3379 			      ICSMIX_RIGHT,
3380 			      ICSMIX_MIN_ATTN);
3381 
3382 	ics2101_mix_attenuate(ic,
3383 			      ICSMIX_CHAN_4,
3384 			      ICSMIX_LEFT,
3385 			      ICSMIX_MAX_ATTN);
3386 	ics2101_mix_attenuate(ic,
3387 			      ICSMIX_CHAN_4,
3388 			      ICSMIX_RIGHT,
3389 			      ICSMIX_MAX_ATTN);
3390 
3391 	ics2101_mix_attenuate(ic,
3392 			      GUSMIX_CHAN_MASTER,
3393 			      ICSMIX_LEFT,
3394 			      ICSMIX_MIN_ATTN);
3395 	ics2101_mix_attenuate(ic,
3396 			      GUSMIX_CHAN_MASTER,
3397 			      ICSMIX_RIGHT,
3398 			      ICSMIX_MIN_ATTN);
3399 	/* unmute other stuff: */
3400 	gusics_cd_mute(ic, 0);
3401 	gusics_dac_mute(ic, 0);
3402 	gusics_linein_mute(ic, 0);
3403 	return;
3404 }
3405 
3406 
3407 
3408 void
3409 gus_subattach(sc, ia)
3410 	struct gus_softc *sc;
3411 	struct isa_attach_args *ia;
3412 {
3413 	int		i;
3414 	bus_space_tag_t iot;
3415 	unsigned char	c,d,m;
3416 
3417 	iot = sc->sc_iot;
3418 
3419 	/*
3420 	 * Figure out our board rev, and see if we need to initialize the
3421 	 * mixer
3422 	 */
3423 
3424 	c = bus_space_read_1(iot, sc->sc_ioh3, GUS_BOARD_REV);
3425 	if (c != 0xff)
3426 		sc->sc_revision = c;
3427 	else
3428 		sc->sc_revision = 0;
3429 
3430 	SELECT_GUS_REG(iot, sc->sc_ioh2, GUSREG_RESET);
3431 	bus_space_write_1(iot, sc->sc_ioh2, GUS_DATA_HIGH, 0x00);
3432 
3433 	gusreset(sc, GUS_MAX_VOICES); /* initialize all voices */
3434 	gusreset(sc, GUS_MIN_VOICES); /* then set to just the ones we use */
3435 
3436 	/*
3437 	 * Setup the IRQ and DRQ lines in software, using values from
3438 	 * config file
3439 	 */
3440 
3441 	m = GUSMASK_LINE_IN|GUSMASK_LINE_OUT;		/* disable all */
3442 
3443 	c = ((unsigned char) gus_irq_map[ia->ia_irq]) | GUSMASK_BOTH_RQ;
3444 
3445 	if (sc->sc_recdrq == sc->sc_drq)
3446 		d = (unsigned char) (gus_drq_map[sc->sc_drq] |
3447 				GUSMASK_BOTH_RQ);
3448 	else
3449 		d = (unsigned char) (gus_drq_map[sc->sc_drq] |
3450 				gus_drq_map[sc->sc_recdrq] << 3);
3451 
3452 	/*
3453 	 * Program the IRQ and DMA channels on the GUS.  Note that we hardwire
3454 	 * the GUS to only use one IRQ channel, but we give the user the
3455 	 * option of using two DMA channels (the other one given by the drq2
3456 	 * option in the config file).  Two DMA channels are needed for full-
3457 	 * duplex operation.
3458 	 *
3459 	 * The order of these operations is very magical.
3460 	 */
3461 
3462 	disable_intr();		/* XXX needed? */
3463 
3464 	bus_space_write_1(iot, sc->sc_ioh1, GUS_REG_CONTROL, GUS_REG_IRQCTL);
3465 	bus_space_write_1(iot, sc->sc_ioh1, GUS_MIX_CONTROL, m);
3466 	bus_space_write_1(iot, sc->sc_ioh1, GUS_IRQCTL_CONTROL, 0x00);
3467 	bus_space_write_1(iot, sc->sc_ioh1, 0x0f, 0x00);
3468 
3469 	bus_space_write_1(iot, sc->sc_ioh1, GUS_MIX_CONTROL, m);
3470 
3471 	/* magic reset? */
3472 	bus_space_write_1(iot, sc->sc_ioh1, GUS_DMA_CONTROL, d | 0x80);
3473 
3474 	bus_space_write_1(iot, sc->sc_ioh1, GUS_MIX_CONTROL,
3475 	    m | GUSMASK_CONTROL_SEL);
3476 	bus_space_write_1(iot, sc->sc_ioh1, GUS_IRQ_CONTROL, c);
3477 
3478 	bus_space_write_1(iot, sc->sc_ioh1, GUS_MIX_CONTROL, m);
3479 	bus_space_write_1(iot, sc->sc_ioh1, GUS_DMA_CONTROL, d);
3480 
3481 	bus_space_write_1(iot, sc->sc_ioh1, GUS_MIX_CONTROL,
3482 	    m | GUSMASK_CONTROL_SEL);
3483 	bus_space_write_1(iot, sc->sc_ioh1, GUS_IRQ_CONTROL, c);
3484 
3485 	bus_space_write_1(iot, sc->sc_ioh2, GUS_VOICE_SELECT, 0x00);
3486 
3487 	/* enable line in, line out.  leave mic disabled. */
3488 	bus_space_write_1(iot, sc->sc_ioh1, GUS_MIX_CONTROL,
3489 	     (m | GUSMASK_LATCHES) & ~(GUSMASK_LINE_OUT|GUSMASK_LINE_IN));
3490 	bus_space_write_1(iot, sc->sc_ioh2, GUS_VOICE_SELECT, 0x00);
3491 
3492 	enable_intr();
3493 
3494 	sc->sc_mixcontrol =
3495 		(m | GUSMASK_LATCHES) & ~(GUSMASK_LINE_OUT|GUSMASK_LINE_IN);
3496 
3497 	sc->sc_codec.sc_isa = sc->sc_isa;
3498 
3499 	if (sc->sc_revision >= 5 && sc->sc_revision <= 9) {
3500 		sc->sc_flags |= GUS_MIXER_INSTALLED;
3501 		gus_init_ics2101(sc);
3502 	}
3503 	if (sc->sc_revision < 10 || !gus_init_cs4231(sc)) {
3504 		/* Not using the CS4231, so create our DMA maps. */
3505 		if (sc->sc_drq != -1) {
3506 			if (isa_dmamap_create(sc->sc_isa, sc->sc_drq,
3507 			    MAX_ISADMA, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) {
3508 				printf("%s: can't create map for drq %d\n",
3509 				       sc->sc_dev.dv_xname, sc->sc_drq);
3510 				return;
3511 			}
3512 		}
3513 		if (sc->sc_recdrq != -1 && sc->sc_recdrq != sc->sc_drq) {
3514 			if (isa_dmamap_create(sc->sc_isa, sc->sc_recdrq,
3515 			    MAX_ISADMA, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) {
3516 				printf("%s: can't create map for drq %d\n",
3517 				       sc->sc_dev.dv_xname, sc->sc_recdrq);
3518 				return;
3519 			}
3520 		}
3521 	}
3522 
3523 	timeout_set(&sc->sc_dma_tmo, gus_dmaout_timeout, sc);
3524 
3525 	SELECT_GUS_REG(iot, sc->sc_ioh2, GUSREG_RESET);
3526 	/*
3527 	 * Check to see how much memory we have on this card; see if any
3528 	 * "mirroring" occurs.  We're assuming at least 256K already exists
3529 	 * on the card; otherwise the initial probe would have failed
3530 	 */
3531 
3532 	guspoke(iot, sc->sc_ioh2, 0L, 0x00);
3533 	for(i = 1; i < 1024; i++) {
3534 		u_long loc;
3535 
3536 		/*
3537 		 * See if we've run into mirroring yet
3538 		 */
3539 
3540 		if (guspeek(iot, sc->sc_ioh2, 0L) != 0)
3541 			break;
3542 
3543 		loc = i << 10;
3544 
3545 		guspoke(iot, sc->sc_ioh2, loc, 0xaa);
3546 		if (guspeek(iot, sc->sc_ioh2, loc) != 0xaa)
3547 			break;
3548 	}
3549 
3550 	sc->sc_dsize = i;
3551 	/*
3552 	 * The "official" (3.x) version number cannot easily be obtained.
3553 	 * The revision register does not correspond to the minor number
3554 	 * of the board version. Simply use the revision register as
3555 	 * identification.
3556 	 */
3557 	snprintf(gus_device.version, sizeof gus_device.version, "%d",
3558 	    sc->sc_revision);
3559 
3560 	printf(": ver %d", sc->sc_revision);
3561 	if (sc->sc_revision >= 10)
3562 		printf(", MAX");
3563 	else {
3564 		if (HAS_MIXER(sc))
3565 			printf(", ICS2101 mixer");
3566 		if (HAS_CODEC(sc))
3567 			printf(", %s codec/mixer", sc->sc_codec.chip_name);
3568 	}
3569 	printf(", %dKB DRAM, ", sc->sc_dsize);
3570 	if (sc->sc_recdrq == sc->sc_drq) {
3571 		printf("half-duplex");
3572 	} else {
3573 		printf("full-duplex, record drq %d", sc->sc_recdrq);
3574 	}
3575 
3576 	printf("\n");
3577 
3578 	/*
3579 	 * Setup a default interrupt handler
3580 	 */
3581 
3582 	/* XXX we shouldn't have to use splgus == splclock, nor should
3583 	 * we use IPL_CLOCK.
3584 	 */
3585 	sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq, IST_EDGE,
3586 	    IPL_AUDIO, gusintr, sc /* sc->sc_gusdsp */, sc->sc_dev.dv_xname);
3587 
3588 	/*
3589 	 * Set some default values
3590 	 * XXX others start with 8kHz mono mulaw
3591 	 */
3592 
3593 	sc->sc_irate = sc->sc_orate = 44100;
3594 	sc->sc_encoding = AUDIO_ENCODING_SLINEAR_LE;
3595 	sc->sc_precision = 16;
3596 	sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_DATA_SIZE16;
3597 	sc->sc_voc[GUS_VOICE_RIGHT].voccntl |= GUSMASK_DATA_SIZE16;
3598 	sc->sc_channels = 1;
3599 	sc->sc_ogain = 340;
3600 	gus_commit_settings(sc);
3601 
3602 	/*
3603 	 * We always put the left channel full left & right channel
3604 	 * full right.
3605 	 * For mono playback, we set up both voices playing the same buffer.
3606 	 */
3607 	bus_space_write_1(iot, sc->sc_ioh2, GUS_VOICE_SELECT,
3608 	    (u_char)GUS_VOICE_LEFT);
3609 	SELECT_GUS_REG(iot, sc->sc_ioh2, GUSREG_PAN_POS);
3610 	bus_space_write_1(iot, sc->sc_ioh2, GUS_DATA_HIGH, GUS_PAN_FULL_LEFT);
3611 
3612 	bus_space_write_1(iot, sc->sc_ioh2, GUS_VOICE_SELECT,
3613 	    (u_char)GUS_VOICE_RIGHT);
3614 	SELECT_GUS_REG(iot, sc->sc_ioh2, GUSREG_PAN_POS);
3615 	bus_space_write_1(iot, sc->sc_ioh2, GUS_DATA_HIGH, GUS_PAN_FULL_RIGHT);
3616 
3617 	/*
3618 	 * Attach to the generic audio layer
3619 	 */
3620 
3621 	audio_attach_mi(&gus_hw_if, HAS_CODEC(sc) ? (void *)&sc->sc_codec :
3622 	    (void *)sc, &sc->sc_dev);
3623 }
3624 
3625 /*
3626  * Test to see if a particular I/O base is valid for the GUS.  Return true
3627  * if it is.
3628  */
3629 
3630 int
3631 gus_test_iobase (iot, iobase)
3632 	bus_space_tag_t iot;
3633 	int iobase;
3634 {
3635 	bus_space_handle_t ioh1, ioh2, ioh3, ioh4;
3636 	u_char s1, s2;
3637 	int s, rv = 0;
3638 
3639 	/* Map i/o space */
3640 	if (bus_space_map(iot, iobase, GUS_NPORT1, 0, &ioh1))
3641 		return 0;
3642 	if (bus_space_map(iot, iobase+GUS_IOH2_OFFSET, GUS_NPORT2, 0, &ioh2))
3643 		goto bad1;
3644 
3645 	/* XXX Maybe we shouldn't fail on mapping this, but just assume
3646 	 * the card is of revision 0? */
3647 	if (bus_space_map(iot, iobase+GUS_IOH3_OFFSET, GUS_NPORT3, 0, &ioh3))
3648 		goto bad2;
3649 
3650 	if (bus_space_map(iot, iobase+GUS_IOH4_OFFSET, GUS_NPORT4, 0, &ioh4))
3651 		goto bad3;
3652 
3653 	/*
3654 	 * Reset GUS to an initial state before we do anything.
3655 	 */
3656 
3657 	s = splgus();
3658 	delay(500);
3659 
3660 	SELECT_GUS_REG(iot, ioh2, GUSREG_RESET);
3661 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
3662 
3663 	delay(500);
3664 
3665 	SELECT_GUS_REG(iot, ioh2, GUSREG_RESET);
3666 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, GUSMASK_MASTER_RESET);
3667 
3668 	delay(500);
3669 
3670 	splx(s);
3671 
3672 	/*
3673 	 * See if we can write to the board's memory
3674 	 */
3675 
3676 	s1 = guspeek(iot, ioh2, 0L);
3677 	s2 = guspeek(iot, ioh2, 1L);
3678 
3679 	guspoke(iot, ioh2, 0L, 0xaa);
3680 	guspoke(iot, ioh2, 1L, 0x55);
3681 
3682 	if (guspeek(iot, ioh2, 0L) != 0xaa)
3683 		goto bad;
3684 
3685 	guspoke(iot, ioh2, 0L, s1);
3686 	guspoke(iot, ioh2, 1L, s2);
3687 
3688 	rv = 1;
3689 
3690 bad:
3691 	bus_space_unmap(iot, ioh4, GUS_NPORT4);
3692 bad3:
3693 	bus_space_unmap(iot, ioh3, GUS_NPORT3);
3694 bad2:
3695 	bus_space_unmap(iot, ioh2, GUS_NPORT2);
3696 bad1:
3697 	bus_space_unmap(iot, ioh1, GUS_NPORT1);
3698 	return rv;
3699 }
3700