gus.c revision 1.47 1 /* $NetBSD: gus.c,v 1.47 1997/10/11 12:36:23 mycroft 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 FOUNDATION OR CONTRIBUTORS
30 * BE 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 device *sc_isa; /* pointer to ISA parent */
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 if ((sc->sc_drq != -1 && !isa_drq_isfree(parent, sc->sc_drq)) ||
750 (sc->sc_recdrq != -1 && !isa_drq_isfree(parent, sc->sc_recdrq)))
751 return 0;
752
753 ia->ia_iobase = iobase;
754 ia->ia_iosize = GUS_NPORT1;
755 return 1;
756 }
757
758 /*
759 * Test to see if a particular I/O base is valid for the GUS. Return true
760 * if it is.
761 */
762
763 STATIC int
764 gus_test_iobase (sc, iobase)
765 struct gus_softc *sc;
766 int iobase;
767 {
768 bus_space_tag_t iot = sc->sc_iot;
769 bus_space_handle_t ioh1, ioh2, ioh3, ioh4;
770 u_char s1, s2;
771 int s;
772
773 /* Map i/o space */
774 if (bus_space_map(iot, iobase, GUS_NPORT1, 0, &ioh1))
775 return 0;
776 sc->sc_ioh1 = ioh1;
777 if (bus_space_map(iot, iobase+GUS_IOH2_OFFSET, GUS_NPORT2, 0, &ioh2))
778 goto bad1;
779 sc->sc_ioh2 = ioh2;
780
781 /* XXX Maybe we shouldn't fail on mapping this, but just assume
782 * the card is of revision 0? */
783 if (bus_space_map(iot, iobase+GUS_IOH3_OFFSET, GUS_NPORT3, 0, &ioh3))
784 goto bad2;
785 sc->sc_ioh3 = ioh3;
786
787 if (bus_space_map(iot, iobase+GUS_IOH4_OFFSET, GUS_NPORT4, 0, &ioh4))
788 goto bad3;
789 sc->sc_ioh4 = ioh4;
790
791 /*
792 * Reset GUS to an initial state before we do anything.
793 */
794
795 s = splgus();
796 delay(500);
797
798 SELECT_GUS_REG(iot, ioh2, GUSREG_RESET);
799 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
800
801 delay(500);
802
803 SELECT_GUS_REG(iot, ioh2, GUSREG_RESET);
804 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, GUSMASK_MASTER_RESET);
805
806 delay(500);
807
808 splx(s);
809
810 /*
811 * See if we can write to the board's memory
812 */
813
814 s1 = guspeek(iot, ioh2, 0L);
815 s2 = guspeek(iot, ioh2, 1L);
816
817 guspoke(iot, ioh2, 0L, 0xaa);
818 guspoke(iot, ioh2, 1L, 0x55);
819
820 if (guspeek(iot, ioh2, 0L) != 0xaa)
821 goto bad;
822
823 guspoke(iot, ioh2, 0L, s1);
824 guspoke(iot, ioh2, 1L, s2);
825
826 return 1;
827
828 bad:
829 bus_space_unmap(sc->sc_iot, sc->sc_ioh4, GUS_NPORT4);
830 bad3:
831 bus_space_unmap(sc->sc_iot, sc->sc_ioh3, GUS_NPORT3);
832 bad2:
833 bus_space_unmap(sc->sc_iot, sc->sc_ioh2, GUS_NPORT2);
834 bad1:
835 bus_space_unmap(sc->sc_iot, sc->sc_ioh1, GUS_NPORT1);
836 return 0;
837 }
838
839 /*
840 * Setup the GUS for use; called shortly after probe
841 */
842
843 void
844 gusattach(parent, self, aux)
845 struct device *parent, *self;
846 void *aux;
847 {
848 struct gus_softc *sc = (void *) self;
849 struct isa_attach_args *ia = aux;
850 bus_space_tag_t iot = sc->sc_iot;
851 bus_space_handle_t ioh1 = sc->sc_ioh1;
852 bus_space_handle_t ioh2 = sc->sc_ioh2;
853 bus_space_handle_t ioh3 = sc->sc_ioh3;
854 int i;
855 unsigned char c,d,m;
856
857 /*
858 * Figure out our board rev, and see if we need to initialize the
859 * mixer
860 */
861
862 sc->sc_isa = parent;
863
864 delay(500);
865
866 c = bus_space_read_1(iot, ioh3, GUS_BOARD_REV);
867 if (c != 0xff)
868 sc->sc_revision = c;
869 else
870 sc->sc_revision = 0;
871
872
873 SELECT_GUS_REG(iot, ioh2, GUSREG_RESET);
874 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
875
876 gusreset(sc, GUS_MAX_VOICES); /* initialize all voices */
877 gusreset(sc, GUS_MIN_VOICES); /* then set to just the ones we use */
878
879 /*
880 * Setup the IRQ and DRQ lines in software, using values from
881 * config file
882 */
883
884 m = GUSMASK_LINE_IN|GUSMASK_LINE_OUT; /* disable all */
885
886 c = ((unsigned char) gus_irq_map[ia->ia_irq]) | GUSMASK_BOTH_RQ;
887
888 if (sc->sc_recdrq == sc->sc_drq)
889 d = (unsigned char) (gus_drq_map[sc->sc_drq] |
890 GUSMASK_BOTH_RQ);
891 else
892 d = (unsigned char) (gus_drq_map[sc->sc_drq] |
893 gus_drq_map[sc->sc_recdrq] << 3);
894
895 /*
896 * Program the IRQ and DMA channels on the GUS. Note that we hardwire
897 * the GUS to only use one IRQ channel, but we give the user the
898 * option of using two DMA channels (the other one given by the flags
899 * option in the config file). Two DMA channels are needed for full-
900 * duplex operation.
901 *
902 * The order of these operations is very magical.
903 */
904
905 disable_intr(); /* XXX needed? */
906
907 bus_space_write_1(iot, ioh1, GUS_REG_CONTROL, GUS_REG_IRQCTL);
908 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, m);
909 bus_space_write_1(iot, ioh1, GUS_IRQCTL_CONTROL, 0x00);
910 bus_space_write_1(iot, ioh1, 0x0f, 0x00);
911
912 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, m);
913 bus_space_write_1(iot, ioh1, GUS_DMA_CONTROL, d | 0x80); /* magic reset? */
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, ioh1, GUS_MIX_CONTROL, m);
919 bus_space_write_1(iot, ioh1, GUS_DMA_CONTROL, d);
920
921 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, m | GUSMASK_CONTROL_SEL);
922 bus_space_write_1(iot, ioh1, GUS_IRQ_CONTROL, c);
923
924 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, 0x00);
925
926 /* enable line in, line out. leave mic disabled. */
927 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL,
928 (m | GUSMASK_LATCHES) & ~(GUSMASK_LINE_OUT|GUSMASK_LINE_IN));
929 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, 0x00);
930
931 enable_intr();
932
933 sc->sc_mixcontrol =
934 (m | GUSMASK_LATCHES) & ~(GUSMASK_LINE_OUT|GUSMASK_LINE_IN);
935
936 /* XXX WILL THIS ALWAYS WORK THE WAY THEY'RE OVERLAYED?! */
937 sc->sc_codec.sc_isa = sc->sc_dev.dv_parent;
938
939 if (sc->sc_revision >= 5 && sc->sc_revision <= 9) {
940 sc->sc_flags |= GUS_MIXER_INSTALLED;
941 gus_init_ics2101(sc);
942 }
943 if (sc->sc_revision >= 0xa) {
944 gus_init_cs4231(sc);
945 } else {
946 /* Not using the CS4231, so create our DMA maps. */
947 if (sc->sc_drq != -1) {
948 if (isa_dmamap_create(sc->sc_isa, sc->sc_drq,
949 MAX_ISADMA, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) {
950 printf("%s: can't create map for drq %d\n",
951 sc->sc_dev.dv_xname, sc->sc_drq);
952 return;
953 }
954 }
955 if (sc->sc_recdrq != -1 && sc->sc_recdrq != sc->sc_drq) {
956 if (isa_dmamap_create(sc->sc_isa, sc->sc_recdrq,
957 MAX_ISADMA, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) {
958 printf("%s: can't create map for drq %d\n",
959 sc->sc_dev.dv_xname, sc->sc_recdrq);
960 return;
961 }
962 }
963 }
964
965 SELECT_GUS_REG(iot, ioh2, GUSREG_RESET);
966 /*
967 * Check to see how much memory we have on this card; see if any
968 * "mirroring" occurs. We're assuming at least 256K already exists
969 * on the card; otherwise the initial probe would have failed
970 */
971
972 guspoke(iot, ioh2, 0L, 0x00);
973 for(i = 1; i < 1024; i++) {
974 u_long loc;
975
976 /*
977 * See if we've run into mirroring yet
978 */
979
980 if (guspeek(iot, ioh2, 0L) != 0)
981 break;
982
983 loc = i << 10;
984
985 guspoke(iot, ioh2, loc, 0xaa);
986 if (guspeek(iot, ioh2, loc) != 0xaa)
987 break;
988 }
989
990 sc->sc_dsize = i;
991 sprintf(gus_device.version, "3.%d", sc->sc_revision);
992
993 printf("\n <Gravis UltraSound version 3.%d, %dKB DRAM, ",
994 sc->sc_revision, sc->sc_dsize);
995 if (HAS_MIXER(sc))
996 printf("ICS2101 mixer, ");
997 if (HAS_CODEC(sc))
998 printf("%s codec/mixer, ", sc->sc_codec.chip_name);
999 if (sc->sc_recdrq == sc->sc_drq) {
1000 printf("half-duplex");
1001 } else {
1002 printf("full-duplex, record drq %d", sc->sc_recdrq);
1003 }
1004
1005 printf(">\n");
1006
1007 /*
1008 * Setup a default interrupt handler
1009 */
1010
1011 /* XXX we shouldn't have to use splgus == splclock, nor should
1012 * we use IPL_CLOCK.
1013 */
1014 sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq, IST_EDGE,
1015 IPL_AUDIO, gusintr, sc /* sc->sc_gusdsp */);
1016
1017 /*
1018 * Set some default values
1019 * XXX others start with 8kHz mono mulaw
1020 */
1021
1022 sc->sc_irate = sc->sc_orate = 44100;
1023 sc->sc_encoding = AUDIO_ENCODING_SLINEAR_LE;
1024 sc->sc_precision = 16;
1025 sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_DATA_SIZE16;
1026 sc->sc_voc[GUS_VOICE_RIGHT].voccntl |= GUSMASK_DATA_SIZE16;
1027 sc->sc_channels = 1;
1028 sc->sc_ogain = 340;
1029 gus_commit_settings(sc);
1030
1031 /*
1032 * We always put the left channel full left & right channel
1033 * full right.
1034 * For mono playback, we set up both voices playing the same buffer.
1035 */
1036 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) GUS_VOICE_LEFT);
1037 SELECT_GUS_REG(iot, ioh2, GUSREG_PAN_POS);
1038 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, GUS_PAN_FULL_LEFT);
1039
1040 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) GUS_VOICE_RIGHT);
1041 SELECT_GUS_REG(iot, ioh2, GUSREG_PAN_POS);
1042 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, GUS_PAN_FULL_RIGHT);
1043
1044 /*
1045 * Attach to the generic audio layer
1046 */
1047
1048 audio_attach_mi(&gus_hw_if, 0, HAS_CODEC(sc) ? (void *)&sc->sc_codec : (void *)sc, &sc->sc_dev);
1049 }
1050
1051 int
1052 gusopen(addr, flags)
1053 void *addr;
1054 int flags;
1055 {
1056 struct gus_softc *sc = addr;
1057
1058 DPRINTF(("gusopen() called\n"));
1059
1060 if (sc->sc_flags & GUS_OPEN)
1061 return EBUSY;
1062
1063 /*
1064 * Some initialization
1065 */
1066
1067 sc->sc_flags |= GUS_OPEN;
1068 sc->sc_dmabuf = 0;
1069 sc->sc_playbuf = -1;
1070 sc->sc_bufcnt = 0;
1071 sc->sc_voc[GUS_VOICE_LEFT].start_addr = GUS_MEM_OFFSET - 1;
1072 sc->sc_voc[GUS_VOICE_LEFT].current_addr = GUS_MEM_OFFSET;
1073
1074 if (HAS_CODEC(sc)) {
1075 ad1848_open(&sc->sc_codec, flags);
1076 sc->sc_codec.aux1_mute = 0;
1077 ad1848_mute_aux1(&sc->sc_codec, 0); /* turn on DAC output */
1078 if (flags & FREAD) {
1079 sc->sc_codec.mono_mute = 0;
1080 cs4231_mute_mono(&sc->sc_codec, 0);
1081 }
1082 } else if (flags & FREAD) {
1083 /* enable/unmute the microphone */
1084 if (HAS_MIXER(sc)) {
1085 gusics_mic_mute(&sc->sc_mixer, 0);
1086 } else
1087 gus_mic_ctl(sc, SPKR_ON);
1088 }
1089 if (sc->sc_nbufs == 0)
1090 gus_round_blocksize(sc, GUS_BUFFER_MULTIPLE); /* default blksiz */
1091 return 0;
1092 }
1093
1094 int
1095 gusmaxopen(addr, flags)
1096 void *addr;
1097 int flags;
1098 {
1099 struct ad1848_softc *ac = addr;
1100 return gusopen(ac->parent, flags);
1101 }
1102
1103 STATIC void
1104 gus_deinterleave(sc, buf, size)
1105 struct gus_softc *sc;
1106 void *buf;
1107 int size;
1108 {
1109 /* deinterleave the stereo data. We can use sc->sc_deintr_buf
1110 for scratch space. */
1111 int i;
1112
1113 if (size > sc->sc_blocksize) {
1114 printf("gus: deinterleave %d > %d\n", size, sc->sc_blocksize);
1115 return;
1116 } else if (size < sc->sc_blocksize) {
1117 DPRINTF(("gus: deinterleave %d < %d\n", size, sc->sc_blocksize));
1118 }
1119
1120 /*
1121 * size is in bytes.
1122 */
1123 if (sc->sc_precision == 16) {
1124 u_short *dei = sc->sc_deintr_buf;
1125 u_short *sbuf = buf;
1126 size >>= 1; /* bytecnt to shortcnt */
1127 /* copy 2nd of each pair of samples to the staging area, while
1128 compacting the 1st of each pair into the original area. */
1129 for (i = 0; i < size/2-1; i++) {
1130 dei[i] = sbuf[i*2+1];
1131 sbuf[i+1] = sbuf[i*2+2];
1132 }
1133 /*
1134 * this has copied one less sample than half of the
1135 * buffer. The first sample of the 1st stream was
1136 * already in place and didn't need copying.
1137 * Therefore, we've moved all of the 1st stream's
1138 * samples into place. We have one sample from 2nd
1139 * stream in the last slot of original area, not
1140 * copied to the staging area (But we don't need to!).
1141 * Copy the remainder of the original stream into place.
1142 */
1143 bcopy(dei, &sbuf[size/2], i * sizeof(short));
1144 } else {
1145 u_char *dei = sc->sc_deintr_buf;
1146 u_char *sbuf = buf;
1147 for (i = 0; i < size/2-1; i++) {
1148 dei[i] = sbuf[i*2+1];
1149 sbuf[i+1] = sbuf[i*2+2];
1150 }
1151 bcopy(dei, &sbuf[size/2], i);
1152 }
1153 }
1154
1155 /*
1156 * Actually output a buffer to the DSP chip
1157 */
1158
1159 int
1160 gusmax_dma_output(addr, buf, size, intr, arg)
1161 void * addr;
1162 void *buf;
1163 int size;
1164 void (*intr) __P((void *));
1165 void *arg;
1166 {
1167 struct ad1848_softc *ac = addr;
1168 return gus_dma_output(ac->parent, buf, size, intr, arg);
1169 }
1170
1171 /*
1172 * called at splgus() from interrupt handler.
1173 */
1174 void
1175 stereo_dmaintr(arg)
1176 void *arg;
1177 {
1178 struct gus_softc *sc = arg;
1179 struct stereo_dma_intr *sa = &sc->sc_stereo;
1180
1181 DMAPRINTF(("stereo_dmaintr"));
1182
1183 /*
1184 * Put other half in its place, then call the real interrupt routine :)
1185 */
1186
1187 sc->sc_dmaoutintr = sa->intr;
1188 sc->sc_outarg = sa->arg;
1189
1190 #ifdef GUSPLAYDEBUG
1191 if (gusstats) {
1192 microtime(&dmarecords[dmarecord_index].tv);
1193 dmarecords[dmarecord_index].gusaddr = sa->dmabuf;
1194 dmarecords[dmarecord_index].bsdaddr = sa->buffer;
1195 dmarecords[dmarecord_index].count = sa->size;
1196 dmarecords[dmarecord_index].channel = 1;
1197 dmarecords[dmarecord_index].direction = 1;
1198 dmarecord_index = ++dmarecord_index % NDMARECS;
1199 }
1200 #endif
1201
1202 gusdmaout(sc, sa->flags, sa->dmabuf, (caddr_t) sa->buffer, sa->size);
1203
1204 sa->flags = 0;
1205 sa->dmabuf = 0;
1206 sa->buffer = 0;
1207 sa->size = 0;
1208 sa->intr = 0;
1209 sa->arg = 0;
1210 }
1211
1212 /*
1213 * Start up DMA output to the card.
1214 * Called at splgus/splaudio already, either from intr handler or from
1215 * generic audio code.
1216 */
1217 int
1218 gus_dma_output(addr, buf, size, intr, arg)
1219 void * addr;
1220 void *buf;
1221 int size;
1222 void (*intr) __P((void *));
1223 void *arg;
1224 {
1225 struct gus_softc *sc = addr;
1226 u_char *buffer = buf;
1227 u_long boarddma;
1228 int flags;
1229
1230 DMAPRINTF(("gus_dma_output %d @ %p\n", size, buf));
1231
1232 if (size != sc->sc_blocksize) {
1233 DPRINTF(("gus_dma_output reqsize %d not sc_blocksize %d\n",
1234 size, sc->sc_blocksize));
1235 return EINVAL;
1236 }
1237
1238 flags = GUSMASK_DMA_WRITE;
1239 if (sc->sc_precision == 16)
1240 flags |= GUSMASK_DMA_DATA_SIZE;
1241 if (sc->sc_encoding == AUDIO_ENCODING_ULAW ||
1242 sc->sc_encoding == AUDIO_ENCODING_ALAW ||
1243 sc->sc_encoding == AUDIO_ENCODING_ULINEAR_BE ||
1244 sc->sc_encoding == AUDIO_ENCODING_ULINEAR_LE)
1245 flags |= GUSMASK_DMA_INVBIT;
1246
1247 if (sc->sc_channels == 2) {
1248 if (sc->sc_precision == 16) {
1249 if (size & 3) {
1250 DPRINTF(("gus_dma_output: unpaired 16bit samples"));
1251 size &= 3;
1252 }
1253 } else if (size & 1) {
1254 DPRINTF(("gus_dma_output: unpaired samples"));
1255 size &= 1;
1256 }
1257 if (size == 0)
1258 return 0;
1259
1260 gus_deinterleave(sc, (void *)buffer, size);
1261
1262 size >>= 1;
1263
1264 boarddma = size * sc->sc_dmabuf + GUS_MEM_OFFSET;
1265
1266 sc->sc_stereo.intr = intr;
1267 sc->sc_stereo.arg = arg;
1268 sc->sc_stereo.size = size;
1269 sc->sc_stereo.dmabuf = boarddma + GUS_LEFT_RIGHT_OFFSET;
1270 sc->sc_stereo.buffer = buffer + size;
1271 sc->sc_stereo.flags = flags;
1272 if (gus_dostereo) {
1273 intr = stereo_dmaintr;
1274 arg = sc;
1275 }
1276 } else
1277 boarddma = size * sc->sc_dmabuf + GUS_MEM_OFFSET;
1278
1279
1280 sc->sc_flags |= GUS_LOCKED;
1281 sc->sc_dmaoutintr = intr;
1282 sc->sc_outarg = arg;
1283
1284 #ifdef GUSPLAYDEBUG
1285 if (gusstats) {
1286 microtime(&dmarecords[dmarecord_index].tv);
1287 dmarecords[dmarecord_index].gusaddr = boarddma;
1288 dmarecords[dmarecord_index].bsdaddr = buffer;
1289 dmarecords[dmarecord_index].count = size;
1290 dmarecords[dmarecord_index].channel = 0;
1291 dmarecords[dmarecord_index].direction = 1;
1292 dmarecord_index = ++dmarecord_index % NDMARECS;
1293 }
1294 #endif
1295
1296 gusdmaout(sc, flags, boarddma, (caddr_t) buffer, size);
1297
1298 return 0;
1299 }
1300
1301 void
1302 gusmax_close(addr)
1303 void *addr;
1304 {
1305 struct ad1848_softc *ac = addr;
1306 struct gus_softc *sc = ac->parent;
1307 #if 0
1308 ac->aux1_mute = 1;
1309 ad1848_mute_aux1(ac, 1); /* turn off DAC output */
1310 #endif
1311 ad1848_close(ac);
1312 gusclose(sc);
1313 }
1314
1315 /*
1316 * Close out device stuff. Called at splgus() from generic audio layer.
1317 */
1318 void
1319 gusclose(addr)
1320 void *addr;
1321 {
1322 struct gus_softc *sc = addr;
1323
1324 DPRINTF(("gus_close: sc=%p\n", sc));
1325
1326
1327 /* if (sc->sc_flags & GUS_DMAOUT_ACTIVE) */ {
1328 gus_halt_out_dma(sc);
1329 }
1330 /* if (sc->sc_flags & GUS_DMAIN_ACTIVE) */ {
1331 gus_halt_in_dma(sc);
1332 }
1333 sc->sc_flags &= ~(GUS_OPEN|GUS_LOCKED|GUS_DMAOUT_ACTIVE|GUS_DMAIN_ACTIVE);
1334
1335 if (sc->sc_deintr_buf) {
1336 FREE(sc->sc_deintr_buf, M_DEVBUF);
1337 sc->sc_deintr_buf = NULL;
1338 }
1339 /* turn off speaker, etc. */
1340
1341 /* make sure the voices shut up: */
1342 gus_stop_voice(sc, GUS_VOICE_LEFT, 1);
1343 gus_stop_voice(sc, GUS_VOICE_RIGHT, 0);
1344 }
1345
1346 /*
1347 * Service interrupts. Farm them off to helper routines if we are using the
1348 * GUS for simple playback/record
1349 */
1350
1351 #ifdef DIAGNOSTIC
1352 int gusintrcnt;
1353 int gusdmaintrcnt;
1354 int gusvocintrcnt;
1355 #endif
1356
1357 int
1358 gusintr(arg)
1359 void *arg;
1360 {
1361 struct gus_softc *sc = arg;
1362 bus_space_tag_t iot = sc->sc_iot;
1363 bus_space_handle_t ioh1 = sc->sc_ioh1;
1364 bus_space_handle_t ioh2 = sc->sc_ioh2;
1365 unsigned char intr;
1366
1367 int retval = 0;
1368
1369 DPRINTF(("gusintr\n"));
1370 #ifdef DIAGNOSTIC
1371 gusintrcnt++;
1372 #endif
1373 if (HAS_CODEC(sc))
1374 retval = ad1848_intr(&sc->sc_codec);
1375 if ((intr = bus_space_read_1(iot, ioh1, GUS_IRQ_STATUS)) & GUSMASK_IRQ_DMATC) {
1376 DMAPRINTF(("gusintr dma flags=%x\n", sc->sc_flags));
1377 #ifdef DIAGNOSTIC
1378 gusdmaintrcnt++;
1379 #endif
1380 retval += gus_dmaout_intr(sc);
1381 if (sc->sc_flags & GUS_DMAIN_ACTIVE) {
1382 SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
1383 intr = bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
1384 if (intr & GUSMASK_SAMPLE_DMATC) {
1385 retval += gus_dmain_intr(sc);
1386 }
1387 }
1388 }
1389 if (intr & (GUSMASK_IRQ_VOICE | GUSMASK_IRQ_VOLUME)) {
1390 DMAPRINTF(("gusintr voice flags=%x\n", sc->sc_flags));
1391 #ifdef DIAGNOSTIC
1392 gusvocintrcnt++;
1393 #endif
1394 retval += gus_voice_intr(sc);
1395 }
1396 if (retval)
1397 return 1;
1398 return retval;
1399 }
1400
1401 int gus_bufcnt[GUS_MEM_FOR_BUFFERS / GUS_BUFFER_MULTIPLE];
1402 int gus_restart; /* how many restarts? */
1403 int gus_stops; /* how many times did voice stop? */
1404 int gus_falsestops; /* stopped but not done? */
1405 int gus_continues;
1406
1407 struct playcont {
1408 struct timeval tv;
1409 u_int playbuf;
1410 u_int dmabuf;
1411 u_char bufcnt;
1412 u_char vaction;
1413 u_char voccntl;
1414 u_char volcntl;
1415 u_long curaddr;
1416 u_long endaddr;
1417 } playstats[NDMARECS];
1418
1419 int playcntr;
1420
1421 STATIC void
1422 gus_dmaout_timeout(arg)
1423 void *arg;
1424 {
1425 struct gus_softc *sc = arg;
1426 bus_space_tag_t iot = sc->sc_iot;
1427 bus_space_handle_t ioh2 = sc->sc_ioh2;
1428 int s;
1429
1430 printf("%s: dmaout timeout\n", sc->sc_dev.dv_xname);
1431 /*
1432 * Stop any DMA.
1433 */
1434
1435 s = splgus();
1436 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
1437 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0);
1438
1439 #if 0
1440 /* XXX we will dmadone below? */
1441 isa_dmaabort(sc->sc_dev.dv_parent, sc->sc_drq);
1442 #endif
1443
1444 gus_dmaout_dointr(sc);
1445 splx(s);
1446 }
1447
1448
1449 /*
1450 * Service DMA interrupts. This routine will only get called if we're doing
1451 * a DMA transfer for playback/record requests from the audio layer.
1452 */
1453
1454 STATIC int
1455 gus_dmaout_intr(sc)
1456 struct gus_softc *sc;
1457 {
1458 bus_space_tag_t iot = sc->sc_iot;
1459 bus_space_handle_t ioh2 = sc->sc_ioh2;
1460
1461 /*
1462 * If we got a DMA transfer complete from the GUS DRAM, then deal
1463 * with it.
1464 */
1465
1466 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
1467 if (bus_space_read_1(iot, ioh2, GUS_DATA_HIGH) & GUSMASK_DMA_IRQPEND) {
1468 untimeout(gus_dmaout_timeout, sc);
1469 gus_dmaout_dointr(sc);
1470 return 1;
1471 }
1472 return 0;
1473 }
1474
1475 STATIC void
1476 gus_dmaout_dointr(sc)
1477 struct gus_softc *sc;
1478 {
1479 bus_space_tag_t iot = sc->sc_iot;
1480 bus_space_handle_t ioh2 = sc->sc_ioh2;
1481
1482 /* sc->sc_dmaoutcnt - 1 because DMA controller counts from zero?. */
1483 isa_dmadone(sc->sc_dev.dv_parent, sc->sc_drq);
1484 sc->sc_flags &= ~GUS_DMAOUT_ACTIVE; /* pending DMA is done */
1485 DMAPRINTF(("gus_dmaout_dointr %d @ %p\n", sc->sc_dmaoutcnt,
1486 sc->sc_dmaoutaddr));
1487
1488 /*
1489 * to prevent clicking, we need to copy last sample
1490 * from last buffer to scratch area just before beginning of
1491 * buffer. However, if we're doing formats that are converted by
1492 * the card during the DMA process, we need to pick up the converted
1493 * byte rather than the one we have in memory.
1494 */
1495 if (sc->sc_dmabuf == sc->sc_nbufs - 1) {
1496 int i;
1497 switch (sc->sc_encoding) {
1498 case AUDIO_ENCODING_SLINEAR_LE:
1499 case AUDIO_ENCODING_SLINEAR_BE:
1500 if (sc->sc_precision == 8)
1501 goto byte;
1502 /* we have the native format */
1503 for (i = 1; i <= 2; i++)
1504 guspoke(iot, ioh2, sc->sc_gusaddr -
1505 (sc->sc_nbufs - 1) * sc->sc_chanblocksize - i,
1506 sc->sc_dmaoutaddr[sc->sc_dmaoutcnt-i]);
1507 break;
1508 case AUDIO_ENCODING_ULINEAR_LE:
1509 case AUDIO_ENCODING_ULINEAR_BE:
1510 guspoke(iot, ioh2, sc->sc_gusaddr -
1511 (sc->sc_nbufs - 1) * sc->sc_chanblocksize - 2,
1512 guspeek(iot, ioh2,
1513 sc->sc_gusaddr + sc->sc_chanblocksize - 2));
1514 case AUDIO_ENCODING_ALAW:
1515 case AUDIO_ENCODING_ULAW:
1516 byte:
1517 /* we need to fetch the translated byte, then stuff it. */
1518 guspoke(iot, ioh2, sc->sc_gusaddr -
1519 (sc->sc_nbufs - 1) * sc->sc_chanblocksize - 1,
1520 guspeek(iot, ioh2,
1521 sc->sc_gusaddr + sc->sc_chanblocksize - 1));
1522 break;
1523 }
1524 }
1525 /*
1526 * If this is the first half of stereo, "ignore" this one
1527 * and copy out the second half.
1528 */
1529 if (sc->sc_dmaoutintr == stereo_dmaintr) {
1530 (*sc->sc_dmaoutintr)(sc->sc_outarg);
1531 return;
1532 }
1533 /*
1534 * If the voice is stopped, then start it. Reset the loop
1535 * and roll bits. Call the audio layer routine, since if
1536 * we're starting a stopped voice, that means that the next
1537 * buffer can be filled
1538 */
1539
1540 sc->sc_flags &= ~GUS_LOCKED;
1541 if (sc->sc_voc[GUS_VOICE_LEFT].voccntl &
1542 GUSMASK_VOICE_STOPPED) {
1543 if (sc->sc_flags & GUS_PLAYING) {
1544 printf("%s: playing yet stopped?\n", sc->sc_dev.dv_xname);
1545 }
1546 sc->sc_bufcnt++; /* another yet to be played */
1547 gus_start_playing(sc, sc->sc_dmabuf);
1548 gus_restart++;
1549 } else {
1550 /*
1551 * set the sound action based on which buffer we
1552 * just transferred. If we just transferred buffer 0
1553 * we want the sound to loop when it gets to the nth
1554 * buffer; if we just transferred
1555 * any other buffer, we want the sound to roll over
1556 * at least one more time. The voice interrupt
1557 * handlers will take care of accounting &
1558 * setting control bits if it's not caught up to us
1559 * yet.
1560 */
1561 if (++sc->sc_bufcnt == 2) {
1562 /*
1563 * XXX
1564 * If we're too slow in reaction here,
1565 * the voice could be just approaching the
1566 * end of its run. It should be set to stop,
1567 * so these adjustments might not DTRT.
1568 */
1569 if (sc->sc_dmabuf == 0 &&
1570 sc->sc_playbuf == sc->sc_nbufs - 1) {
1571 /* player is just at the last buf, we're at the
1572 first. Turn on looping, turn off rolling. */
1573 sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_LOOP_ENABLE;
1574 sc->sc_voc[GUS_VOICE_LEFT].volcntl &= ~GUSMASK_VOICE_ROLL;
1575 playstats[playcntr].vaction = 3;
1576 } else {
1577 /* player is at previous buf:
1578 turn on rolling, turn off looping */
1579 sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~GUSMASK_LOOP_ENABLE;
1580 sc->sc_voc[GUS_VOICE_LEFT].volcntl |= GUSMASK_VOICE_ROLL;
1581 playstats[playcntr].vaction = 4;
1582 }
1583 #ifdef GUSPLAYDEBUG
1584 if (gusstats) {
1585 microtime(&playstats[playcntr].tv);
1586 playstats[playcntr].endaddr = sc->sc_voc[GUS_VOICE_LEFT].end_addr;
1587 playstats[playcntr].voccntl = sc->sc_voc[GUS_VOICE_LEFT].voccntl;
1588 playstats[playcntr].volcntl = sc->sc_voc[GUS_VOICE_LEFT].volcntl;
1589 playstats[playcntr].playbuf = sc->sc_playbuf;
1590 playstats[playcntr].dmabuf = sc->sc_dmabuf;
1591 playstats[playcntr].bufcnt = sc->sc_bufcnt;
1592 playstats[playcntr].curaddr = gus_get_curaddr(sc, GUS_VOICE_LEFT);
1593 playcntr = ++playcntr % NDMARECS;
1594 }
1595 #endif
1596 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, GUS_VOICE_LEFT);
1597 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
1598 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_LEFT].voccntl);
1599 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
1600 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_LEFT].volcntl);
1601 }
1602 }
1603 gus_bufcnt[sc->sc_bufcnt-1]++;
1604 /*
1605 * flip to the next DMA buffer
1606 */
1607
1608 sc->sc_dmabuf = ++sc->sc_dmabuf % sc->sc_nbufs;
1609 /*
1610 * See comments below about DMA admission control strategy.
1611 * We can call the upper level here if we have an
1612 * idle buffer (not currently playing) to DMA into.
1613 */
1614 if (sc->sc_dmaoutintr && sc->sc_bufcnt < sc->sc_nbufs) {
1615 /* clean out to prevent double calls */
1616 void (*pfunc) __P((void *)) = sc->sc_dmaoutintr;
1617 void *arg = sc->sc_outarg;
1618
1619 sc->sc_outarg = 0;
1620 sc->sc_dmaoutintr = 0;
1621 (*pfunc)(arg);
1622 }
1623 }
1624
1625 /*
1626 * Service voice interrupts
1627 */
1628
1629 STATIC int
1630 gus_voice_intr(sc)
1631 struct gus_softc *sc;
1632 {
1633 bus_space_tag_t iot = sc->sc_iot;
1634 bus_space_handle_t ioh2 = sc->sc_ioh2;
1635 int ignore = 0, voice, rval = 0;
1636 unsigned char intr, status;
1637
1638 /*
1639 * The point of this may not be obvious at first. A voice can
1640 * interrupt more than once; according to the GUS SDK we are supposed
1641 * to ignore multiple interrupts for the same voice.
1642 */
1643
1644 while(1) {
1645 SELECT_GUS_REG(iot, ioh2, GUSREG_IRQ_STATUS);
1646 intr = bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
1647
1648 if ((intr & (GUSMASK_WIRQ_VOLUME | GUSMASK_WIRQ_VOICE))
1649 == (GUSMASK_WIRQ_VOLUME | GUSMASK_WIRQ_VOICE))
1650 /*
1651 * No more interrupts, time to return
1652 */
1653 return rval;
1654
1655 if ((intr & GUSMASK_WIRQ_VOICE) == 0) {
1656
1657 /*
1658 * We've got a voice interrupt. Ignore previous
1659 * interrupts by the same voice.
1660 */
1661
1662 rval = 1;
1663 voice = intr & GUSMASK_WIRQ_VOICEMASK;
1664
1665 if ((1 << voice) & ignore)
1666 break;
1667
1668 ignore |= 1 << voice;
1669
1670 /*
1671 * If the voice is stopped, then force it to stop
1672 * (this stops it from continuously generating IRQs)
1673 */
1674
1675 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL+0x80);
1676 status = bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
1677 if (status & GUSMASK_VOICE_STOPPED) {
1678 if (voice != GUS_VOICE_LEFT) {
1679 DMAPRINTF(("%s: spurious voice %d stop?\n",
1680 sc->sc_dev.dv_xname, voice));
1681 gus_stop_voice(sc, voice, 0);
1682 continue;
1683 }
1684 gus_stop_voice(sc, voice, 1);
1685 /* also kill right voice */
1686 gus_stop_voice(sc, GUS_VOICE_RIGHT, 0);
1687 sc->sc_bufcnt--; /* it finished a buffer */
1688 if (sc->sc_bufcnt > 0) {
1689 /*
1690 * probably a race to get here: the voice
1691 * stopped while the DMA code was just trying to
1692 * get the next buffer in place.
1693 * Start the voice again.
1694 */
1695 printf("%s: stopped voice not drained? (%x)\n",
1696 sc->sc_dev.dv_xname, sc->sc_bufcnt);
1697 gus_falsestops++;
1698
1699 sc->sc_playbuf = ++sc->sc_playbuf % sc->sc_nbufs;
1700 gus_start_playing(sc, sc->sc_playbuf);
1701 } else if (sc->sc_bufcnt < 0) {
1702 #ifdef DDB
1703 printf("%s: negative bufcnt in stopped voice\n",
1704 sc->sc_dev.dv_xname);
1705 Debugger();
1706 #else
1707 panic("%s: negative bufcnt in stopped voice",
1708 sc->sc_dev.dv_xname);
1709 #endif
1710 } else {
1711 sc->sc_playbuf = -1; /* none are active */
1712 gus_stops++;
1713 }
1714 /* fall through to callback and admit another
1715 buffer.... */
1716 } else if (sc->sc_bufcnt != 0) {
1717 /*
1718 * This should always be taken if the voice
1719 * is not stopped.
1720 */
1721 gus_continues++;
1722 if (gus_continue_playing(sc, voice)) {
1723 /*
1724 * we shouldn't have continued--active DMA
1725 * is in the way in the ring, for
1726 * some as-yet undebugged reason.
1727 */
1728 gus_stop_voice(sc, GUS_VOICE_LEFT, 1);
1729 /* also kill right voice */
1730 gus_stop_voice(sc, GUS_VOICE_RIGHT, 0);
1731 sc->sc_playbuf = -1;
1732 gus_stops++;
1733 }
1734 }
1735 /*
1736 * call the upper level to send on down another
1737 * block. We do admission rate control as follows:
1738 *
1739 * When starting up output (in the first N
1740 * blocks), call the upper layer after the DMA is
1741 * complete (see above in gus_dmaout_intr()).
1742 *
1743 * When output is already in progress and we have
1744 * no more GUS buffers to use for DMA, the DMA
1745 * output routines do not call the upper layer.
1746 * Instead, we call the DMA completion routine
1747 * here, after the voice interrupts indicating
1748 * that it's finished with a buffer.
1749 *
1750 * However, don't call anything here if the DMA
1751 * output flag is set, (which shouldn't happen)
1752 * because we'll squish somebody else's DMA if
1753 * that's the case. When DMA is done, it will
1754 * call back if there is a spare buffer.
1755 */
1756 if (sc->sc_dmaoutintr && !(sc->sc_flags & GUS_LOCKED)) {
1757 if (sc->sc_dmaoutintr == stereo_dmaintr)
1758 printf("gusdmaout botch?\n");
1759 else {
1760 /* clean out to avoid double calls */
1761 void (*pfunc) __P((void *)) = sc->sc_dmaoutintr;
1762 void *arg = sc->sc_outarg;
1763
1764 sc->sc_outarg = 0;
1765 sc->sc_dmaoutintr = 0;
1766 (*pfunc)(arg);
1767 }
1768 }
1769 }
1770
1771 /*
1772 * Ignore other interrupts for now
1773 */
1774 }
1775 return 0;
1776 }
1777
1778 STATIC void
1779 gus_start_playing(sc, bufno)
1780 struct gus_softc *sc;
1781 int bufno;
1782 {
1783 bus_space_tag_t iot = sc->sc_iot;
1784 bus_space_handle_t ioh2 = sc->sc_ioh2;
1785 /*
1786 * Start the voices playing, with buffer BUFNO.
1787 */
1788
1789 /*
1790 * Loop or roll if we have buffers ready.
1791 */
1792
1793 if (sc->sc_bufcnt == 1) {
1794 sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~(GUSMASK_LOOP_ENABLE);
1795 sc->sc_voc[GUS_VOICE_LEFT].volcntl &= ~(GUSMASK_VOICE_ROLL);
1796 } else {
1797 if (bufno == sc->sc_nbufs - 1) {
1798 sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_LOOP_ENABLE;
1799 sc->sc_voc[GUS_VOICE_LEFT].volcntl &= ~(GUSMASK_VOICE_ROLL);
1800 } else {
1801 sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~GUSMASK_LOOP_ENABLE;
1802 sc->sc_voc[GUS_VOICE_LEFT].volcntl |= GUSMASK_VOICE_ROLL;
1803 }
1804 }
1805
1806 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, GUS_VOICE_LEFT);
1807
1808 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
1809 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_LEFT].voccntl);
1810
1811 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
1812 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_LEFT].volcntl);
1813
1814 sc->sc_voc[GUS_VOICE_LEFT].current_addr =
1815 GUS_MEM_OFFSET + sc->sc_chanblocksize * bufno;
1816 sc->sc_voc[GUS_VOICE_LEFT].end_addr =
1817 sc->sc_voc[GUS_VOICE_LEFT].current_addr + sc->sc_chanblocksize - 1;
1818 sc->sc_voc[GUS_VOICE_RIGHT].current_addr =
1819 sc->sc_voc[GUS_VOICE_LEFT].current_addr +
1820 (gus_dostereo && sc->sc_channels == 2 ? GUS_LEFT_RIGHT_OFFSET : 0);
1821 /*
1822 * set up right channel to just loop forever, no interrupts,
1823 * starting at the buffer we just filled. We'll feed it data
1824 * at the same time as left channel.
1825 */
1826 sc->sc_voc[GUS_VOICE_RIGHT].voccntl |= GUSMASK_LOOP_ENABLE;
1827 sc->sc_voc[GUS_VOICE_RIGHT].volcntl &= ~(GUSMASK_VOICE_ROLL);
1828
1829 #ifdef GUSPLAYDEBUG
1830 if (gusstats) {
1831 microtime(&playstats[playcntr].tv);
1832 playstats[playcntr].curaddr = sc->sc_voc[GUS_VOICE_LEFT].current_addr;
1833
1834 playstats[playcntr].voccntl = sc->sc_voc[GUS_VOICE_LEFT].voccntl;
1835 playstats[playcntr].volcntl = sc->sc_voc[GUS_VOICE_LEFT].volcntl;
1836 playstats[playcntr].endaddr = sc->sc_voc[GUS_VOICE_LEFT].end_addr;
1837 playstats[playcntr].playbuf = bufno;
1838 playstats[playcntr].dmabuf = sc->sc_dmabuf;
1839 playstats[playcntr].bufcnt = sc->sc_bufcnt;
1840 playstats[playcntr].vaction = 5;
1841 playcntr = ++playcntr % NDMARECS;
1842 }
1843 #endif
1844
1845 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, GUS_VOICE_RIGHT);
1846 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
1847 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_RIGHT].voccntl);
1848 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
1849 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_RIGHT].volcntl);
1850
1851 gus_start_voice(sc, GUS_VOICE_RIGHT, 0);
1852 gus_start_voice(sc, GUS_VOICE_LEFT, 1);
1853 if (sc->sc_playbuf == -1)
1854 /* mark start of playing */
1855 sc->sc_playbuf = bufno;
1856 }
1857
1858 STATIC int
1859 gus_continue_playing(sc, voice)
1860 struct gus_softc *sc;
1861 int voice;
1862 {
1863 bus_space_tag_t iot = sc->sc_iot;
1864 bus_space_handle_t ioh2 = sc->sc_ioh2;
1865
1866 /*
1867 * stop this voice from interrupting while we work.
1868 */
1869
1870 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
1871 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl & ~(GUSMASK_VOICE_IRQ));
1872
1873 /*
1874 * update playbuf to point to the buffer the hardware just started
1875 * playing
1876 */
1877 sc->sc_playbuf = ++sc->sc_playbuf % sc->sc_nbufs;
1878
1879 /*
1880 * account for buffer just finished
1881 */
1882 if (--sc->sc_bufcnt == 0) {
1883 DPRINTF(("gus: bufcnt 0 on continuing voice?\n"));
1884 }
1885 if (sc->sc_playbuf == sc->sc_dmabuf && (sc->sc_flags & GUS_LOCKED)) {
1886 printf("%s: continue into active dmabuf?\n", sc->sc_dev.dv_xname);
1887 return 1;
1888 }
1889
1890 /*
1891 * Select the end of the buffer based on the currently active
1892 * buffer, [plus extra contiguous buffers (if ready)].
1893 */
1894
1895 /*
1896 * set endpoint at end of buffer we just started playing.
1897 *
1898 * The total gets -1 because end addrs are one less than you might
1899 * think (the end_addr is the address of the last sample to play)
1900 */
1901 gus_set_endaddr(sc, voice, GUS_MEM_OFFSET +
1902 sc->sc_chanblocksize * (sc->sc_playbuf + 1) - 1);
1903
1904 if (sc->sc_bufcnt < 2) {
1905 /*
1906 * Clear out the loop and roll flags, and rotate the currently
1907 * playing buffer. That way, if we don't manage to get more
1908 * data before this buffer finishes, we'll just stop.
1909 */
1910 sc->sc_voc[voice].voccntl &= ~GUSMASK_LOOP_ENABLE;
1911 sc->sc_voc[voice].volcntl &= ~GUSMASK_VOICE_ROLL;
1912 playstats[playcntr].vaction = 0;
1913 } else {
1914 /*
1915 * We have some buffers to play. set LOOP if we're on the
1916 * last buffer in the ring, otherwise set ROLL.
1917 */
1918 if (sc->sc_playbuf == sc->sc_nbufs - 1) {
1919 sc->sc_voc[voice].voccntl |= GUSMASK_LOOP_ENABLE;
1920 sc->sc_voc[voice].volcntl &= ~GUSMASK_VOICE_ROLL;
1921 playstats[playcntr].vaction = 1;
1922 } else {
1923 sc->sc_voc[voice].voccntl &= ~GUSMASK_LOOP_ENABLE;
1924 sc->sc_voc[voice].volcntl |= GUSMASK_VOICE_ROLL;
1925 playstats[playcntr].vaction = 2;
1926 }
1927 }
1928 #ifdef GUSPLAYDEBUG
1929 if (gusstats) {
1930 microtime(&playstats[playcntr].tv);
1931 playstats[playcntr].curaddr = gus_get_curaddr(sc, voice);
1932
1933 playstats[playcntr].voccntl = sc->sc_voc[voice].voccntl;
1934 playstats[playcntr].volcntl = sc->sc_voc[voice].volcntl;
1935 playstats[playcntr].endaddr = sc->sc_voc[voice].end_addr;
1936 playstats[playcntr].playbuf = sc->sc_playbuf;
1937 playstats[playcntr].dmabuf = sc->sc_dmabuf;
1938 playstats[playcntr].bufcnt = sc->sc_bufcnt;
1939 playcntr = ++playcntr % NDMARECS;
1940 }
1941 #endif
1942
1943 /*
1944 * (re-)set voice parameters. This will reenable interrupts from this
1945 * voice.
1946 */
1947
1948 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
1949 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
1950 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
1951 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].volcntl);
1952 return 0;
1953 }
1954
1955 /*
1956 * Send/receive data into GUS's DRAM using DMA. Called at splgus()
1957 */
1958
1959 STATIC void
1960 gusdmaout(sc, flags, gusaddr, buffaddr, length)
1961 struct gus_softc *sc;
1962 int flags, length;
1963 u_long gusaddr;
1964 caddr_t buffaddr;
1965 {
1966 unsigned char c = (unsigned char) flags;
1967 bus_space_tag_t iot = sc->sc_iot;
1968 bus_space_handle_t ioh2 = sc->sc_ioh2;
1969
1970 DMAPRINTF(("gusdmaout flags=%x scflags=%x\n", flags, sc->sc_flags));
1971
1972 sc->sc_gusaddr = gusaddr;
1973
1974 /*
1975 * If we're using a 16 bit DMA channel, we have to jump through some
1976 * extra hoops; this includes translating the DRAM address a bit
1977 */
1978
1979 if (sc->sc_drq >= 4) {
1980 c |= GUSMASK_DMA_WIDTH;
1981 gusaddr = convert_to_16bit(gusaddr);
1982 }
1983
1984 /*
1985 * Add flag bits that we always set - fast DMA, enable IRQ
1986 */
1987
1988 c |= GUSMASK_DMA_ENABLE | GUSMASK_DMA_R0 | GUSMASK_DMA_IRQ;
1989
1990 /*
1991 * Make sure the GUS _isn't_ setup for DMA
1992 */
1993
1994 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
1995 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0);
1996
1997 /*
1998 * Tell the PC DMA controller to start doing DMA
1999 */
2000
2001 sc->sc_dmaoutaddr = (u_char *) buffaddr;
2002 sc->sc_dmaoutcnt = length;
2003 isa_dmastart(sc->sc_dev.dv_parent, sc->sc_drq, buffaddr, length,
2004 NULL, DMAMODE_WRITE, BUS_DMA_NOWAIT);
2005
2006 /*
2007 * Set up DMA address - use the upper 16 bits ONLY
2008 */
2009
2010 sc->sc_flags |= GUS_DMAOUT_ACTIVE;
2011
2012 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_START);
2013 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, (int) (gusaddr >> 4));
2014
2015 /*
2016 * Tell the GUS to start doing DMA
2017 */
2018
2019 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
2020 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, c);
2021
2022 /*
2023 * XXX If we don't finish in one second, give up...
2024 */
2025 untimeout(gus_dmaout_timeout, sc); /* flush old one, if there is one */
2026 timeout(gus_dmaout_timeout, sc, hz);
2027 }
2028
2029 /*
2030 * Start a voice playing on the GUS. Called from interrupt handler at
2031 * splgus().
2032 */
2033
2034 STATIC void
2035 gus_start_voice(sc, voice, intrs)
2036 struct gus_softc *sc;
2037 int voice;
2038 int intrs;
2039 {
2040 bus_space_tag_t iot = sc->sc_iot;
2041 bus_space_handle_t ioh2 = sc->sc_ioh2;
2042 u_long start;
2043 u_long current;
2044 u_long end;
2045
2046 /*
2047 * Pick all the values for the voice out of the gus_voice struct
2048 * and use those to program the voice
2049 */
2050
2051 start = sc->sc_voc[voice].start_addr;
2052 current = sc->sc_voc[voice].current_addr;
2053 end = sc->sc_voc[voice].end_addr;
2054
2055 /*
2056 * If we're using 16 bit data, mangle the addresses a bit
2057 */
2058
2059 if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16) {
2060 /* -1 on start so that we get onto sample boundary--other
2061 code always sets it for 1-byte rollover protection */
2062 start = convert_to_16bit(start-1);
2063 current = convert_to_16bit(current);
2064 end = convert_to_16bit(end);
2065 }
2066
2067 /*
2068 * Select the voice we want to use, and program the data addresses
2069 */
2070
2071 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
2072
2073 SELECT_GUS_REG(iot, ioh2, GUSREG_START_ADDR_HIGH);
2074 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(start));
2075 SELECT_GUS_REG(iot, ioh2, GUSREG_START_ADDR_LOW);
2076 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(start));
2077
2078 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH);
2079 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(current));
2080 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW);
2081 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(current));
2082
2083 SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_HIGH);
2084 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(end));
2085 SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_LOW);
2086 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(end));
2087
2088 /*
2089 * (maybe) enable interrupts, disable voice stopping
2090 */
2091
2092 if (intrs) {
2093 sc->sc_flags |= GUS_PLAYING; /* playing is about to start */
2094 sc->sc_voc[voice].voccntl |= GUSMASK_VOICE_IRQ;
2095 DMAPRINTF(("gus voice playing=%x\n", sc->sc_flags));
2096 } else
2097 sc->sc_voc[voice].voccntl &= ~GUSMASK_VOICE_IRQ;
2098 sc->sc_voc[voice].voccntl &= ~(GUSMASK_VOICE_STOPPED |
2099 GUSMASK_STOP_VOICE);
2100
2101 /*
2102 * Tell the GUS about it. Note that we're doing volume ramping here
2103 * from 0 up to the set volume to help reduce clicks.
2104 */
2105
2106 SELECT_GUS_REG(iot, ioh2, GUSREG_START_VOLUME);
2107 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
2108 SELECT_GUS_REG(iot, ioh2, GUSREG_END_VOLUME);
2109 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].current_volume >> 4);
2110 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME);
2111 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x00);
2112 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_RATE);
2113 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 63);
2114
2115 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
2116 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
2117 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
2118 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
2119 delay(50);
2120 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
2121 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
2122 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
2123 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
2124
2125 }
2126
2127 /*
2128 * Stop a given voice. called at splgus()
2129 */
2130
2131 STATIC void
2132 gus_stop_voice(sc, voice, intrs_too)
2133 struct gus_softc *sc;
2134 int voice;
2135 int intrs_too;
2136 {
2137 bus_space_tag_t iot = sc->sc_iot;
2138 bus_space_handle_t ioh2 = sc->sc_ioh2;
2139
2140 sc->sc_voc[voice].voccntl |= GUSMASK_VOICE_STOPPED |
2141 GUSMASK_STOP_VOICE;
2142 if (intrs_too) {
2143 sc->sc_voc[voice].voccntl &= ~(GUSMASK_VOICE_IRQ);
2144 /* no more DMA to do */
2145 sc->sc_flags &= ~GUS_PLAYING;
2146 }
2147 DMAPRINTF(("gusintr voice notplaying=%x\n", sc->sc_flags));
2148
2149 guspoke(iot, ioh2, 0L, 0);
2150
2151 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
2152
2153 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME);
2154 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2155 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
2156 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
2157 delay(100);
2158 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME);
2159 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2160 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
2161 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
2162
2163 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH);
2164 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2165 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW);
2166 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2167
2168 }
2169
2170
2171 /*
2172 * Set the volume of a given voice. Called at splgus().
2173 */
2174 STATIC void
2175 gus_set_volume(sc, voice, volume)
2176 struct gus_softc *sc;
2177 int voice, volume;
2178 {
2179 bus_space_tag_t iot = sc->sc_iot;
2180 bus_space_handle_t ioh2 = sc->sc_ioh2;
2181 unsigned int gusvol;
2182
2183 gusvol = gus_log_volumes[volume < 512 ? volume : 511];
2184
2185 sc->sc_voc[voice].current_volume = gusvol;
2186
2187 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
2188
2189 SELECT_GUS_REG(iot, ioh2, GUSREG_START_VOLUME);
2190 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (unsigned char) (gusvol >> 4));
2191
2192 SELECT_GUS_REG(iot, ioh2, GUSREG_END_VOLUME);
2193 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (unsigned char) (gusvol >> 4));
2194
2195 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME);
2196 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, gusvol << 4);
2197 delay(500);
2198 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, gusvol << 4);
2199
2200 }
2201
2202 /*
2203 * Interface to the audio layer.
2204 */
2205
2206 int
2207 gusmax_set_params(addr, setmode, usemode, p, r)
2208 void *addr;
2209 int setmode, usemode;
2210 struct audio_params *p, *r;
2211 {
2212 struct ad1848_softc *ac = addr;
2213 struct gus_softc *sc = ac->parent;
2214 int error;
2215
2216 error = ad1848_set_params(ac, setmode, usemode, p, r);
2217 if (error)
2218 return error;
2219 error = gus_set_params(sc, setmode, usemode, p, r);
2220 return error;
2221 }
2222
2223 int
2224 gus_set_params(addr, setmode, usemode, p, r)
2225 void *addr;
2226 int setmode, usemode;
2227 struct audio_params *p, *r;
2228 {
2229 struct gus_softc *sc = addr;
2230 int s;
2231
2232 switch (p->encoding) {
2233 case AUDIO_ENCODING_ULAW:
2234 case AUDIO_ENCODING_ALAW:
2235 case AUDIO_ENCODING_SLINEAR_LE:
2236 case AUDIO_ENCODING_ULINEAR_LE:
2237 case AUDIO_ENCODING_SLINEAR_BE:
2238 case AUDIO_ENCODING_ULINEAR_BE:
2239 break;
2240 default:
2241 return (EINVAL);
2242 }
2243
2244 s = splaudio();
2245
2246 if (p->precision == 8) {
2247 sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~GUSMASK_DATA_SIZE16;
2248 sc->sc_voc[GUS_VOICE_RIGHT].voccntl &= ~GUSMASK_DATA_SIZE16;
2249 } else {
2250 sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_DATA_SIZE16;
2251 sc->sc_voc[GUS_VOICE_RIGHT].voccntl |= GUSMASK_DATA_SIZE16;
2252 }
2253
2254 sc->sc_encoding = p->encoding;
2255 sc->sc_precision = p->precision;
2256 sc->sc_channels = p->channels;
2257
2258 splx(s);
2259
2260 if (p->sample_rate > gus_max_frequency[sc->sc_voices - GUS_MIN_VOICES])
2261 p->sample_rate = gus_max_frequency[sc->sc_voices - GUS_MIN_VOICES];
2262 if (setmode & AUMODE_RECORD)
2263 sc->sc_irate = p->sample_rate;
2264 if (setmode & AUMODE_PLAY)
2265 sc->sc_orate = p->sample_rate;
2266
2267 switch (p->encoding) {
2268 case AUDIO_ENCODING_ULAW:
2269 p->sw_code = mulaw_to_ulinear8;
2270 r->sw_code = ulinear8_to_mulaw;
2271 break;
2272 case AUDIO_ENCODING_ALAW:
2273 p->sw_code = alaw_to_ulinear8;
2274 r->sw_code = ulinear8_to_alaw;
2275 break;
2276 case AUDIO_ENCODING_ULINEAR_BE:
2277 case AUDIO_ENCODING_SLINEAR_BE:
2278 r->sw_code = p->sw_code = swap_bytes;
2279 break;
2280 }
2281
2282 return 0;
2283 }
2284
2285 /*
2286 * Interface to the audio layer - set the blocksize to the correct number
2287 * of units
2288 */
2289
2290 int
2291 gusmax_round_blocksize(addr, blocksize)
2292 void * addr;
2293 int blocksize;
2294 {
2295 struct ad1848_softc *ac = addr;
2296 struct gus_softc *sc = ac->parent;
2297
2298 /* blocksize = ad1848_round_blocksize(ac, blocksize);*/
2299 return gus_round_blocksize(sc, blocksize);
2300 }
2301
2302 int
2303 gus_round_blocksize(addr, blocksize)
2304 void * addr;
2305 int blocksize;
2306 {
2307 struct gus_softc *sc = addr;
2308
2309 DPRINTF(("gus_round_blocksize called\n"));
2310
2311 if ((sc->sc_encoding == AUDIO_ENCODING_ULAW ||
2312 sc->sc_encoding == AUDIO_ENCODING_ALAW) && blocksize > 32768)
2313 blocksize = 32768;
2314 else if (blocksize > 65536)
2315 blocksize = 65536;
2316
2317 if ((blocksize % GUS_BUFFER_MULTIPLE) != 0)
2318 blocksize = (blocksize / GUS_BUFFER_MULTIPLE + 1) *
2319 GUS_BUFFER_MULTIPLE;
2320
2321 /* set up temporary buffer to hold the deinterleave, if necessary
2322 for stereo output */
2323 if (sc->sc_deintr_buf) {
2324 FREE(sc->sc_deintr_buf, M_DEVBUF);
2325 sc->sc_deintr_buf = NULL;
2326 }
2327 MALLOC(sc->sc_deintr_buf, void *, blocksize>>1, M_DEVBUF, M_WAITOK);
2328
2329 sc->sc_blocksize = blocksize;
2330 /* multi-buffering not quite working yet. */
2331 sc->sc_nbufs = /*GUS_MEM_FOR_BUFFERS / blocksize*/ 2;
2332
2333 gus_set_chan_addrs(sc);
2334
2335 return blocksize;
2336 }
2337
2338 int
2339 gus_get_out_gain(addr)
2340 caddr_t addr;
2341 {
2342 struct gus_softc *sc = (struct gus_softc *) addr;
2343
2344 DPRINTF(("gus_get_out_gain called\n"));
2345 return sc->sc_ogain / 2;
2346 }
2347
2348 STATIC inline void gus_set_voices(sc, voices)
2349 struct gus_softc *sc;
2350 int voices;
2351 {
2352 bus_space_tag_t iot = sc->sc_iot;
2353 bus_space_handle_t ioh2 = sc->sc_ioh2;
2354 /*
2355 * Select the active number of voices
2356 */
2357
2358 SELECT_GUS_REG(iot, ioh2, GUSREG_ACTIVE_VOICES);
2359 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (voices-1) | 0xc0);
2360
2361 sc->sc_voices = voices;
2362 }
2363
2364 /*
2365 * Actually set the settings of various values on the card
2366 */
2367
2368 int
2369 gusmax_commit_settings(addr)
2370 void * addr;
2371 {
2372 struct ad1848_softc *ac = addr;
2373 struct gus_softc *sc = ac->parent;
2374 int error;
2375
2376 error = ad1848_commit_settings(ac);
2377 if (error)
2378 return error;
2379 return gus_commit_settings(sc);
2380 }
2381
2382 /*
2383 * Commit the settings. Called at normal IPL.
2384 */
2385 int
2386 gus_commit_settings(addr)
2387 void * addr;
2388 {
2389 struct gus_softc *sc = addr;
2390 int s;
2391
2392 DPRINTF(("gus_commit_settings called (gain = %d)\n",sc->sc_ogain));
2393
2394
2395 s = splgus();
2396
2397 gus_set_recrate(sc, sc->sc_irate);
2398 gus_set_volume(sc, GUS_VOICE_LEFT, sc->sc_ogain);
2399 gus_set_volume(sc, GUS_VOICE_RIGHT, sc->sc_ogain);
2400 gus_set_samprate(sc, GUS_VOICE_LEFT, sc->sc_orate);
2401 gus_set_samprate(sc, GUS_VOICE_RIGHT, sc->sc_orate);
2402 splx(s);
2403 gus_set_chan_addrs(sc);
2404
2405 return 0;
2406 }
2407
2408 STATIC void
2409 gus_set_chan_addrs(sc)
2410 struct gus_softc *sc;
2411 {
2412 /*
2413 * We use sc_nbufs * blocksize bytes of storage in the on-board GUS
2414 * ram.
2415 * For mono, each of the sc_nbufs buffers is DMA'd to in one chunk,
2416 * and both left & right channels play the same buffer.
2417 *
2418 * For stereo, each channel gets a contiguous half of the memory,
2419 * and each has sc_nbufs buffers of size blocksize/2.
2420 * Stereo data are deinterleaved in main memory before the DMA out
2421 * routines are called to queue the output.
2422 *
2423 * The blocksize per channel is kept in sc_chanblocksize.
2424 */
2425 if (sc->sc_channels == 2)
2426 sc->sc_chanblocksize = sc->sc_blocksize/2;
2427 else
2428 sc->sc_chanblocksize = sc->sc_blocksize;
2429
2430 sc->sc_voc[GUS_VOICE_LEFT].start_addr = GUS_MEM_OFFSET - 1;
2431 sc->sc_voc[GUS_VOICE_RIGHT].start_addr =
2432 (gus_dostereo && sc->sc_channels == 2 ? GUS_LEFT_RIGHT_OFFSET : 0)
2433 + GUS_MEM_OFFSET - 1;
2434 sc->sc_voc[GUS_VOICE_RIGHT].current_addr =
2435 sc->sc_voc[GUS_VOICE_RIGHT].start_addr + 1;
2436 sc->sc_voc[GUS_VOICE_RIGHT].end_addr =
2437 sc->sc_voc[GUS_VOICE_RIGHT].start_addr +
2438 sc->sc_nbufs * sc->sc_chanblocksize;
2439
2440 }
2441
2442 /*
2443 * Set the sample rate of the given voice. Called at splgus().
2444 */
2445
2446 STATIC void
2447 gus_set_samprate(sc, voice, freq)
2448 struct gus_softc *sc;
2449 int voice, freq;
2450 {
2451 bus_space_tag_t iot = sc->sc_iot;
2452 bus_space_handle_t ioh2 = sc->sc_ioh2;
2453 unsigned int fc;
2454 u_long temp, f = (u_long) freq;
2455
2456 /*
2457 * calculate fc based on the number of active voices;
2458 * we need to use longs to preserve enough bits
2459 */
2460
2461 temp = (u_long) gus_max_frequency[sc->sc_voices-GUS_MIN_VOICES];
2462
2463 fc = (unsigned int)(((f << 9L) + (temp >> 1L)) / temp);
2464
2465 fc <<= 1;
2466
2467
2468 /*
2469 * Program the voice frequency, and set it in the voice data record
2470 */
2471
2472 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
2473 SELECT_GUS_REG(iot, ioh2, GUSREG_FREQ_CONTROL);
2474 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, fc);
2475
2476 sc->sc_voc[voice].rate = freq;
2477
2478 }
2479
2480 /*
2481 * Set the sample rate of the recording frequency. Formula is from the GUS
2482 * SDK. Called at splgus().
2483 */
2484
2485 STATIC void
2486 gus_set_recrate(sc, rate)
2487 struct gus_softc *sc;
2488 u_long rate;
2489 {
2490 bus_space_tag_t iot = sc->sc_iot;
2491 bus_space_handle_t ioh2 = sc->sc_ioh2;
2492 u_char realrate;
2493 DPRINTF(("gus_set_recrate %lu\n", rate));
2494
2495 #if 0
2496 realrate = 9878400/(16*(rate+2)); /* formula from GUS docs */
2497 #endif
2498 realrate = (9878400 >> 4)/rate - 2; /* formula from code, sigh. */
2499
2500 SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_FREQ);
2501 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, realrate);
2502 }
2503
2504 /*
2505 * Interface to the audio layer - turn the output on or off. Note that some
2506 * of these bits are flipped in the register
2507 */
2508
2509 int
2510 gusmax_speaker_ctl(addr, newstate)
2511 void * addr;
2512 int newstate;
2513 {
2514 struct ad1848_softc *sc = addr;
2515 return gus_speaker_ctl(sc->parent, newstate);
2516 }
2517
2518 int
2519 gus_speaker_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 out bit is flipped: 0 enables, 1 disables */
2528 if ((newstate == SPKR_ON) &&
2529 (sc->sc_mixcontrol & GUSMASK_LINE_OUT)) {
2530 sc->sc_mixcontrol &= ~GUSMASK_LINE_OUT;
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_OUT) == 0) {
2535 sc->sc_mixcontrol |= GUSMASK_LINE_OUT;
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_linein_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 /* Line in bit is flipped: 0 enables, 1 disables */
2552 if ((newstate == SPKR_ON) &&
2553 (sc->sc_mixcontrol & GUSMASK_LINE_IN)) {
2554 sc->sc_mixcontrol &= ~GUSMASK_LINE_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_LINE_IN) == 0) {
2559 sc->sc_mixcontrol |= GUSMASK_LINE_IN;
2560 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
2561 }
2562
2563 return 0;
2564 }
2565
2566 STATIC int
2567 gus_mic_ctl(addr, newstate)
2568 void * addr;
2569 int newstate;
2570 {
2571 struct gus_softc *sc = (struct gus_softc *) addr;
2572 bus_space_tag_t iot = sc->sc_iot;
2573 bus_space_handle_t ioh1 = sc->sc_ioh1;
2574
2575 /* Mic bit is normal: 1 enables, 0 disables */
2576 if ((newstate == SPKR_ON) &&
2577 (sc->sc_mixcontrol & GUSMASK_MIC_IN) == 0) {
2578 sc->sc_mixcontrol |= GUSMASK_MIC_IN;
2579 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
2580 }
2581 if ((newstate == SPKR_OFF) &&
2582 (sc->sc_mixcontrol & GUSMASK_MIC_IN)) {
2583 sc->sc_mixcontrol &= ~GUSMASK_MIC_IN;
2584 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
2585 }
2586
2587 return 0;
2588 }
2589
2590 /*
2591 * Set the end address of a give voice. Called at splgus()
2592 */
2593
2594 STATIC void
2595 gus_set_endaddr(sc, voice, addr)
2596 struct gus_softc *sc;
2597 int voice;
2598 u_long addr;
2599 {
2600 bus_space_tag_t iot = sc->sc_iot;
2601 bus_space_handle_t ioh2 = sc->sc_ioh2;
2602
2603 sc->sc_voc[voice].end_addr = addr;
2604
2605 if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16)
2606 addr = convert_to_16bit(addr);
2607
2608 SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_HIGH);
2609 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(addr));
2610 SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_LOW);
2611 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(addr));
2612
2613 }
2614
2615 #ifdef GUSPLAYDEBUG
2616 /*
2617 * Set current address. called at splgus()
2618 */
2619 STATIC void
2620 gus_set_curaddr(sc, voice, addr)
2621 struct gus_softc *sc;
2622 int voice;
2623 u_long addr;
2624 {
2625 bus_space_tag_t iot = sc->sc_iot;
2626 bus_space_handle_t ioh2 = sc->sc_ioh2;
2627
2628 sc->sc_voc[voice].current_addr = addr;
2629
2630 if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16)
2631 addr = convert_to_16bit(addr);
2632
2633 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
2634
2635 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH);
2636 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(addr));
2637 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW);
2638 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(addr));
2639
2640 }
2641
2642 /*
2643 * Get current GUS playback address. Called at splgus().
2644 */
2645 STATIC u_long
2646 gus_get_curaddr(sc, voice)
2647 struct gus_softc *sc;
2648 int voice;
2649 {
2650 bus_space_tag_t iot = sc->sc_iot;
2651 bus_space_handle_t ioh2 = sc->sc_ioh2;
2652 u_long addr;
2653
2654 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
2655 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH|GUSREG_READ);
2656 addr = (bus_space_read_2(iot, ioh2, GUS_DATA_LOW) & 0x1fff) << 7;
2657 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW|GUSREG_READ);
2658 addr |= (bus_space_read_2(iot, ioh2, GUS_DATA_LOW) >> 9L) & 0x7f;
2659
2660 if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16)
2661 addr = (addr & 0xc0000) | ((addr & 0x1ffff) << 1); /* undo 16-bit change */
2662 DPRINTF(("gus voice %d curaddr %ld end_addr %ld\n",
2663 voice, addr, sc->sc_voc[voice].end_addr));
2664 /* XXX sanity check the address? */
2665
2666 return(addr);
2667 }
2668 #endif
2669
2670 /*
2671 * Convert an address value to a "16 bit" value - why this is necessary I
2672 * have NO idea
2673 */
2674
2675 STATIC u_long
2676 convert_to_16bit(address)
2677 u_long address;
2678 {
2679 u_long old_address;
2680
2681 old_address = address;
2682 address >>= 1;
2683 address &= 0x0001ffffL;
2684 address |= (old_address & 0x000c0000L);
2685
2686 return (address);
2687 }
2688
2689 /*
2690 * Write a value into the GUS's DRAM
2691 */
2692
2693 STATIC void
2694 guspoke(iot, ioh2, address, value)
2695 bus_space_tag_t iot;
2696 bus_space_handle_t ioh2;
2697 long address;
2698 unsigned char value;
2699 {
2700
2701 /*
2702 * Select the DRAM address
2703 */
2704
2705 SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_LOW);
2706 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, (unsigned int) (address & 0xffff));
2707 SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_HIGH);
2708 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (unsigned char) ((address >> 16) & 0xff));
2709
2710 /*
2711 * Actually write the data
2712 */
2713
2714 bus_space_write_1(iot, ioh2, GUS_DRAM_DATA, value);
2715 }
2716
2717 /*
2718 * Read a value from the GUS's DRAM
2719 */
2720
2721 STATIC unsigned char
2722 guspeek(iot, ioh2, address)
2723 bus_space_tag_t iot;
2724 bus_space_handle_t ioh2;
2725 u_long address;
2726 {
2727
2728 /*
2729 * Select the DRAM address
2730 */
2731
2732 SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_LOW);
2733 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, (unsigned int) (address & 0xffff));
2734 SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_HIGH);
2735 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (unsigned char) ((address >> 16) & 0xff));
2736
2737 /*
2738 * Read in the data from the board
2739 */
2740
2741 return (unsigned char) bus_space_read_1(iot, ioh2, GUS_DRAM_DATA);
2742 }
2743
2744 /*
2745 * Reset the Gravis UltraSound card, completely
2746 */
2747
2748 STATIC void
2749 gusreset(sc, voices)
2750 struct gus_softc *sc;
2751 int voices;
2752 {
2753 bus_space_tag_t iot = sc->sc_iot;
2754 bus_space_handle_t ioh1 = sc->sc_ioh1;
2755 bus_space_handle_t ioh2 = sc->sc_ioh2;
2756 bus_space_handle_t ioh4 = sc->sc_ioh4;
2757 int i,s;
2758
2759 s = splgus();
2760
2761 /*
2762 * Reset the GF1 chip
2763 */
2764
2765 SELECT_GUS_REG(iot, ioh2, GUSREG_RESET);
2766 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
2767
2768 delay(500);
2769
2770 /*
2771 * Release reset
2772 */
2773
2774 SELECT_GUS_REG(iot, ioh2, GUSREG_RESET);
2775 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, GUSMASK_MASTER_RESET);
2776
2777 delay(500);
2778
2779 /*
2780 * Reset MIDI port as well
2781 */
2782
2783 bus_space_write_1(iot, ioh4, GUS_MIDI_CONTROL, MIDI_RESET);
2784
2785 delay(500);
2786
2787 bus_space_write_1(iot, ioh4, GUS_MIDI_CONTROL, 0x00);
2788
2789 /*
2790 * Clear interrupts
2791 */
2792
2793 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
2794 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
2795 SELECT_GUS_REG(iot, ioh2, GUSREG_TIMER_CONTROL);
2796 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
2797 SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
2798 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
2799
2800 gus_set_voices(sc, voices);
2801
2802 bus_space_read_1(iot, ioh1, GUS_IRQ_STATUS);
2803 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
2804 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
2805 SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
2806 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
2807 SELECT_GUS_REG(iot, ioh2, GUSREG_IRQ_STATUS);
2808 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
2809
2810 /*
2811 * Reset voice specific information
2812 */
2813
2814 for(i = 0; i < voices; i++) {
2815 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) i);
2816
2817 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
2818
2819 sc->sc_voc[i].voccntl = GUSMASK_VOICE_STOPPED |
2820 GUSMASK_STOP_VOICE;
2821
2822 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[i].voccntl);
2823
2824 sc->sc_voc[i].volcntl = GUSMASK_VOLUME_STOPPED |
2825 GUSMASK_STOP_VOLUME;
2826
2827 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
2828 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[i].volcntl);
2829
2830 delay(100);
2831
2832 gus_set_samprate(sc, i, 8000);
2833 SELECT_GUS_REG(iot, ioh2, GUSREG_START_ADDR_HIGH);
2834 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2835 SELECT_GUS_REG(iot, ioh2, GUSREG_START_ADDR_LOW);
2836 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2837 SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_HIGH);
2838 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2839 SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_LOW);
2840 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2841 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_RATE);
2842 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x01);
2843 SELECT_GUS_REG(iot, ioh2, GUSREG_START_VOLUME);
2844 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x10);
2845 SELECT_GUS_REG(iot, ioh2, GUSREG_END_VOLUME);
2846 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0xe0);
2847 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME);
2848 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2849
2850 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH);
2851 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2852 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW);
2853 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2854 SELECT_GUS_REG(iot, ioh2, GUSREG_PAN_POS);
2855 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x07);
2856 }
2857
2858 /*
2859 * Clear out any pending IRQs
2860 */
2861
2862 bus_space_read_1(iot, ioh1, GUS_IRQ_STATUS);
2863 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
2864 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
2865 SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
2866 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
2867 SELECT_GUS_REG(iot, ioh2, GUSREG_IRQ_STATUS);
2868 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
2869
2870 SELECT_GUS_REG(iot, ioh2, GUSREG_RESET);
2871 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, GUSMASK_MASTER_RESET | GUSMASK_DAC_ENABLE |
2872 GUSMASK_IRQ_ENABLE);
2873
2874 splx(s);
2875 }
2876
2877
2878 STATIC void
2879 gus_init_cs4231(sc)
2880 struct gus_softc *sc;
2881 {
2882 bus_space_tag_t iot = sc->sc_iot;
2883 bus_space_handle_t ioh1 = sc->sc_ioh1;
2884 int port = sc->sc_iobase;
2885 u_char ctrl;
2886
2887 ctrl = (port & 0xf0) >> 4; /* set port address middle nibble */
2888 /*
2889 * The codec is a bit weird--swapped dma channels.
2890 */
2891 ctrl |= GUS_MAX_CODEC_ENABLE;
2892 if (sc->sc_drq >= 4)
2893 ctrl |= GUS_MAX_RECCHAN16;
2894 if (sc->sc_recdrq >= 4)
2895 ctrl |= GUS_MAX_PLAYCHAN16;
2896
2897 bus_space_write_1(iot, ioh1, GUS_MAX_CTRL, ctrl);
2898
2899 sc->sc_codec.sc_iot = sc->sc_iot;
2900 sc->sc_codec.sc_iobase = port+GUS_MAX_CODEC_BASE;
2901
2902 if (ad1848_probe(&sc->sc_codec) == 0) {
2903 sc->sc_flags &= ~GUS_CODEC_INSTALLED;
2904 } else {
2905 struct ad1848_volume vol = {AUDIO_MAX_GAIN, AUDIO_MAX_GAIN};
2906 sc->sc_flags |= GUS_CODEC_INSTALLED;
2907 sc->sc_codec.parent = sc;
2908 sc->sc_codec.sc_drq = sc->sc_recdrq;
2909 sc->sc_codec.sc_recdrq = sc->sc_drq;
2910 gus_hw_if = gusmax_hw_if;
2911 /* enable line in and mic in the GUS mixer; the codec chip
2912 will do the real mixing for them. */
2913 sc->sc_mixcontrol &= ~GUSMASK_LINE_IN; /* 0 enables. */
2914 sc->sc_mixcontrol |= GUSMASK_MIC_IN; /* 1 enables. */
2915 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
2916
2917 ad1848_attach(&sc->sc_codec);
2918 /* turn on pre-MUX microphone gain. */
2919 ad1848_set_mic_gain(&sc->sc_codec, &vol);
2920 }
2921 }
2922
2923
2924 /*
2925 * Return info about the audio device, for the AUDIO_GETINFO ioctl
2926 */
2927
2928 int
2929 gus_getdev(addr, dev)
2930 void * addr;
2931 struct audio_device *dev;
2932 {
2933 *dev = gus_device;
2934 return 0;
2935 }
2936
2937 /*
2938 * stubs (XXX)
2939 */
2940
2941 int
2942 gus_set_in_gain(addr, gain, balance)
2943 caddr_t addr;
2944 u_int gain;
2945 u_char balance;
2946 {
2947 DPRINTF(("gus_set_in_gain called\n"));
2948 return 0;
2949 }
2950
2951 int
2952 gus_get_in_gain(addr)
2953 caddr_t addr;
2954 {
2955 DPRINTF(("gus_get_in_gain called\n"));
2956 return 0;
2957 }
2958
2959 int
2960 gusmax_set_out_port(addr, port)
2961 void * addr;
2962 int port;
2963 {
2964 struct ad1848_softc *sc = addr;
2965 return gus_set_out_port(sc->parent, port);
2966 }
2967
2968 int
2969 gus_set_out_port(addr, port)
2970 void * addr;
2971 int port;
2972 {
2973 struct gus_softc *sc = addr;
2974 DPRINTF(("gus_set_out_port called\n"));
2975 sc->sc_out_port = port;
2976
2977 return 0;
2978 }
2979
2980 int
2981 gusmax_get_out_port(addr)
2982 void * addr;
2983 {
2984 struct ad1848_softc *sc = addr;
2985 return gus_get_out_port(sc->parent);
2986 }
2987
2988 int
2989 gus_get_out_port(addr)
2990 void * addr;
2991 {
2992 struct gus_softc *sc = addr;
2993 DPRINTF(("gus_get_out_port() called\n"));
2994 return sc->sc_out_port;
2995 }
2996
2997 int
2998 gusmax_set_in_port(addr, port)
2999 void * addr;
3000 int port;
3001 {
3002 struct ad1848_softc *sc = addr;
3003 DPRINTF(("gusmax_set_in_port: %d\n", port));
3004
3005 switch(port) {
3006 case MIC_IN_PORT:
3007 case LINE_IN_PORT:
3008 case AUX1_IN_PORT:
3009 case DAC_IN_PORT:
3010 break;
3011 default:
3012 return(EINVAL);
3013 /*NOTREACHED*/
3014 }
3015 return(ad1848_set_rec_port(sc, port));
3016 }
3017
3018 int
3019 gusmax_get_in_port(addr)
3020 void * addr;
3021 {
3022 struct ad1848_softc *sc = addr;
3023 int port;
3024
3025 port = ad1848_get_rec_port(sc);
3026 DPRINTF(("gusmax_get_in_port: %d\n", port));
3027
3028 return(port);
3029 }
3030
3031 int
3032 gus_set_in_port(addr, port)
3033 void * addr;
3034 int port;
3035 {
3036 struct gus_softc *sc = addr;
3037 DPRINTF(("gus_set_in_port called\n"));
3038 /*
3039 * On the GUS with ICS mixer, the ADC input is after the mixer stage,
3040 * so we can't set the input port.
3041 *
3042 * On the GUS with CS4231 codec/mixer, see gusmax_set_in_port().
3043 */
3044 sc->sc_in_port = port;
3045
3046 return 0;
3047 }
3048
3049
3050 int
3051 gus_get_in_port(addr)
3052 void * addr;
3053 {
3054 struct gus_softc *sc = addr;
3055 DPRINTF(("gus_get_in_port called\n"));
3056 return sc->sc_in_port;
3057 }
3058
3059
3060 int
3061 gusmax_dma_input(addr, buf, size, callback, arg)
3062 void * addr;
3063 void *buf;
3064 int size;
3065 void (*callback) __P((void *));
3066 void *arg;
3067 {
3068 struct ad1848_softc *sc = addr;
3069 return gus_dma_input(sc->parent, buf, size, callback, arg);
3070 }
3071
3072 /*
3073 * Start sampling the input source into the requested DMA buffer.
3074 * Called at splgus(), either from top-half or from interrupt handler.
3075 */
3076 int
3077 gus_dma_input(addr, buf, size, callback, arg)
3078 void * addr;
3079 void *buf;
3080 int size;
3081 void (*callback) __P((void *));
3082 void *arg;
3083 {
3084 struct gus_softc *sc = addr;
3085 bus_space_tag_t iot = sc->sc_iot;
3086 bus_space_handle_t ioh2 = sc->sc_ioh2;
3087 u_char dmac;
3088 DMAPRINTF(("gus_dma_input called\n"));
3089
3090 /*
3091 * Sample SIZE bytes of data from the card, into buffer at BUF.
3092 */
3093
3094 if (sc->sc_precision == 16)
3095 return EINVAL; /* XXX */
3096
3097 /* set DMA modes */
3098 dmac = GUSMASK_SAMPLE_IRQ|GUSMASK_SAMPLE_START;
3099 if (sc->sc_recdrq >= 4)
3100 dmac |= GUSMASK_SAMPLE_DATA16;
3101 if (sc->sc_encoding == AUDIO_ENCODING_ULAW ||
3102 sc->sc_encoding == AUDIO_ENCODING_ALAW ||
3103 sc->sc_encoding == AUDIO_ENCODING_ULINEAR_LE ||
3104 sc->sc_encoding == AUDIO_ENCODING_ULINEAR_BE)
3105 dmac |= GUSMASK_SAMPLE_INVBIT;
3106 if (sc->sc_channels == 2)
3107 dmac |= GUSMASK_SAMPLE_STEREO;
3108 isa_dmastart(sc->sc_dev.dv_parent, sc->sc_recdrq, buf, size,
3109 NULL, DMAMODE_READ, BUS_DMA_NOWAIT);
3110
3111 DMAPRINTF(("gus_dma_input isa_dmastarted\n"));
3112 sc->sc_flags |= GUS_DMAIN_ACTIVE;
3113 sc->sc_dmainintr = callback;
3114 sc->sc_inarg = arg;
3115 sc->sc_dmaincnt = size;
3116 sc->sc_dmainaddr = buf;
3117
3118 SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
3119 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, dmac); /* Go! */
3120
3121
3122 DMAPRINTF(("gus_dma_input returning\n"));
3123
3124 return 0;
3125 }
3126
3127 STATIC int
3128 gus_dmain_intr(sc)
3129 struct gus_softc *sc;
3130 {
3131 void (*callback) __P((void *));
3132 void *arg;
3133
3134 DMAPRINTF(("gus_dmain_intr called\n"));
3135 if (sc->sc_dmainintr) {
3136 isa_dmadone(sc->sc_dev.dv_parent, sc->sc_recdrq);
3137 callback = sc->sc_dmainintr;
3138 arg = sc->sc_inarg;
3139
3140 sc->sc_dmainaddr = 0;
3141 sc->sc_dmaincnt = 0;
3142 sc->sc_dmainintr = 0;
3143 sc->sc_inarg = 0;
3144
3145 sc->sc_flags &= ~GUS_DMAIN_ACTIVE;
3146 DMAPRINTF(("calling dmain_intr callback %p(%p)\n", callback, arg));
3147 (*callback)(arg);
3148 return 1;
3149 } else {
3150 DMAPRINTF(("gus_dmain_intr false?\n"));
3151 return 0; /* XXX ??? */
3152 }
3153 }
3154
3155 int
3156 gusmax_halt_out_dma(addr)
3157 void * addr;
3158 {
3159 struct ad1848_softc *sc = addr;
3160 return gus_halt_out_dma(sc->parent);
3161 }
3162
3163
3164 int
3165 gusmax_halt_in_dma(addr)
3166 void * addr;
3167 {
3168 struct ad1848_softc *sc = addr;
3169 return gus_halt_in_dma(sc->parent);
3170 }
3171
3172 int
3173 gusmax_cont_out_dma(addr)
3174 void * addr;
3175 {
3176 struct ad1848_softc *sc = addr;
3177 return gus_cont_out_dma(sc->parent);
3178 }
3179
3180 int
3181 gusmax_cont_in_dma(addr)
3182 void * addr;
3183 {
3184 struct ad1848_softc *sc = addr;
3185 return gus_cont_in_dma(sc->parent);
3186 }
3187
3188 /*
3189 * Stop any DMA output. Called at splgus().
3190 */
3191 int
3192 gus_halt_out_dma(addr)
3193 void * addr;
3194 {
3195 struct gus_softc *sc = addr;
3196 bus_space_tag_t iot = sc->sc_iot;
3197 bus_space_handle_t ioh2 = sc->sc_ioh2;
3198
3199 DMAPRINTF(("gus_halt_out_dma called\n"));
3200 /*
3201 * Make sure the GUS _isn't_ setup for DMA
3202 */
3203
3204 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
3205 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0);
3206
3207 untimeout(gus_dmaout_timeout, sc);
3208 isa_dmaabort(sc->sc_dev.dv_parent, sc->sc_drq);
3209 sc->sc_flags &= ~(GUS_DMAOUT_ACTIVE|GUS_LOCKED);
3210 sc->sc_dmaoutintr = 0;
3211 sc->sc_outarg = 0;
3212 sc->sc_dmaoutaddr = 0;
3213 sc->sc_dmaoutcnt = 0;
3214 sc->sc_dmabuf = 0;
3215 sc->sc_bufcnt = 0;
3216 sc->sc_playbuf = -1;
3217 /* also stop playing */
3218 gus_stop_voice(sc, GUS_VOICE_LEFT, 1);
3219 gus_stop_voice(sc, GUS_VOICE_RIGHT, 0);
3220
3221 return 0;
3222 }
3223
3224 /*
3225 * Stop any DMA output. Called at splgus().
3226 */
3227 int
3228 gus_halt_in_dma(addr)
3229 void * addr;
3230 {
3231 struct gus_softc *sc = addr;
3232 bus_space_tag_t iot = sc->sc_iot;
3233 bus_space_handle_t ioh2 = sc->sc_ioh2;
3234 DMAPRINTF(("gus_halt_in_dma called\n"));
3235
3236 /*
3237 * Make sure the GUS _isn't_ setup for DMA
3238 */
3239
3240 SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
3241 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH,
3242 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH) & ~(GUSMASK_SAMPLE_START|GUSMASK_SAMPLE_IRQ));
3243
3244 isa_dmaabort(sc->sc_dev.dv_parent, sc->sc_recdrq);
3245 sc->sc_flags &= ~GUS_DMAIN_ACTIVE;
3246 sc->sc_dmainintr = 0;
3247 sc->sc_inarg = 0;
3248 sc->sc_dmainaddr = 0;
3249 sc->sc_dmaincnt = 0;
3250
3251 return 0;
3252 }
3253
3254 int
3255 gus_cont_out_dma(addr)
3256 void * addr;
3257 {
3258 DPRINTF(("gus_cont_out_dma called\n"));
3259 return EOPNOTSUPP;
3260 }
3261
3262 int
3263 gus_cont_in_dma(addr)
3264 void * addr;
3265 {
3266 DPRINTF(("gus_cont_in_dma called\n"));
3267 return EOPNOTSUPP;
3268 }
3269
3270
3271 STATIC __inline int
3272 gus_to_vol(cp, vol)
3273 mixer_ctrl_t *cp;
3274 struct ad1848_volume *vol;
3275 {
3276 if (cp->un.value.num_channels == 1) {
3277 vol->left = vol->right = cp->un.value.level[AUDIO_MIXER_LEVEL_MONO];
3278 return(1);
3279 }
3280 else if (cp->un.value.num_channels == 2) {
3281 vol->left = cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT];
3282 vol->right = cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT];
3283 return(1);
3284 }
3285 return(0);
3286 }
3287
3288 STATIC __inline int
3289 gus_from_vol(cp, vol)
3290 mixer_ctrl_t *cp;
3291 struct ad1848_volume *vol;
3292 {
3293 if (cp->un.value.num_channels == 1) {
3294 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = vol->left;
3295 return(1);
3296 }
3297 else if (cp->un.value.num_channels == 2) {
3298 cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = vol->left;
3299 cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = vol->right;
3300 return(1);
3301 }
3302 return(0);
3303 }
3304
3305 STATIC int
3306 gusmax_mixer_get_port(addr, cp)
3307 void *addr;
3308 mixer_ctrl_t *cp;
3309 {
3310 struct ad1848_softc *ac = addr;
3311 struct gus_softc *sc = ac->parent;
3312 struct ad1848_volume vol;
3313 int error = EINVAL;
3314
3315 DPRINTF(("gusmax_mixer_get_port: port=%d\n", cp->dev));
3316
3317 switch (cp->dev) {
3318 #if 0 /* use mono level instead */
3319 case GUSMAX_MIC_IN_LVL: /* Microphone */
3320 if (cp->type == AUDIO_MIXER_VALUE) {
3321 error = ad1848_get_mic_gain(ac, &vol);
3322 if (!error)
3323 gus_from_vol(cp, &vol);
3324 }
3325 break;
3326 #endif
3327
3328 case GUSMAX_DAC_LVL: /* dac out */
3329 if (cp->type == AUDIO_MIXER_VALUE) {
3330 error = ad1848_get_aux1_gain(ac, &vol);
3331 if (!error)
3332 gus_from_vol(cp, &vol);
3333 }
3334 break;
3335
3336 case GUSMAX_LINE_IN_LVL: /* line in */
3337 if (cp->type == AUDIO_MIXER_VALUE) {
3338 error = cs4231_get_linein_gain(ac, &vol);
3339 if (!error)
3340 gus_from_vol(cp, &vol);
3341 }
3342 break;
3343
3344 case GUSMAX_MONO_LVL: /* mono */
3345 if (cp->type == AUDIO_MIXER_VALUE &&
3346 cp->un.value.num_channels == 1) {
3347 error = cs4231_get_mono_gain(ac, &vol);
3348 if (!error)
3349 gus_from_vol(cp, &vol);
3350 }
3351 break;
3352
3353 case GUSMAX_CD_LVL: /* CD */
3354 if (cp->type == AUDIO_MIXER_VALUE) {
3355 error = ad1848_get_aux2_gain(ac, &vol);
3356 if (!error)
3357 gus_from_vol(cp, &vol);
3358 }
3359 break;
3360
3361 case GUSMAX_MONITOR_LVL: /* monitor level */
3362 if (cp->type == AUDIO_MIXER_VALUE &&
3363 cp->un.value.num_channels == 1) {
3364 error = ad1848_get_mon_gain(ac, &vol);
3365 if (!error)
3366 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
3367 vol.left;
3368 }
3369 break;
3370
3371 case GUSMAX_OUT_LVL: /* output level */
3372 if (cp->type == AUDIO_MIXER_VALUE) {
3373 error = ad1848_get_out_gain(ac, &vol);
3374 if (!error)
3375 gus_from_vol(cp, &vol);
3376 }
3377 break;
3378
3379 case GUSMAX_SPEAKER_LVL: /* fake speaker for mute naming */
3380 if (cp->type == AUDIO_MIXER_VALUE) {
3381 if (sc->sc_mixcontrol & GUSMASK_LINE_OUT)
3382 vol.left = vol.right = AUDIO_MAX_GAIN;
3383 else
3384 vol.left = vol.right = AUDIO_MIN_GAIN;
3385 error = 0;
3386 gus_from_vol(cp, &vol);
3387 }
3388 break;
3389
3390 case GUSMAX_LINE_IN_MUTE:
3391 if (cp->type == AUDIO_MIXER_ENUM) {
3392 cp->un.ord = ac->line_mute;
3393 error = 0;
3394 }
3395 break;
3396
3397
3398 case GUSMAX_DAC_MUTE:
3399 if (cp->type == AUDIO_MIXER_ENUM) {
3400 cp->un.ord = ac->aux1_mute;
3401 error = 0;
3402 }
3403 break;
3404
3405 case GUSMAX_CD_MUTE:
3406 if (cp->type == AUDIO_MIXER_ENUM) {
3407 cp->un.ord = ac->aux2_mute;
3408 error = 0;
3409 }
3410 break;
3411
3412 case GUSMAX_MONO_MUTE:
3413 if (cp->type == AUDIO_MIXER_ENUM) {
3414 cp->un.ord = ac->mono_mute;
3415 error = 0;
3416 }
3417 break;
3418
3419 case GUSMAX_MONITOR_MUTE:
3420 if (cp->type == AUDIO_MIXER_ENUM) {
3421 cp->un.ord = ac->mon_mute;
3422 error = 0;
3423 }
3424 break;
3425
3426 case GUSMAX_SPEAKER_MUTE:
3427 if (cp->type == AUDIO_MIXER_ENUM) {
3428 cp->un.ord = sc->sc_mixcontrol & GUSMASK_LINE_OUT ? 1 : 0;
3429 error = 0;
3430 }
3431 break;
3432
3433 case GUSMAX_REC_LVL: /* record level */
3434 if (cp->type == AUDIO_MIXER_VALUE) {
3435 error = ad1848_get_rec_gain(ac, &vol);
3436 if (!error)
3437 gus_from_vol(cp, &vol);
3438 }
3439 break;
3440
3441 case GUSMAX_RECORD_SOURCE:
3442 if (cp->type == AUDIO_MIXER_ENUM) {
3443 cp->un.ord = ad1848_get_rec_port(ac);
3444 error = 0;
3445 }
3446 break;
3447
3448 default:
3449 error = ENXIO;
3450 break;
3451 }
3452
3453 return(error);
3454 }
3455
3456 STATIC int
3457 gus_mixer_get_port(addr, cp)
3458 void *addr;
3459 mixer_ctrl_t *cp;
3460 {
3461 struct gus_softc *sc = addr;
3462 struct ics2101_softc *ic = &sc->sc_mixer;
3463 struct ad1848_volume vol;
3464 int error = EINVAL;
3465
3466 DPRINTF(("gus_mixer_get_port: dev=%d type=%d\n", cp->dev, cp->type));
3467
3468 if (!HAS_MIXER(sc) && cp->dev > GUSICS_MASTER_MUTE)
3469 return ENXIO;
3470
3471 switch (cp->dev) {
3472
3473 case GUSICS_MIC_IN_MUTE: /* Microphone */
3474 if (cp->type == AUDIO_MIXER_ENUM) {
3475 if (HAS_MIXER(sc))
3476 cp->un.ord = ic->sc_mute[GUSMIX_CHAN_MIC][ICSMIX_LEFT];
3477 else
3478 cp->un.ord =
3479 sc->sc_mixcontrol & GUSMASK_MIC_IN ? 0 : 1;
3480 error = 0;
3481 }
3482 break;
3483
3484 case GUSICS_LINE_IN_MUTE:
3485 if (cp->type == AUDIO_MIXER_ENUM) {
3486 if (HAS_MIXER(sc))
3487 cp->un.ord = ic->sc_mute[GUSMIX_CHAN_LINE][ICSMIX_LEFT];
3488 else
3489 cp->un.ord =
3490 sc->sc_mixcontrol & GUSMASK_LINE_IN ? 1 : 0;
3491 error = 0;
3492 }
3493 break;
3494
3495 case GUSICS_MASTER_MUTE:
3496 if (cp->type == AUDIO_MIXER_ENUM) {
3497 if (HAS_MIXER(sc))
3498 cp->un.ord = ic->sc_mute[GUSMIX_CHAN_MASTER][ICSMIX_LEFT];
3499 else
3500 cp->un.ord =
3501 sc->sc_mixcontrol & GUSMASK_LINE_OUT ? 1 : 0;
3502 error = 0;
3503 }
3504 break;
3505
3506 case GUSICS_DAC_MUTE:
3507 if (cp->type == AUDIO_MIXER_ENUM) {
3508 cp->un.ord = ic->sc_mute[GUSMIX_CHAN_DAC][ICSMIX_LEFT];
3509 error = 0;
3510 }
3511 break;
3512
3513 case GUSICS_CD_MUTE:
3514 if (cp->type == AUDIO_MIXER_ENUM) {
3515 cp->un.ord = ic->sc_mute[GUSMIX_CHAN_CD][ICSMIX_LEFT];
3516 error = 0;
3517 }
3518 break;
3519
3520 case GUSICS_MASTER_LVL:
3521 if (cp->type == AUDIO_MIXER_VALUE) {
3522 vol.left = ic->sc_setting[GUSMIX_CHAN_MASTER][ICSMIX_LEFT];
3523 vol.right = ic->sc_setting[GUSMIX_CHAN_MASTER][ICSMIX_RIGHT];
3524 if (gus_from_vol(cp, &vol))
3525 error = 0;
3526 }
3527 break;
3528
3529 case GUSICS_MIC_IN_LVL: /* Microphone */
3530 if (cp->type == AUDIO_MIXER_VALUE) {
3531 vol.left = ic->sc_setting[GUSMIX_CHAN_MIC][ICSMIX_LEFT];
3532 vol.right = ic->sc_setting[GUSMIX_CHAN_MIC][ICSMIX_RIGHT];
3533 if (gus_from_vol(cp, &vol))
3534 error = 0;
3535 }
3536 break;
3537
3538 case GUSICS_LINE_IN_LVL: /* line in */
3539 if (cp->type == AUDIO_MIXER_VALUE) {
3540 vol.left = ic->sc_setting[GUSMIX_CHAN_LINE][ICSMIX_LEFT];
3541 vol.right = ic->sc_setting[GUSMIX_CHAN_LINE][ICSMIX_RIGHT];
3542 if (gus_from_vol(cp, &vol))
3543 error = 0;
3544 }
3545 break;
3546
3547
3548 case GUSICS_CD_LVL:
3549 if (cp->type == AUDIO_MIXER_VALUE) {
3550 vol.left = ic->sc_setting[GUSMIX_CHAN_CD][ICSMIX_LEFT];
3551 vol.right = ic->sc_setting[GUSMIX_CHAN_CD][ICSMIX_RIGHT];
3552 if (gus_from_vol(cp, &vol))
3553 error = 0;
3554 }
3555 break;
3556
3557 case GUSICS_DAC_LVL: /* dac out */
3558 if (cp->type == AUDIO_MIXER_VALUE) {
3559 vol.left = ic->sc_setting[GUSMIX_CHAN_DAC][ICSMIX_LEFT];
3560 vol.right = ic->sc_setting[GUSMIX_CHAN_DAC][ICSMIX_RIGHT];
3561 if (gus_from_vol(cp, &vol))
3562 error = 0;
3563 }
3564 break;
3565
3566
3567 case GUSICS_RECORD_SOURCE:
3568 if (cp->type == AUDIO_MIXER_ENUM) {
3569 /* Can't set anything else useful, sigh. */
3570 cp->un.ord = 0;
3571 }
3572 break;
3573
3574 default:
3575 return ENXIO;
3576 /*NOTREACHED*/
3577 }
3578 return error;
3579 }
3580
3581 STATIC void
3582 gusics_master_mute(ic, mute)
3583 struct ics2101_softc *ic;
3584 int mute;
3585 {
3586 ics2101_mix_mute(ic, GUSMIX_CHAN_MASTER, ICSMIX_LEFT, mute);
3587 ics2101_mix_mute(ic, GUSMIX_CHAN_MASTER, ICSMIX_RIGHT, mute);
3588 }
3589
3590 STATIC void
3591 gusics_mic_mute(ic, mute)
3592 struct ics2101_softc *ic;
3593 int mute;
3594 {
3595 ics2101_mix_mute(ic, GUSMIX_CHAN_MIC, ICSMIX_LEFT, mute);
3596 ics2101_mix_mute(ic, GUSMIX_CHAN_MIC, ICSMIX_RIGHT, mute);
3597 }
3598
3599 STATIC void
3600 gusics_linein_mute(ic, mute)
3601 struct ics2101_softc *ic;
3602 int mute;
3603 {
3604 ics2101_mix_mute(ic, GUSMIX_CHAN_LINE, ICSMIX_LEFT, mute);
3605 ics2101_mix_mute(ic, GUSMIX_CHAN_LINE, ICSMIX_RIGHT, mute);
3606 }
3607
3608 STATIC void
3609 gusics_cd_mute(ic, mute)
3610 struct ics2101_softc *ic;
3611 int mute;
3612 {
3613 ics2101_mix_mute(ic, GUSMIX_CHAN_CD, ICSMIX_LEFT, mute);
3614 ics2101_mix_mute(ic, GUSMIX_CHAN_CD, ICSMIX_RIGHT, mute);
3615 }
3616
3617 STATIC void
3618 gusics_dac_mute(ic, mute)
3619 struct ics2101_softc *ic;
3620 int mute;
3621 {
3622 ics2101_mix_mute(ic, GUSMIX_CHAN_DAC, ICSMIX_LEFT, mute);
3623 ics2101_mix_mute(ic, GUSMIX_CHAN_DAC, ICSMIX_RIGHT, mute);
3624 }
3625
3626 STATIC int
3627 gusmax_mixer_set_port(addr, cp)
3628 void *addr;
3629 mixer_ctrl_t *cp;
3630 {
3631 struct ad1848_softc *ac = addr;
3632 struct gus_softc *sc = ac->parent;
3633 struct ad1848_volume vol;
3634 int error = EINVAL;
3635
3636 DPRINTF(("gusmax_mixer_set_port: dev=%d type=%d\n", cp->dev, cp->type));
3637
3638 switch (cp->dev) {
3639 #if 0
3640 case GUSMAX_MIC_IN_LVL: /* Microphone */
3641 if (cp->type == AUDIO_MIXER_VALUE &&
3642 cp->un.value.num_channels == 1) {
3643 /* XXX enable/disable pre-MUX fixed gain */
3644 if (gus_to_vol(cp, &vol))
3645 error = ad1848_set_mic_gain(ac, &vol);
3646 }
3647 break;
3648 #endif
3649
3650 case GUSMAX_DAC_LVL: /* dac out */
3651 if (cp->type == AUDIO_MIXER_VALUE) {
3652 if (gus_to_vol(cp, &vol))
3653 error = ad1848_set_aux1_gain(ac, &vol);
3654 }
3655 break;
3656
3657 case GUSMAX_LINE_IN_LVL: /* line in */
3658 if (cp->type == AUDIO_MIXER_VALUE) {
3659 if (gus_to_vol(cp, &vol))
3660 error = cs4231_set_linein_gain(ac, &vol);
3661 }
3662 break;
3663
3664 case GUSMAX_MONO_LVL: /* mic/mono in */
3665 if (cp->type == AUDIO_MIXER_VALUE &&
3666 cp->un.value.num_channels == 1) {
3667 if (gus_to_vol(cp, &vol))
3668 error = cs4231_set_mono_gain(ac, &vol);
3669 }
3670 break;
3671
3672 case GUSMAX_CD_LVL: /* CD: AUX2 */
3673 if (cp->type == AUDIO_MIXER_VALUE) {
3674 if (gus_to_vol(cp, &vol))
3675 error = ad1848_set_aux2_gain(ac, &vol);
3676 }
3677 break;
3678
3679 case GUSMAX_MONITOR_LVL:
3680 if (cp->type == AUDIO_MIXER_VALUE &&
3681 cp->un.value.num_channels == 1) {
3682 vol.left = cp->un.value.level[AUDIO_MIXER_LEVEL_MONO];
3683 error = ad1848_set_mon_gain(ac, &vol);
3684 }
3685 break;
3686
3687 case GUSMAX_OUT_LVL: /* output volume */
3688 if (cp->type == AUDIO_MIXER_VALUE) {
3689 if (gus_to_vol(cp, &vol))
3690 error = ad1848_set_out_gain(ac, &vol);
3691 }
3692 break;
3693
3694 case GUSMAX_SPEAKER_LVL:
3695 if (cp->type == AUDIO_MIXER_VALUE &&
3696 cp->un.value.num_channels == 1) {
3697 if (gus_to_vol(cp, &vol)) {
3698 gus_speaker_ctl(sc, vol.left > AUDIO_MIN_GAIN ?
3699 SPKR_ON : SPKR_OFF);
3700 error = 0;
3701 }
3702 }
3703 break;
3704
3705 case GUSMAX_LINE_IN_MUTE:
3706 if (cp->type == AUDIO_MIXER_ENUM) {
3707 ac->line_mute = cp->un.ord ? 1 : 0;
3708 DPRINTF(("line mute %d\n", cp->un.ord));
3709 cs4231_mute_line(ac, ac->line_mute);
3710 gus_linein_ctl(sc, ac->line_mute ? SPKR_OFF : SPKR_ON);
3711 error = 0;
3712 }
3713 break;
3714
3715 case GUSMAX_DAC_MUTE:
3716 if (cp->type == AUDIO_MIXER_ENUM) {
3717 ac->aux1_mute = cp->un.ord ? 1 : 0;
3718 DPRINTF(("dac mute %d\n", cp->un.ord));
3719 ad1848_mute_aux1(ac, ac->aux1_mute);
3720 error = 0;
3721 }
3722 break;
3723
3724 case GUSMAX_CD_MUTE:
3725 if (cp->type == AUDIO_MIXER_ENUM) {
3726 ac->aux2_mute = cp->un.ord ? 1 : 0;
3727 DPRINTF(("cd mute %d\n", cp->un.ord));
3728 ad1848_mute_aux2(ac, ac->aux2_mute);
3729 error = 0;
3730 }
3731 break;
3732
3733 case GUSMAX_MONO_MUTE: /* Microphone */
3734 if (cp->type == AUDIO_MIXER_ENUM) {
3735 ac->mono_mute = cp->un.ord ? 1 : 0;
3736 DPRINTF(("mono mute %d\n", cp->un.ord));
3737 cs4231_mute_mono(ac, ac->mono_mute);
3738 gus_mic_ctl(sc, ac->mono_mute ? SPKR_OFF : SPKR_ON);
3739 error = 0;
3740 }
3741 break;
3742
3743 case GUSMAX_MONITOR_MUTE:
3744 if (cp->type == AUDIO_MIXER_ENUM) {
3745 ac->mon_mute = cp->un.ord ? 1 : 0;
3746 DPRINTF(("mono mute %d\n", cp->un.ord));
3747 cs4231_mute_monitor(ac, ac->mon_mute);
3748 error = 0;
3749 }
3750 break;
3751
3752 case GUSMAX_SPEAKER_MUTE:
3753 if (cp->type == AUDIO_MIXER_ENUM) {
3754 gus_speaker_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON);
3755 error = 0;
3756 }
3757 break;
3758
3759 case GUSMAX_REC_LVL: /* record level */
3760 if (cp->type == AUDIO_MIXER_VALUE) {
3761 if (gus_to_vol(cp, &vol))
3762 error = ad1848_set_rec_gain(ac, &vol);
3763 }
3764 break;
3765
3766 case GUSMAX_RECORD_SOURCE:
3767 if (cp->type == AUDIO_MIXER_ENUM) {
3768 error = ad1848_set_rec_port(ac, cp->un.ord);
3769 }
3770 break;
3771
3772 default:
3773 return ENXIO;
3774 /*NOTREACHED*/
3775 }
3776 return error;
3777 }
3778
3779 STATIC int
3780 gus_mixer_set_port(addr, cp)
3781 void *addr;
3782 mixer_ctrl_t *cp;
3783 {
3784 struct gus_softc *sc = addr;
3785 struct ics2101_softc *ic = &sc->sc_mixer;
3786 struct ad1848_volume vol;
3787 int error = EINVAL;
3788
3789 DPRINTF(("gus_mixer_set_port: dev=%d type=%d\n", cp->dev, cp->type));
3790
3791 if (!HAS_MIXER(sc) && cp->dev > GUSICS_MASTER_MUTE)
3792 return ENXIO;
3793
3794 switch (cp->dev) {
3795
3796 case GUSICS_MIC_IN_MUTE: /* Microphone */
3797 if (cp->type == AUDIO_MIXER_ENUM) {
3798 DPRINTF(("mic mute %d\n", cp->un.ord));
3799 if (HAS_MIXER(sc)) {
3800 gusics_mic_mute(ic, cp->un.ord);
3801 }
3802 gus_mic_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON);
3803 error = 0;
3804 }
3805 break;
3806
3807 case GUSICS_LINE_IN_MUTE:
3808 if (cp->type == AUDIO_MIXER_ENUM) {
3809 DPRINTF(("linein mute %d\n", cp->un.ord));
3810 if (HAS_MIXER(sc)) {
3811 gusics_linein_mute(ic, cp->un.ord);
3812 }
3813 gus_linein_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON);
3814 error = 0;
3815 }
3816 break;
3817
3818 case GUSICS_MASTER_MUTE:
3819 if (cp->type == AUDIO_MIXER_ENUM) {
3820 DPRINTF(("master mute %d\n", cp->un.ord));
3821 if (HAS_MIXER(sc)) {
3822 gusics_master_mute(ic, cp->un.ord);
3823 }
3824 gus_speaker_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON);
3825 error = 0;
3826 }
3827 break;
3828
3829 case GUSICS_DAC_MUTE:
3830 if (cp->type == AUDIO_MIXER_ENUM) {
3831 gusics_dac_mute(ic, cp->un.ord);
3832 error = 0;
3833 }
3834 break;
3835
3836 case GUSICS_CD_MUTE:
3837 if (cp->type == AUDIO_MIXER_ENUM) {
3838 gusics_cd_mute(ic, cp->un.ord);
3839 error = 0;
3840 }
3841 break;
3842
3843 case GUSICS_MASTER_LVL:
3844 if (cp->type == AUDIO_MIXER_VALUE) {
3845 if (gus_to_vol(cp, &vol)) {
3846 ics2101_mix_attenuate(ic,
3847 GUSMIX_CHAN_MASTER,
3848 ICSMIX_LEFT,
3849 vol.left);
3850 ics2101_mix_attenuate(ic,
3851 GUSMIX_CHAN_MASTER,
3852 ICSMIX_RIGHT,
3853 vol.right);
3854 error = 0;
3855 }
3856 }
3857 break;
3858
3859 case GUSICS_MIC_IN_LVL: /* Microphone */
3860 if (cp->type == AUDIO_MIXER_VALUE) {
3861 if (gus_to_vol(cp, &vol)) {
3862 ics2101_mix_attenuate(ic,
3863 GUSMIX_CHAN_MIC,
3864 ICSMIX_LEFT,
3865 vol.left);
3866 ics2101_mix_attenuate(ic,
3867 GUSMIX_CHAN_MIC,
3868 ICSMIX_RIGHT,
3869 vol.right);
3870 error = 0;
3871 }
3872 }
3873 break;
3874
3875 case GUSICS_LINE_IN_LVL: /* line in */
3876 if (cp->type == AUDIO_MIXER_VALUE) {
3877 if (gus_to_vol(cp, &vol)) {
3878 ics2101_mix_attenuate(ic,
3879 GUSMIX_CHAN_LINE,
3880 ICSMIX_LEFT,
3881 vol.left);
3882 ics2101_mix_attenuate(ic,
3883 GUSMIX_CHAN_LINE,
3884 ICSMIX_RIGHT,
3885 vol.right);
3886 error = 0;
3887 }
3888 }
3889 break;
3890
3891
3892 case GUSICS_CD_LVL:
3893 if (cp->type == AUDIO_MIXER_VALUE) {
3894 if (gus_to_vol(cp, &vol)) {
3895 ics2101_mix_attenuate(ic,
3896 GUSMIX_CHAN_CD,
3897 ICSMIX_LEFT,
3898 vol.left);
3899 ics2101_mix_attenuate(ic,
3900 GUSMIX_CHAN_CD,
3901 ICSMIX_RIGHT,
3902 vol.right);
3903 error = 0;
3904 }
3905 }
3906 break;
3907
3908 case GUSICS_DAC_LVL: /* dac out */
3909 if (cp->type == AUDIO_MIXER_VALUE) {
3910 if (gus_to_vol(cp, &vol)) {
3911 ics2101_mix_attenuate(ic,
3912 GUSMIX_CHAN_DAC,
3913 ICSMIX_LEFT,
3914 vol.left);
3915 ics2101_mix_attenuate(ic,
3916 GUSMIX_CHAN_DAC,
3917 ICSMIX_RIGHT,
3918 vol.right);
3919 error = 0;
3920 }
3921 }
3922 break;
3923
3924
3925 case GUSICS_RECORD_SOURCE:
3926 if (cp->type == AUDIO_MIXER_ENUM && cp->un.ord == 0) {
3927 /* Can't set anything else useful, sigh. */
3928 error = 0;
3929 }
3930 break;
3931
3932 default:
3933 return ENXIO;
3934 /*NOTREACHED*/
3935 }
3936 return error;
3937 }
3938
3939 STATIC int
3940 gus_get_props(addr)
3941 void *addr;
3942 {
3943 struct gus_softc *sc = addr;
3944 return sc->sc_recdrq == sc->sc_drq ? 0 : AUDIO_PROP_FULLDUPLEX;
3945 }
3946
3947 STATIC int
3948 gusmax_get_props(addr)
3949 void *addr;
3950 {
3951 struct ad1848_softc *ac = addr;
3952 return gus_get_props(ac->parent);
3953 }
3954
3955 STATIC int
3956 gusmax_mixer_query_devinfo(addr, dip)
3957 void *addr;
3958 mixer_devinfo_t *dip;
3959 {
3960 DPRINTF(("gusmax_query_devinfo: index=%d\n", dip->index));
3961
3962 switch(dip->index) {
3963 #if 0
3964 case GUSMAX_MIC_IN_LVL: /* Microphone */
3965 dip->type = AUDIO_MIXER_VALUE;
3966 dip->mixer_class = GUSMAX_INPUT_CLASS;
3967 dip->prev = AUDIO_MIXER_LAST;
3968 dip->next = GUSMAX_MIC_IN_MUTE;
3969 strcpy(dip->label.name, AudioNmicrophone);
3970 dip->un.v.num_channels = 2;
3971 strcpy(dip->un.v.units.name, AudioNvolume);
3972 break;
3973 #endif
3974
3975 case GUSMAX_MONO_LVL: /* mono/microphone mixer */
3976 dip->type = AUDIO_MIXER_VALUE;
3977 dip->mixer_class = GUSMAX_INPUT_CLASS;
3978 dip->prev = AUDIO_MIXER_LAST;
3979 dip->next = GUSMAX_MONO_MUTE;
3980 strcpy(dip->label.name, AudioNmicrophone);
3981 dip->un.v.num_channels = 1;
3982 strcpy(dip->un.v.units.name, AudioNvolume);
3983 break;
3984
3985 case GUSMAX_DAC_LVL: /* dacout */
3986 dip->type = AUDIO_MIXER_VALUE;
3987 dip->mixer_class = GUSMAX_INPUT_CLASS;
3988 dip->prev = AUDIO_MIXER_LAST;
3989 dip->next = GUSMAX_DAC_MUTE;
3990 strcpy(dip->label.name, AudioNdac);
3991 dip->un.v.num_channels = 2;
3992 strcpy(dip->un.v.units.name, AudioNvolume);
3993 break;
3994
3995 case GUSMAX_LINE_IN_LVL: /* line */
3996 dip->type = AUDIO_MIXER_VALUE;
3997 dip->mixer_class = GUSMAX_INPUT_CLASS;
3998 dip->prev = AUDIO_MIXER_LAST;
3999 dip->next = GUSMAX_LINE_IN_MUTE;
4000 strcpy(dip->label.name, AudioNline);
4001 dip->un.v.num_channels = 2;
4002 strcpy(dip->un.v.units.name, AudioNvolume);
4003 break;
4004
4005 case GUSMAX_CD_LVL: /* cd */
4006 dip->type = AUDIO_MIXER_VALUE;
4007 dip->mixer_class = GUSMAX_INPUT_CLASS;
4008 dip->prev = AUDIO_MIXER_LAST;
4009 dip->next = GUSMAX_CD_MUTE;
4010 strcpy(dip->label.name, AudioNcd);
4011 dip->un.v.num_channels = 2;
4012 strcpy(dip->un.v.units.name, AudioNvolume);
4013 break;
4014
4015
4016 case GUSMAX_MONITOR_LVL: /* monitor level */
4017 dip->type = AUDIO_MIXER_VALUE;
4018 dip->mixer_class = GUSMAX_MONITOR_CLASS;
4019 dip->next = GUSMAX_MONITOR_MUTE;
4020 dip->prev = AUDIO_MIXER_LAST;
4021 strcpy(dip->label.name, AudioNmonitor);
4022 dip->un.v.num_channels = 1;
4023 strcpy(dip->un.v.units.name, AudioNvolume);
4024 break;
4025
4026 case GUSMAX_OUT_LVL: /* cs4231 output volume: not useful? */
4027 dip->type = AUDIO_MIXER_VALUE;
4028 dip->mixer_class = GUSMAX_MONITOR_CLASS;
4029 dip->prev = dip->next = AUDIO_MIXER_LAST;
4030 strcpy(dip->label.name, AudioNoutput);
4031 dip->un.v.num_channels = 2;
4032 strcpy(dip->un.v.units.name, AudioNvolume);
4033 break;
4034
4035 case GUSMAX_SPEAKER_LVL: /* fake speaker volume */
4036 dip->type = AUDIO_MIXER_VALUE;
4037 dip->mixer_class = GUSMAX_MONITOR_CLASS;
4038 dip->prev = AUDIO_MIXER_LAST;
4039 dip->next = GUSMAX_SPEAKER_MUTE;
4040 strcpy(dip->label.name, AudioNspeaker);
4041 dip->un.v.num_channels = 2;
4042 strcpy(dip->un.v.units.name, AudioNvolume);
4043 break;
4044
4045 case GUSMAX_LINE_IN_MUTE:
4046 dip->mixer_class = GUSMAX_INPUT_CLASS;
4047 dip->type = AUDIO_MIXER_ENUM;
4048 dip->prev = GUSMAX_LINE_IN_LVL;
4049 dip->next = AUDIO_MIXER_LAST;
4050 goto mute;
4051
4052 case GUSMAX_DAC_MUTE:
4053 dip->mixer_class = GUSMAX_INPUT_CLASS;
4054 dip->type = AUDIO_MIXER_ENUM;
4055 dip->prev = GUSMAX_DAC_LVL;
4056 dip->next = AUDIO_MIXER_LAST;
4057 goto mute;
4058
4059 case GUSMAX_CD_MUTE:
4060 dip->mixer_class = GUSMAX_INPUT_CLASS;
4061 dip->type = AUDIO_MIXER_ENUM;
4062 dip->prev = GUSMAX_CD_LVL;
4063 dip->next = AUDIO_MIXER_LAST;
4064 goto mute;
4065
4066 case GUSMAX_MONO_MUTE:
4067 dip->mixer_class = GUSMAX_INPUT_CLASS;
4068 dip->type = AUDIO_MIXER_ENUM;
4069 dip->prev = GUSMAX_MONO_LVL;
4070 dip->next = AUDIO_MIXER_LAST;
4071 goto mute;
4072
4073 case GUSMAX_MONITOR_MUTE:
4074 dip->mixer_class = GUSMAX_OUTPUT_CLASS;
4075 dip->type = AUDIO_MIXER_ENUM;
4076 dip->prev = GUSMAX_MONITOR_LVL;
4077 dip->next = AUDIO_MIXER_LAST;
4078 goto mute;
4079
4080 case GUSMAX_SPEAKER_MUTE:
4081 dip->mixer_class = GUSMAX_OUTPUT_CLASS;
4082 dip->type = AUDIO_MIXER_ENUM;
4083 dip->prev = GUSMAX_SPEAKER_LVL;
4084 dip->next = AUDIO_MIXER_LAST;
4085 mute:
4086 strcpy(dip->label.name, AudioNmute);
4087 dip->un.e.num_mem = 2;
4088 strcpy(dip->un.e.member[0].label.name, AudioNoff);
4089 dip->un.e.member[0].ord = 0;
4090 strcpy(dip->un.e.member[1].label.name, AudioNon);
4091 dip->un.e.member[1].ord = 1;
4092 break;
4093
4094 case GUSMAX_REC_LVL: /* record level */
4095 dip->type = AUDIO_MIXER_VALUE;
4096 dip->mixer_class = GUSMAX_RECORD_CLASS;
4097 dip->prev = AUDIO_MIXER_LAST;
4098 dip->next = GUSMAX_RECORD_SOURCE;
4099 strcpy(dip->label.name, AudioNrecord);
4100 dip->un.v.num_channels = 2;
4101 strcpy(dip->un.v.units.name, AudioNvolume);
4102 break;
4103
4104 case GUSMAX_RECORD_SOURCE:
4105 dip->mixer_class = GUSMAX_RECORD_CLASS;
4106 dip->type = AUDIO_MIXER_ENUM;
4107 dip->prev = GUSMAX_REC_LVL;
4108 dip->next = AUDIO_MIXER_LAST;
4109 strcpy(dip->label.name, AudioNsource);
4110 dip->un.e.num_mem = 4;
4111 strcpy(dip->un.e.member[0].label.name, AudioNoutput);
4112 dip->un.e.member[0].ord = DAC_IN_PORT;
4113 strcpy(dip->un.e.member[1].label.name, AudioNmicrophone);
4114 dip->un.e.member[1].ord = MIC_IN_PORT;
4115 strcpy(dip->un.e.member[2].label.name, AudioNdac);
4116 dip->un.e.member[2].ord = AUX1_IN_PORT;
4117 strcpy(dip->un.e.member[3].label.name, AudioNline);
4118 dip->un.e.member[3].ord = LINE_IN_PORT;
4119 break;
4120
4121 case GUSMAX_INPUT_CLASS: /* input class descriptor */
4122 dip->type = AUDIO_MIXER_CLASS;
4123 dip->mixer_class = GUSMAX_INPUT_CLASS;
4124 dip->next = dip->prev = AUDIO_MIXER_LAST;
4125 strcpy(dip->label.name, AudioCinputs);
4126 break;
4127
4128 case GUSMAX_OUTPUT_CLASS: /* output class descriptor */
4129 dip->type = AUDIO_MIXER_CLASS;
4130 dip->mixer_class = GUSMAX_OUTPUT_CLASS;
4131 dip->next = dip->prev = AUDIO_MIXER_LAST;
4132 strcpy(dip->label.name, AudioCoutputs);
4133 break;
4134
4135 case GUSMAX_MONITOR_CLASS: /* monitor class descriptor */
4136 dip->type = AUDIO_MIXER_CLASS;
4137 dip->mixer_class = GUSMAX_MONITOR_CLASS;
4138 dip->next = dip->prev = AUDIO_MIXER_LAST;
4139 strcpy(dip->label.name, AudioCmonitor);
4140 break;
4141
4142 case GUSMAX_RECORD_CLASS: /* record source class */
4143 dip->type = AUDIO_MIXER_CLASS;
4144 dip->mixer_class = GUSMAX_RECORD_CLASS;
4145 dip->next = dip->prev = AUDIO_MIXER_LAST;
4146 strcpy(dip->label.name, AudioCrecord);
4147 break;
4148
4149 default:
4150 return ENXIO;
4151 /*NOTREACHED*/
4152 }
4153 DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name));
4154 return 0;
4155 }
4156
4157 STATIC int
4158 gus_mixer_query_devinfo(addr, dip)
4159 void *addr;
4160 mixer_devinfo_t *dip;
4161 {
4162 struct gus_softc *sc = addr;
4163
4164 DPRINTF(("gusmax_query_devinfo: index=%d\n", dip->index));
4165
4166 if (!HAS_MIXER(sc) && dip->index > GUSICS_MASTER_MUTE)
4167 return ENXIO;
4168
4169 switch(dip->index) {
4170
4171 case GUSICS_MIC_IN_LVL: /* Microphone */
4172 dip->type = AUDIO_MIXER_VALUE;
4173 dip->mixer_class = GUSICS_INPUT_CLASS;
4174 dip->prev = AUDIO_MIXER_LAST;
4175 dip->next = GUSICS_MIC_IN_MUTE;
4176 strcpy(dip->label.name, AudioNmicrophone);
4177 dip->un.v.num_channels = 2;
4178 strcpy(dip->un.v.units.name, AudioNvolume);
4179 break;
4180
4181 case GUSICS_LINE_IN_LVL: /* line */
4182 dip->type = AUDIO_MIXER_VALUE;
4183 dip->mixer_class = GUSICS_INPUT_CLASS;
4184 dip->prev = AUDIO_MIXER_LAST;
4185 dip->next = GUSICS_LINE_IN_MUTE;
4186 strcpy(dip->label.name, AudioNline);
4187 dip->un.v.num_channels = 2;
4188 strcpy(dip->un.v.units.name, AudioNvolume);
4189 break;
4190
4191 case GUSICS_CD_LVL: /* cd */
4192 dip->type = AUDIO_MIXER_VALUE;
4193 dip->mixer_class = GUSICS_INPUT_CLASS;
4194 dip->prev = AUDIO_MIXER_LAST;
4195 dip->next = GUSICS_CD_MUTE;
4196 strcpy(dip->label.name, AudioNcd);
4197 dip->un.v.num_channels = 2;
4198 strcpy(dip->un.v.units.name, AudioNvolume);
4199 break;
4200
4201 case GUSICS_DAC_LVL: /* dacout */
4202 dip->type = AUDIO_MIXER_VALUE;
4203 dip->mixer_class = GUSICS_INPUT_CLASS;
4204 dip->prev = AUDIO_MIXER_LAST;
4205 dip->next = GUSICS_DAC_MUTE;
4206 strcpy(dip->label.name, AudioNdac);
4207 dip->un.v.num_channels = 2;
4208 strcpy(dip->un.v.units.name, AudioNvolume);
4209 break;
4210
4211 case GUSICS_MASTER_LVL: /* master output */
4212 dip->type = AUDIO_MIXER_VALUE;
4213 dip->mixer_class = GUSICS_OUTPUT_CLASS;
4214 dip->prev = AUDIO_MIXER_LAST;
4215 dip->next = GUSICS_MASTER_MUTE;
4216 strcpy(dip->label.name, AudioNvolume);
4217 dip->un.v.num_channels = 2;
4218 strcpy(dip->un.v.units.name, AudioNvolume);
4219 break;
4220
4221
4222 case GUSICS_LINE_IN_MUTE:
4223 dip->mixer_class = GUSICS_INPUT_CLASS;
4224 dip->type = AUDIO_MIXER_ENUM;
4225 dip->prev = GUSICS_LINE_IN_LVL;
4226 dip->next = AUDIO_MIXER_LAST;
4227 goto mute;
4228
4229 case GUSICS_DAC_MUTE:
4230 dip->mixer_class = GUSICS_INPUT_CLASS;
4231 dip->type = AUDIO_MIXER_ENUM;
4232 dip->prev = GUSICS_DAC_LVL;
4233 dip->next = AUDIO_MIXER_LAST;
4234 goto mute;
4235
4236 case GUSICS_CD_MUTE:
4237 dip->mixer_class = GUSICS_INPUT_CLASS;
4238 dip->type = AUDIO_MIXER_ENUM;
4239 dip->prev = GUSICS_CD_LVL;
4240 dip->next = AUDIO_MIXER_LAST;
4241 goto mute;
4242
4243 case GUSICS_MIC_IN_MUTE:
4244 dip->mixer_class = GUSICS_INPUT_CLASS;
4245 dip->type = AUDIO_MIXER_ENUM;
4246 dip->prev = GUSICS_MIC_IN_LVL;
4247 dip->next = AUDIO_MIXER_LAST;
4248 goto mute;
4249
4250 case GUSICS_MASTER_MUTE:
4251 dip->mixer_class = GUSICS_OUTPUT_CLASS;
4252 dip->type = AUDIO_MIXER_ENUM;
4253 dip->prev = GUSICS_MASTER_LVL;
4254 dip->next = AUDIO_MIXER_LAST;
4255 mute:
4256 strcpy(dip->label.name, AudioNmute);
4257 dip->un.e.num_mem = 2;
4258 strcpy(dip->un.e.member[0].label.name, AudioNoff);
4259 dip->un.e.member[0].ord = 0;
4260 strcpy(dip->un.e.member[1].label.name, AudioNon);
4261 dip->un.e.member[1].ord = 1;
4262 break;
4263
4264 case GUSICS_RECORD_SOURCE:
4265 dip->mixer_class = GUSICS_RECORD_CLASS;
4266 dip->type = AUDIO_MIXER_ENUM;
4267 dip->prev = dip->next = AUDIO_MIXER_LAST;
4268 strcpy(dip->label.name, AudioNsource);
4269 dip->un.e.num_mem = 1;
4270 strcpy(dip->un.e.member[0].label.name, AudioNoutput);
4271 dip->un.e.member[0].ord = GUSICS_MASTER_LVL;
4272 break;
4273
4274 case GUSICS_INPUT_CLASS:
4275 dip->type = AUDIO_MIXER_CLASS;
4276 dip->mixer_class = GUSICS_INPUT_CLASS;
4277 dip->next = dip->prev = AUDIO_MIXER_LAST;
4278 strcpy(dip->label.name, AudioCinputs);
4279 break;
4280
4281 case GUSICS_OUTPUT_CLASS:
4282 dip->type = AUDIO_MIXER_CLASS;
4283 dip->mixer_class = GUSICS_OUTPUT_CLASS;
4284 dip->next = dip->prev = AUDIO_MIXER_LAST;
4285 strcpy(dip->label.name, AudioCoutputs);
4286 break;
4287
4288 case GUSICS_RECORD_CLASS:
4289 dip->type = AUDIO_MIXER_CLASS;
4290 dip->mixer_class = GUSICS_RECORD_CLASS;
4291 dip->next = dip->prev = AUDIO_MIXER_LAST;
4292 strcpy(dip->label.name, AudioCrecord);
4293 break;
4294
4295 default:
4296 return ENXIO;
4297 /*NOTREACHED*/
4298 }
4299 DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name));
4300 return 0;
4301 }
4302
4303 STATIC int
4304 gus_query_encoding(addr, fp)
4305 void *addr;
4306 struct audio_encoding *fp;
4307 {
4308 switch (fp->index) {
4309 case 0:
4310 strcpy(fp->name, AudioEmulaw);
4311 fp->encoding = AUDIO_ENCODING_ULAW;
4312 fp->precision = 8;
4313 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
4314 break;
4315 case 1:
4316 strcpy(fp->name, AudioEslinear);
4317 fp->encoding = AUDIO_ENCODING_SLINEAR;
4318 fp->precision = 8;
4319 fp->flags = 0;
4320 break;
4321 case 2:
4322 strcpy(fp->name, AudioEslinear_le);
4323 fp->encoding = AUDIO_ENCODING_SLINEAR_LE;
4324 fp->precision = 16;
4325 fp->flags = 0;
4326 break;
4327 case 3:
4328 strcpy(fp->name, AudioEulinear);
4329 fp->encoding = AUDIO_ENCODING_ULINEAR;
4330 fp->precision = 8;
4331 fp->flags = 0;
4332 break;
4333 case 4:
4334 strcpy(fp->name, AudioEulinear_le);
4335 fp->encoding = AUDIO_ENCODING_ULINEAR_LE;
4336 fp->precision = 16;
4337 fp->flags = 0;
4338 break;
4339 case 5:
4340 strcpy(fp->name, AudioEslinear_be);
4341 fp->encoding = AUDIO_ENCODING_SLINEAR_BE;
4342 fp->precision = 16;
4343 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
4344 break;
4345 case 6:
4346 strcpy(fp->name, AudioEulinear_be);
4347 fp->encoding = AUDIO_ENCODING_ULINEAR_BE;
4348 fp->precision = 16;
4349 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
4350 break;
4351 case 7:
4352 strcpy(fp->name, AudioEalaw);
4353 fp->encoding = AUDIO_ENCODING_ALAW;
4354 fp->precision = 8;
4355 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
4356 break;
4357
4358 default:
4359 return(EINVAL);
4360 /*NOTREACHED*/
4361 }
4362 return (0);
4363 }
4364
4365 /*
4366 * Setup the ICS mixer in "transparent" mode: reset everything to a sensible
4367 * level. Levels as suggested by GUS SDK code.
4368 */
4369
4370 STATIC void
4371 gus_init_ics2101(sc)
4372 struct gus_softc *sc;
4373 {
4374 struct ics2101_softc *ic = &sc->sc_mixer;
4375 sc->sc_mixer.sc_iot = sc->sc_iot;
4376 sc->sc_mixer.sc_selio = GUS_MIXER_SELECT;
4377 sc->sc_mixer.sc_selio_ioh = sc->sc_ioh3;
4378 sc->sc_mixer.sc_dataio = GUS_MIXER_DATA;
4379 sc->sc_mixer.sc_dataio_ioh = sc->sc_ioh2;
4380 sc->sc_mixer.sc_flags = (sc->sc_revision == 5) ? ICS_FLIP : 0;
4381
4382 ics2101_mix_attenuate(ic,
4383 GUSMIX_CHAN_MIC,
4384 ICSMIX_LEFT,
4385 ICSMIX_MIN_ATTN);
4386 ics2101_mix_attenuate(ic,
4387 GUSMIX_CHAN_MIC,
4388 ICSMIX_RIGHT,
4389 ICSMIX_MIN_ATTN);
4390 /*
4391 * Start with microphone muted by the mixer...
4392 */
4393 gusics_mic_mute(ic, 1);
4394
4395 /* ... and enabled by the GUS master mix control */
4396 gus_mic_ctl(sc, SPKR_ON);
4397
4398 ics2101_mix_attenuate(ic,
4399 GUSMIX_CHAN_LINE,
4400 ICSMIX_LEFT,
4401 ICSMIX_MIN_ATTN);
4402 ics2101_mix_attenuate(ic,
4403 GUSMIX_CHAN_LINE,
4404 ICSMIX_RIGHT,
4405 ICSMIX_MIN_ATTN);
4406
4407 ics2101_mix_attenuate(ic,
4408 GUSMIX_CHAN_CD,
4409 ICSMIX_LEFT,
4410 ICSMIX_MIN_ATTN);
4411 ics2101_mix_attenuate(ic,
4412 GUSMIX_CHAN_CD,
4413 ICSMIX_RIGHT,
4414 ICSMIX_MIN_ATTN);
4415
4416 ics2101_mix_attenuate(ic,
4417 GUSMIX_CHAN_DAC,
4418 ICSMIX_LEFT,
4419 ICSMIX_MIN_ATTN);
4420 ics2101_mix_attenuate(ic,
4421 GUSMIX_CHAN_DAC,
4422 ICSMIX_RIGHT,
4423 ICSMIX_MIN_ATTN);
4424
4425 ics2101_mix_attenuate(ic,
4426 ICSMIX_CHAN_4,
4427 ICSMIX_LEFT,
4428 ICSMIX_MAX_ATTN);
4429 ics2101_mix_attenuate(ic,
4430 ICSMIX_CHAN_4,
4431 ICSMIX_RIGHT,
4432 ICSMIX_MAX_ATTN);
4433
4434 ics2101_mix_attenuate(ic,
4435 GUSMIX_CHAN_MASTER,
4436 ICSMIX_LEFT,
4437 ICSMIX_MIN_ATTN);
4438 ics2101_mix_attenuate(ic,
4439 GUSMIX_CHAN_MASTER,
4440 ICSMIX_RIGHT,
4441 ICSMIX_MIN_ATTN);
4442 /* unmute other stuff: */
4443 gusics_cd_mute(ic, 0);
4444 gusics_dac_mute(ic, 0);
4445 gusics_linein_mute(ic, 0);
4446 return;
4447 }
4448
4449
4450 #endif /* NGUS */
4451