FreeBSD/Linux Kernel Cross Reference
sys/dev/isa/gus.c
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 }
Cache object: e8feac3b2f9edbee7508268d8b0c3ecf
|