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