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