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