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