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