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