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