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