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