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