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