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