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