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