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