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