gus.c revision 1.52 1 /* $NetBSD: gus.c,v 1.52 1998/03/09 06:32:51 mikel 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 panic("%s: negative bufcnt in stopped voice",
1690 sc->sc_dev.dv_xname);
1691 } else {
1692 sc->sc_playbuf = -1; /* none are active */
1693 gus_stops++;
1694 }
1695 /* fall through to callback and admit another
1696 buffer.... */
1697 } else if (sc->sc_bufcnt != 0) {
1698 /*
1699 * This should always be taken if the voice
1700 * is not stopped.
1701 */
1702 gus_continues++;
1703 if (gus_continue_playing(sc, voice)) {
1704 /*
1705 * we shouldn't have continued--active DMA
1706 * is in the way in the ring, for
1707 * some as-yet undebugged reason.
1708 */
1709 gus_stop_voice(sc, GUS_VOICE_LEFT, 1);
1710 /* also kill right voice */
1711 gus_stop_voice(sc, GUS_VOICE_RIGHT, 0);
1712 sc->sc_playbuf = -1;
1713 gus_stops++;
1714 }
1715 }
1716 /*
1717 * call the upper level to send on down another
1718 * block. We do admission rate control as follows:
1719 *
1720 * When starting up output (in the first N
1721 * blocks), call the upper layer after the DMA is
1722 * complete (see above in gus_dmaout_intr()).
1723 *
1724 * When output is already in progress and we have
1725 * no more GUS buffers to use for DMA, the DMA
1726 * output routines do not call the upper layer.
1727 * Instead, we call the DMA completion routine
1728 * here, after the voice interrupts indicating
1729 * that it's finished with a buffer.
1730 *
1731 * However, don't call anything here if the DMA
1732 * output flag is set, (which shouldn't happen)
1733 * because we'll squish somebody else's DMA if
1734 * that's the case. When DMA is done, it will
1735 * call back if there is a spare buffer.
1736 */
1737 if (sc->sc_dmaoutintr && !(sc->sc_flags & GUS_LOCKED)) {
1738 if (sc->sc_dmaoutintr == stereo_dmaintr)
1739 printf("gusdmaout botch?\n");
1740 else {
1741 /* clean out to avoid double calls */
1742 void (*pfunc) __P((void *)) = sc->sc_dmaoutintr;
1743 void *arg = sc->sc_outarg;
1744
1745 sc->sc_outarg = 0;
1746 sc->sc_dmaoutintr = 0;
1747 (*pfunc)(arg);
1748 }
1749 }
1750 }
1751
1752 /*
1753 * Ignore other interrupts for now
1754 */
1755 }
1756 return 0;
1757 }
1758
1759 STATIC void
1760 gus_start_playing(sc, bufno)
1761 struct gus_softc *sc;
1762 int bufno;
1763 {
1764 bus_space_tag_t iot = sc->sc_iot;
1765 bus_space_handle_t ioh2 = sc->sc_ioh2;
1766 /*
1767 * Start the voices playing, with buffer BUFNO.
1768 */
1769
1770 /*
1771 * Loop or roll if we have buffers ready.
1772 */
1773
1774 if (sc->sc_bufcnt == 1) {
1775 sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~(GUSMASK_LOOP_ENABLE);
1776 sc->sc_voc[GUS_VOICE_LEFT].volcntl &= ~(GUSMASK_VOICE_ROLL);
1777 } else {
1778 if (bufno == sc->sc_nbufs - 1) {
1779 sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_LOOP_ENABLE;
1780 sc->sc_voc[GUS_VOICE_LEFT].volcntl &= ~(GUSMASK_VOICE_ROLL);
1781 } else {
1782 sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~GUSMASK_LOOP_ENABLE;
1783 sc->sc_voc[GUS_VOICE_LEFT].volcntl |= GUSMASK_VOICE_ROLL;
1784 }
1785 }
1786
1787 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, GUS_VOICE_LEFT);
1788
1789 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
1790 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_LEFT].voccntl);
1791
1792 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
1793 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_LEFT].volcntl);
1794
1795 sc->sc_voc[GUS_VOICE_LEFT].current_addr =
1796 GUS_MEM_OFFSET + sc->sc_chanblocksize * bufno;
1797 sc->sc_voc[GUS_VOICE_LEFT].end_addr =
1798 sc->sc_voc[GUS_VOICE_LEFT].current_addr + sc->sc_chanblocksize - 1;
1799 sc->sc_voc[GUS_VOICE_RIGHT].current_addr =
1800 sc->sc_voc[GUS_VOICE_LEFT].current_addr +
1801 (gus_dostereo && sc->sc_channels == 2 ? GUS_LEFT_RIGHT_OFFSET : 0);
1802 /*
1803 * set up right channel to just loop forever, no interrupts,
1804 * starting at the buffer we just filled. We'll feed it data
1805 * at the same time as left channel.
1806 */
1807 sc->sc_voc[GUS_VOICE_RIGHT].voccntl |= GUSMASK_LOOP_ENABLE;
1808 sc->sc_voc[GUS_VOICE_RIGHT].volcntl &= ~(GUSMASK_VOICE_ROLL);
1809
1810 #ifdef GUSPLAYDEBUG
1811 if (gusstats) {
1812 microtime(&playstats[playcntr].tv);
1813 playstats[playcntr].curaddr = sc->sc_voc[GUS_VOICE_LEFT].current_addr;
1814
1815 playstats[playcntr].voccntl = sc->sc_voc[GUS_VOICE_LEFT].voccntl;
1816 playstats[playcntr].volcntl = sc->sc_voc[GUS_VOICE_LEFT].volcntl;
1817 playstats[playcntr].endaddr = sc->sc_voc[GUS_VOICE_LEFT].end_addr;
1818 playstats[playcntr].playbuf = bufno;
1819 playstats[playcntr].dmabuf = sc->sc_dmabuf;
1820 playstats[playcntr].bufcnt = sc->sc_bufcnt;
1821 playstats[playcntr].vaction = 5;
1822 playcntr = ++playcntr % NDMARECS;
1823 }
1824 #endif
1825
1826 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, GUS_VOICE_RIGHT);
1827 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
1828 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_RIGHT].voccntl);
1829 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
1830 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_RIGHT].volcntl);
1831
1832 gus_start_voice(sc, GUS_VOICE_RIGHT, 0);
1833 gus_start_voice(sc, GUS_VOICE_LEFT, 1);
1834 if (sc->sc_playbuf == -1)
1835 /* mark start of playing */
1836 sc->sc_playbuf = bufno;
1837 }
1838
1839 STATIC int
1840 gus_continue_playing(sc, voice)
1841 struct gus_softc *sc;
1842 int voice;
1843 {
1844 bus_space_tag_t iot = sc->sc_iot;
1845 bus_space_handle_t ioh2 = sc->sc_ioh2;
1846
1847 /*
1848 * stop this voice from interrupting while we work.
1849 */
1850
1851 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
1852 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl & ~(GUSMASK_VOICE_IRQ));
1853
1854 /*
1855 * update playbuf to point to the buffer the hardware just started
1856 * playing
1857 */
1858 sc->sc_playbuf = ++sc->sc_playbuf % sc->sc_nbufs;
1859
1860 /*
1861 * account for buffer just finished
1862 */
1863 if (--sc->sc_bufcnt == 0) {
1864 DPRINTF(("gus: bufcnt 0 on continuing voice?\n"));
1865 }
1866 if (sc->sc_playbuf == sc->sc_dmabuf && (sc->sc_flags & GUS_LOCKED)) {
1867 printf("%s: continue into active dmabuf?\n", sc->sc_dev.dv_xname);
1868 return 1;
1869 }
1870
1871 /*
1872 * Select the end of the buffer based on the currently active
1873 * buffer, [plus extra contiguous buffers (if ready)].
1874 */
1875
1876 /*
1877 * set endpoint at end of buffer we just started playing.
1878 *
1879 * The total gets -1 because end addrs are one less than you might
1880 * think (the end_addr is the address of the last sample to play)
1881 */
1882 gus_set_endaddr(sc, voice, GUS_MEM_OFFSET +
1883 sc->sc_chanblocksize * (sc->sc_playbuf + 1) - 1);
1884
1885 if (sc->sc_bufcnt < 2) {
1886 /*
1887 * Clear out the loop and roll flags, and rotate the currently
1888 * playing buffer. That way, if we don't manage to get more
1889 * data before this buffer finishes, we'll just stop.
1890 */
1891 sc->sc_voc[voice].voccntl &= ~GUSMASK_LOOP_ENABLE;
1892 sc->sc_voc[voice].volcntl &= ~GUSMASK_VOICE_ROLL;
1893 playstats[playcntr].vaction = 0;
1894 } else {
1895 /*
1896 * We have some buffers to play. set LOOP if we're on the
1897 * last buffer in the ring, otherwise set ROLL.
1898 */
1899 if (sc->sc_playbuf == sc->sc_nbufs - 1) {
1900 sc->sc_voc[voice].voccntl |= GUSMASK_LOOP_ENABLE;
1901 sc->sc_voc[voice].volcntl &= ~GUSMASK_VOICE_ROLL;
1902 playstats[playcntr].vaction = 1;
1903 } else {
1904 sc->sc_voc[voice].voccntl &= ~GUSMASK_LOOP_ENABLE;
1905 sc->sc_voc[voice].volcntl |= GUSMASK_VOICE_ROLL;
1906 playstats[playcntr].vaction = 2;
1907 }
1908 }
1909 #ifdef GUSPLAYDEBUG
1910 if (gusstats) {
1911 microtime(&playstats[playcntr].tv);
1912 playstats[playcntr].curaddr = gus_get_curaddr(sc, voice);
1913
1914 playstats[playcntr].voccntl = sc->sc_voc[voice].voccntl;
1915 playstats[playcntr].volcntl = sc->sc_voc[voice].volcntl;
1916 playstats[playcntr].endaddr = sc->sc_voc[voice].end_addr;
1917 playstats[playcntr].playbuf = sc->sc_playbuf;
1918 playstats[playcntr].dmabuf = sc->sc_dmabuf;
1919 playstats[playcntr].bufcnt = sc->sc_bufcnt;
1920 playcntr = ++playcntr % NDMARECS;
1921 }
1922 #endif
1923
1924 /*
1925 * (re-)set voice parameters. This will reenable interrupts from this
1926 * voice.
1927 */
1928
1929 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
1930 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
1931 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
1932 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].volcntl);
1933 return 0;
1934 }
1935
1936 /*
1937 * Send/receive data into GUS's DRAM using DMA. Called at splgus()
1938 */
1939
1940 STATIC void
1941 gusdmaout(sc, flags, gusaddr, buffaddr, length)
1942 struct gus_softc *sc;
1943 int flags, length;
1944 u_long gusaddr;
1945 caddr_t buffaddr;
1946 {
1947 unsigned char c = (unsigned char) flags;
1948 bus_space_tag_t iot = sc->sc_iot;
1949 bus_space_handle_t ioh2 = sc->sc_ioh2;
1950
1951 DMAPRINTF(("gusdmaout flags=%x scflags=%x\n", flags, sc->sc_flags));
1952
1953 sc->sc_gusaddr = gusaddr;
1954
1955 /*
1956 * If we're using a 16 bit DMA channel, we have to jump through some
1957 * extra hoops; this includes translating the DRAM address a bit
1958 */
1959
1960 if (sc->sc_drq >= 4) {
1961 c |= GUSMASK_DMA_WIDTH;
1962 gusaddr = convert_to_16bit(gusaddr);
1963 }
1964
1965 /*
1966 * Add flag bits that we always set - fast DMA, enable IRQ
1967 */
1968
1969 c |= GUSMASK_DMA_ENABLE | GUSMASK_DMA_R0 | GUSMASK_DMA_IRQ;
1970
1971 /*
1972 * Make sure the GUS _isn't_ setup for DMA
1973 */
1974
1975 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
1976 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0);
1977
1978 /*
1979 * Tell the PC DMA controller to start doing DMA
1980 */
1981
1982 sc->sc_dmaoutaddr = (u_char *) buffaddr;
1983 sc->sc_dmaoutcnt = length;
1984 isa_dmastart(sc->sc_dev.dv_parent, sc->sc_drq, buffaddr, length,
1985 NULL, DMAMODE_WRITE, BUS_DMA_NOWAIT);
1986
1987 /*
1988 * Set up DMA address - use the upper 16 bits ONLY
1989 */
1990
1991 sc->sc_flags |= GUS_DMAOUT_ACTIVE;
1992
1993 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_START);
1994 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, (int) (gusaddr >> 4));
1995
1996 /*
1997 * Tell the GUS to start doing DMA
1998 */
1999
2000 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
2001 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, c);
2002
2003 /*
2004 * XXX If we don't finish in one second, give up...
2005 */
2006 untimeout(gus_dmaout_timeout, sc); /* flush old one, if there is one */
2007 timeout(gus_dmaout_timeout, sc, hz);
2008 }
2009
2010 /*
2011 * Start a voice playing on the GUS. Called from interrupt handler at
2012 * splgus().
2013 */
2014
2015 STATIC void
2016 gus_start_voice(sc, voice, intrs)
2017 struct gus_softc *sc;
2018 int voice;
2019 int intrs;
2020 {
2021 bus_space_tag_t iot = sc->sc_iot;
2022 bus_space_handle_t ioh2 = sc->sc_ioh2;
2023 u_long start;
2024 u_long current;
2025 u_long end;
2026
2027 /*
2028 * Pick all the values for the voice out of the gus_voice struct
2029 * and use those to program the voice
2030 */
2031
2032 start = sc->sc_voc[voice].start_addr;
2033 current = sc->sc_voc[voice].current_addr;
2034 end = sc->sc_voc[voice].end_addr;
2035
2036 /*
2037 * If we're using 16 bit data, mangle the addresses a bit
2038 */
2039
2040 if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16) {
2041 /* -1 on start so that we get onto sample boundary--other
2042 code always sets it for 1-byte rollover protection */
2043 start = convert_to_16bit(start-1);
2044 current = convert_to_16bit(current);
2045 end = convert_to_16bit(end);
2046 }
2047
2048 /*
2049 * Select the voice we want to use, and program the data addresses
2050 */
2051
2052 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
2053
2054 SELECT_GUS_REG(iot, ioh2, GUSREG_START_ADDR_HIGH);
2055 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(start));
2056 SELECT_GUS_REG(iot, ioh2, GUSREG_START_ADDR_LOW);
2057 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(start));
2058
2059 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH);
2060 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(current));
2061 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW);
2062 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(current));
2063
2064 SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_HIGH);
2065 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(end));
2066 SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_LOW);
2067 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(end));
2068
2069 /*
2070 * (maybe) enable interrupts, disable voice stopping
2071 */
2072
2073 if (intrs) {
2074 sc->sc_flags |= GUS_PLAYING; /* playing is about to start */
2075 sc->sc_voc[voice].voccntl |= GUSMASK_VOICE_IRQ;
2076 DMAPRINTF(("gus voice playing=%x\n", sc->sc_flags));
2077 } else
2078 sc->sc_voc[voice].voccntl &= ~GUSMASK_VOICE_IRQ;
2079 sc->sc_voc[voice].voccntl &= ~(GUSMASK_VOICE_STOPPED |
2080 GUSMASK_STOP_VOICE);
2081
2082 /*
2083 * Tell the GUS about it. Note that we're doing volume ramping here
2084 * from 0 up to the set volume to help reduce clicks.
2085 */
2086
2087 SELECT_GUS_REG(iot, ioh2, GUSREG_START_VOLUME);
2088 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
2089 SELECT_GUS_REG(iot, ioh2, GUSREG_END_VOLUME);
2090 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].current_volume >> 4);
2091 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME);
2092 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x00);
2093 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_RATE);
2094 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 63);
2095
2096 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
2097 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
2098 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
2099 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
2100 delay(50);
2101 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
2102 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
2103 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
2104 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
2105
2106 }
2107
2108 /*
2109 * Stop a given voice. called at splgus()
2110 */
2111
2112 STATIC void
2113 gus_stop_voice(sc, voice, intrs_too)
2114 struct gus_softc *sc;
2115 int voice;
2116 int intrs_too;
2117 {
2118 bus_space_tag_t iot = sc->sc_iot;
2119 bus_space_handle_t ioh2 = sc->sc_ioh2;
2120
2121 sc->sc_voc[voice].voccntl |= GUSMASK_VOICE_STOPPED |
2122 GUSMASK_STOP_VOICE;
2123 if (intrs_too) {
2124 sc->sc_voc[voice].voccntl &= ~(GUSMASK_VOICE_IRQ);
2125 /* no more DMA to do */
2126 sc->sc_flags &= ~GUS_PLAYING;
2127 }
2128 DMAPRINTF(("gusintr voice notplaying=%x\n", sc->sc_flags));
2129
2130 guspoke(iot, ioh2, 0L, 0);
2131
2132 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
2133
2134 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME);
2135 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2136 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
2137 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
2138 delay(100);
2139 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME);
2140 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2141 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
2142 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
2143
2144 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH);
2145 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2146 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW);
2147 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2148
2149 }
2150
2151
2152 /*
2153 * Set the volume of a given voice. Called at splgus().
2154 */
2155 STATIC void
2156 gus_set_volume(sc, voice, volume)
2157 struct gus_softc *sc;
2158 int voice, volume;
2159 {
2160 bus_space_tag_t iot = sc->sc_iot;
2161 bus_space_handle_t ioh2 = sc->sc_ioh2;
2162 unsigned int gusvol;
2163
2164 gusvol = gus_log_volumes[volume < 512 ? volume : 511];
2165
2166 sc->sc_voc[voice].current_volume = gusvol;
2167
2168 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
2169
2170 SELECT_GUS_REG(iot, ioh2, GUSREG_START_VOLUME);
2171 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (unsigned char) (gusvol >> 4));
2172
2173 SELECT_GUS_REG(iot, ioh2, GUSREG_END_VOLUME);
2174 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (unsigned char) (gusvol >> 4));
2175
2176 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME);
2177 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, gusvol << 4);
2178 delay(500);
2179 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, gusvol << 4);
2180
2181 }
2182
2183 /*
2184 * Interface to the audio layer.
2185 */
2186
2187 int
2188 gusmax_set_params(addr, setmode, usemode, p, r)
2189 void *addr;
2190 int setmode, usemode;
2191 struct audio_params *p, *r;
2192 {
2193 struct ad1848_softc *ac = addr;
2194 struct gus_softc *sc = ac->parent;
2195 int error;
2196
2197 error = ad1848_set_params(ac, setmode, usemode, p, r);
2198 if (error)
2199 return error;
2200 error = gus_set_params(sc, setmode, usemode, p, r);
2201 return error;
2202 }
2203
2204 int
2205 gus_set_params(addr, setmode, usemode, p, r)
2206 void *addr;
2207 int setmode, usemode;
2208 struct audio_params *p, *r;
2209 {
2210 struct gus_softc *sc = addr;
2211 int s;
2212
2213 switch (p->encoding) {
2214 case AUDIO_ENCODING_ULAW:
2215 case AUDIO_ENCODING_ALAW:
2216 case AUDIO_ENCODING_SLINEAR_LE:
2217 case AUDIO_ENCODING_ULINEAR_LE:
2218 case AUDIO_ENCODING_SLINEAR_BE:
2219 case AUDIO_ENCODING_ULINEAR_BE:
2220 break;
2221 default:
2222 return (EINVAL);
2223 }
2224
2225 s = splaudio();
2226
2227 if (p->precision == 8) {
2228 sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~GUSMASK_DATA_SIZE16;
2229 sc->sc_voc[GUS_VOICE_RIGHT].voccntl &= ~GUSMASK_DATA_SIZE16;
2230 } else {
2231 sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_DATA_SIZE16;
2232 sc->sc_voc[GUS_VOICE_RIGHT].voccntl |= GUSMASK_DATA_SIZE16;
2233 }
2234
2235 sc->sc_encoding = p->encoding;
2236 sc->sc_precision = p->precision;
2237 sc->sc_channels = p->channels;
2238
2239 splx(s);
2240
2241 if (p->sample_rate > gus_max_frequency[sc->sc_voices - GUS_MIN_VOICES])
2242 p->sample_rate = gus_max_frequency[sc->sc_voices - GUS_MIN_VOICES];
2243 if (setmode & AUMODE_RECORD)
2244 sc->sc_irate = p->sample_rate;
2245 if (setmode & AUMODE_PLAY)
2246 sc->sc_orate = p->sample_rate;
2247
2248 switch (p->encoding) {
2249 case AUDIO_ENCODING_ULAW:
2250 p->sw_code = mulaw_to_ulinear8;
2251 r->sw_code = ulinear8_to_mulaw;
2252 break;
2253 case AUDIO_ENCODING_ALAW:
2254 p->sw_code = alaw_to_ulinear8;
2255 r->sw_code = ulinear8_to_alaw;
2256 break;
2257 case AUDIO_ENCODING_ULINEAR_BE:
2258 case AUDIO_ENCODING_SLINEAR_BE:
2259 r->sw_code = p->sw_code = swap_bytes;
2260 break;
2261 }
2262
2263 return 0;
2264 }
2265
2266 /*
2267 * Interface to the audio layer - set the blocksize to the correct number
2268 * of units
2269 */
2270
2271 int
2272 gusmax_round_blocksize(addr, blocksize)
2273 void * addr;
2274 int blocksize;
2275 {
2276 struct ad1848_softc *ac = addr;
2277 struct gus_softc *sc = ac->parent;
2278
2279 /* blocksize = ad1848_round_blocksize(ac, blocksize);*/
2280 return gus_round_blocksize(sc, blocksize);
2281 }
2282
2283 int
2284 gus_round_blocksize(addr, blocksize)
2285 void * addr;
2286 int blocksize;
2287 {
2288 struct gus_softc *sc = addr;
2289
2290 DPRINTF(("gus_round_blocksize called\n"));
2291
2292 if ((sc->sc_encoding == AUDIO_ENCODING_ULAW ||
2293 sc->sc_encoding == AUDIO_ENCODING_ALAW) && blocksize > 32768)
2294 blocksize = 32768;
2295 else if (blocksize > 65536)
2296 blocksize = 65536;
2297
2298 if ((blocksize % GUS_BUFFER_MULTIPLE) != 0)
2299 blocksize = (blocksize / GUS_BUFFER_MULTIPLE + 1) *
2300 GUS_BUFFER_MULTIPLE;
2301
2302 /* set up temporary buffer to hold the deinterleave, if necessary
2303 for stereo output */
2304 if (sc->sc_deintr_buf) {
2305 FREE(sc->sc_deintr_buf, M_DEVBUF);
2306 sc->sc_deintr_buf = NULL;
2307 }
2308 MALLOC(sc->sc_deintr_buf, void *, blocksize>>1, M_DEVBUF, M_WAITOK);
2309
2310 sc->sc_blocksize = blocksize;
2311 /* multi-buffering not quite working yet. */
2312 sc->sc_nbufs = /*GUS_MEM_FOR_BUFFERS / blocksize*/ 2;
2313
2314 gus_set_chan_addrs(sc);
2315
2316 return blocksize;
2317 }
2318
2319 int
2320 gus_get_out_gain(addr)
2321 caddr_t addr;
2322 {
2323 struct gus_softc *sc = (struct gus_softc *) addr;
2324
2325 DPRINTF(("gus_get_out_gain called\n"));
2326 return sc->sc_ogain / 2;
2327 }
2328
2329 STATIC inline void gus_set_voices(sc, voices)
2330 struct gus_softc *sc;
2331 int voices;
2332 {
2333 bus_space_tag_t iot = sc->sc_iot;
2334 bus_space_handle_t ioh2 = sc->sc_ioh2;
2335 /*
2336 * Select the active number of voices
2337 */
2338
2339 SELECT_GUS_REG(iot, ioh2, GUSREG_ACTIVE_VOICES);
2340 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (voices-1) | 0xc0);
2341
2342 sc->sc_voices = voices;
2343 }
2344
2345 /*
2346 * Actually set the settings of various values on the card
2347 */
2348
2349 int
2350 gusmax_commit_settings(addr)
2351 void * addr;
2352 {
2353 struct ad1848_softc *ac = addr;
2354 struct gus_softc *sc = ac->parent;
2355 int error;
2356
2357 error = ad1848_commit_settings(ac);
2358 if (error)
2359 return error;
2360 return gus_commit_settings(sc);
2361 }
2362
2363 /*
2364 * Commit the settings. Called at normal IPL.
2365 */
2366 int
2367 gus_commit_settings(addr)
2368 void * addr;
2369 {
2370 struct gus_softc *sc = addr;
2371 int s;
2372
2373 DPRINTF(("gus_commit_settings called (gain = %d)\n",sc->sc_ogain));
2374
2375
2376 s = splgus();
2377
2378 gus_set_recrate(sc, sc->sc_irate);
2379 gus_set_volume(sc, GUS_VOICE_LEFT, sc->sc_ogain);
2380 gus_set_volume(sc, GUS_VOICE_RIGHT, sc->sc_ogain);
2381 gus_set_samprate(sc, GUS_VOICE_LEFT, sc->sc_orate);
2382 gus_set_samprate(sc, GUS_VOICE_RIGHT, sc->sc_orate);
2383 splx(s);
2384 gus_set_chan_addrs(sc);
2385
2386 return 0;
2387 }
2388
2389 STATIC void
2390 gus_set_chan_addrs(sc)
2391 struct gus_softc *sc;
2392 {
2393 /*
2394 * We use sc_nbufs * blocksize bytes of storage in the on-board GUS
2395 * ram.
2396 * For mono, each of the sc_nbufs buffers is DMA'd to in one chunk,
2397 * and both left & right channels play the same buffer.
2398 *
2399 * For stereo, each channel gets a contiguous half of the memory,
2400 * and each has sc_nbufs buffers of size blocksize/2.
2401 * Stereo data are deinterleaved in main memory before the DMA out
2402 * routines are called to queue the output.
2403 *
2404 * The blocksize per channel is kept in sc_chanblocksize.
2405 */
2406 if (sc->sc_channels == 2)
2407 sc->sc_chanblocksize = sc->sc_blocksize/2;
2408 else
2409 sc->sc_chanblocksize = sc->sc_blocksize;
2410
2411 sc->sc_voc[GUS_VOICE_LEFT].start_addr = GUS_MEM_OFFSET - 1;
2412 sc->sc_voc[GUS_VOICE_RIGHT].start_addr =
2413 (gus_dostereo && sc->sc_channels == 2 ? GUS_LEFT_RIGHT_OFFSET : 0)
2414 + GUS_MEM_OFFSET - 1;
2415 sc->sc_voc[GUS_VOICE_RIGHT].current_addr =
2416 sc->sc_voc[GUS_VOICE_RIGHT].start_addr + 1;
2417 sc->sc_voc[GUS_VOICE_RIGHT].end_addr =
2418 sc->sc_voc[GUS_VOICE_RIGHT].start_addr +
2419 sc->sc_nbufs * sc->sc_chanblocksize;
2420
2421 }
2422
2423 /*
2424 * Set the sample rate of the given voice. Called at splgus().
2425 */
2426
2427 STATIC void
2428 gus_set_samprate(sc, voice, freq)
2429 struct gus_softc *sc;
2430 int voice, freq;
2431 {
2432 bus_space_tag_t iot = sc->sc_iot;
2433 bus_space_handle_t ioh2 = sc->sc_ioh2;
2434 unsigned int fc;
2435 u_long temp, f = (u_long) freq;
2436
2437 /*
2438 * calculate fc based on the number of active voices;
2439 * we need to use longs to preserve enough bits
2440 */
2441
2442 temp = (u_long) gus_max_frequency[sc->sc_voices-GUS_MIN_VOICES];
2443
2444 fc = (unsigned int)(((f << 9L) + (temp >> 1L)) / temp);
2445
2446 fc <<= 1;
2447
2448
2449 /*
2450 * Program the voice frequency, and set it in the voice data record
2451 */
2452
2453 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
2454 SELECT_GUS_REG(iot, ioh2, GUSREG_FREQ_CONTROL);
2455 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, fc);
2456
2457 sc->sc_voc[voice].rate = freq;
2458
2459 }
2460
2461 /*
2462 * Set the sample rate of the recording frequency. Formula is from the GUS
2463 * SDK. Called at splgus().
2464 */
2465
2466 STATIC void
2467 gus_set_recrate(sc, rate)
2468 struct gus_softc *sc;
2469 u_long rate;
2470 {
2471 bus_space_tag_t iot = sc->sc_iot;
2472 bus_space_handle_t ioh2 = sc->sc_ioh2;
2473 u_char realrate;
2474 DPRINTF(("gus_set_recrate %lu\n", rate));
2475
2476 #if 0
2477 realrate = 9878400/(16*(rate+2)); /* formula from GUS docs */
2478 #endif
2479 realrate = (9878400 >> 4)/rate - 2; /* formula from code, sigh. */
2480
2481 SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_FREQ);
2482 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, realrate);
2483 }
2484
2485 /*
2486 * Interface to the audio layer - turn the output on or off. Note that some
2487 * of these bits are flipped in the register
2488 */
2489
2490 int
2491 gusmax_speaker_ctl(addr, newstate)
2492 void * addr;
2493 int newstate;
2494 {
2495 struct ad1848_softc *sc = addr;
2496 return gus_speaker_ctl(sc->parent, newstate);
2497 }
2498
2499 int
2500 gus_speaker_ctl(addr, newstate)
2501 void * addr;
2502 int newstate;
2503 {
2504 struct gus_softc *sc = (struct gus_softc *) addr;
2505 bus_space_tag_t iot = sc->sc_iot;
2506 bus_space_handle_t ioh1 = sc->sc_ioh1;
2507
2508 /* Line out bit is flipped: 0 enables, 1 disables */
2509 if ((newstate == SPKR_ON) &&
2510 (sc->sc_mixcontrol & GUSMASK_LINE_OUT)) {
2511 sc->sc_mixcontrol &= ~GUSMASK_LINE_OUT;
2512 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
2513 }
2514 if ((newstate == SPKR_OFF) &&
2515 (sc->sc_mixcontrol & GUSMASK_LINE_OUT) == 0) {
2516 sc->sc_mixcontrol |= GUSMASK_LINE_OUT;
2517 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
2518 }
2519
2520 return 0;
2521 }
2522
2523 STATIC int
2524 gus_linein_ctl(addr, newstate)
2525 void * addr;
2526 int newstate;
2527 {
2528 struct gus_softc *sc = (struct gus_softc *) addr;
2529 bus_space_tag_t iot = sc->sc_iot;
2530 bus_space_handle_t ioh1 = sc->sc_ioh1;
2531
2532 /* Line in bit is flipped: 0 enables, 1 disables */
2533 if ((newstate == SPKR_ON) &&
2534 (sc->sc_mixcontrol & GUSMASK_LINE_IN)) {
2535 sc->sc_mixcontrol &= ~GUSMASK_LINE_IN;
2536 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
2537 }
2538 if ((newstate == SPKR_OFF) &&
2539 (sc->sc_mixcontrol & GUSMASK_LINE_IN) == 0) {
2540 sc->sc_mixcontrol |= GUSMASK_LINE_IN;
2541 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
2542 }
2543
2544 return 0;
2545 }
2546
2547 STATIC int
2548 gus_mic_ctl(addr, newstate)
2549 void * addr;
2550 int newstate;
2551 {
2552 struct gus_softc *sc = (struct gus_softc *) addr;
2553 bus_space_tag_t iot = sc->sc_iot;
2554 bus_space_handle_t ioh1 = sc->sc_ioh1;
2555
2556 /* Mic bit is normal: 1 enables, 0 disables */
2557 if ((newstate == SPKR_ON) &&
2558 (sc->sc_mixcontrol & GUSMASK_MIC_IN) == 0) {
2559 sc->sc_mixcontrol |= GUSMASK_MIC_IN;
2560 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
2561 }
2562 if ((newstate == SPKR_OFF) &&
2563 (sc->sc_mixcontrol & GUSMASK_MIC_IN)) {
2564 sc->sc_mixcontrol &= ~GUSMASK_MIC_IN;
2565 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
2566 }
2567
2568 return 0;
2569 }
2570
2571 /*
2572 * Set the end address of a give voice. Called at splgus()
2573 */
2574
2575 STATIC void
2576 gus_set_endaddr(sc, voice, addr)
2577 struct gus_softc *sc;
2578 int voice;
2579 u_long addr;
2580 {
2581 bus_space_tag_t iot = sc->sc_iot;
2582 bus_space_handle_t ioh2 = sc->sc_ioh2;
2583
2584 sc->sc_voc[voice].end_addr = addr;
2585
2586 if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16)
2587 addr = convert_to_16bit(addr);
2588
2589 SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_HIGH);
2590 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(addr));
2591 SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_LOW);
2592 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(addr));
2593
2594 }
2595
2596 #ifdef GUSPLAYDEBUG
2597 /*
2598 * Set current address. called at splgus()
2599 */
2600 STATIC void
2601 gus_set_curaddr(sc, voice, addr)
2602 struct gus_softc *sc;
2603 int voice;
2604 u_long addr;
2605 {
2606 bus_space_tag_t iot = sc->sc_iot;
2607 bus_space_handle_t ioh2 = sc->sc_ioh2;
2608
2609 sc->sc_voc[voice].current_addr = addr;
2610
2611 if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16)
2612 addr = convert_to_16bit(addr);
2613
2614 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
2615
2616 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH);
2617 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(addr));
2618 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW);
2619 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(addr));
2620
2621 }
2622
2623 /*
2624 * Get current GUS playback address. Called at splgus().
2625 */
2626 STATIC u_long
2627 gus_get_curaddr(sc, voice)
2628 struct gus_softc *sc;
2629 int voice;
2630 {
2631 bus_space_tag_t iot = sc->sc_iot;
2632 bus_space_handle_t ioh2 = sc->sc_ioh2;
2633 u_long addr;
2634
2635 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
2636 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH|GUSREG_READ);
2637 addr = (bus_space_read_2(iot, ioh2, GUS_DATA_LOW) & 0x1fff) << 7;
2638 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW|GUSREG_READ);
2639 addr |= (bus_space_read_2(iot, ioh2, GUS_DATA_LOW) >> 9L) & 0x7f;
2640
2641 if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16)
2642 addr = (addr & 0xc0000) | ((addr & 0x1ffff) << 1); /* undo 16-bit change */
2643 DPRINTF(("gus voice %d curaddr %ld end_addr %ld\n",
2644 voice, addr, sc->sc_voc[voice].end_addr));
2645 /* XXX sanity check the address? */
2646
2647 return(addr);
2648 }
2649 #endif
2650
2651 /*
2652 * Convert an address value to a "16 bit" value - why this is necessary I
2653 * have NO idea
2654 */
2655
2656 STATIC u_long
2657 convert_to_16bit(address)
2658 u_long address;
2659 {
2660 u_long old_address;
2661
2662 old_address = address;
2663 address >>= 1;
2664 address &= 0x0001ffffL;
2665 address |= (old_address & 0x000c0000L);
2666
2667 return (address);
2668 }
2669
2670 /*
2671 * Write a value into the GUS's DRAM
2672 */
2673
2674 STATIC void
2675 guspoke(iot, ioh2, address, value)
2676 bus_space_tag_t iot;
2677 bus_space_handle_t ioh2;
2678 long address;
2679 unsigned char value;
2680 {
2681
2682 /*
2683 * Select the DRAM address
2684 */
2685
2686 SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_LOW);
2687 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, (unsigned int) (address & 0xffff));
2688 SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_HIGH);
2689 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (unsigned char) ((address >> 16) & 0xff));
2690
2691 /*
2692 * Actually write the data
2693 */
2694
2695 bus_space_write_1(iot, ioh2, GUS_DRAM_DATA, value);
2696 }
2697
2698 /*
2699 * Read a value from the GUS's DRAM
2700 */
2701
2702 STATIC unsigned char
2703 guspeek(iot, ioh2, address)
2704 bus_space_tag_t iot;
2705 bus_space_handle_t ioh2;
2706 u_long address;
2707 {
2708
2709 /*
2710 * Select the DRAM address
2711 */
2712
2713 SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_LOW);
2714 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, (unsigned int) (address & 0xffff));
2715 SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_HIGH);
2716 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (unsigned char) ((address >> 16) & 0xff));
2717
2718 /*
2719 * Read in the data from the board
2720 */
2721
2722 return (unsigned char) bus_space_read_1(iot, ioh2, GUS_DRAM_DATA);
2723 }
2724
2725 /*
2726 * Reset the Gravis UltraSound card, completely
2727 */
2728
2729 STATIC void
2730 gusreset(sc, voices)
2731 struct gus_softc *sc;
2732 int voices;
2733 {
2734 bus_space_tag_t iot = sc->sc_iot;
2735 bus_space_handle_t ioh1 = sc->sc_ioh1;
2736 bus_space_handle_t ioh2 = sc->sc_ioh2;
2737 bus_space_handle_t ioh4 = sc->sc_ioh4;
2738 int i,s;
2739
2740 s = splgus();
2741
2742 /*
2743 * Reset the GF1 chip
2744 */
2745
2746 SELECT_GUS_REG(iot, ioh2, GUSREG_RESET);
2747 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
2748
2749 delay(500);
2750
2751 /*
2752 * Release reset
2753 */
2754
2755 SELECT_GUS_REG(iot, ioh2, GUSREG_RESET);
2756 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, GUSMASK_MASTER_RESET);
2757
2758 delay(500);
2759
2760 /*
2761 * Reset MIDI port as well
2762 */
2763
2764 bus_space_write_1(iot, ioh4, GUS_MIDI_CONTROL, MIDI_RESET);
2765
2766 delay(500);
2767
2768 bus_space_write_1(iot, ioh4, GUS_MIDI_CONTROL, 0x00);
2769
2770 /*
2771 * Clear interrupts
2772 */
2773
2774 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
2775 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
2776 SELECT_GUS_REG(iot, ioh2, GUSREG_TIMER_CONTROL);
2777 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
2778 SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
2779 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
2780
2781 gus_set_voices(sc, voices);
2782
2783 bus_space_read_1(iot, ioh1, GUS_IRQ_STATUS);
2784 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
2785 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
2786 SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
2787 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
2788 SELECT_GUS_REG(iot, ioh2, GUSREG_IRQ_STATUS);
2789 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
2790
2791 /*
2792 * Reset voice specific information
2793 */
2794
2795 for(i = 0; i < voices; i++) {
2796 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) i);
2797
2798 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
2799
2800 sc->sc_voc[i].voccntl = GUSMASK_VOICE_STOPPED |
2801 GUSMASK_STOP_VOICE;
2802
2803 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[i].voccntl);
2804
2805 sc->sc_voc[i].volcntl = GUSMASK_VOLUME_STOPPED |
2806 GUSMASK_STOP_VOLUME;
2807
2808 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
2809 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[i].volcntl);
2810
2811 delay(100);
2812
2813 gus_set_samprate(sc, i, 8000);
2814 SELECT_GUS_REG(iot, ioh2, GUSREG_START_ADDR_HIGH);
2815 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2816 SELECT_GUS_REG(iot, ioh2, GUSREG_START_ADDR_LOW);
2817 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2818 SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_HIGH);
2819 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2820 SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_LOW);
2821 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2822 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_RATE);
2823 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x01);
2824 SELECT_GUS_REG(iot, ioh2, GUSREG_START_VOLUME);
2825 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x10);
2826 SELECT_GUS_REG(iot, ioh2, GUSREG_END_VOLUME);
2827 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0xe0);
2828 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME);
2829 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2830
2831 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH);
2832 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2833 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW);
2834 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2835 SELECT_GUS_REG(iot, ioh2, GUSREG_PAN_POS);
2836 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x07);
2837 }
2838
2839 /*
2840 * Clear out any pending IRQs
2841 */
2842
2843 bus_space_read_1(iot, ioh1, GUS_IRQ_STATUS);
2844 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
2845 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
2846 SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
2847 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
2848 SELECT_GUS_REG(iot, ioh2, GUSREG_IRQ_STATUS);
2849 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
2850
2851 SELECT_GUS_REG(iot, ioh2, GUSREG_RESET);
2852 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, GUSMASK_MASTER_RESET | GUSMASK_DAC_ENABLE |
2853 GUSMASK_IRQ_ENABLE);
2854
2855 splx(s);
2856 }
2857
2858
2859 STATIC int
2860 gus_init_cs4231(sc)
2861 struct gus_softc *sc;
2862 {
2863 bus_space_tag_t iot = sc->sc_iot;
2864 bus_space_handle_t ioh1 = sc->sc_ioh1;
2865 int port = sc->sc_iobase;
2866 u_char ctrl;
2867
2868 ctrl = (port & 0xf0) >> 4; /* set port address middle nibble */
2869 /*
2870 * The codec is a bit weird--swapped dma channels.
2871 */
2872 ctrl |= GUS_MAX_CODEC_ENABLE;
2873 if (sc->sc_drq >= 4)
2874 ctrl |= GUS_MAX_RECCHAN16;
2875 if (sc->sc_recdrq >= 4)
2876 ctrl |= GUS_MAX_PLAYCHAN16;
2877
2878 bus_space_write_1(iot, ioh1, GUS_MAX_CTRL, ctrl);
2879
2880 sc->sc_codec.sc_iot = sc->sc_iot;
2881 sc->sc_codec.sc_iobase = port+GUS_MAX_CODEC_BASE;
2882
2883 if (ad1848_probe(&sc->sc_codec) == 0) {
2884 sc->sc_flags &= ~GUS_CODEC_INSTALLED;
2885 return (0);
2886 } else {
2887 struct ad1848_volume vol = {AUDIO_MAX_GAIN, AUDIO_MAX_GAIN};
2888 sc->sc_flags |= GUS_CODEC_INSTALLED;
2889 sc->sc_codec.parent = sc;
2890 sc->sc_codec.sc_drq = sc->sc_recdrq;
2891 sc->sc_codec.sc_recdrq = sc->sc_drq;
2892 gus_hw_if = gusmax_hw_if;
2893 /* enable line in and mic in the GUS mixer; the codec chip
2894 will do the real mixing for them. */
2895 sc->sc_mixcontrol &= ~GUSMASK_LINE_IN; /* 0 enables. */
2896 sc->sc_mixcontrol |= GUSMASK_MIC_IN; /* 1 enables. */
2897 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
2898
2899 ad1848_attach(&sc->sc_codec);
2900 /* turn on pre-MUX microphone gain. */
2901 ad1848_set_mic_gain(&sc->sc_codec, &vol);
2902
2903 return (1);
2904 }
2905 }
2906
2907
2908 /*
2909 * Return info about the audio device, for the AUDIO_GETINFO ioctl
2910 */
2911
2912 int
2913 gus_getdev(addr, dev)
2914 void * addr;
2915 struct audio_device *dev;
2916 {
2917 *dev = gus_device;
2918 return 0;
2919 }
2920
2921 /*
2922 * stubs (XXX)
2923 */
2924
2925 int
2926 gus_set_in_gain(addr, gain, balance)
2927 caddr_t addr;
2928 u_int gain;
2929 u_char balance;
2930 {
2931 DPRINTF(("gus_set_in_gain called\n"));
2932 return 0;
2933 }
2934
2935 int
2936 gus_get_in_gain(addr)
2937 caddr_t addr;
2938 {
2939 DPRINTF(("gus_get_in_gain called\n"));
2940 return 0;
2941 }
2942
2943 int
2944 gusmax_dma_input(addr, buf, size, callback, arg)
2945 void * addr;
2946 void *buf;
2947 int size;
2948 void (*callback) __P((void *));
2949 void *arg;
2950 {
2951 struct ad1848_softc *sc = addr;
2952 return gus_dma_input(sc->parent, buf, size, callback, arg);
2953 }
2954
2955 /*
2956 * Start sampling the input source into the requested DMA buffer.
2957 * Called at splgus(), either from top-half or from interrupt handler.
2958 */
2959 int
2960 gus_dma_input(addr, buf, size, callback, arg)
2961 void * addr;
2962 void *buf;
2963 int size;
2964 void (*callback) __P((void *));
2965 void *arg;
2966 {
2967 struct gus_softc *sc = addr;
2968 bus_space_tag_t iot = sc->sc_iot;
2969 bus_space_handle_t ioh2 = sc->sc_ioh2;
2970 u_char dmac;
2971 DMAPRINTF(("gus_dma_input called\n"));
2972
2973 /*
2974 * Sample SIZE bytes of data from the card, into buffer at BUF.
2975 */
2976
2977 if (sc->sc_precision == 16)
2978 return EINVAL; /* XXX */
2979
2980 /* set DMA modes */
2981 dmac = GUSMASK_SAMPLE_IRQ|GUSMASK_SAMPLE_START;
2982 if (sc->sc_recdrq >= 4)
2983 dmac |= GUSMASK_SAMPLE_DATA16;
2984 if (sc->sc_encoding == AUDIO_ENCODING_ULAW ||
2985 sc->sc_encoding == AUDIO_ENCODING_ALAW ||
2986 sc->sc_encoding == AUDIO_ENCODING_ULINEAR_LE ||
2987 sc->sc_encoding == AUDIO_ENCODING_ULINEAR_BE)
2988 dmac |= GUSMASK_SAMPLE_INVBIT;
2989 if (sc->sc_channels == 2)
2990 dmac |= GUSMASK_SAMPLE_STEREO;
2991 isa_dmastart(sc->sc_dev.dv_parent, sc->sc_recdrq, buf, size,
2992 NULL, DMAMODE_READ, BUS_DMA_NOWAIT);
2993
2994 DMAPRINTF(("gus_dma_input isa_dmastarted\n"));
2995 sc->sc_flags |= GUS_DMAIN_ACTIVE;
2996 sc->sc_dmainintr = callback;
2997 sc->sc_inarg = arg;
2998 sc->sc_dmaincnt = size;
2999 sc->sc_dmainaddr = buf;
3000
3001 SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
3002 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, dmac); /* Go! */
3003
3004
3005 DMAPRINTF(("gus_dma_input returning\n"));
3006
3007 return 0;
3008 }
3009
3010 STATIC int
3011 gus_dmain_intr(sc)
3012 struct gus_softc *sc;
3013 {
3014 void (*callback) __P((void *));
3015 void *arg;
3016
3017 DMAPRINTF(("gus_dmain_intr called\n"));
3018 if (sc->sc_dmainintr) {
3019 isa_dmadone(sc->sc_dev.dv_parent, sc->sc_recdrq);
3020 callback = sc->sc_dmainintr;
3021 arg = sc->sc_inarg;
3022
3023 sc->sc_dmainaddr = 0;
3024 sc->sc_dmaincnt = 0;
3025 sc->sc_dmainintr = 0;
3026 sc->sc_inarg = 0;
3027
3028 sc->sc_flags &= ~GUS_DMAIN_ACTIVE;
3029 DMAPRINTF(("calling dmain_intr callback %p(%p)\n", callback, arg));
3030 (*callback)(arg);
3031 return 1;
3032 } else {
3033 DMAPRINTF(("gus_dmain_intr false?\n"));
3034 return 0; /* XXX ??? */
3035 }
3036 }
3037
3038 int
3039 gusmax_halt_out_dma(addr)
3040 void * addr;
3041 {
3042 struct ad1848_softc *sc = addr;
3043 return gus_halt_out_dma(sc->parent);
3044 }
3045
3046
3047 int
3048 gusmax_halt_in_dma(addr)
3049 void * addr;
3050 {
3051 struct ad1848_softc *sc = addr;
3052 return gus_halt_in_dma(sc->parent);
3053 }
3054
3055 /*
3056 * Stop any DMA output. Called at splgus().
3057 */
3058 int
3059 gus_halt_out_dma(addr)
3060 void * addr;
3061 {
3062 struct gus_softc *sc = addr;
3063 bus_space_tag_t iot = sc->sc_iot;
3064 bus_space_handle_t ioh2 = sc->sc_ioh2;
3065
3066 DMAPRINTF(("gus_halt_out_dma called\n"));
3067 /*
3068 * Make sure the GUS _isn't_ setup for DMA
3069 */
3070
3071 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
3072 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0);
3073
3074 untimeout(gus_dmaout_timeout, sc);
3075 isa_dmaabort(sc->sc_dev.dv_parent, sc->sc_drq);
3076 sc->sc_flags &= ~(GUS_DMAOUT_ACTIVE|GUS_LOCKED);
3077 sc->sc_dmaoutintr = 0;
3078 sc->sc_outarg = 0;
3079 sc->sc_dmaoutaddr = 0;
3080 sc->sc_dmaoutcnt = 0;
3081 sc->sc_dmabuf = 0;
3082 sc->sc_bufcnt = 0;
3083 sc->sc_playbuf = -1;
3084 /* also stop playing */
3085 gus_stop_voice(sc, GUS_VOICE_LEFT, 1);
3086 gus_stop_voice(sc, GUS_VOICE_RIGHT, 0);
3087
3088 return 0;
3089 }
3090
3091 /*
3092 * Stop any DMA output. Called at splgus().
3093 */
3094 int
3095 gus_halt_in_dma(addr)
3096 void * addr;
3097 {
3098 struct gus_softc *sc = addr;
3099 bus_space_tag_t iot = sc->sc_iot;
3100 bus_space_handle_t ioh2 = sc->sc_ioh2;
3101 DMAPRINTF(("gus_halt_in_dma called\n"));
3102
3103 /*
3104 * Make sure the GUS _isn't_ setup for DMA
3105 */
3106
3107 SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
3108 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH,
3109 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH) & ~(GUSMASK_SAMPLE_START|GUSMASK_SAMPLE_IRQ));
3110
3111 isa_dmaabort(sc->sc_dev.dv_parent, sc->sc_recdrq);
3112 sc->sc_flags &= ~GUS_DMAIN_ACTIVE;
3113 sc->sc_dmainintr = 0;
3114 sc->sc_inarg = 0;
3115 sc->sc_dmainaddr = 0;
3116 sc->sc_dmaincnt = 0;
3117
3118 return 0;
3119 }
3120
3121 STATIC __inline int
3122 gus_to_vol(cp, vol)
3123 mixer_ctrl_t *cp;
3124 struct ad1848_volume *vol;
3125 {
3126 if (cp->un.value.num_channels == 1) {
3127 vol->left = vol->right = cp->un.value.level[AUDIO_MIXER_LEVEL_MONO];
3128 return(1);
3129 }
3130 else if (cp->un.value.num_channels == 2) {
3131 vol->left = cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT];
3132 vol->right = cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT];
3133 return(1);
3134 }
3135 return(0);
3136 }
3137
3138 STATIC __inline int
3139 gus_from_vol(cp, vol)
3140 mixer_ctrl_t *cp;
3141 struct ad1848_volume *vol;
3142 {
3143 if (cp->un.value.num_channels == 1) {
3144 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = vol->left;
3145 return(1);
3146 }
3147 else if (cp->un.value.num_channels == 2) {
3148 cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = vol->left;
3149 cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = vol->right;
3150 return(1);
3151 }
3152 return(0);
3153 }
3154
3155 STATIC int
3156 gusmax_mixer_get_port(addr, cp)
3157 void *addr;
3158 mixer_ctrl_t *cp;
3159 {
3160 struct ad1848_softc *ac = addr;
3161 struct gus_softc *sc = ac->parent;
3162 struct ad1848_volume vol;
3163 int error = EINVAL;
3164
3165 DPRINTF(("gusmax_mixer_get_port: port=%d\n", cp->dev));
3166
3167 switch (cp->dev) {
3168 #if 0 /* use mono level instead */
3169 case GUSMAX_MIC_IN_LVL: /* Microphone */
3170 if (cp->type == AUDIO_MIXER_VALUE) {
3171 error = ad1848_get_mic_gain(ac, &vol);
3172 if (!error)
3173 gus_from_vol(cp, &vol);
3174 }
3175 break;
3176 #endif
3177
3178 case GUSMAX_DAC_LVL: /* dac out */
3179 if (cp->type == AUDIO_MIXER_VALUE) {
3180 error = ad1848_get_aux1_gain(ac, &vol);
3181 if (!error)
3182 gus_from_vol(cp, &vol);
3183 }
3184 break;
3185
3186 case GUSMAX_LINE_IN_LVL: /* line in */
3187 if (cp->type == AUDIO_MIXER_VALUE) {
3188 error = cs4231_get_linein_gain(ac, &vol);
3189 if (!error)
3190 gus_from_vol(cp, &vol);
3191 }
3192 break;
3193
3194 case GUSMAX_MONO_LVL: /* mono */
3195 if (cp->type == AUDIO_MIXER_VALUE &&
3196 cp->un.value.num_channels == 1) {
3197 error = cs4231_get_mono_gain(ac, &vol);
3198 if (!error)
3199 gus_from_vol(cp, &vol);
3200 }
3201 break;
3202
3203 case GUSMAX_CD_LVL: /* CD */
3204 if (cp->type == AUDIO_MIXER_VALUE) {
3205 error = ad1848_get_aux2_gain(ac, &vol);
3206 if (!error)
3207 gus_from_vol(cp, &vol);
3208 }
3209 break;
3210
3211 case GUSMAX_MONITOR_LVL: /* monitor level */
3212 if (cp->type == AUDIO_MIXER_VALUE &&
3213 cp->un.value.num_channels == 1) {
3214 error = ad1848_get_mon_gain(ac, &vol);
3215 if (!error)
3216 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
3217 vol.left;
3218 }
3219 break;
3220
3221 case GUSMAX_OUT_LVL: /* output level */
3222 if (cp->type == AUDIO_MIXER_VALUE) {
3223 error = ad1848_get_out_gain(ac, &vol);
3224 if (!error)
3225 gus_from_vol(cp, &vol);
3226 }
3227 break;
3228
3229 case GUSMAX_SPEAKER_LVL: /* fake speaker for mute naming */
3230 if (cp->type == AUDIO_MIXER_VALUE) {
3231 if (sc->sc_mixcontrol & GUSMASK_LINE_OUT)
3232 vol.left = vol.right = AUDIO_MAX_GAIN;
3233 else
3234 vol.left = vol.right = AUDIO_MIN_GAIN;
3235 error = 0;
3236 gus_from_vol(cp, &vol);
3237 }
3238 break;
3239
3240 case GUSMAX_LINE_IN_MUTE:
3241 if (cp->type == AUDIO_MIXER_ENUM) {
3242 cp->un.ord = ac->line_mute;
3243 error = 0;
3244 }
3245 break;
3246
3247
3248 case GUSMAX_DAC_MUTE:
3249 if (cp->type == AUDIO_MIXER_ENUM) {
3250 cp->un.ord = ac->aux1_mute;
3251 error = 0;
3252 }
3253 break;
3254
3255 case GUSMAX_CD_MUTE:
3256 if (cp->type == AUDIO_MIXER_ENUM) {
3257 cp->un.ord = ac->aux2_mute;
3258 error = 0;
3259 }
3260 break;
3261
3262 case GUSMAX_MONO_MUTE:
3263 if (cp->type == AUDIO_MIXER_ENUM) {
3264 cp->un.ord = ac->mono_mute;
3265 error = 0;
3266 }
3267 break;
3268
3269 case GUSMAX_MONITOR_MUTE:
3270 if (cp->type == AUDIO_MIXER_ENUM) {
3271 cp->un.ord = ac->mon_mute;
3272 error = 0;
3273 }
3274 break;
3275
3276 case GUSMAX_SPEAKER_MUTE:
3277 if (cp->type == AUDIO_MIXER_ENUM) {
3278 cp->un.ord = sc->sc_mixcontrol & GUSMASK_LINE_OUT ? 1 : 0;
3279 error = 0;
3280 }
3281 break;
3282
3283 case GUSMAX_REC_LVL: /* record level */
3284 if (cp->type == AUDIO_MIXER_VALUE) {
3285 error = ad1848_get_rec_gain(ac, &vol);
3286 if (!error)
3287 gus_from_vol(cp, &vol);
3288 }
3289 break;
3290
3291 case GUSMAX_RECORD_SOURCE:
3292 if (cp->type == AUDIO_MIXER_ENUM) {
3293 cp->un.ord = ad1848_get_rec_port(ac);
3294 error = 0;
3295 }
3296 break;
3297
3298 default:
3299 error = ENXIO;
3300 break;
3301 }
3302
3303 return(error);
3304 }
3305
3306 STATIC int
3307 gus_mixer_get_port(addr, cp)
3308 void *addr;
3309 mixer_ctrl_t *cp;
3310 {
3311 struct gus_softc *sc = addr;
3312 struct ics2101_softc *ic = &sc->sc_mixer;
3313 struct ad1848_volume vol;
3314 int error = EINVAL;
3315
3316 DPRINTF(("gus_mixer_get_port: dev=%d type=%d\n", cp->dev, cp->type));
3317
3318 if (!HAS_MIXER(sc) && cp->dev > GUSICS_MASTER_MUTE)
3319 return ENXIO;
3320
3321 switch (cp->dev) {
3322
3323 case GUSICS_MIC_IN_MUTE: /* Microphone */
3324 if (cp->type == AUDIO_MIXER_ENUM) {
3325 if (HAS_MIXER(sc))
3326 cp->un.ord = ic->sc_mute[GUSMIX_CHAN_MIC][ICSMIX_LEFT];
3327 else
3328 cp->un.ord =
3329 sc->sc_mixcontrol & GUSMASK_MIC_IN ? 0 : 1;
3330 error = 0;
3331 }
3332 break;
3333
3334 case GUSICS_LINE_IN_MUTE:
3335 if (cp->type == AUDIO_MIXER_ENUM) {
3336 if (HAS_MIXER(sc))
3337 cp->un.ord = ic->sc_mute[GUSMIX_CHAN_LINE][ICSMIX_LEFT];
3338 else
3339 cp->un.ord =
3340 sc->sc_mixcontrol & GUSMASK_LINE_IN ? 1 : 0;
3341 error = 0;
3342 }
3343 break;
3344
3345 case GUSICS_MASTER_MUTE:
3346 if (cp->type == AUDIO_MIXER_ENUM) {
3347 if (HAS_MIXER(sc))
3348 cp->un.ord = ic->sc_mute[GUSMIX_CHAN_MASTER][ICSMIX_LEFT];
3349 else
3350 cp->un.ord =
3351 sc->sc_mixcontrol & GUSMASK_LINE_OUT ? 1 : 0;
3352 error = 0;
3353 }
3354 break;
3355
3356 case GUSICS_DAC_MUTE:
3357 if (cp->type == AUDIO_MIXER_ENUM) {
3358 cp->un.ord = ic->sc_mute[GUSMIX_CHAN_DAC][ICSMIX_LEFT];
3359 error = 0;
3360 }
3361 break;
3362
3363 case GUSICS_CD_MUTE:
3364 if (cp->type == AUDIO_MIXER_ENUM) {
3365 cp->un.ord = ic->sc_mute[GUSMIX_CHAN_CD][ICSMIX_LEFT];
3366 error = 0;
3367 }
3368 break;
3369
3370 case GUSICS_MASTER_LVL:
3371 if (cp->type == AUDIO_MIXER_VALUE) {
3372 vol.left = ic->sc_setting[GUSMIX_CHAN_MASTER][ICSMIX_LEFT];
3373 vol.right = ic->sc_setting[GUSMIX_CHAN_MASTER][ICSMIX_RIGHT];
3374 if (gus_from_vol(cp, &vol))
3375 error = 0;
3376 }
3377 break;
3378
3379 case GUSICS_MIC_IN_LVL: /* Microphone */
3380 if (cp->type == AUDIO_MIXER_VALUE) {
3381 vol.left = ic->sc_setting[GUSMIX_CHAN_MIC][ICSMIX_LEFT];
3382 vol.right = ic->sc_setting[GUSMIX_CHAN_MIC][ICSMIX_RIGHT];
3383 if (gus_from_vol(cp, &vol))
3384 error = 0;
3385 }
3386 break;
3387
3388 case GUSICS_LINE_IN_LVL: /* line in */
3389 if (cp->type == AUDIO_MIXER_VALUE) {
3390 vol.left = ic->sc_setting[GUSMIX_CHAN_LINE][ICSMIX_LEFT];
3391 vol.right = ic->sc_setting[GUSMIX_CHAN_LINE][ICSMIX_RIGHT];
3392 if (gus_from_vol(cp, &vol))
3393 error = 0;
3394 }
3395 break;
3396
3397
3398 case GUSICS_CD_LVL:
3399 if (cp->type == AUDIO_MIXER_VALUE) {
3400 vol.left = ic->sc_setting[GUSMIX_CHAN_CD][ICSMIX_LEFT];
3401 vol.right = ic->sc_setting[GUSMIX_CHAN_CD][ICSMIX_RIGHT];
3402 if (gus_from_vol(cp, &vol))
3403 error = 0;
3404 }
3405 break;
3406
3407 case GUSICS_DAC_LVL: /* dac out */
3408 if (cp->type == AUDIO_MIXER_VALUE) {
3409 vol.left = ic->sc_setting[GUSMIX_CHAN_DAC][ICSMIX_LEFT];
3410 vol.right = ic->sc_setting[GUSMIX_CHAN_DAC][ICSMIX_RIGHT];
3411 if (gus_from_vol(cp, &vol))
3412 error = 0;
3413 }
3414 break;
3415
3416
3417 case GUSICS_RECORD_SOURCE:
3418 if (cp->type == AUDIO_MIXER_ENUM) {
3419 /* Can't set anything else useful, sigh. */
3420 cp->un.ord = 0;
3421 }
3422 break;
3423
3424 default:
3425 return ENXIO;
3426 /*NOTREACHED*/
3427 }
3428 return error;
3429 }
3430
3431 STATIC void
3432 gusics_master_mute(ic, mute)
3433 struct ics2101_softc *ic;
3434 int mute;
3435 {
3436 ics2101_mix_mute(ic, GUSMIX_CHAN_MASTER, ICSMIX_LEFT, mute);
3437 ics2101_mix_mute(ic, GUSMIX_CHAN_MASTER, ICSMIX_RIGHT, mute);
3438 }
3439
3440 STATIC void
3441 gusics_mic_mute(ic, mute)
3442 struct ics2101_softc *ic;
3443 int mute;
3444 {
3445 ics2101_mix_mute(ic, GUSMIX_CHAN_MIC, ICSMIX_LEFT, mute);
3446 ics2101_mix_mute(ic, GUSMIX_CHAN_MIC, ICSMIX_RIGHT, mute);
3447 }
3448
3449 STATIC void
3450 gusics_linein_mute(ic, mute)
3451 struct ics2101_softc *ic;
3452 int mute;
3453 {
3454 ics2101_mix_mute(ic, GUSMIX_CHAN_LINE, ICSMIX_LEFT, mute);
3455 ics2101_mix_mute(ic, GUSMIX_CHAN_LINE, ICSMIX_RIGHT, mute);
3456 }
3457
3458 STATIC void
3459 gusics_cd_mute(ic, mute)
3460 struct ics2101_softc *ic;
3461 int mute;
3462 {
3463 ics2101_mix_mute(ic, GUSMIX_CHAN_CD, ICSMIX_LEFT, mute);
3464 ics2101_mix_mute(ic, GUSMIX_CHAN_CD, ICSMIX_RIGHT, mute);
3465 }
3466
3467 STATIC void
3468 gusics_dac_mute(ic, mute)
3469 struct ics2101_softc *ic;
3470 int mute;
3471 {
3472 ics2101_mix_mute(ic, GUSMIX_CHAN_DAC, ICSMIX_LEFT, mute);
3473 ics2101_mix_mute(ic, GUSMIX_CHAN_DAC, ICSMIX_RIGHT, mute);
3474 }
3475
3476 STATIC int
3477 gusmax_mixer_set_port(addr, cp)
3478 void *addr;
3479 mixer_ctrl_t *cp;
3480 {
3481 struct ad1848_softc *ac = addr;
3482 struct gus_softc *sc = ac->parent;
3483 struct ad1848_volume vol;
3484 int error = EINVAL;
3485
3486 DPRINTF(("gusmax_mixer_set_port: dev=%d type=%d\n", cp->dev, cp->type));
3487
3488 switch (cp->dev) {
3489 #if 0
3490 case GUSMAX_MIC_IN_LVL: /* Microphone */
3491 if (cp->type == AUDIO_MIXER_VALUE &&
3492 cp->un.value.num_channels == 1) {
3493 /* XXX enable/disable pre-MUX fixed gain */
3494 if (gus_to_vol(cp, &vol))
3495 error = ad1848_set_mic_gain(ac, &vol);
3496 }
3497 break;
3498 #endif
3499
3500 case GUSMAX_DAC_LVL: /* dac out */
3501 if (cp->type == AUDIO_MIXER_VALUE) {
3502 if (gus_to_vol(cp, &vol))
3503 error = ad1848_set_aux1_gain(ac, &vol);
3504 }
3505 break;
3506
3507 case GUSMAX_LINE_IN_LVL: /* line in */
3508 if (cp->type == AUDIO_MIXER_VALUE) {
3509 if (gus_to_vol(cp, &vol))
3510 error = cs4231_set_linein_gain(ac, &vol);
3511 }
3512 break;
3513
3514 case GUSMAX_MONO_LVL: /* mic/mono in */
3515 if (cp->type == AUDIO_MIXER_VALUE &&
3516 cp->un.value.num_channels == 1) {
3517 if (gus_to_vol(cp, &vol))
3518 error = cs4231_set_mono_gain(ac, &vol);
3519 }
3520 break;
3521
3522 case GUSMAX_CD_LVL: /* CD: AUX2 */
3523 if (cp->type == AUDIO_MIXER_VALUE) {
3524 if (gus_to_vol(cp, &vol))
3525 error = ad1848_set_aux2_gain(ac, &vol);
3526 }
3527 break;
3528
3529 case GUSMAX_MONITOR_LVL:
3530 if (cp->type == AUDIO_MIXER_VALUE &&
3531 cp->un.value.num_channels == 1) {
3532 vol.left = cp->un.value.level[AUDIO_MIXER_LEVEL_MONO];
3533 error = ad1848_set_mon_gain(ac, &vol);
3534 }
3535 break;
3536
3537 case GUSMAX_OUT_LVL: /* output volume */
3538 if (cp->type == AUDIO_MIXER_VALUE) {
3539 if (gus_to_vol(cp, &vol))
3540 error = ad1848_set_out_gain(ac, &vol);
3541 }
3542 break;
3543
3544 case GUSMAX_SPEAKER_LVL:
3545 if (cp->type == AUDIO_MIXER_VALUE &&
3546 cp->un.value.num_channels == 1) {
3547 if (gus_to_vol(cp, &vol)) {
3548 gus_speaker_ctl(sc, vol.left > AUDIO_MIN_GAIN ?
3549 SPKR_ON : SPKR_OFF);
3550 error = 0;
3551 }
3552 }
3553 break;
3554
3555 case GUSMAX_LINE_IN_MUTE:
3556 if (cp->type == AUDIO_MIXER_ENUM) {
3557 ac->line_mute = cp->un.ord ? 1 : 0;
3558 DPRINTF(("line mute %d\n", cp->un.ord));
3559 cs4231_mute_line(ac, ac->line_mute);
3560 gus_linein_ctl(sc, ac->line_mute ? SPKR_OFF : SPKR_ON);
3561 error = 0;
3562 }
3563 break;
3564
3565 case GUSMAX_DAC_MUTE:
3566 if (cp->type == AUDIO_MIXER_ENUM) {
3567 ac->aux1_mute = cp->un.ord ? 1 : 0;
3568 DPRINTF(("dac mute %d\n", cp->un.ord));
3569 ad1848_mute_aux1(ac, ac->aux1_mute);
3570 error = 0;
3571 }
3572 break;
3573
3574 case GUSMAX_CD_MUTE:
3575 if (cp->type == AUDIO_MIXER_ENUM) {
3576 ac->aux2_mute = cp->un.ord ? 1 : 0;
3577 DPRINTF(("cd mute %d\n", cp->un.ord));
3578 ad1848_mute_aux2(ac, ac->aux2_mute);
3579 error = 0;
3580 }
3581 break;
3582
3583 case GUSMAX_MONO_MUTE: /* Microphone */
3584 if (cp->type == AUDIO_MIXER_ENUM) {
3585 ac->mono_mute = cp->un.ord ? 1 : 0;
3586 DPRINTF(("mono mute %d\n", cp->un.ord));
3587 cs4231_mute_mono(ac, ac->mono_mute);
3588 gus_mic_ctl(sc, ac->mono_mute ? SPKR_OFF : SPKR_ON);
3589 error = 0;
3590 }
3591 break;
3592
3593 case GUSMAX_MONITOR_MUTE:
3594 if (cp->type == AUDIO_MIXER_ENUM) {
3595 ac->mon_mute = cp->un.ord ? 1 : 0;
3596 DPRINTF(("mono mute %d\n", cp->un.ord));
3597 cs4231_mute_monitor(ac, ac->mon_mute);
3598 error = 0;
3599 }
3600 break;
3601
3602 case GUSMAX_SPEAKER_MUTE:
3603 if (cp->type == AUDIO_MIXER_ENUM) {
3604 gus_speaker_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON);
3605 error = 0;
3606 }
3607 break;
3608
3609 case GUSMAX_REC_LVL: /* record level */
3610 if (cp->type == AUDIO_MIXER_VALUE) {
3611 if (gus_to_vol(cp, &vol))
3612 error = ad1848_set_rec_gain(ac, &vol);
3613 }
3614 break;
3615
3616 case GUSMAX_RECORD_SOURCE:
3617 if (cp->type == AUDIO_MIXER_ENUM) {
3618 error = ad1848_set_rec_port(ac, cp->un.ord);
3619 }
3620 break;
3621
3622 default:
3623 return ENXIO;
3624 /*NOTREACHED*/
3625 }
3626 return error;
3627 }
3628
3629 STATIC int
3630 gus_mixer_set_port(addr, cp)
3631 void *addr;
3632 mixer_ctrl_t *cp;
3633 {
3634 struct gus_softc *sc = addr;
3635 struct ics2101_softc *ic = &sc->sc_mixer;
3636 struct ad1848_volume vol;
3637 int error = EINVAL;
3638
3639 DPRINTF(("gus_mixer_set_port: dev=%d type=%d\n", cp->dev, cp->type));
3640
3641 if (!HAS_MIXER(sc) && cp->dev > GUSICS_MASTER_MUTE)
3642 return ENXIO;
3643
3644 switch (cp->dev) {
3645
3646 case GUSICS_MIC_IN_MUTE: /* Microphone */
3647 if (cp->type == AUDIO_MIXER_ENUM) {
3648 DPRINTF(("mic mute %d\n", cp->un.ord));
3649 if (HAS_MIXER(sc)) {
3650 gusics_mic_mute(ic, cp->un.ord);
3651 }
3652 gus_mic_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON);
3653 error = 0;
3654 }
3655 break;
3656
3657 case GUSICS_LINE_IN_MUTE:
3658 if (cp->type == AUDIO_MIXER_ENUM) {
3659 DPRINTF(("linein mute %d\n", cp->un.ord));
3660 if (HAS_MIXER(sc)) {
3661 gusics_linein_mute(ic, cp->un.ord);
3662 }
3663 gus_linein_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON);
3664 error = 0;
3665 }
3666 break;
3667
3668 case GUSICS_MASTER_MUTE:
3669 if (cp->type == AUDIO_MIXER_ENUM) {
3670 DPRINTF(("master mute %d\n", cp->un.ord));
3671 if (HAS_MIXER(sc)) {
3672 gusics_master_mute(ic, cp->un.ord);
3673 }
3674 gus_speaker_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON);
3675 error = 0;
3676 }
3677 break;
3678
3679 case GUSICS_DAC_MUTE:
3680 if (cp->type == AUDIO_MIXER_ENUM) {
3681 gusics_dac_mute(ic, cp->un.ord);
3682 error = 0;
3683 }
3684 break;
3685
3686 case GUSICS_CD_MUTE:
3687 if (cp->type == AUDIO_MIXER_ENUM) {
3688 gusics_cd_mute(ic, cp->un.ord);
3689 error = 0;
3690 }
3691 break;
3692
3693 case GUSICS_MASTER_LVL:
3694 if (cp->type == AUDIO_MIXER_VALUE) {
3695 if (gus_to_vol(cp, &vol)) {
3696 ics2101_mix_attenuate(ic,
3697 GUSMIX_CHAN_MASTER,
3698 ICSMIX_LEFT,
3699 vol.left);
3700 ics2101_mix_attenuate(ic,
3701 GUSMIX_CHAN_MASTER,
3702 ICSMIX_RIGHT,
3703 vol.right);
3704 error = 0;
3705 }
3706 }
3707 break;
3708
3709 case GUSICS_MIC_IN_LVL: /* Microphone */
3710 if (cp->type == AUDIO_MIXER_VALUE) {
3711 if (gus_to_vol(cp, &vol)) {
3712 ics2101_mix_attenuate(ic,
3713 GUSMIX_CHAN_MIC,
3714 ICSMIX_LEFT,
3715 vol.left);
3716 ics2101_mix_attenuate(ic,
3717 GUSMIX_CHAN_MIC,
3718 ICSMIX_RIGHT,
3719 vol.right);
3720 error = 0;
3721 }
3722 }
3723 break;
3724
3725 case GUSICS_LINE_IN_LVL: /* line in */
3726 if (cp->type == AUDIO_MIXER_VALUE) {
3727 if (gus_to_vol(cp, &vol)) {
3728 ics2101_mix_attenuate(ic,
3729 GUSMIX_CHAN_LINE,
3730 ICSMIX_LEFT,
3731 vol.left);
3732 ics2101_mix_attenuate(ic,
3733 GUSMIX_CHAN_LINE,
3734 ICSMIX_RIGHT,
3735 vol.right);
3736 error = 0;
3737 }
3738 }
3739 break;
3740
3741
3742 case GUSICS_CD_LVL:
3743 if (cp->type == AUDIO_MIXER_VALUE) {
3744 if (gus_to_vol(cp, &vol)) {
3745 ics2101_mix_attenuate(ic,
3746 GUSMIX_CHAN_CD,
3747 ICSMIX_LEFT,
3748 vol.left);
3749 ics2101_mix_attenuate(ic,
3750 GUSMIX_CHAN_CD,
3751 ICSMIX_RIGHT,
3752 vol.right);
3753 error = 0;
3754 }
3755 }
3756 break;
3757
3758 case GUSICS_DAC_LVL: /* dac out */
3759 if (cp->type == AUDIO_MIXER_VALUE) {
3760 if (gus_to_vol(cp, &vol)) {
3761 ics2101_mix_attenuate(ic,
3762 GUSMIX_CHAN_DAC,
3763 ICSMIX_LEFT,
3764 vol.left);
3765 ics2101_mix_attenuate(ic,
3766 GUSMIX_CHAN_DAC,
3767 ICSMIX_RIGHT,
3768 vol.right);
3769 error = 0;
3770 }
3771 }
3772 break;
3773
3774
3775 case GUSICS_RECORD_SOURCE:
3776 if (cp->type == AUDIO_MIXER_ENUM && cp->un.ord == 0) {
3777 /* Can't set anything else useful, sigh. */
3778 error = 0;
3779 }
3780 break;
3781
3782 default:
3783 return ENXIO;
3784 /*NOTREACHED*/
3785 }
3786 return error;
3787 }
3788
3789 STATIC int
3790 gus_get_props(addr)
3791 void *addr;
3792 {
3793 struct gus_softc *sc = addr;
3794 return sc->sc_recdrq == sc->sc_drq ? 0 : AUDIO_PROP_FULLDUPLEX;
3795 }
3796
3797 STATIC int
3798 gusmax_get_props(addr)
3799 void *addr;
3800 {
3801 struct ad1848_softc *ac = addr;
3802 return gus_get_props(ac->parent);
3803 }
3804
3805 STATIC int
3806 gusmax_mixer_query_devinfo(addr, dip)
3807 void *addr;
3808 mixer_devinfo_t *dip;
3809 {
3810 DPRINTF(("gusmax_query_devinfo: index=%d\n", dip->index));
3811
3812 switch(dip->index) {
3813 #if 0
3814 case GUSMAX_MIC_IN_LVL: /* Microphone */
3815 dip->type = AUDIO_MIXER_VALUE;
3816 dip->mixer_class = GUSMAX_INPUT_CLASS;
3817 dip->prev = AUDIO_MIXER_LAST;
3818 dip->next = GUSMAX_MIC_IN_MUTE;
3819 strcpy(dip->label.name, AudioNmicrophone);
3820 dip->un.v.num_channels = 2;
3821 strcpy(dip->un.v.units.name, AudioNvolume);
3822 break;
3823 #endif
3824
3825 case GUSMAX_MONO_LVL: /* mono/microphone mixer */
3826 dip->type = AUDIO_MIXER_VALUE;
3827 dip->mixer_class = GUSMAX_INPUT_CLASS;
3828 dip->prev = AUDIO_MIXER_LAST;
3829 dip->next = GUSMAX_MONO_MUTE;
3830 strcpy(dip->label.name, AudioNmicrophone);
3831 dip->un.v.num_channels = 1;
3832 strcpy(dip->un.v.units.name, AudioNvolume);
3833 break;
3834
3835 case GUSMAX_DAC_LVL: /* dacout */
3836 dip->type = AUDIO_MIXER_VALUE;
3837 dip->mixer_class = GUSMAX_INPUT_CLASS;
3838 dip->prev = AUDIO_MIXER_LAST;
3839 dip->next = GUSMAX_DAC_MUTE;
3840 strcpy(dip->label.name, AudioNdac);
3841 dip->un.v.num_channels = 2;
3842 strcpy(dip->un.v.units.name, AudioNvolume);
3843 break;
3844
3845 case GUSMAX_LINE_IN_LVL: /* line */
3846 dip->type = AUDIO_MIXER_VALUE;
3847 dip->mixer_class = GUSMAX_INPUT_CLASS;
3848 dip->prev = AUDIO_MIXER_LAST;
3849 dip->next = GUSMAX_LINE_IN_MUTE;
3850 strcpy(dip->label.name, AudioNline);
3851 dip->un.v.num_channels = 2;
3852 strcpy(dip->un.v.units.name, AudioNvolume);
3853 break;
3854
3855 case GUSMAX_CD_LVL: /* cd */
3856 dip->type = AUDIO_MIXER_VALUE;
3857 dip->mixer_class = GUSMAX_INPUT_CLASS;
3858 dip->prev = AUDIO_MIXER_LAST;
3859 dip->next = GUSMAX_CD_MUTE;
3860 strcpy(dip->label.name, AudioNcd);
3861 dip->un.v.num_channels = 2;
3862 strcpy(dip->un.v.units.name, AudioNvolume);
3863 break;
3864
3865
3866 case GUSMAX_MONITOR_LVL: /* monitor level */
3867 dip->type = AUDIO_MIXER_VALUE;
3868 dip->mixer_class = GUSMAX_MONITOR_CLASS;
3869 dip->next = GUSMAX_MONITOR_MUTE;
3870 dip->prev = AUDIO_MIXER_LAST;
3871 strcpy(dip->label.name, AudioNmonitor);
3872 dip->un.v.num_channels = 1;
3873 strcpy(dip->un.v.units.name, AudioNvolume);
3874 break;
3875
3876 case GUSMAX_OUT_LVL: /* cs4231 output volume: not useful? */
3877 dip->type = AUDIO_MIXER_VALUE;
3878 dip->mixer_class = GUSMAX_MONITOR_CLASS;
3879 dip->prev = dip->next = AUDIO_MIXER_LAST;
3880 strcpy(dip->label.name, AudioNoutput);
3881 dip->un.v.num_channels = 2;
3882 strcpy(dip->un.v.units.name, AudioNvolume);
3883 break;
3884
3885 case GUSMAX_SPEAKER_LVL: /* fake speaker volume */
3886 dip->type = AUDIO_MIXER_VALUE;
3887 dip->mixer_class = GUSMAX_MONITOR_CLASS;
3888 dip->prev = AUDIO_MIXER_LAST;
3889 dip->next = GUSMAX_SPEAKER_MUTE;
3890 strcpy(dip->label.name, AudioNmaster);
3891 dip->un.v.num_channels = 2;
3892 strcpy(dip->un.v.units.name, AudioNvolume);
3893 break;
3894
3895 case GUSMAX_LINE_IN_MUTE:
3896 dip->mixer_class = GUSMAX_INPUT_CLASS;
3897 dip->type = AUDIO_MIXER_ENUM;
3898 dip->prev = GUSMAX_LINE_IN_LVL;
3899 dip->next = AUDIO_MIXER_LAST;
3900 goto mute;
3901
3902 case GUSMAX_DAC_MUTE:
3903 dip->mixer_class = GUSMAX_INPUT_CLASS;
3904 dip->type = AUDIO_MIXER_ENUM;
3905 dip->prev = GUSMAX_DAC_LVL;
3906 dip->next = AUDIO_MIXER_LAST;
3907 goto mute;
3908
3909 case GUSMAX_CD_MUTE:
3910 dip->mixer_class = GUSMAX_INPUT_CLASS;
3911 dip->type = AUDIO_MIXER_ENUM;
3912 dip->prev = GUSMAX_CD_LVL;
3913 dip->next = AUDIO_MIXER_LAST;
3914 goto mute;
3915
3916 case GUSMAX_MONO_MUTE:
3917 dip->mixer_class = GUSMAX_INPUT_CLASS;
3918 dip->type = AUDIO_MIXER_ENUM;
3919 dip->prev = GUSMAX_MONO_LVL;
3920 dip->next = AUDIO_MIXER_LAST;
3921 goto mute;
3922
3923 case GUSMAX_MONITOR_MUTE:
3924 dip->mixer_class = GUSMAX_OUTPUT_CLASS;
3925 dip->type = AUDIO_MIXER_ENUM;
3926 dip->prev = GUSMAX_MONITOR_LVL;
3927 dip->next = AUDIO_MIXER_LAST;
3928 goto mute;
3929
3930 case GUSMAX_SPEAKER_MUTE:
3931 dip->mixer_class = GUSMAX_OUTPUT_CLASS;
3932 dip->type = AUDIO_MIXER_ENUM;
3933 dip->prev = GUSMAX_SPEAKER_LVL;
3934 dip->next = AUDIO_MIXER_LAST;
3935 mute:
3936 strcpy(dip->label.name, AudioNmute);
3937 dip->un.e.num_mem = 2;
3938 strcpy(dip->un.e.member[0].label.name, AudioNoff);
3939 dip->un.e.member[0].ord = 0;
3940 strcpy(dip->un.e.member[1].label.name, AudioNon);
3941 dip->un.e.member[1].ord = 1;
3942 break;
3943
3944 case GUSMAX_REC_LVL: /* record level */
3945 dip->type = AUDIO_MIXER_VALUE;
3946 dip->mixer_class = GUSMAX_RECORD_CLASS;
3947 dip->prev = AUDIO_MIXER_LAST;
3948 dip->next = GUSMAX_RECORD_SOURCE;
3949 strcpy(dip->label.name, AudioNrecord);
3950 dip->un.v.num_channels = 2;
3951 strcpy(dip->un.v.units.name, AudioNvolume);
3952 break;
3953
3954 case GUSMAX_RECORD_SOURCE:
3955 dip->mixer_class = GUSMAX_RECORD_CLASS;
3956 dip->type = AUDIO_MIXER_ENUM;
3957 dip->prev = GUSMAX_REC_LVL;
3958 dip->next = AUDIO_MIXER_LAST;
3959 strcpy(dip->label.name, AudioNsource);
3960 dip->un.e.num_mem = 4;
3961 strcpy(dip->un.e.member[0].label.name, AudioNoutput);
3962 dip->un.e.member[0].ord = DAC_IN_PORT;
3963 strcpy(dip->un.e.member[1].label.name, AudioNmicrophone);
3964 dip->un.e.member[1].ord = MIC_IN_PORT;
3965 strcpy(dip->un.e.member[2].label.name, AudioNdac);
3966 dip->un.e.member[2].ord = AUX1_IN_PORT;
3967 strcpy(dip->un.e.member[3].label.name, AudioNline);
3968 dip->un.e.member[3].ord = LINE_IN_PORT;
3969 break;
3970
3971 case GUSMAX_INPUT_CLASS: /* input class descriptor */
3972 dip->type = AUDIO_MIXER_CLASS;
3973 dip->mixer_class = GUSMAX_INPUT_CLASS;
3974 dip->next = dip->prev = AUDIO_MIXER_LAST;
3975 strcpy(dip->label.name, AudioCinputs);
3976 break;
3977
3978 case GUSMAX_OUTPUT_CLASS: /* output class descriptor */
3979 dip->type = AUDIO_MIXER_CLASS;
3980 dip->mixer_class = GUSMAX_OUTPUT_CLASS;
3981 dip->next = dip->prev = AUDIO_MIXER_LAST;
3982 strcpy(dip->label.name, AudioCoutputs);
3983 break;
3984
3985 case GUSMAX_MONITOR_CLASS: /* monitor class descriptor */
3986 dip->type = AUDIO_MIXER_CLASS;
3987 dip->mixer_class = GUSMAX_MONITOR_CLASS;
3988 dip->next = dip->prev = AUDIO_MIXER_LAST;
3989 strcpy(dip->label.name, AudioCmonitor);
3990 break;
3991
3992 case GUSMAX_RECORD_CLASS: /* record source class */
3993 dip->type = AUDIO_MIXER_CLASS;
3994 dip->mixer_class = GUSMAX_RECORD_CLASS;
3995 dip->next = dip->prev = AUDIO_MIXER_LAST;
3996 strcpy(dip->label.name, AudioCrecord);
3997 break;
3998
3999 default:
4000 return ENXIO;
4001 /*NOTREACHED*/
4002 }
4003 DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name));
4004 return 0;
4005 }
4006
4007 STATIC int
4008 gus_mixer_query_devinfo(addr, dip)
4009 void *addr;
4010 mixer_devinfo_t *dip;
4011 {
4012 struct gus_softc *sc = addr;
4013
4014 DPRINTF(("gusmax_query_devinfo: index=%d\n", dip->index));
4015
4016 if (!HAS_MIXER(sc) && dip->index > GUSICS_MASTER_MUTE)
4017 return ENXIO;
4018
4019 switch(dip->index) {
4020
4021 case GUSICS_MIC_IN_LVL: /* Microphone */
4022 dip->type = AUDIO_MIXER_VALUE;
4023 dip->mixer_class = GUSICS_INPUT_CLASS;
4024 dip->prev = AUDIO_MIXER_LAST;
4025 dip->next = GUSICS_MIC_IN_MUTE;
4026 strcpy(dip->label.name, AudioNmicrophone);
4027 dip->un.v.num_channels = 2;
4028 strcpy(dip->un.v.units.name, AudioNvolume);
4029 break;
4030
4031 case GUSICS_LINE_IN_LVL: /* line */
4032 dip->type = AUDIO_MIXER_VALUE;
4033 dip->mixer_class = GUSICS_INPUT_CLASS;
4034 dip->prev = AUDIO_MIXER_LAST;
4035 dip->next = GUSICS_LINE_IN_MUTE;
4036 strcpy(dip->label.name, AudioNline);
4037 dip->un.v.num_channels = 2;
4038 strcpy(dip->un.v.units.name, AudioNvolume);
4039 break;
4040
4041 case GUSICS_CD_LVL: /* cd */
4042 dip->type = AUDIO_MIXER_VALUE;
4043 dip->mixer_class = GUSICS_INPUT_CLASS;
4044 dip->prev = AUDIO_MIXER_LAST;
4045 dip->next = GUSICS_CD_MUTE;
4046 strcpy(dip->label.name, AudioNcd);
4047 dip->un.v.num_channels = 2;
4048 strcpy(dip->un.v.units.name, AudioNvolume);
4049 break;
4050
4051 case GUSICS_DAC_LVL: /* dacout */
4052 dip->type = AUDIO_MIXER_VALUE;
4053 dip->mixer_class = GUSICS_INPUT_CLASS;
4054 dip->prev = AUDIO_MIXER_LAST;
4055 dip->next = GUSICS_DAC_MUTE;
4056 strcpy(dip->label.name, AudioNdac);
4057 dip->un.v.num_channels = 2;
4058 strcpy(dip->un.v.units.name, AudioNvolume);
4059 break;
4060
4061 case GUSICS_MASTER_LVL: /* master output */
4062 dip->type = AUDIO_MIXER_VALUE;
4063 dip->mixer_class = GUSICS_OUTPUT_CLASS;
4064 dip->prev = AUDIO_MIXER_LAST;
4065 dip->next = GUSICS_MASTER_MUTE;
4066 strcpy(dip->label.name, AudioNmaster);
4067 dip->un.v.num_channels = 2;
4068 strcpy(dip->un.v.units.name, AudioNvolume);
4069 break;
4070
4071
4072 case GUSICS_LINE_IN_MUTE:
4073 dip->mixer_class = GUSICS_INPUT_CLASS;
4074 dip->type = AUDIO_MIXER_ENUM;
4075 dip->prev = GUSICS_LINE_IN_LVL;
4076 dip->next = AUDIO_MIXER_LAST;
4077 goto mute;
4078
4079 case GUSICS_DAC_MUTE:
4080 dip->mixer_class = GUSICS_INPUT_CLASS;
4081 dip->type = AUDIO_MIXER_ENUM;
4082 dip->prev = GUSICS_DAC_LVL;
4083 dip->next = AUDIO_MIXER_LAST;
4084 goto mute;
4085
4086 case GUSICS_CD_MUTE:
4087 dip->mixer_class = GUSICS_INPUT_CLASS;
4088 dip->type = AUDIO_MIXER_ENUM;
4089 dip->prev = GUSICS_CD_LVL;
4090 dip->next = AUDIO_MIXER_LAST;
4091 goto mute;
4092
4093 case GUSICS_MIC_IN_MUTE:
4094 dip->mixer_class = GUSICS_INPUT_CLASS;
4095 dip->type = AUDIO_MIXER_ENUM;
4096 dip->prev = GUSICS_MIC_IN_LVL;
4097 dip->next = AUDIO_MIXER_LAST;
4098 goto mute;
4099
4100 case GUSICS_MASTER_MUTE:
4101 dip->mixer_class = GUSICS_OUTPUT_CLASS;
4102 dip->type = AUDIO_MIXER_ENUM;
4103 dip->prev = GUSICS_MASTER_LVL;
4104 dip->next = AUDIO_MIXER_LAST;
4105 mute:
4106 strcpy(dip->label.name, AudioNmute);
4107 dip->un.e.num_mem = 2;
4108 strcpy(dip->un.e.member[0].label.name, AudioNoff);
4109 dip->un.e.member[0].ord = 0;
4110 strcpy(dip->un.e.member[1].label.name, AudioNon);
4111 dip->un.e.member[1].ord = 1;
4112 break;
4113
4114 case GUSICS_RECORD_SOURCE:
4115 dip->mixer_class = GUSICS_RECORD_CLASS;
4116 dip->type = AUDIO_MIXER_ENUM;
4117 dip->prev = dip->next = AUDIO_MIXER_LAST;
4118 strcpy(dip->label.name, AudioNsource);
4119 dip->un.e.num_mem = 1;
4120 strcpy(dip->un.e.member[0].label.name, AudioNoutput);
4121 dip->un.e.member[0].ord = GUSICS_MASTER_LVL;
4122 break;
4123
4124 case GUSICS_INPUT_CLASS:
4125 dip->type = AUDIO_MIXER_CLASS;
4126 dip->mixer_class = GUSICS_INPUT_CLASS;
4127 dip->next = dip->prev = AUDIO_MIXER_LAST;
4128 strcpy(dip->label.name, AudioCinputs);
4129 break;
4130
4131 case GUSICS_OUTPUT_CLASS:
4132 dip->type = AUDIO_MIXER_CLASS;
4133 dip->mixer_class = GUSICS_OUTPUT_CLASS;
4134 dip->next = dip->prev = AUDIO_MIXER_LAST;
4135 strcpy(dip->label.name, AudioCoutputs);
4136 break;
4137
4138 case GUSICS_RECORD_CLASS:
4139 dip->type = AUDIO_MIXER_CLASS;
4140 dip->mixer_class = GUSICS_RECORD_CLASS;
4141 dip->next = dip->prev = AUDIO_MIXER_LAST;
4142 strcpy(dip->label.name, AudioCrecord);
4143 break;
4144
4145 default:
4146 return ENXIO;
4147 /*NOTREACHED*/
4148 }
4149 DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name));
4150 return 0;
4151 }
4152
4153 STATIC int
4154 gus_query_encoding(addr, fp)
4155 void *addr;
4156 struct audio_encoding *fp;
4157 {
4158 switch (fp->index) {
4159 case 0:
4160 strcpy(fp->name, AudioEmulaw);
4161 fp->encoding = AUDIO_ENCODING_ULAW;
4162 fp->precision = 8;
4163 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
4164 break;
4165 case 1:
4166 strcpy(fp->name, AudioEslinear);
4167 fp->encoding = AUDIO_ENCODING_SLINEAR;
4168 fp->precision = 8;
4169 fp->flags = 0;
4170 break;
4171 case 2:
4172 strcpy(fp->name, AudioEslinear_le);
4173 fp->encoding = AUDIO_ENCODING_SLINEAR_LE;
4174 fp->precision = 16;
4175 fp->flags = 0;
4176 break;
4177 case 3:
4178 strcpy(fp->name, AudioEulinear);
4179 fp->encoding = AUDIO_ENCODING_ULINEAR;
4180 fp->precision = 8;
4181 fp->flags = 0;
4182 break;
4183 case 4:
4184 strcpy(fp->name, AudioEulinear_le);
4185 fp->encoding = AUDIO_ENCODING_ULINEAR_LE;
4186 fp->precision = 16;
4187 fp->flags = 0;
4188 break;
4189 case 5:
4190 strcpy(fp->name, AudioEslinear_be);
4191 fp->encoding = AUDIO_ENCODING_SLINEAR_BE;
4192 fp->precision = 16;
4193 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
4194 break;
4195 case 6:
4196 strcpy(fp->name, AudioEulinear_be);
4197 fp->encoding = AUDIO_ENCODING_ULINEAR_BE;
4198 fp->precision = 16;
4199 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
4200 break;
4201 case 7:
4202 strcpy(fp->name, AudioEalaw);
4203 fp->encoding = AUDIO_ENCODING_ALAW;
4204 fp->precision = 8;
4205 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
4206 break;
4207
4208 default:
4209 return(EINVAL);
4210 /*NOTREACHED*/
4211 }
4212 return (0);
4213 }
4214
4215 /*
4216 * Setup the ICS mixer in "transparent" mode: reset everything to a sensible
4217 * level. Levels as suggested by GUS SDK code.
4218 */
4219
4220 STATIC void
4221 gus_init_ics2101(sc)
4222 struct gus_softc *sc;
4223 {
4224 struct ics2101_softc *ic = &sc->sc_mixer;
4225 sc->sc_mixer.sc_iot = sc->sc_iot;
4226 sc->sc_mixer.sc_selio = GUS_MIXER_SELECT;
4227 sc->sc_mixer.sc_selio_ioh = sc->sc_ioh3;
4228 sc->sc_mixer.sc_dataio = GUS_MIXER_DATA;
4229 sc->sc_mixer.sc_dataio_ioh = sc->sc_ioh2;
4230 sc->sc_mixer.sc_flags = (sc->sc_revision == 5) ? ICS_FLIP : 0;
4231
4232 ics2101_mix_attenuate(ic,
4233 GUSMIX_CHAN_MIC,
4234 ICSMIX_LEFT,
4235 ICSMIX_MIN_ATTN);
4236 ics2101_mix_attenuate(ic,
4237 GUSMIX_CHAN_MIC,
4238 ICSMIX_RIGHT,
4239 ICSMIX_MIN_ATTN);
4240 /*
4241 * Start with microphone muted by the mixer...
4242 */
4243 gusics_mic_mute(ic, 1);
4244
4245 /* ... and enabled by the GUS master mix control */
4246 gus_mic_ctl(sc, SPKR_ON);
4247
4248 ics2101_mix_attenuate(ic,
4249 GUSMIX_CHAN_LINE,
4250 ICSMIX_LEFT,
4251 ICSMIX_MIN_ATTN);
4252 ics2101_mix_attenuate(ic,
4253 GUSMIX_CHAN_LINE,
4254 ICSMIX_RIGHT,
4255 ICSMIX_MIN_ATTN);
4256
4257 ics2101_mix_attenuate(ic,
4258 GUSMIX_CHAN_CD,
4259 ICSMIX_LEFT,
4260 ICSMIX_MIN_ATTN);
4261 ics2101_mix_attenuate(ic,
4262 GUSMIX_CHAN_CD,
4263 ICSMIX_RIGHT,
4264 ICSMIX_MIN_ATTN);
4265
4266 ics2101_mix_attenuate(ic,
4267 GUSMIX_CHAN_DAC,
4268 ICSMIX_LEFT,
4269 ICSMIX_MIN_ATTN);
4270 ics2101_mix_attenuate(ic,
4271 GUSMIX_CHAN_DAC,
4272 ICSMIX_RIGHT,
4273 ICSMIX_MIN_ATTN);
4274
4275 ics2101_mix_attenuate(ic,
4276 ICSMIX_CHAN_4,
4277 ICSMIX_LEFT,
4278 ICSMIX_MAX_ATTN);
4279 ics2101_mix_attenuate(ic,
4280 ICSMIX_CHAN_4,
4281 ICSMIX_RIGHT,
4282 ICSMIX_MAX_ATTN);
4283
4284 ics2101_mix_attenuate(ic,
4285 GUSMIX_CHAN_MASTER,
4286 ICSMIX_LEFT,
4287 ICSMIX_MIN_ATTN);
4288 ics2101_mix_attenuate(ic,
4289 GUSMIX_CHAN_MASTER,
4290 ICSMIX_RIGHT,
4291 ICSMIX_MIN_ATTN);
4292 /* unmute other stuff: */
4293 gusics_cd_mute(ic, 0);
4294 gusics_dac_mute(ic, 0);
4295 gusics_linein_mute(ic, 0);
4296 return;
4297 }
4298
4299
4300 #endif /* NGUS */
4301