gus.c revision 1.52
1/*	$NetBSD: gus.c,v 1.52 1998/03/09 06:32:51 mikel Exp $	*/
2
3/*-
4 * Copyright (c) 1996 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Ken Hornstein and John Kohl.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 *    must display the following acknowledgement:
20 *        This product includes software developed by the NetBSD
21 *	  Foundation, Inc. and its contributors.
22 * 4. Neither the name of The NetBSD Foundation nor the names of its
23 *    contributors may be used to endorse or promote products derived
24 *    from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 */
38
39/*
40 *
41 * TODO:
42 *	. figure out why mixer activity while sound is playing causes problems
43 *	  (phantom interrupts?)
44 *  	. figure out a better deinterleave strategy that avoids sucking up
45 *	  CPU, memory and cache bandwidth.  (Maybe a special encoding?
46 *	  Maybe use the double-speed sampling/hardware deinterleave trick
47 *	  from the GUS SDK?)  A 486/33 isn't quite fast enough to keep
48 *	  up with 44.1kHz 16-bit stereo output without some drop-outs.
49 *	. use CS4231 for 16-bit sampling, for a-law and mu-law playback.
50 *	. actually test full-duplex sampling(recording) and playback.
51 */
52
53/*
54 * Gravis UltraSound driver
55 *
56 * For more detailed information, see the GUS developers' kit
57 * available on the net at:
58 *
59 * ftp://freedom.nmsu.edu/pub/ultrasound/gravis/util/
60 * 	gusdkXXX.zip (developers' kit--get rev 2.22 or later)
61 *		See ultrawrd.doc inside--it's MS Word (ick), but it's the bible
62 *
63 */
64
65/*
66 * The GUS Max has a slightly strange set of connections between the CS4231
67 * and the GF1 and the DMA interconnects.  It's set up so that the CS4231 can
68 * be playing while the GF1 is loading patches from the system.
69 *
70 * Here's a recreation of the DMA interconnect diagram:
71 *
72 *       GF1
73 *   +---------+				 digital
74 *   |         |  record			 ASIC
75 *   |         |--------------+
76 *   |         |              |		       +--------+
77 *   |         | play (dram)  |      +----+    |	|
78 *   |         |--------------(------|-\  |    |   +-+  |
79 *   +---------+              |      |  >-|----|---|C|--|------  dma chan 1
80 *                            |  +---|-/  |    |   +-+ 	|
81 *                            |  |   +----+    |    |   |
82 *                            |	 |   +----+    |    |   |
83 *   +---------+        +-+   +--(---|-\  |    |    |   |
84 *   |         | play   |8|      |   |  >-|----|----+---|------  dma chan 2
85 *   | ---C----|--------|/|------(---|-/  |    |        |
86 *   |    ^    |record  |1|      |   +----+    |	|
87 *   |    |    |   /----|6|------+   	       +--------+
88 *   | ---+----|--/     +-+
89 *   +---------+
90 *     CS4231   	8-to-16 bit bus conversion, if needed
91 *
92 *
93 * "C" is an optional combiner.
94 *
95 */
96
97#include "gus.h"
98#if NGUS > 0
99
100#include <sys/param.h>
101#include <sys/systm.h>
102#include <sys/errno.h>
103#include <sys/ioctl.h>
104#include <sys/syslog.h>
105#include <sys/device.h>
106#include <sys/proc.h>
107#include <sys/buf.h>
108#include <sys/fcntl.h>
109#include <sys/malloc.h>
110#include <sys/kernel.h>
111
112#include <machine/cpu.h>
113#include <machine/intr.h>
114#include <machine/bus.h>
115#include <machine/pio.h>
116#include <machine/cpufunc.h>
117#include <sys/audioio.h>
118#include <dev/audio_if.h>
119#include <dev/mulaw.h>
120#include <dev/auconv.h>
121
122#include <dev/isa/isavar.h>
123#include <dev/isa/isadmavar.h>
124#include <i386/isa/icu.h>
125
126#include <dev/ic/ics2101reg.h>
127#include <dev/ic/cs4231reg.h>
128#include <dev/ic/ad1848reg.h>
129#include <dev/isa/ics2101var.h>
130#include <dev/isa/ad1848var.h>
131#include <dev/isa/cs4231var.h>
132#include "gusreg.h"
133
134#ifdef AUDIO_DEBUG
135#define STATIC /* empty; for debugging symbols */
136#else
137#define STATIC static
138#endif
139
140/*
141 * Software state of a single "voice" on the GUS
142 */
143
144struct gus_voice {
145
146	/*
147	 * Various control bits
148	 */
149
150	unsigned char voccntl;	/* State of voice control register */
151	unsigned char volcntl;	/* State of volume control register */
152	unsigned char pan_pos;	/* Position of volume panning (4 bits) */
153	int rate;		/* Sample rate of voice being played back */
154
155	/*
156	 * Address of the voice data into the GUS's DRAM.  20 bits each
157	 */
158
159	u_long start_addr;	/* Starting address of voice data loop area */
160	u_long end_addr;	/* Ending address of voice data loop */
161	u_long current_addr;	/* Beginning address of voice data
162				   (start playing here) */
163
164	/*
165	 * linear volume values for the GUS's volume ramp.  0-511 (9 bits).
166	 * These values must be translated into the logarithmic values using
167	 * gus_log_volumes[]
168	 */
169
170	int start_volume;	/* Starting position of volume ramp */
171	int current_volume;	/* Current position of volume on volume ramp */
172	int end_volume;		/* Ending position of volume on volume ramp */
173};
174
175/*
176 * Software state of GUS
177 */
178
179struct gus_softc {
180	struct device sc_dev;		/* base device */
181	struct device *sc_isa;		/* pointer to ISA parent */
182	void *sc_ih;			/* interrupt vector */
183	bus_space_tag_t sc_iot;		/* tag */
184	bus_space_handle_t sc_ioh1;	/* handle */
185	bus_space_handle_t sc_ioh2;	/* handle */
186	bus_space_handle_t sc_ioh3;	/* ICS2101 handle */
187	bus_space_handle_t sc_ioh4;	/* MIDI handle */
188
189	int sc_iobase;			/* I/O base address */
190	int sc_irq;			/* IRQ used */
191	int sc_drq;			/* DMA channel for play */
192	int sc_recdrq;			/* DMA channel for recording */
193
194	int sc_flags;			/* Various flags about the GUS */
195#define GUS_MIXER_INSTALLED	0x01	/* An ICS mixer is installed */
196#define GUS_LOCKED		0x02	/* GUS is busy doing multi-phase DMA */
197#define GUS_CODEC_INSTALLED	0x04	/* CS4231 installed/MAX */
198#define GUS_PLAYING		0x08	/* GUS is playing a voice */
199#define GUS_DMAOUT_ACTIVE	0x10	/* GUS is busy doing audio DMA */
200#define GUS_DMAIN_ACTIVE	0x20	/* GUS is busy sampling  */
201#define GUS_OPEN		0x100	/* GUS is open */
202	int sc_dsize;			/* Size of GUS DRAM */
203	int sc_voices;			/* Number of active voices */
204	u_char sc_revision;		/* Board revision of GUS */
205	u_char sc_mixcontrol;		/* Value of GUS_MIX_CONTROL register */
206
207	u_long sc_orate;		/* Output sampling rate */
208	u_long sc_irate;		/* Input sampling rate */
209
210	int sc_encoding;		/* Current data encoding type */
211	int sc_precision;		/* # of bits of precision */
212	int sc_channels;		/* Number of active channels */
213	int sc_blocksize;		/* Current blocksize */
214	int sc_chanblocksize;		/* Current blocksize for each in-use
215					   channel */
216	short sc_nbufs;			/* how many on-GUS bufs per-channel */
217	short sc_bufcnt;		/* how many need to be played */
218	void *sc_deintr_buf;		/* deinterleave buffer for stereo */
219
220	int sc_ogain;			/* Output gain control */
221	u_char sc_out_port;		/* Current out port (generic only) */
222	u_char sc_in_port;		/* keep track of it when no codec */
223
224	void (*sc_dmaoutintr) __P((void*)); /* DMA completion intr handler */
225	void *sc_outarg;		/* argument for sc_dmaoutintr() */
226	u_char *sc_dmaoutaddr;		/* for isa_dmadone */
227	u_long sc_gusaddr;		/* where did we just put it? */
228	int sc_dmaoutcnt;		/* for isa_dmadone */
229
230	void (*sc_dmainintr) __P((void*)); /* DMA completion intr handler */
231	void *sc_inarg;			/* argument for sc_dmaoutintr() */
232	u_char *sc_dmainaddr;		/* for isa_dmadone */
233	int sc_dmaincnt;		/* for isa_dmadone */
234
235	struct stereo_dma_intr {
236		void (*intr)__P((void *));
237		void *arg;
238		u_char *buffer;
239		u_long dmabuf;
240		int size;
241		int flags;
242	} sc_stereo;
243
244	/*
245	 * State information for linear audio layer
246	 */
247
248	int sc_dmabuf;			/* Which ring buffer we're DMA'ing to */
249	int sc_playbuf;			/* Which ring buffer we're playing */
250
251	/*
252	 * Voice information array.  All voice-specific information is stored
253	 * here
254	 */
255
256	struct gus_voice sc_voc[32];	/* Voice data for each voice */
257	union {
258		struct ics2101_softc sc_mixer_u;
259		struct ad1848_softc sc_codec_u;
260	} u;
261#define sc_mixer u.sc_mixer_u
262#define sc_codec u.sc_codec_u
263};
264
265struct ics2101_volume {
266	u_char left;
267	u_char right;
268};
269
270#define HAS_CODEC(sc) ((sc)->sc_flags & GUS_CODEC_INSTALLED)
271#define HAS_MIXER(sc) ((sc)->sc_flags & GUS_MIXER_INSTALLED)
272
273/*
274 * Mixer devices for ICS2101
275 */
276/* MIC IN mute, line in mute, line out mute are first since they can be done
277   even if no ICS mixer. */
278#define GUSICS_MIC_IN_MUTE		0
279#define GUSICS_LINE_IN_MUTE		1
280#define GUSICS_MASTER_MUTE		2
281#define GUSICS_CD_MUTE			3
282#define GUSICS_DAC_MUTE			4
283#define GUSICS_MIC_IN_LVL		5
284#define GUSICS_LINE_IN_LVL		6
285#define GUSICS_CD_LVL			7
286#define GUSICS_DAC_LVL			8
287#define GUSICS_MASTER_LVL		9
288
289#define GUSICS_RECORD_SOURCE		10
290
291/* Classes */
292#define GUSICS_INPUT_CLASS		11
293#define GUSICS_OUTPUT_CLASS		12
294#define GUSICS_RECORD_CLASS		13
295
296/*
297 * Mixer & MUX devices for CS4231
298 */
299#define GUSMAX_MONO_LVL			0 /* mic input to MUX;
300					     also mono mixer input */
301#define GUSMAX_DAC_LVL			1 /* input to MUX; also mixer input */
302#define GUSMAX_LINE_IN_LVL		2 /* input to MUX; also mixer input */
303#define GUSMAX_CD_LVL			3 /* mixer input only */
304#define GUSMAX_MONITOR_LVL		4 /* digital mix (?) */
305#define GUSMAX_OUT_LVL			5 /* output level. (?) */
306#define GUSMAX_SPEAKER_LVL		6 /* pseudo-device for mute */
307#define GUSMAX_LINE_IN_MUTE		7 /* pre-mixer */
308#define GUSMAX_DAC_MUTE			8 /* pre-mixer */
309#define GUSMAX_CD_MUTE			9 /* pre-mixer */
310#define GUSMAX_MONO_MUTE		10 /* pre-mixer--microphone/mono */
311#define GUSMAX_MONITOR_MUTE		11 /* post-mixer level/mute */
312#define GUSMAX_SPEAKER_MUTE		12 /* speaker mute */
313
314#define GUSMAX_REC_LVL			13 /* post-MUX gain */
315
316#define GUSMAX_RECORD_SOURCE		14
317
318/* Classes */
319#define GUSMAX_INPUT_CLASS		15
320#define GUSMAX_RECORD_CLASS		16
321#define GUSMAX_MONITOR_CLASS		17
322#define GUSMAX_OUTPUT_CLASS		18
323
324#ifdef AUDIO_DEBUG
325#define GUSPLAYDEBUG	/*XXX*/
326#define DPRINTF(x)	if (gusdebug) printf x
327#define DMAPRINTF(x)	if (gusdmadebug) printf x
328int	gusdebug = 0;
329int	gusdmadebug = 0;
330#else
331#define DPRINTF(x)
332#define DMAPRINTF(x)
333#endif
334int	gus_dostereo = 1;
335
336#define NDMARECS 2048
337#ifdef GUSPLAYDEBUG
338int	gusstats = 0;
339struct dma_record {
340    struct timeval tv;
341    u_long gusaddr;
342    caddr_t bsdaddr;
343    u_short count;
344    u_char channel;
345    u_char direction;
346} dmarecords[NDMARECS];
347
348int dmarecord_index = 0;
349#endif
350
351/*
352 * local routines
353 */
354
355int	gusopen __P((void *, int));
356void	gusclose __P((void *));
357void	gusmax_close __P((void *));
358int	gusintr __P((void *));
359int	gus_set_in_gain __P((caddr_t, u_int, u_char));
360int	gus_get_in_gain __P((caddr_t));
361int	gus_set_out_gain __P((caddr_t, u_int, u_char));
362int	gus_get_out_gain __P((caddr_t));
363int 	gus_set_params __P((void *, int, int, struct audio_params *, struct audio_params *));
364int 	gusmax_set_params __P((void *, int, int, struct audio_params *, struct audio_params *));
365int	gus_round_blocksize __P((void *, int));
366int	gus_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 flags
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	sprintf(gus_device.version, "3.%d", sc->sc_revision);
979
980	printf("\n <Gravis UltraSound version 3.%d, %dKB DRAM, ",
981	       sc->sc_revision, sc->sc_dsize);
982	if (HAS_MIXER(sc))
983		printf("ICS2101 mixer, ");
984	if (HAS_CODEC(sc))
985		printf("%s codec/mixer, ", sc->sc_codec.chip_name);
986	if (sc->sc_recdrq == sc->sc_drq) {
987		printf("half-duplex");
988	} else {
989		printf("full-duplex, record drq %d", sc->sc_recdrq);
990	}
991
992	printf(">\n");
993
994	/*
995	 * Setup a default interrupt handler
996	 */
997
998	/* XXX we shouldn't have to use splgus == splclock, nor should
999	 * we use IPL_CLOCK.
1000	 */
1001	sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq, IST_EDGE,
1002	    IPL_AUDIO, gusintr, sc /* sc->sc_gusdsp */);
1003
1004	/*
1005	 * Set some default values
1006	 * XXX others start with 8kHz mono mulaw
1007	 */
1008
1009	sc->sc_irate = sc->sc_orate = 44100;
1010	sc->sc_encoding = AUDIO_ENCODING_SLINEAR_LE;
1011	sc->sc_precision = 16;
1012	sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_DATA_SIZE16;
1013	sc->sc_voc[GUS_VOICE_RIGHT].voccntl |= GUSMASK_DATA_SIZE16;
1014	sc->sc_channels = 1;
1015	sc->sc_ogain = 340;
1016	gus_commit_settings(sc);
1017
1018	/*
1019	 * We always put the left channel full left & right channel
1020	 * full right.
1021	 * For mono playback, we set up both voices playing the same buffer.
1022	 */
1023	bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) GUS_VOICE_LEFT);
1024	SELECT_GUS_REG(iot, ioh2, GUSREG_PAN_POS);
1025	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, GUS_PAN_FULL_LEFT);
1026
1027	bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) GUS_VOICE_RIGHT);
1028	SELECT_GUS_REG(iot, ioh2, GUSREG_PAN_POS);
1029	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, GUS_PAN_FULL_RIGHT);
1030
1031	/*
1032	 * Attach to the generic audio layer
1033	 */
1034
1035	audio_attach_mi(&gus_hw_if, 0, HAS_CODEC(sc) ? (void *)&sc->sc_codec : (void *)sc, &sc->sc_dev);
1036}
1037
1038int
1039gusopen(addr, flags)
1040	void *addr;
1041	int flags;
1042{
1043	struct gus_softc *sc = addr;
1044
1045	DPRINTF(("gusopen() called\n"));
1046
1047	if (sc->sc_flags & GUS_OPEN)
1048		return EBUSY;
1049
1050	/*
1051	 * Some initialization
1052	 */
1053
1054	sc->sc_flags |= GUS_OPEN;
1055	sc->sc_dmabuf = 0;
1056	sc->sc_playbuf = -1;
1057	sc->sc_bufcnt = 0;
1058	sc->sc_voc[GUS_VOICE_LEFT].start_addr = GUS_MEM_OFFSET - 1;
1059	sc->sc_voc[GUS_VOICE_LEFT].current_addr = GUS_MEM_OFFSET;
1060
1061	if (HAS_CODEC(sc)) {
1062		ad1848_open(&sc->sc_codec, flags);
1063		sc->sc_codec.aux1_mute = 0;
1064		ad1848_mute_aux1(&sc->sc_codec, 0); /* turn on DAC output */
1065		if (flags & FREAD) {
1066			sc->sc_codec.mono_mute = 0;
1067			cs4231_mute_mono(&sc->sc_codec, 0);
1068		}
1069	} else if (flags & FREAD) {
1070		/* enable/unmute the microphone */
1071		if (HAS_MIXER(sc)) {
1072			gusics_mic_mute(&sc->sc_mixer, 0);
1073		} else
1074			gus_mic_ctl(sc, SPKR_ON);
1075	}
1076	if (sc->sc_nbufs == 0)
1077	    gus_round_blocksize(sc, GUS_BUFFER_MULTIPLE); /* default blksiz */
1078	return 0;
1079}
1080
1081int
1082gusmaxopen(addr, flags)
1083	void *addr;
1084	int flags;
1085{
1086	struct ad1848_softc *ac = addr;
1087	return gusopen(ac->parent, flags);
1088}
1089
1090STATIC void
1091gus_deinterleave(sc, buf, size)
1092	struct gus_softc *sc;
1093	void *buf;
1094	int size;
1095{
1096	/* deinterleave the stereo data.  We can use sc->sc_deintr_buf
1097	   for scratch space. */
1098	int i;
1099
1100	if (size > sc->sc_blocksize) {
1101		printf("gus: deinterleave %d > %d\n", size, sc->sc_blocksize);
1102		return;
1103	} else if (size < sc->sc_blocksize) {
1104		DPRINTF(("gus: deinterleave %d < %d\n", size, sc->sc_blocksize));
1105	}
1106
1107	/*
1108	 * size is in bytes.
1109	 */
1110	if (sc->sc_precision == 16) {
1111		u_short *dei = sc->sc_deintr_buf;
1112		u_short *sbuf = buf;
1113		size >>= 1;		/* bytecnt to shortcnt */
1114		/* copy 2nd of each pair of samples to the staging area, while
1115		   compacting the 1st of each pair into the original area. */
1116		for (i = 0; i < size/2-1; i++)  {
1117			dei[i] = sbuf[i*2+1];
1118			sbuf[i+1] = sbuf[i*2+2];
1119		}
1120		/*
1121		 * this has copied one less sample than half of the
1122		 * buffer.  The first sample of the 1st stream was
1123		 * already in place and didn't need copying.
1124		 * Therefore, we've moved all of the 1st stream's
1125		 * samples into place.  We have one sample from 2nd
1126		 * stream in the last slot of original area, not
1127		 * copied to the staging area (But we don't need to!).
1128		 * Copy the remainder of the original stream into place.
1129		 */
1130		bcopy(dei, &sbuf[size/2], i * sizeof(short));
1131	} else {
1132		u_char *dei = sc->sc_deintr_buf;
1133		u_char *sbuf = buf;
1134		for (i = 0; i < size/2-1; i++)  {
1135			dei[i] = sbuf[i*2+1];
1136			sbuf[i+1] = sbuf[i*2+2];
1137		}
1138		bcopy(dei, &sbuf[size/2], i);
1139	}
1140}
1141
1142/*
1143 * Actually output a buffer to the DSP chip
1144 */
1145
1146int
1147gusmax_dma_output(addr, buf, size, intr, arg)
1148	void * addr;
1149	void *buf;
1150	int size;
1151	void (*intr) __P((void *));
1152	void *arg;
1153{
1154	struct ad1848_softc *ac = addr;
1155	return gus_dma_output(ac->parent, buf, size, intr, arg);
1156}
1157
1158/*
1159 * called at splgus() from interrupt handler.
1160 */
1161void
1162stereo_dmaintr(arg)
1163	void *arg;
1164{
1165    struct gus_softc *sc = arg;
1166    struct stereo_dma_intr *sa = &sc->sc_stereo;
1167
1168    DMAPRINTF(("stereo_dmaintr"));
1169
1170    /*
1171     * Put other half in its place, then call the real interrupt routine :)
1172     */
1173
1174    sc->sc_dmaoutintr = sa->intr;
1175    sc->sc_outarg = sa->arg;
1176
1177#ifdef GUSPLAYDEBUG
1178    if (gusstats) {
1179      microtime(&dmarecords[dmarecord_index].tv);
1180      dmarecords[dmarecord_index].gusaddr = sa->dmabuf;
1181      dmarecords[dmarecord_index].bsdaddr = sa->buffer;
1182      dmarecords[dmarecord_index].count = sa->size;
1183      dmarecords[dmarecord_index].channel = 1;
1184      dmarecords[dmarecord_index].direction = 1;
1185      dmarecord_index = ++dmarecord_index % NDMARECS;
1186    }
1187#endif
1188
1189    gusdmaout(sc, sa->flags, sa->dmabuf, (caddr_t) sa->buffer, sa->size);
1190
1191    sa->flags = 0;
1192    sa->dmabuf = 0;
1193    sa->buffer = 0;
1194    sa->size = 0;
1195    sa->intr = 0;
1196    sa->arg = 0;
1197}
1198
1199/*
1200 * Start up DMA output to the card.
1201 * Called at splgus/splaudio already, either from intr handler or from
1202 * generic audio code.
1203 */
1204int
1205gus_dma_output(addr, buf, size, intr, arg)
1206	void * addr;
1207	void *buf;
1208	int size;
1209	void (*intr) __P((void *));
1210	void *arg;
1211{
1212	struct gus_softc *sc = addr;
1213	u_char *buffer = buf;
1214	u_long boarddma;
1215	int flags;
1216
1217	DMAPRINTF(("gus_dma_output %d @ %p\n", size, buf));
1218
1219	if (size != sc->sc_blocksize) {
1220	    DPRINTF(("gus_dma_output reqsize %d not sc_blocksize %d\n",
1221		     size, sc->sc_blocksize));
1222	    return EINVAL;
1223	}
1224
1225	flags = GUSMASK_DMA_WRITE;
1226	if (sc->sc_precision == 16)
1227	    flags |= GUSMASK_DMA_DATA_SIZE;
1228	if (sc->sc_encoding == AUDIO_ENCODING_ULAW ||
1229	    sc->sc_encoding == AUDIO_ENCODING_ALAW ||
1230	    sc->sc_encoding == AUDIO_ENCODING_ULINEAR_BE ||
1231	    sc->sc_encoding == AUDIO_ENCODING_ULINEAR_LE)
1232	    flags |= GUSMASK_DMA_INVBIT;
1233
1234	if (sc->sc_channels == 2) {
1235		if (sc->sc_precision == 16) {
1236			if (size & 3) {
1237				DPRINTF(("gus_dma_output: unpaired 16bit samples"));
1238				size &= 3;
1239			}
1240		} else if (size & 1) {
1241			DPRINTF(("gus_dma_output: unpaired samples"));
1242			size &= 1;
1243		}
1244		if (size == 0)
1245			return 0;
1246
1247		gus_deinterleave(sc, (void *)buffer, size);
1248
1249		size >>= 1;
1250
1251 		boarddma = size * sc->sc_dmabuf + GUS_MEM_OFFSET;
1252
1253		sc->sc_stereo.intr = intr;
1254		sc->sc_stereo.arg = arg;
1255		sc->sc_stereo.size = size;
1256		sc->sc_stereo.dmabuf = boarddma + GUS_LEFT_RIGHT_OFFSET;
1257		sc->sc_stereo.buffer = buffer + size;
1258		sc->sc_stereo.flags = flags;
1259		if (gus_dostereo) {
1260		  intr = stereo_dmaintr;
1261		  arg = sc;
1262		}
1263	} else
1264		boarddma = size * sc->sc_dmabuf + GUS_MEM_OFFSET;
1265
1266
1267	sc->sc_flags |= GUS_LOCKED;
1268	sc->sc_dmaoutintr = intr;
1269	sc->sc_outarg = arg;
1270
1271#ifdef GUSPLAYDEBUG
1272	if (gusstats) {
1273	  microtime(&dmarecords[dmarecord_index].tv);
1274	  dmarecords[dmarecord_index].gusaddr = boarddma;
1275	  dmarecords[dmarecord_index].bsdaddr = buffer;
1276	  dmarecords[dmarecord_index].count = size;
1277	  dmarecords[dmarecord_index].channel = 0;
1278	  dmarecords[dmarecord_index].direction = 1;
1279	  dmarecord_index = ++dmarecord_index % NDMARECS;
1280	}
1281#endif
1282
1283	gusdmaout(sc, flags, boarddma, (caddr_t) buffer, size);
1284
1285	return 0;
1286}
1287
1288void
1289gusmax_close(addr)
1290	void *addr;
1291{
1292	struct ad1848_softc *ac = addr;
1293	struct gus_softc *sc = ac->parent;
1294#if 0
1295	ac->aux1_mute = 1;
1296	ad1848_mute_aux1(ac, 1);	/* turn off DAC output */
1297#endif
1298	ad1848_close(ac);
1299	gusclose(sc);
1300}
1301
1302/*
1303 * Close out device stuff.  Called at splgus() from generic audio layer.
1304 */
1305void
1306gusclose(addr)
1307	void *addr;
1308{
1309	struct gus_softc *sc = addr;
1310
1311        DPRINTF(("gus_close: sc=%p\n", sc));
1312
1313
1314/*	if (sc->sc_flags & GUS_DMAOUT_ACTIVE) */ {
1315		gus_halt_out_dma(sc);
1316	}
1317/*	if (sc->sc_flags & GUS_DMAIN_ACTIVE) */ {
1318		gus_halt_in_dma(sc);
1319	}
1320	sc->sc_flags &= ~(GUS_OPEN|GUS_LOCKED|GUS_DMAOUT_ACTIVE|GUS_DMAIN_ACTIVE);
1321
1322	if (sc->sc_deintr_buf) {
1323		FREE(sc->sc_deintr_buf, M_DEVBUF);
1324		sc->sc_deintr_buf = NULL;
1325	}
1326	/* turn off speaker, etc. */
1327
1328	/* make sure the voices shut up: */
1329	gus_stop_voice(sc, GUS_VOICE_LEFT, 1);
1330	gus_stop_voice(sc, GUS_VOICE_RIGHT, 0);
1331}
1332
1333/*
1334 * Service interrupts.  Farm them off to helper routines if we are using the
1335 * GUS for simple playback/record
1336 */
1337
1338#ifdef DIAGNOSTIC
1339int gusintrcnt;
1340int gusdmaintrcnt;
1341int gusvocintrcnt;
1342#endif
1343
1344int
1345gusintr(arg)
1346	void *arg;
1347{
1348	struct gus_softc *sc = arg;
1349	bus_space_tag_t iot = sc->sc_iot;
1350	bus_space_handle_t ioh1 = sc->sc_ioh1;
1351	bus_space_handle_t ioh2 = sc->sc_ioh2;
1352	unsigned char intr;
1353
1354	int retval = 0;
1355
1356	DPRINTF(("gusintr\n"));
1357#ifdef DIAGNOSTIC
1358	gusintrcnt++;
1359#endif
1360	if (HAS_CODEC(sc))
1361		retval = ad1848_intr(&sc->sc_codec);
1362	if ((intr = bus_space_read_1(iot, ioh1, GUS_IRQ_STATUS)) & GUSMASK_IRQ_DMATC) {
1363		DMAPRINTF(("gusintr dma flags=%x\n", sc->sc_flags));
1364#ifdef DIAGNOSTIC
1365		gusdmaintrcnt++;
1366#endif
1367		retval += gus_dmaout_intr(sc);
1368		if (sc->sc_flags & GUS_DMAIN_ACTIVE) {
1369		    SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
1370		    intr = bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
1371		    if (intr & GUSMASK_SAMPLE_DMATC) {
1372			retval += gus_dmain_intr(sc);
1373		    }
1374		}
1375	}
1376	if (intr & (GUSMASK_IRQ_VOICE | GUSMASK_IRQ_VOLUME)) {
1377		DMAPRINTF(("gusintr voice flags=%x\n", sc->sc_flags));
1378#ifdef DIAGNOSTIC
1379		gusvocintrcnt++;
1380#endif
1381		retval += gus_voice_intr(sc);
1382	}
1383	if (retval)
1384		return 1;
1385	return retval;
1386}
1387
1388int gus_bufcnt[GUS_MEM_FOR_BUFFERS / GUS_BUFFER_MULTIPLE];
1389int gus_restart;				/* how many restarts? */
1390int gus_stops;				/* how many times did voice stop? */
1391int gus_falsestops;			/* stopped but not done? */
1392int gus_continues;
1393
1394struct playcont {
1395	struct timeval tv;
1396	u_int playbuf;
1397	u_int dmabuf;
1398	u_char bufcnt;
1399	u_char vaction;
1400	u_char voccntl;
1401	u_char volcntl;
1402	u_long curaddr;
1403	u_long endaddr;
1404} playstats[NDMARECS];
1405
1406int playcntr;
1407
1408STATIC void
1409gus_dmaout_timeout(arg)
1410	void *arg;
1411{
1412	struct gus_softc *sc = arg;
1413	bus_space_tag_t iot = sc->sc_iot;
1414	bus_space_handle_t ioh2 = sc->sc_ioh2;
1415	int s;
1416
1417	printf("%s: dmaout timeout\n", sc->sc_dev.dv_xname);
1418	/*
1419	 * Stop any DMA.
1420	 */
1421
1422	s = splgus();
1423	SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
1424	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0);
1425
1426#if 0
1427	/* XXX we will dmadone below? */
1428	isa_dmaabort(sc->sc_dev.dv_parent, sc->sc_drq);
1429#endif
1430
1431	gus_dmaout_dointr(sc);
1432	splx(s);
1433}
1434
1435
1436/*
1437 * Service DMA interrupts.  This routine will only get called if we're doing
1438 * a DMA transfer for playback/record requests from the audio layer.
1439 */
1440
1441STATIC int
1442gus_dmaout_intr(sc)
1443	struct gus_softc *sc;
1444{
1445	bus_space_tag_t iot = sc->sc_iot;
1446	bus_space_handle_t ioh2 = sc->sc_ioh2;
1447
1448	/*
1449	 * If we got a DMA transfer complete from the GUS DRAM, then deal
1450	 * with it.
1451	 */
1452
1453	SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
1454 	if (bus_space_read_1(iot, ioh2, GUS_DATA_HIGH) & GUSMASK_DMA_IRQPEND) {
1455	    untimeout(gus_dmaout_timeout, sc);
1456	    gus_dmaout_dointr(sc);
1457	    return 1;
1458	}
1459	return 0;
1460}
1461
1462STATIC void
1463gus_dmaout_dointr(sc)
1464	struct gus_softc *sc;
1465{
1466	bus_space_tag_t iot = sc->sc_iot;
1467	bus_space_handle_t ioh2 = sc->sc_ioh2;
1468
1469	/* sc->sc_dmaoutcnt - 1 because DMA controller counts from zero?. */
1470	isa_dmadone(sc->sc_dev.dv_parent, sc->sc_drq);
1471	sc->sc_flags &= ~GUS_DMAOUT_ACTIVE;  /* pending DMA is done */
1472	DMAPRINTF(("gus_dmaout_dointr %d @ %p\n", sc->sc_dmaoutcnt,
1473		   sc->sc_dmaoutaddr));
1474
1475	/*
1476	 * to prevent clicking, we need to copy last sample
1477	 * from last buffer to scratch area just before beginning of
1478	 * buffer.  However, if we're doing formats that are converted by
1479	 * the card during the DMA process, we need to pick up the converted
1480	 * byte rather than the one we have in memory.
1481	 */
1482	if (sc->sc_dmabuf == sc->sc_nbufs - 1) {
1483	  int i;
1484	  switch (sc->sc_encoding) {
1485	  case AUDIO_ENCODING_SLINEAR_LE:
1486	  case AUDIO_ENCODING_SLINEAR_BE:
1487	    if (sc->sc_precision == 8)
1488	      goto byte;
1489	    /* we have the native format */
1490	    for (i = 1; i <= 2; i++)
1491	      guspoke(iot, ioh2, sc->sc_gusaddr -
1492		      (sc->sc_nbufs - 1) * sc->sc_chanblocksize - i,
1493		      sc->sc_dmaoutaddr[sc->sc_dmaoutcnt-i]);
1494	    break;
1495	  case AUDIO_ENCODING_ULINEAR_LE:
1496	  case AUDIO_ENCODING_ULINEAR_BE:
1497	    guspoke(iot, ioh2, sc->sc_gusaddr -
1498		    (sc->sc_nbufs - 1) * sc->sc_chanblocksize - 2,
1499		    guspeek(iot, ioh2,
1500			    sc->sc_gusaddr + sc->sc_chanblocksize - 2));
1501	  case AUDIO_ENCODING_ALAW:
1502	  case AUDIO_ENCODING_ULAW:
1503	  byte:
1504	    /* we need to fetch the translated byte, then stuff it. */
1505	    guspoke(iot, ioh2, sc->sc_gusaddr -
1506		    (sc->sc_nbufs - 1) * sc->sc_chanblocksize - 1,
1507		    guspeek(iot, ioh2,
1508			    sc->sc_gusaddr + sc->sc_chanblocksize - 1));
1509	    break;
1510	  }
1511	}
1512	/*
1513	 * If this is the first half of stereo, "ignore" this one
1514	 * and copy out the second half.
1515	 */
1516	if (sc->sc_dmaoutintr == stereo_dmaintr) {
1517	    (*sc->sc_dmaoutintr)(sc->sc_outarg);
1518	    return;
1519	}
1520	/*
1521	 * If the voice is stopped, then start it.  Reset the loop
1522	 * and roll bits.  Call the audio layer routine, since if
1523	 * we're starting a stopped voice, that means that the next
1524	 * buffer can be filled
1525	 */
1526
1527	sc->sc_flags &= ~GUS_LOCKED;
1528	if (sc->sc_voc[GUS_VOICE_LEFT].voccntl &
1529	    GUSMASK_VOICE_STOPPED) {
1530	    if (sc->sc_flags & GUS_PLAYING) {
1531		printf("%s: playing yet stopped?\n", sc->sc_dev.dv_xname);
1532	    }
1533	    sc->sc_bufcnt++; /* another yet to be played */
1534	    gus_start_playing(sc, sc->sc_dmabuf);
1535	    gus_restart++;
1536	} else {
1537	    /*
1538	     * set the sound action based on which buffer we
1539	     * just transferred.  If we just transferred buffer 0
1540	     * we want the sound to loop when it gets to the nth
1541	     * buffer; if we just transferred
1542	     * any other buffer, we want the sound to roll over
1543	     * at least one more time.  The voice interrupt
1544	     * handlers will take care of accounting &
1545	     * setting control bits if it's not caught up to us
1546	     * yet.
1547	     */
1548	    if (++sc->sc_bufcnt == 2) {
1549		/*
1550		 * XXX
1551		 * If we're too slow in reaction here,
1552		 * the voice could be just approaching the
1553		 * end of its run.  It should be set to stop,
1554		 * so these adjustments might not DTRT.
1555		 */
1556		if (sc->sc_dmabuf == 0 &&
1557		    sc->sc_playbuf == sc->sc_nbufs - 1) {
1558		    /* player is just at the last buf, we're at the
1559		       first.  Turn on looping, turn off rolling. */
1560		    sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_LOOP_ENABLE;
1561		    sc->sc_voc[GUS_VOICE_LEFT].volcntl &= ~GUSMASK_VOICE_ROLL;
1562		    playstats[playcntr].vaction = 3;
1563		} else {
1564		    /* player is at previous buf:
1565		       turn on rolling, turn off looping */
1566		    sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~GUSMASK_LOOP_ENABLE;
1567		    sc->sc_voc[GUS_VOICE_LEFT].volcntl |= GUSMASK_VOICE_ROLL;
1568		    playstats[playcntr].vaction = 4;
1569		}
1570#ifdef GUSPLAYDEBUG
1571		if (gusstats) {
1572		  microtime(&playstats[playcntr].tv);
1573		  playstats[playcntr].endaddr = sc->sc_voc[GUS_VOICE_LEFT].end_addr;
1574		  playstats[playcntr].voccntl = sc->sc_voc[GUS_VOICE_LEFT].voccntl;
1575		  playstats[playcntr].volcntl = sc->sc_voc[GUS_VOICE_LEFT].volcntl;
1576		  playstats[playcntr].playbuf = sc->sc_playbuf;
1577		  playstats[playcntr].dmabuf = sc->sc_dmabuf;
1578		  playstats[playcntr].bufcnt = sc->sc_bufcnt;
1579		  playstats[playcntr].curaddr = gus_get_curaddr(sc, GUS_VOICE_LEFT);
1580		  playcntr = ++playcntr % NDMARECS;
1581		}
1582#endif
1583		bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, GUS_VOICE_LEFT);
1584		SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
1585		bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_LEFT].voccntl);
1586		SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
1587		bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_LEFT].volcntl);
1588	    }
1589	}
1590	gus_bufcnt[sc->sc_bufcnt-1]++;
1591	/*
1592	 * flip to the next DMA buffer
1593	 */
1594
1595	sc->sc_dmabuf = ++sc->sc_dmabuf % sc->sc_nbufs;
1596	/*
1597	 * See comments below about DMA admission control strategy.
1598	 * We can call the upper level here if we have an
1599	 * idle buffer (not currently playing) to DMA into.
1600	 */
1601	if (sc->sc_dmaoutintr && sc->sc_bufcnt < sc->sc_nbufs) {
1602	    /* clean out to prevent double calls */
1603	    void (*pfunc) __P((void *)) = sc->sc_dmaoutintr;
1604	    void *arg = sc->sc_outarg;
1605
1606	    sc->sc_outarg = 0;
1607	    sc->sc_dmaoutintr = 0;
1608	    (*pfunc)(arg);
1609	}
1610}
1611
1612/*
1613 * Service voice interrupts
1614 */
1615
1616STATIC int
1617gus_voice_intr(sc)
1618	struct gus_softc *sc;
1619{
1620	bus_space_tag_t iot = sc->sc_iot;
1621	bus_space_handle_t ioh2 = sc->sc_ioh2;
1622	int ignore = 0, voice, rval = 0;
1623	unsigned char intr, status;
1624
1625	/*
1626	 * The point of this may not be obvious at first.  A voice can
1627	 * interrupt more than once; according to the GUS SDK we are supposed
1628	 * to ignore multiple interrupts for the same voice.
1629	 */
1630
1631	while(1) {
1632		SELECT_GUS_REG(iot, ioh2, GUSREG_IRQ_STATUS);
1633		intr = bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
1634
1635		if ((intr & (GUSMASK_WIRQ_VOLUME | GUSMASK_WIRQ_VOICE))
1636			== (GUSMASK_WIRQ_VOLUME | GUSMASK_WIRQ_VOICE))
1637			/*
1638			 * No more interrupts, time to return
1639			 */
1640		 	return rval;
1641
1642		if ((intr & GUSMASK_WIRQ_VOICE) == 0) {
1643
1644		    /*
1645		     * We've got a voice interrupt.  Ignore previous
1646		     * interrupts by the same voice.
1647		     */
1648
1649		    rval = 1;
1650		    voice = intr & GUSMASK_WIRQ_VOICEMASK;
1651
1652		    if ((1 << voice) & ignore)
1653			break;
1654
1655		    ignore |= 1 << voice;
1656
1657		    /*
1658		     * If the voice is stopped, then force it to stop
1659		     * (this stops it from continuously generating IRQs)
1660		     */
1661
1662		    SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL+0x80);
1663		    status = bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
1664		    if (status & GUSMASK_VOICE_STOPPED) {
1665			if (voice != GUS_VOICE_LEFT) {
1666			    DMAPRINTF(("%s: spurious voice %d stop?\n",
1667				       sc->sc_dev.dv_xname, voice));
1668			    gus_stop_voice(sc, voice, 0);
1669			    continue;
1670			}
1671			gus_stop_voice(sc, voice, 1);
1672			/* also kill right voice */
1673			gus_stop_voice(sc, GUS_VOICE_RIGHT, 0);
1674			sc->sc_bufcnt--; /* it finished a buffer */
1675			if (sc->sc_bufcnt > 0) {
1676			    /*
1677			     * probably a race to get here: the voice
1678			     * stopped while the DMA code was just trying to
1679			     * get the next buffer in place.
1680			     * Start the voice again.
1681			     */
1682			    printf("%s: stopped voice not drained? (%x)\n",
1683				   sc->sc_dev.dv_xname, sc->sc_bufcnt);
1684			    gus_falsestops++;
1685
1686			    sc->sc_playbuf = ++sc->sc_playbuf % sc->sc_nbufs;
1687			    gus_start_playing(sc, sc->sc_playbuf);
1688			} else if (sc->sc_bufcnt < 0) {
1689			    panic("%s: negative bufcnt in stopped voice",
1690				  sc->sc_dev.dv_xname);
1691			} else {
1692			    sc->sc_playbuf = -1; /* none are active */
1693			    gus_stops++;
1694			}
1695			/* fall through to callback and admit another
1696			   buffer.... */
1697		    } else if (sc->sc_bufcnt != 0) {
1698			/*
1699			 * This should always be taken if the voice
1700			 * is not stopped.
1701			 */
1702			gus_continues++;
1703			if (gus_continue_playing(sc, voice)) {
1704				/*
1705				 * we shouldn't have continued--active DMA
1706				 * is in the way in the ring, for
1707				 * some as-yet undebugged reason.
1708				 */
1709				gus_stop_voice(sc, GUS_VOICE_LEFT, 1);
1710				/* also kill right voice */
1711				gus_stop_voice(sc, GUS_VOICE_RIGHT, 0);
1712				sc->sc_playbuf = -1;
1713				gus_stops++;
1714			}
1715		    }
1716		    /*
1717		     * call the upper level to send on down another
1718		     * block. We do admission rate control as follows:
1719		     *
1720		     * When starting up output (in the first N
1721		     * blocks), call the upper layer after the DMA is
1722		     * complete (see above in gus_dmaout_intr()).
1723		     *
1724		     * When output is already in progress and we have
1725		     * no more GUS buffers to use for DMA, the DMA
1726		     * output routines do not call the upper layer.
1727		     * Instead, we call the DMA completion routine
1728		     * here, after the voice interrupts indicating
1729		     * that it's finished with a buffer.
1730		     *
1731		     * However, don't call anything here if the DMA
1732		     * output flag is set, (which shouldn't happen)
1733		     * because we'll squish somebody else's DMA if
1734		     * that's the case.  When DMA is done, it will
1735		     * call back if there is a spare buffer.
1736		     */
1737		    if (sc->sc_dmaoutintr && !(sc->sc_flags & GUS_LOCKED)) {
1738			if (sc->sc_dmaoutintr == stereo_dmaintr)
1739			    printf("gusdmaout botch?\n");
1740			else {
1741			    /* clean out to avoid double calls */
1742			    void (*pfunc) __P((void *)) = sc->sc_dmaoutintr;
1743			    void *arg = sc->sc_outarg;
1744
1745			    sc->sc_outarg = 0;
1746			    sc->sc_dmaoutintr = 0;
1747			    (*pfunc)(arg);
1748			}
1749		    }
1750		}
1751
1752		/*
1753		 * Ignore other interrupts for now
1754		 */
1755	}
1756	return 0;
1757}
1758
1759STATIC void
1760gus_start_playing(sc, bufno)
1761	struct gus_softc *sc;
1762	int bufno;
1763{
1764	bus_space_tag_t iot = sc->sc_iot;
1765	bus_space_handle_t ioh2 = sc->sc_ioh2;
1766	/*
1767	 * Start the voices playing, with buffer BUFNO.
1768	 */
1769
1770	/*
1771	 * Loop or roll if we have buffers ready.
1772	 */
1773
1774	if (sc->sc_bufcnt == 1) {
1775		sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~(GUSMASK_LOOP_ENABLE);
1776		sc->sc_voc[GUS_VOICE_LEFT].volcntl &= ~(GUSMASK_VOICE_ROLL);
1777	} else {
1778		if (bufno == sc->sc_nbufs - 1) {
1779			sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_LOOP_ENABLE;
1780			sc->sc_voc[GUS_VOICE_LEFT].volcntl &= ~(GUSMASK_VOICE_ROLL);
1781		} else {
1782			sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~GUSMASK_LOOP_ENABLE;
1783			sc->sc_voc[GUS_VOICE_LEFT].volcntl |= GUSMASK_VOICE_ROLL;
1784		}
1785	}
1786
1787	bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, GUS_VOICE_LEFT);
1788
1789	SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
1790	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_LEFT].voccntl);
1791
1792	SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
1793	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_LEFT].volcntl);
1794
1795	sc->sc_voc[GUS_VOICE_LEFT].current_addr =
1796		GUS_MEM_OFFSET + sc->sc_chanblocksize * bufno;
1797	sc->sc_voc[GUS_VOICE_LEFT].end_addr =
1798		sc->sc_voc[GUS_VOICE_LEFT].current_addr + sc->sc_chanblocksize - 1;
1799	sc->sc_voc[GUS_VOICE_RIGHT].current_addr =
1800		sc->sc_voc[GUS_VOICE_LEFT].current_addr +
1801		(gus_dostereo && sc->sc_channels == 2 ? GUS_LEFT_RIGHT_OFFSET : 0);
1802	/*
1803	 * set up right channel to just loop forever, no interrupts,
1804	 * starting at the buffer we just filled.  We'll feed it data
1805	 * at the same time as left channel.
1806	 */
1807	sc->sc_voc[GUS_VOICE_RIGHT].voccntl |= GUSMASK_LOOP_ENABLE;
1808	sc->sc_voc[GUS_VOICE_RIGHT].volcntl &= ~(GUSMASK_VOICE_ROLL);
1809
1810#ifdef GUSPLAYDEBUG
1811	if (gusstats) {
1812		microtime(&playstats[playcntr].tv);
1813		playstats[playcntr].curaddr = sc->sc_voc[GUS_VOICE_LEFT].current_addr;
1814
1815		playstats[playcntr].voccntl = sc->sc_voc[GUS_VOICE_LEFT].voccntl;
1816		playstats[playcntr].volcntl = sc->sc_voc[GUS_VOICE_LEFT].volcntl;
1817		playstats[playcntr].endaddr = sc->sc_voc[GUS_VOICE_LEFT].end_addr;
1818		playstats[playcntr].playbuf = bufno;
1819		playstats[playcntr].dmabuf = sc->sc_dmabuf;
1820		playstats[playcntr].bufcnt = sc->sc_bufcnt;
1821		playstats[playcntr].vaction = 5;
1822		playcntr = ++playcntr % NDMARECS;
1823	}
1824#endif
1825
1826	bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, GUS_VOICE_RIGHT);
1827	SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
1828	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_RIGHT].voccntl);
1829	SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
1830	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_RIGHT].volcntl);
1831
1832	gus_start_voice(sc, GUS_VOICE_RIGHT, 0);
1833	gus_start_voice(sc, GUS_VOICE_LEFT, 1);
1834	if (sc->sc_playbuf == -1)
1835		/* mark start of playing */
1836		sc->sc_playbuf = bufno;
1837}
1838
1839STATIC int
1840gus_continue_playing(sc, voice)
1841	struct gus_softc *sc;
1842	int voice;
1843{
1844	bus_space_tag_t iot = sc->sc_iot;
1845	bus_space_handle_t ioh2 = sc->sc_ioh2;
1846
1847	/*
1848	 * stop this voice from interrupting while we work.
1849	 */
1850
1851	SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
1852	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl & ~(GUSMASK_VOICE_IRQ));
1853
1854	/*
1855	 * update playbuf to point to the buffer the hardware just started
1856	 * playing
1857	 */
1858	sc->sc_playbuf = ++sc->sc_playbuf % sc->sc_nbufs;
1859
1860	/*
1861	 * account for buffer just finished
1862	 */
1863	if (--sc->sc_bufcnt == 0) {
1864		DPRINTF(("gus: bufcnt 0 on continuing voice?\n"));
1865	}
1866	if (sc->sc_playbuf == sc->sc_dmabuf && (sc->sc_flags & GUS_LOCKED)) {
1867		printf("%s: continue into active dmabuf?\n", sc->sc_dev.dv_xname);
1868		return 1;
1869	}
1870
1871	/*
1872	 * Select the end of the buffer based on the currently active
1873	 * buffer, [plus extra contiguous buffers (if ready)].
1874	 */
1875
1876	/*
1877	 * set endpoint at end of buffer we just started playing.
1878	 *
1879	 * The total gets -1 because end addrs are one less than you might
1880	 * think (the end_addr is the address of the last sample to play)
1881	 */
1882	gus_set_endaddr(sc, voice, GUS_MEM_OFFSET +
1883			sc->sc_chanblocksize * (sc->sc_playbuf + 1) - 1);
1884
1885	if (sc->sc_bufcnt < 2) {
1886		/*
1887		 * Clear out the loop and roll flags, and rotate the currently
1888		 * playing buffer.  That way, if we don't manage to get more
1889		 * data before this buffer finishes, we'll just stop.
1890		 */
1891		sc->sc_voc[voice].voccntl &= ~GUSMASK_LOOP_ENABLE;
1892		sc->sc_voc[voice].volcntl &= ~GUSMASK_VOICE_ROLL;
1893		playstats[playcntr].vaction = 0;
1894	} else {
1895		/*
1896		 * We have some buffers to play.  set LOOP if we're on the
1897		 * last buffer in the ring, otherwise set ROLL.
1898		 */
1899		if (sc->sc_playbuf == sc->sc_nbufs - 1) {
1900			sc->sc_voc[voice].voccntl |= GUSMASK_LOOP_ENABLE;
1901			sc->sc_voc[voice].volcntl &= ~GUSMASK_VOICE_ROLL;
1902			playstats[playcntr].vaction = 1;
1903		} else {
1904			sc->sc_voc[voice].voccntl &= ~GUSMASK_LOOP_ENABLE;
1905			sc->sc_voc[voice].volcntl |= GUSMASK_VOICE_ROLL;
1906			playstats[playcntr].vaction = 2;
1907		}
1908	}
1909#ifdef GUSPLAYDEBUG
1910	if (gusstats) {
1911		microtime(&playstats[playcntr].tv);
1912		playstats[playcntr].curaddr = gus_get_curaddr(sc, voice);
1913
1914		playstats[playcntr].voccntl = sc->sc_voc[voice].voccntl;
1915		playstats[playcntr].volcntl = sc->sc_voc[voice].volcntl;
1916		playstats[playcntr].endaddr = sc->sc_voc[voice].end_addr;
1917		playstats[playcntr].playbuf = sc->sc_playbuf;
1918		playstats[playcntr].dmabuf = sc->sc_dmabuf;
1919		playstats[playcntr].bufcnt = sc->sc_bufcnt;
1920		playcntr = ++playcntr % NDMARECS;
1921	}
1922#endif
1923
1924	/*
1925	 * (re-)set voice parameters.  This will reenable interrupts from this
1926	 * voice.
1927	 */
1928
1929	SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
1930	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
1931	SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
1932	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].volcntl);
1933	return 0;
1934}
1935
1936/*
1937 * Send/receive data into GUS's DRAM using DMA.  Called at splgus()
1938 */
1939
1940STATIC void
1941gusdmaout(sc, flags, gusaddr, buffaddr, length)
1942	struct gus_softc *sc;
1943	int flags, length;
1944	u_long gusaddr;
1945	caddr_t buffaddr;
1946{
1947	unsigned char c = (unsigned char) flags;
1948	bus_space_tag_t iot = sc->sc_iot;
1949	bus_space_handle_t ioh2 = sc->sc_ioh2;
1950
1951	DMAPRINTF(("gusdmaout flags=%x scflags=%x\n", flags, sc->sc_flags));
1952
1953	sc->sc_gusaddr = gusaddr;
1954
1955	/*
1956	 * If we're using a 16 bit DMA channel, we have to jump through some
1957	 * extra hoops; this includes translating the DRAM address a bit
1958	 */
1959
1960	if (sc->sc_drq >= 4) {
1961		c |= GUSMASK_DMA_WIDTH;
1962		gusaddr = convert_to_16bit(gusaddr);
1963	}
1964
1965	/*
1966	 * Add flag bits that we always set - fast DMA, enable IRQ
1967	 */
1968
1969	c |= GUSMASK_DMA_ENABLE | GUSMASK_DMA_R0 | GUSMASK_DMA_IRQ;
1970
1971	/*
1972	 * Make sure the GUS _isn't_ setup for DMA
1973	 */
1974
1975 	SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
1976	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0);
1977
1978	/*
1979	 * Tell the PC DMA controller to start doing DMA
1980	 */
1981
1982	sc->sc_dmaoutaddr = (u_char *) buffaddr;
1983	sc->sc_dmaoutcnt = length;
1984	isa_dmastart(sc->sc_dev.dv_parent, sc->sc_drq, buffaddr, length,
1985	    NULL, DMAMODE_WRITE, BUS_DMA_NOWAIT);
1986
1987	/*
1988	 * Set up DMA address - use the upper 16 bits ONLY
1989	 */
1990
1991	sc->sc_flags |= GUS_DMAOUT_ACTIVE;
1992
1993 	SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_START);
1994 	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, (int) (gusaddr >> 4));
1995
1996 	/*
1997 	 * Tell the GUS to start doing DMA
1998 	 */
1999
2000 	SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
2001	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, c);
2002
2003	/*
2004	 * XXX If we don't finish in one second, give up...
2005	 */
2006	untimeout(gus_dmaout_timeout, sc); /* flush old one, if there is one */
2007	timeout(gus_dmaout_timeout, sc, hz);
2008}
2009
2010/*
2011 * Start a voice playing on the GUS.  Called from interrupt handler at
2012 * splgus().
2013 */
2014
2015STATIC void
2016gus_start_voice(sc, voice, intrs)
2017	struct gus_softc *sc;
2018	int voice;
2019	int intrs;
2020{
2021	bus_space_tag_t iot = sc->sc_iot;
2022	bus_space_handle_t ioh2 = sc->sc_ioh2;
2023	u_long start;
2024	u_long current;
2025	u_long end;
2026
2027	/*
2028	 * Pick all the values for the voice out of the gus_voice struct
2029	 * and use those to program the voice
2030	 */
2031
2032 	start = sc->sc_voc[voice].start_addr;
2033 	current = sc->sc_voc[voice].current_addr;
2034 	end = sc->sc_voc[voice].end_addr;
2035
2036 	/*
2037	 * If we're using 16 bit data, mangle the addresses a bit
2038	 */
2039
2040	if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16) {
2041	        /* -1 on start so that we get onto sample boundary--other
2042		   code always sets it for 1-byte rollover protection */
2043		start = convert_to_16bit(start-1);
2044		current = convert_to_16bit(current);
2045		end = convert_to_16bit(end);
2046	}
2047
2048	/*
2049	 * Select the voice we want to use, and program the data addresses
2050	 */
2051
2052	bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
2053
2054	SELECT_GUS_REG(iot, ioh2, GUSREG_START_ADDR_HIGH);
2055	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(start));
2056	SELECT_GUS_REG(iot, ioh2, GUSREG_START_ADDR_LOW);
2057	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(start));
2058
2059	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH);
2060	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(current));
2061	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW);
2062	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(current));
2063
2064	SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_HIGH);
2065	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(end));
2066	SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_LOW);
2067	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(end));
2068
2069	/*
2070	 * (maybe) enable interrupts, disable voice stopping
2071	 */
2072
2073	if (intrs) {
2074		sc->sc_flags |= GUS_PLAYING; /* playing is about to start */
2075		sc->sc_voc[voice].voccntl |= GUSMASK_VOICE_IRQ;
2076		DMAPRINTF(("gus voice playing=%x\n", sc->sc_flags));
2077	} else
2078		sc->sc_voc[voice].voccntl &= ~GUSMASK_VOICE_IRQ;
2079	sc->sc_voc[voice].voccntl &= ~(GUSMASK_VOICE_STOPPED |
2080		GUSMASK_STOP_VOICE);
2081
2082	/*
2083	 * Tell the GUS about it.  Note that we're doing volume ramping here
2084	 * from 0 up to the set volume to help reduce clicks.
2085	 */
2086
2087	SELECT_GUS_REG(iot, ioh2, GUSREG_START_VOLUME);
2088	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
2089	SELECT_GUS_REG(iot, ioh2, GUSREG_END_VOLUME);
2090	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].current_volume >> 4);
2091	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME);
2092	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x00);
2093	SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_RATE);
2094	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 63);
2095
2096	SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
2097	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
2098	SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
2099	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
2100	delay(50);
2101	SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
2102	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
2103	SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
2104	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
2105
2106}
2107
2108/*
2109 * Stop a given voice.  called at splgus()
2110 */
2111
2112STATIC void
2113gus_stop_voice(sc, voice, intrs_too)
2114	struct gus_softc *sc;
2115	int voice;
2116	int intrs_too;
2117{
2118	bus_space_tag_t iot = sc->sc_iot;
2119	bus_space_handle_t ioh2 = sc->sc_ioh2;
2120
2121	sc->sc_voc[voice].voccntl |= GUSMASK_VOICE_STOPPED |
2122		GUSMASK_STOP_VOICE;
2123	if (intrs_too) {
2124	  sc->sc_voc[voice].voccntl &= ~(GUSMASK_VOICE_IRQ);
2125	  /* no more DMA to do */
2126	  sc->sc_flags &= ~GUS_PLAYING;
2127	}
2128	DMAPRINTF(("gusintr voice notplaying=%x\n", sc->sc_flags));
2129
2130	guspoke(iot, ioh2, 0L, 0);
2131
2132	bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
2133
2134	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME);
2135	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2136	SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
2137	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
2138	delay(100);
2139	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME);
2140	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2141	SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
2142	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
2143
2144	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH);
2145	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2146	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW);
2147	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2148
2149}
2150
2151
2152/*
2153 * Set the volume of a given voice.  Called at splgus().
2154 */
2155STATIC void
2156gus_set_volume(sc, voice, volume)
2157	struct gus_softc *sc;
2158	int voice, volume;
2159{
2160	bus_space_tag_t iot = sc->sc_iot;
2161	bus_space_handle_t ioh2 = sc->sc_ioh2;
2162	unsigned int gusvol;
2163
2164	gusvol = gus_log_volumes[volume < 512 ? volume : 511];
2165
2166	sc->sc_voc[voice].current_volume = gusvol;
2167
2168	bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
2169
2170	SELECT_GUS_REG(iot, ioh2, GUSREG_START_VOLUME);
2171	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (unsigned char) (gusvol >> 4));
2172
2173	SELECT_GUS_REG(iot, ioh2, GUSREG_END_VOLUME);
2174	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (unsigned char) (gusvol >> 4));
2175
2176	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME);
2177	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, gusvol << 4);
2178	delay(500);
2179	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, gusvol << 4);
2180
2181}
2182
2183/*
2184 * Interface to the audio layer.
2185 */
2186
2187int
2188gusmax_set_params(addr, setmode, usemode, p, r)
2189	void *addr;
2190	int setmode, usemode;
2191	struct audio_params *p, *r;
2192{
2193	struct ad1848_softc *ac = addr;
2194	struct gus_softc *sc = ac->parent;
2195	int error;
2196
2197	error = ad1848_set_params(ac, setmode, usemode, p, r);
2198	if (error)
2199		return error;
2200	error = gus_set_params(sc, setmode, usemode, p, r);
2201	return error;
2202}
2203
2204int
2205gus_set_params(addr, setmode, usemode, p, r)
2206	void *addr;
2207	int setmode, usemode;
2208	struct audio_params *p, *r;
2209{
2210	struct gus_softc *sc = addr;
2211	int s;
2212
2213	switch (p->encoding) {
2214	case AUDIO_ENCODING_ULAW:
2215	case AUDIO_ENCODING_ALAW:
2216	case AUDIO_ENCODING_SLINEAR_LE:
2217	case AUDIO_ENCODING_ULINEAR_LE:
2218	case AUDIO_ENCODING_SLINEAR_BE:
2219	case AUDIO_ENCODING_ULINEAR_BE:
2220		break;
2221	default:
2222		return (EINVAL);
2223	}
2224
2225	s = splaudio();
2226
2227	if (p->precision == 8) {
2228		sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~GUSMASK_DATA_SIZE16;
2229		sc->sc_voc[GUS_VOICE_RIGHT].voccntl &= ~GUSMASK_DATA_SIZE16;
2230	} else {
2231		sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_DATA_SIZE16;
2232		sc->sc_voc[GUS_VOICE_RIGHT].voccntl |= GUSMASK_DATA_SIZE16;
2233	}
2234
2235	sc->sc_encoding = p->encoding;
2236	sc->sc_precision = p->precision;
2237	sc->sc_channels = p->channels;
2238
2239	splx(s);
2240
2241	if (p->sample_rate > gus_max_frequency[sc->sc_voices - GUS_MIN_VOICES])
2242		p->sample_rate = gus_max_frequency[sc->sc_voices - GUS_MIN_VOICES];
2243	if (setmode & AUMODE_RECORD)
2244		sc->sc_irate = p->sample_rate;
2245	if (setmode & AUMODE_PLAY)
2246		sc->sc_orate = p->sample_rate;
2247
2248	switch (p->encoding) {
2249	case AUDIO_ENCODING_ULAW:
2250		p->sw_code = mulaw_to_ulinear8;
2251		r->sw_code = ulinear8_to_mulaw;
2252		break;
2253	case AUDIO_ENCODING_ALAW:
2254		p->sw_code = alaw_to_ulinear8;
2255		r->sw_code = ulinear8_to_alaw;
2256		break;
2257	case AUDIO_ENCODING_ULINEAR_BE:
2258	case AUDIO_ENCODING_SLINEAR_BE:
2259		r->sw_code = p->sw_code = swap_bytes;
2260		break;
2261	}
2262
2263	return 0;
2264}
2265
2266/*
2267 * Interface to the audio layer - set the blocksize to the correct number
2268 * of units
2269 */
2270
2271int
2272gusmax_round_blocksize(addr, blocksize)
2273	void * addr;
2274	int blocksize;
2275{
2276	struct ad1848_softc *ac = addr;
2277	struct gus_softc *sc = ac->parent;
2278
2279/*	blocksize = ad1848_round_blocksize(ac, blocksize);*/
2280	return gus_round_blocksize(sc, blocksize);
2281}
2282
2283int
2284gus_round_blocksize(addr, blocksize)
2285	void * addr;
2286	int blocksize;
2287{
2288	struct gus_softc *sc = addr;
2289
2290	DPRINTF(("gus_round_blocksize called\n"));
2291
2292	if ((sc->sc_encoding == AUDIO_ENCODING_ULAW ||
2293	     sc->sc_encoding == AUDIO_ENCODING_ALAW) && blocksize > 32768)
2294		blocksize = 32768;
2295	else if (blocksize > 65536)
2296		blocksize = 65536;
2297
2298	if ((blocksize % GUS_BUFFER_MULTIPLE) != 0)
2299		blocksize = (blocksize / GUS_BUFFER_MULTIPLE + 1) *
2300			GUS_BUFFER_MULTIPLE;
2301
2302	/* set up temporary buffer to hold the deinterleave, if necessary
2303	   for stereo output */
2304	if (sc->sc_deintr_buf) {
2305		FREE(sc->sc_deintr_buf, M_DEVBUF);
2306		sc->sc_deintr_buf = NULL;
2307	}
2308	MALLOC(sc->sc_deintr_buf, void *, blocksize>>1, M_DEVBUF, M_WAITOK);
2309
2310	sc->sc_blocksize = blocksize;
2311	/* multi-buffering not quite working yet. */
2312	sc->sc_nbufs = /*GUS_MEM_FOR_BUFFERS / blocksize*/ 2;
2313
2314	gus_set_chan_addrs(sc);
2315
2316	return blocksize;
2317}
2318
2319int
2320gus_get_out_gain(addr)
2321	caddr_t addr;
2322{
2323	struct gus_softc *sc = (struct gus_softc *) addr;
2324
2325	DPRINTF(("gus_get_out_gain called\n"));
2326	return sc->sc_ogain / 2;
2327}
2328
2329STATIC inline void gus_set_voices(sc, voices)
2330struct gus_softc *sc;
2331int voices;
2332{
2333	bus_space_tag_t iot = sc->sc_iot;
2334	bus_space_handle_t ioh2 = sc->sc_ioh2;
2335	/*
2336	 * Select the active number of voices
2337	 */
2338
2339	SELECT_GUS_REG(iot, ioh2, GUSREG_ACTIVE_VOICES);
2340	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (voices-1) | 0xc0);
2341
2342	sc->sc_voices = voices;
2343}
2344
2345/*
2346 * Actually set the settings of various values on the card
2347 */
2348
2349int
2350gusmax_commit_settings(addr)
2351	void * addr;
2352{
2353	struct ad1848_softc *ac = addr;
2354	struct gus_softc *sc = ac->parent;
2355	int error;
2356
2357	error = ad1848_commit_settings(ac);
2358	if (error)
2359		return error;
2360	return gus_commit_settings(sc);
2361}
2362
2363/*
2364 * Commit the settings.  Called at normal IPL.
2365 */
2366int
2367gus_commit_settings(addr)
2368	void * addr;
2369{
2370	struct gus_softc *sc = addr;
2371	int s;
2372
2373	DPRINTF(("gus_commit_settings called (gain = %d)\n",sc->sc_ogain));
2374
2375
2376	s = splgus();
2377
2378	gus_set_recrate(sc, sc->sc_irate);
2379	gus_set_volume(sc, GUS_VOICE_LEFT, sc->sc_ogain);
2380	gus_set_volume(sc, GUS_VOICE_RIGHT, sc->sc_ogain);
2381	gus_set_samprate(sc, GUS_VOICE_LEFT, sc->sc_orate);
2382	gus_set_samprate(sc, GUS_VOICE_RIGHT, sc->sc_orate);
2383	splx(s);
2384	gus_set_chan_addrs(sc);
2385
2386	return 0;
2387}
2388
2389STATIC void
2390gus_set_chan_addrs(sc)
2391struct gus_softc *sc;
2392{
2393	/*
2394	 * We use sc_nbufs * blocksize bytes of storage in the on-board GUS
2395	 * ram.
2396	 * For mono, each of the sc_nbufs buffers is DMA'd to in one chunk,
2397	 * and both left & right channels play the same buffer.
2398	 *
2399	 * For stereo, each channel gets a contiguous half of the memory,
2400	 * and each has sc_nbufs buffers of size blocksize/2.
2401	 * Stereo data are deinterleaved in main memory before the DMA out
2402	 * routines are called to queue the output.
2403	 *
2404	 * The blocksize per channel is kept in sc_chanblocksize.
2405	 */
2406	if (sc->sc_channels == 2)
2407	    sc->sc_chanblocksize = sc->sc_blocksize/2;
2408	else
2409	    sc->sc_chanblocksize = sc->sc_blocksize;
2410
2411	sc->sc_voc[GUS_VOICE_LEFT].start_addr = GUS_MEM_OFFSET - 1;
2412	sc->sc_voc[GUS_VOICE_RIGHT].start_addr =
2413	    (gus_dostereo && sc->sc_channels == 2 ? GUS_LEFT_RIGHT_OFFSET : 0)
2414	      + GUS_MEM_OFFSET - 1;
2415	sc->sc_voc[GUS_VOICE_RIGHT].current_addr =
2416	    sc->sc_voc[GUS_VOICE_RIGHT].start_addr + 1;
2417	sc->sc_voc[GUS_VOICE_RIGHT].end_addr =
2418	    sc->sc_voc[GUS_VOICE_RIGHT].start_addr +
2419	    sc->sc_nbufs * sc->sc_chanblocksize;
2420
2421}
2422
2423/*
2424 * Set the sample rate of the given voice.  Called at splgus().
2425 */
2426
2427STATIC void
2428gus_set_samprate(sc, voice, freq)
2429	struct gus_softc *sc;
2430	int voice, freq;
2431{
2432	bus_space_tag_t iot = sc->sc_iot;
2433	bus_space_handle_t ioh2 = sc->sc_ioh2;
2434	unsigned int fc;
2435	u_long temp, f = (u_long) freq;
2436
2437	/*
2438	 * calculate fc based on the number of active voices;
2439	 * we need to use longs to preserve enough bits
2440	 */
2441
2442	temp = (u_long) gus_max_frequency[sc->sc_voices-GUS_MIN_VOICES];
2443
2444 	fc = (unsigned int)(((f << 9L) + (temp >> 1L)) / temp);
2445
2446 	fc <<= 1;
2447
2448
2449	/*
2450	 * Program the voice frequency, and set it in the voice data record
2451	 */
2452
2453	bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
2454	SELECT_GUS_REG(iot, ioh2, GUSREG_FREQ_CONTROL);
2455	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, fc);
2456
2457	sc->sc_voc[voice].rate = freq;
2458
2459}
2460
2461/*
2462 * Set the sample rate of the recording frequency.  Formula is from the GUS
2463 * SDK.  Called at splgus().
2464 */
2465
2466STATIC void
2467gus_set_recrate(sc, rate)
2468	struct gus_softc *sc;
2469	u_long rate;
2470{
2471	bus_space_tag_t iot = sc->sc_iot;
2472	bus_space_handle_t ioh2 = sc->sc_ioh2;
2473	u_char realrate;
2474	DPRINTF(("gus_set_recrate %lu\n", rate));
2475
2476#if 0
2477	realrate = 9878400/(16*(rate+2)); /* formula from GUS docs */
2478#endif
2479	realrate = (9878400 >> 4)/rate - 2; /* formula from code, sigh. */
2480
2481	SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_FREQ);
2482 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, realrate);
2483}
2484
2485/*
2486 * Interface to the audio layer - turn the output on or off.  Note that some
2487 * of these bits are flipped in the register
2488 */
2489
2490int
2491gusmax_speaker_ctl(addr, newstate)
2492	void * addr;
2493	int newstate;
2494{
2495	struct ad1848_softc *sc = addr;
2496	return gus_speaker_ctl(sc->parent, newstate);
2497}
2498
2499int
2500gus_speaker_ctl(addr, newstate)
2501	void * addr;
2502	int newstate;
2503{
2504	struct gus_softc *sc = (struct gus_softc *) addr;
2505	bus_space_tag_t iot = sc->sc_iot;
2506	bus_space_handle_t ioh1 = sc->sc_ioh1;
2507
2508	/* Line out bit is flipped: 0 enables, 1 disables */
2509	if ((newstate == SPKR_ON) &&
2510	    (sc->sc_mixcontrol & GUSMASK_LINE_OUT)) {
2511		sc->sc_mixcontrol &= ~GUSMASK_LINE_OUT;
2512		bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
2513	}
2514	if ((newstate == SPKR_OFF) &&
2515	    (sc->sc_mixcontrol & GUSMASK_LINE_OUT) == 0) {
2516		sc->sc_mixcontrol |= GUSMASK_LINE_OUT;
2517		bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
2518	}
2519
2520	return 0;
2521}
2522
2523STATIC int
2524gus_linein_ctl(addr, newstate)
2525	void * addr;
2526	int newstate;
2527{
2528	struct gus_softc *sc = (struct gus_softc *) addr;
2529	bus_space_tag_t iot = sc->sc_iot;
2530	bus_space_handle_t ioh1 = sc->sc_ioh1;
2531
2532	/* Line in bit is flipped: 0 enables, 1 disables */
2533	if ((newstate == SPKR_ON) &&
2534	    (sc->sc_mixcontrol & GUSMASK_LINE_IN)) {
2535		sc->sc_mixcontrol &= ~GUSMASK_LINE_IN;
2536		bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
2537	}
2538	if ((newstate == SPKR_OFF) &&
2539	    (sc->sc_mixcontrol & GUSMASK_LINE_IN) == 0) {
2540		sc->sc_mixcontrol |= GUSMASK_LINE_IN;
2541		bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
2542	}
2543
2544	return 0;
2545}
2546
2547STATIC int
2548gus_mic_ctl(addr, newstate)
2549	void * addr;
2550	int newstate;
2551{
2552	struct gus_softc *sc = (struct gus_softc *) addr;
2553	bus_space_tag_t iot = sc->sc_iot;
2554	bus_space_handle_t ioh1 = sc->sc_ioh1;
2555
2556	/* Mic bit is normal: 1 enables, 0 disables */
2557	if ((newstate == SPKR_ON) &&
2558	    (sc->sc_mixcontrol & GUSMASK_MIC_IN) == 0) {
2559		sc->sc_mixcontrol |= GUSMASK_MIC_IN;
2560		bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
2561	}
2562	if ((newstate == SPKR_OFF) &&
2563	    (sc->sc_mixcontrol & GUSMASK_MIC_IN)) {
2564		sc->sc_mixcontrol &= ~GUSMASK_MIC_IN;
2565		bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
2566	}
2567
2568	return 0;
2569}
2570
2571/*
2572 * Set the end address of a give voice.  Called at splgus()
2573 */
2574
2575STATIC void
2576gus_set_endaddr(sc, voice, addr)
2577	struct gus_softc *sc;
2578	int voice;
2579	u_long addr;
2580{
2581	bus_space_tag_t iot = sc->sc_iot;
2582	bus_space_handle_t ioh2 = sc->sc_ioh2;
2583
2584	sc->sc_voc[voice].end_addr = addr;
2585
2586	if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16)
2587		addr = convert_to_16bit(addr);
2588
2589	SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_HIGH);
2590	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(addr));
2591	SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_LOW);
2592	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(addr));
2593
2594}
2595
2596#ifdef GUSPLAYDEBUG
2597/*
2598 * Set current address.  called at splgus()
2599 */
2600STATIC void
2601gus_set_curaddr(sc, voice, addr)
2602	struct gus_softc *sc;
2603	int voice;
2604	u_long addr;
2605{
2606	bus_space_tag_t iot = sc->sc_iot;
2607	bus_space_handle_t ioh2 = sc->sc_ioh2;
2608
2609	sc->sc_voc[voice].current_addr = addr;
2610
2611	if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16)
2612		addr = convert_to_16bit(addr);
2613
2614	bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
2615
2616	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH);
2617	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(addr));
2618	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW);
2619	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(addr));
2620
2621}
2622
2623/*
2624 * Get current GUS playback address.  Called at splgus().
2625 */
2626STATIC u_long
2627gus_get_curaddr(sc, voice)
2628	struct gus_softc *sc;
2629	int voice;
2630{
2631	bus_space_tag_t iot = sc->sc_iot;
2632	bus_space_handle_t ioh2 = sc->sc_ioh2;
2633	u_long addr;
2634
2635	bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
2636	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH|GUSREG_READ);
2637	addr = (bus_space_read_2(iot, ioh2, GUS_DATA_LOW) & 0x1fff) << 7;
2638	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW|GUSREG_READ);
2639	addr |= (bus_space_read_2(iot, ioh2, GUS_DATA_LOW) >> 9L) & 0x7f;
2640
2641	if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16)
2642	    addr = (addr & 0xc0000) | ((addr & 0x1ffff) << 1); /* undo 16-bit change */
2643	DPRINTF(("gus voice %d curaddr %ld end_addr %ld\n",
2644		 voice, addr, sc->sc_voc[voice].end_addr));
2645	/* XXX sanity check the address? */
2646
2647	return(addr);
2648}
2649#endif
2650
2651/*
2652 * Convert an address value to a "16 bit" value - why this is necessary I
2653 * have NO idea
2654 */
2655
2656STATIC u_long
2657convert_to_16bit(address)
2658	u_long address;
2659{
2660	u_long old_address;
2661
2662	old_address = address;
2663	address >>= 1;
2664	address &= 0x0001ffffL;
2665	address |= (old_address & 0x000c0000L);
2666
2667	return (address);
2668}
2669
2670/*
2671 * Write a value into the GUS's DRAM
2672 */
2673
2674STATIC void
2675guspoke(iot, ioh2, address, value)
2676	bus_space_tag_t iot;
2677	bus_space_handle_t ioh2;
2678	long address;
2679	unsigned char value;
2680{
2681
2682	/*
2683	 * Select the DRAM address
2684	 */
2685
2686 	SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_LOW);
2687 	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, (unsigned int) (address & 0xffff));
2688 	SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_HIGH);
2689 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (unsigned char) ((address >> 16) & 0xff));
2690
2691	/*
2692	 * Actually write the data
2693	 */
2694
2695	bus_space_write_1(iot, ioh2, GUS_DRAM_DATA, value);
2696}
2697
2698/*
2699 * Read a value from the GUS's DRAM
2700 */
2701
2702STATIC unsigned char
2703guspeek(iot, ioh2, address)
2704	bus_space_tag_t iot;
2705	bus_space_handle_t ioh2;
2706	u_long address;
2707{
2708
2709	/*
2710	 * Select the DRAM address
2711	 */
2712
2713 	SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_LOW);
2714 	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, (unsigned int) (address & 0xffff));
2715 	SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_HIGH);
2716 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (unsigned char) ((address >> 16) & 0xff));
2717
2718	/*
2719	 * Read in the data from the board
2720	 */
2721
2722	return (unsigned char) bus_space_read_1(iot, ioh2, GUS_DRAM_DATA);
2723}
2724
2725/*
2726 * Reset the Gravis UltraSound card, completely
2727 */
2728
2729STATIC void
2730gusreset(sc, voices)
2731	struct gus_softc *sc;
2732	int voices;
2733{
2734	bus_space_tag_t iot = sc->sc_iot;
2735	bus_space_handle_t ioh1 = sc->sc_ioh1;
2736	bus_space_handle_t ioh2 = sc->sc_ioh2;
2737	bus_space_handle_t ioh4 = sc->sc_ioh4;
2738	int i,s;
2739
2740	s = splgus();
2741
2742	/*
2743	 * Reset the GF1 chip
2744	 */
2745
2746	SELECT_GUS_REG(iot, ioh2, GUSREG_RESET);
2747	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
2748
2749	delay(500);
2750
2751	/*
2752	 * Release reset
2753	 */
2754
2755	SELECT_GUS_REG(iot, ioh2, GUSREG_RESET);
2756	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, GUSMASK_MASTER_RESET);
2757
2758	delay(500);
2759
2760	/*
2761	 * Reset MIDI port as well
2762	 */
2763
2764	bus_space_write_1(iot, ioh4, GUS_MIDI_CONTROL, MIDI_RESET);
2765
2766	delay(500);
2767
2768	bus_space_write_1(iot, ioh4, GUS_MIDI_CONTROL, 0x00);
2769
2770	/*
2771	 * Clear interrupts
2772	 */
2773
2774	SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
2775	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
2776	SELECT_GUS_REG(iot, ioh2, GUSREG_TIMER_CONTROL);
2777	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
2778	SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
2779	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
2780
2781	gus_set_voices(sc, voices);
2782
2783	bus_space_read_1(iot, ioh1, GUS_IRQ_STATUS);
2784	SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
2785	bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
2786	SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
2787	bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
2788	SELECT_GUS_REG(iot, ioh2, GUSREG_IRQ_STATUS);
2789	bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
2790
2791	/*
2792	 * Reset voice specific information
2793	 */
2794
2795	for(i = 0; i < voices; i++) {
2796		bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) i);
2797
2798		SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
2799
2800		sc->sc_voc[i].voccntl = GUSMASK_VOICE_STOPPED |
2801			GUSMASK_STOP_VOICE;
2802
2803		bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[i].voccntl);
2804
2805		sc->sc_voc[i].volcntl = GUSMASK_VOLUME_STOPPED |
2806				GUSMASK_STOP_VOLUME;
2807
2808		SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
2809		bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[i].volcntl);
2810
2811		delay(100);
2812
2813		gus_set_samprate(sc, i, 8000);
2814		SELECT_GUS_REG(iot, ioh2, GUSREG_START_ADDR_HIGH);
2815		bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2816		SELECT_GUS_REG(iot, ioh2, GUSREG_START_ADDR_LOW);
2817		bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2818		SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_HIGH);
2819		bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2820		SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_LOW);
2821		bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2822		SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_RATE);
2823		bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x01);
2824		SELECT_GUS_REG(iot, ioh2, GUSREG_START_VOLUME);
2825		bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x10);
2826		SELECT_GUS_REG(iot, ioh2, GUSREG_END_VOLUME);
2827		bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0xe0);
2828		SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME);
2829		bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2830
2831		SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH);
2832		bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2833		SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW);
2834		bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2835		SELECT_GUS_REG(iot, ioh2, GUSREG_PAN_POS);
2836		bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x07);
2837	}
2838
2839	/*
2840	 * Clear out any pending IRQs
2841	 */
2842
2843	bus_space_read_1(iot, ioh1, GUS_IRQ_STATUS);
2844	SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
2845	bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
2846	SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
2847	bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
2848	SELECT_GUS_REG(iot, ioh2, GUSREG_IRQ_STATUS);
2849	bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
2850
2851	SELECT_GUS_REG(iot, ioh2, GUSREG_RESET);
2852	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, GUSMASK_MASTER_RESET | GUSMASK_DAC_ENABLE |
2853		GUSMASK_IRQ_ENABLE);
2854
2855	splx(s);
2856}
2857
2858
2859STATIC int
2860gus_init_cs4231(sc)
2861	struct gus_softc *sc;
2862{
2863	bus_space_tag_t iot = sc->sc_iot;
2864	bus_space_handle_t ioh1 = sc->sc_ioh1;
2865	int port = sc->sc_iobase;
2866	u_char ctrl;
2867
2868	ctrl = (port & 0xf0) >> 4;	/* set port address middle nibble */
2869	/*
2870	 * The codec is a bit weird--swapped dma channels.
2871	 */
2872	ctrl |= GUS_MAX_CODEC_ENABLE;
2873	if (sc->sc_drq >= 4)
2874		ctrl |= GUS_MAX_RECCHAN16;
2875	if (sc->sc_recdrq >= 4)
2876		ctrl |= GUS_MAX_PLAYCHAN16;
2877
2878	bus_space_write_1(iot, ioh1, GUS_MAX_CTRL, ctrl);
2879
2880	sc->sc_codec.sc_iot = sc->sc_iot;
2881	sc->sc_codec.sc_iobase = port+GUS_MAX_CODEC_BASE;
2882
2883	if (ad1848_probe(&sc->sc_codec) == 0) {
2884		sc->sc_flags &= ~GUS_CODEC_INSTALLED;
2885		return (0);
2886	} else {
2887		struct ad1848_volume vol = {AUDIO_MAX_GAIN, AUDIO_MAX_GAIN};
2888		sc->sc_flags |= GUS_CODEC_INSTALLED;
2889		sc->sc_codec.parent = sc;
2890		sc->sc_codec.sc_drq = sc->sc_recdrq;
2891		sc->sc_codec.sc_recdrq = sc->sc_drq;
2892		gus_hw_if = gusmax_hw_if;
2893		/* enable line in and mic in the GUS mixer; the codec chip
2894		   will do the real mixing for them. */
2895		sc->sc_mixcontrol &= ~GUSMASK_LINE_IN; /* 0 enables. */
2896		sc->sc_mixcontrol |= GUSMASK_MIC_IN; /* 1 enables. */
2897		bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
2898
2899		ad1848_attach(&sc->sc_codec);
2900		/* turn on pre-MUX microphone gain. */
2901		ad1848_set_mic_gain(&sc->sc_codec, &vol);
2902
2903		return (1);
2904	}
2905}
2906
2907
2908/*
2909 * Return info about the audio device, for the AUDIO_GETINFO ioctl
2910 */
2911
2912int
2913gus_getdev(addr, dev)
2914	void * addr;
2915	struct audio_device *dev;
2916{
2917	*dev = gus_device;
2918	return 0;
2919}
2920
2921/*
2922 * stubs (XXX)
2923 */
2924
2925int
2926gus_set_in_gain(addr, gain, balance)
2927	caddr_t addr;
2928	u_int gain;
2929	u_char balance;
2930{
2931	DPRINTF(("gus_set_in_gain called\n"));
2932	return 0;
2933}
2934
2935int
2936gus_get_in_gain(addr)
2937	caddr_t addr;
2938{
2939	DPRINTF(("gus_get_in_gain called\n"));
2940	return 0;
2941}
2942
2943int
2944gusmax_dma_input(addr, buf, size, callback, arg)
2945	void * addr;
2946	void *buf;
2947	int size;
2948	void (*callback) __P((void *));
2949	void *arg;
2950{
2951	struct ad1848_softc *sc = addr;
2952	return gus_dma_input(sc->parent, buf, size, callback, arg);
2953}
2954
2955/*
2956 * Start sampling the input source into the requested DMA buffer.
2957 * Called at splgus(), either from top-half or from interrupt handler.
2958 */
2959int
2960gus_dma_input(addr, buf, size, callback, arg)
2961	void * addr;
2962	void *buf;
2963	int size;
2964	void (*callback) __P((void *));
2965	void *arg;
2966{
2967	struct gus_softc *sc = addr;
2968	bus_space_tag_t iot = sc->sc_iot;
2969	bus_space_handle_t ioh2 = sc->sc_ioh2;
2970	u_char dmac;
2971	DMAPRINTF(("gus_dma_input called\n"));
2972
2973	/*
2974	 * Sample SIZE bytes of data from the card, into buffer at BUF.
2975	 */
2976
2977	if (sc->sc_precision == 16)
2978	    return EINVAL;		/* XXX */
2979
2980	/* set DMA modes */
2981	dmac = GUSMASK_SAMPLE_IRQ|GUSMASK_SAMPLE_START;
2982	if (sc->sc_recdrq >= 4)
2983		dmac |= GUSMASK_SAMPLE_DATA16;
2984	if (sc->sc_encoding == AUDIO_ENCODING_ULAW ||
2985	    sc->sc_encoding == AUDIO_ENCODING_ALAW ||
2986	    sc->sc_encoding == AUDIO_ENCODING_ULINEAR_LE ||
2987	    sc->sc_encoding == AUDIO_ENCODING_ULINEAR_BE)
2988	    dmac |= GUSMASK_SAMPLE_INVBIT;
2989	if (sc->sc_channels == 2)
2990	    dmac |= GUSMASK_SAMPLE_STEREO;
2991	isa_dmastart(sc->sc_dev.dv_parent, sc->sc_recdrq, buf, size,
2992	    NULL, DMAMODE_READ, BUS_DMA_NOWAIT);
2993
2994	DMAPRINTF(("gus_dma_input isa_dmastarted\n"));
2995	sc->sc_flags |= GUS_DMAIN_ACTIVE;
2996	sc->sc_dmainintr = callback;
2997	sc->sc_inarg = arg;
2998	sc->sc_dmaincnt = size;
2999	sc->sc_dmainaddr = buf;
3000
3001	SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
3002	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, dmac);	/* Go! */
3003
3004
3005	DMAPRINTF(("gus_dma_input returning\n"));
3006
3007	return 0;
3008}
3009
3010STATIC int
3011gus_dmain_intr(sc)
3012	struct gus_softc *sc;
3013{
3014        void (*callback) __P((void *));
3015	void *arg;
3016
3017	DMAPRINTF(("gus_dmain_intr called\n"));
3018	if (sc->sc_dmainintr) {
3019	    isa_dmadone(sc->sc_dev.dv_parent, sc->sc_recdrq);
3020	    callback = sc->sc_dmainintr;
3021	    arg = sc->sc_inarg;
3022
3023	    sc->sc_dmainaddr = 0;
3024	    sc->sc_dmaincnt = 0;
3025	    sc->sc_dmainintr = 0;
3026	    sc->sc_inarg = 0;
3027
3028	    sc->sc_flags &= ~GUS_DMAIN_ACTIVE;
3029	    DMAPRINTF(("calling dmain_intr callback %p(%p)\n", callback, arg));
3030	    (*callback)(arg);
3031	    return 1;
3032	} else {
3033	    DMAPRINTF(("gus_dmain_intr false?\n"));
3034	    return 0;			/* XXX ??? */
3035	}
3036}
3037
3038int
3039gusmax_halt_out_dma(addr)
3040	void * addr;
3041{
3042	struct ad1848_softc *sc = addr;
3043	return gus_halt_out_dma(sc->parent);
3044}
3045
3046
3047int
3048gusmax_halt_in_dma(addr)
3049	void * addr;
3050{
3051	struct ad1848_softc *sc = addr;
3052	return gus_halt_in_dma(sc->parent);
3053}
3054
3055/*
3056 * Stop any DMA output.  Called at splgus().
3057 */
3058int
3059gus_halt_out_dma(addr)
3060	void * addr;
3061{
3062	struct gus_softc *sc = addr;
3063	bus_space_tag_t iot = sc->sc_iot;
3064	bus_space_handle_t ioh2 = sc->sc_ioh2;
3065
3066	DMAPRINTF(("gus_halt_out_dma called\n"));
3067	/*
3068	 * Make sure the GUS _isn't_ setup for DMA
3069	 */
3070
3071 	SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
3072	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0);
3073
3074	untimeout(gus_dmaout_timeout, sc);
3075	isa_dmaabort(sc->sc_dev.dv_parent, sc->sc_drq);
3076	sc->sc_flags &= ~(GUS_DMAOUT_ACTIVE|GUS_LOCKED);
3077	sc->sc_dmaoutintr = 0;
3078	sc->sc_outarg = 0;
3079	sc->sc_dmaoutaddr = 0;
3080	sc->sc_dmaoutcnt = 0;
3081	sc->sc_dmabuf = 0;
3082	sc->sc_bufcnt = 0;
3083	sc->sc_playbuf = -1;
3084	/* also stop playing */
3085	gus_stop_voice(sc, GUS_VOICE_LEFT, 1);
3086	gus_stop_voice(sc, GUS_VOICE_RIGHT, 0);
3087
3088	return 0;
3089}
3090
3091/*
3092 * Stop any DMA output.  Called at splgus().
3093 */
3094int
3095gus_halt_in_dma(addr)
3096	void * addr;
3097{
3098	struct gus_softc *sc = addr;
3099	bus_space_tag_t iot = sc->sc_iot;
3100	bus_space_handle_t ioh2 = sc->sc_ioh2;
3101	DMAPRINTF(("gus_halt_in_dma called\n"));
3102
3103	/*
3104	 * Make sure the GUS _isn't_ setup for DMA
3105	 */
3106
3107 	SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
3108	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH,
3109	     bus_space_read_1(iot, ioh2, GUS_DATA_HIGH) & ~(GUSMASK_SAMPLE_START|GUSMASK_SAMPLE_IRQ));
3110
3111	isa_dmaabort(sc->sc_dev.dv_parent, sc->sc_recdrq);
3112	sc->sc_flags &= ~GUS_DMAIN_ACTIVE;
3113	sc->sc_dmainintr = 0;
3114	sc->sc_inarg = 0;
3115	sc->sc_dmainaddr = 0;
3116	sc->sc_dmaincnt = 0;
3117
3118	return 0;
3119}
3120
3121STATIC __inline int
3122gus_to_vol(cp, vol)
3123	mixer_ctrl_t *cp;
3124	struct ad1848_volume *vol;
3125{
3126	if (cp->un.value.num_channels == 1) {
3127		vol->left = vol->right = cp->un.value.level[AUDIO_MIXER_LEVEL_MONO];
3128		return(1);
3129	}
3130	else if (cp->un.value.num_channels == 2) {
3131		vol->left  = cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT];
3132		vol->right = cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT];
3133		return(1);
3134	}
3135	return(0);
3136}
3137
3138STATIC __inline int
3139gus_from_vol(cp, vol)
3140	mixer_ctrl_t *cp;
3141	struct ad1848_volume *vol;
3142{
3143	if (cp->un.value.num_channels == 1) {
3144		cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = vol->left;
3145		return(1);
3146	}
3147	else if (cp->un.value.num_channels == 2) {
3148		cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = vol->left;
3149		cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = vol->right;
3150		return(1);
3151	}
3152	return(0);
3153}
3154
3155STATIC int
3156gusmax_mixer_get_port(addr, cp)
3157	void *addr;
3158	mixer_ctrl_t *cp;
3159{
3160	struct ad1848_softc *ac = addr;
3161	struct gus_softc *sc = ac->parent;
3162	struct ad1848_volume vol;
3163	int error = EINVAL;
3164
3165	DPRINTF(("gusmax_mixer_get_port: port=%d\n", cp->dev));
3166
3167	switch (cp->dev) {
3168#if 0 /* use mono level instead */
3169	case GUSMAX_MIC_IN_LVL:	/* Microphone */
3170		if (cp->type == AUDIO_MIXER_VALUE) {
3171			error = ad1848_get_mic_gain(ac, &vol);
3172			if (!error)
3173				gus_from_vol(cp, &vol);
3174		}
3175		break;
3176#endif
3177
3178	case GUSMAX_DAC_LVL:		/* dac out */
3179		if (cp->type == AUDIO_MIXER_VALUE) {
3180			error = ad1848_get_aux1_gain(ac, &vol);
3181			if (!error)
3182				gus_from_vol(cp, &vol);
3183		}
3184		break;
3185
3186	case GUSMAX_LINE_IN_LVL:	/* line in */
3187		if (cp->type == AUDIO_MIXER_VALUE) {
3188			error = cs4231_get_linein_gain(ac, &vol);
3189			if (!error)
3190				gus_from_vol(cp, &vol);
3191		}
3192		break;
3193
3194	case GUSMAX_MONO_LVL:	/* mono */
3195		if (cp->type == AUDIO_MIXER_VALUE &&
3196		    cp->un.value.num_channels == 1) {
3197			error = cs4231_get_mono_gain(ac, &vol);
3198			if (!error)
3199				gus_from_vol(cp, &vol);
3200		}
3201		break;
3202
3203	case GUSMAX_CD_LVL:	/* CD */
3204		if (cp->type == AUDIO_MIXER_VALUE) {
3205			error = ad1848_get_aux2_gain(ac, &vol);
3206			if (!error)
3207				gus_from_vol(cp, &vol);
3208		}
3209		break;
3210
3211	case GUSMAX_MONITOR_LVL:	/* monitor level */
3212		if (cp->type == AUDIO_MIXER_VALUE &&
3213		    cp->un.value.num_channels == 1) {
3214			error = ad1848_get_mon_gain(ac, &vol);
3215			if (!error)
3216				cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
3217					vol.left;
3218		}
3219		break;
3220
3221	case GUSMAX_OUT_LVL:	/* output level */
3222		if (cp->type == AUDIO_MIXER_VALUE) {
3223			error = ad1848_get_out_gain(ac, &vol);
3224			if (!error)
3225				gus_from_vol(cp, &vol);
3226		}
3227		break;
3228
3229	case GUSMAX_SPEAKER_LVL:	/* fake speaker for mute naming */
3230		if (cp->type == AUDIO_MIXER_VALUE) {
3231			if (sc->sc_mixcontrol & GUSMASK_LINE_OUT)
3232				vol.left = vol.right = AUDIO_MAX_GAIN;
3233			else
3234				vol.left = vol.right = AUDIO_MIN_GAIN;
3235			error = 0;
3236			gus_from_vol(cp, &vol);
3237		}
3238		break;
3239
3240	case GUSMAX_LINE_IN_MUTE:
3241		if (cp->type == AUDIO_MIXER_ENUM) {
3242			cp->un.ord = ac->line_mute;
3243			error = 0;
3244		}
3245		break;
3246
3247
3248	case GUSMAX_DAC_MUTE:
3249		if (cp->type == AUDIO_MIXER_ENUM) {
3250			cp->un.ord = ac->aux1_mute;
3251			error = 0;
3252		}
3253		break;
3254
3255	case GUSMAX_CD_MUTE:
3256		if (cp->type == AUDIO_MIXER_ENUM) {
3257			cp->un.ord = ac->aux2_mute;
3258			error = 0;
3259		}
3260		break;
3261
3262	case GUSMAX_MONO_MUTE:
3263		if (cp->type == AUDIO_MIXER_ENUM) {
3264			cp->un.ord = ac->mono_mute;
3265			error = 0;
3266		}
3267		break;
3268
3269	case GUSMAX_MONITOR_MUTE:
3270		if (cp->type == AUDIO_MIXER_ENUM) {
3271			cp->un.ord = ac->mon_mute;
3272			error = 0;
3273		}
3274		break;
3275
3276	case GUSMAX_SPEAKER_MUTE:
3277		if (cp->type == AUDIO_MIXER_ENUM) {
3278			cp->un.ord = sc->sc_mixcontrol & GUSMASK_LINE_OUT ? 1 : 0;
3279			error = 0;
3280		}
3281		break;
3282
3283	case GUSMAX_REC_LVL:		/* record level */
3284		if (cp->type == AUDIO_MIXER_VALUE) {
3285			error = ad1848_get_rec_gain(ac, &vol);
3286			if (!error)
3287				gus_from_vol(cp, &vol);
3288		}
3289		break;
3290
3291	case GUSMAX_RECORD_SOURCE:
3292		if (cp->type == AUDIO_MIXER_ENUM) {
3293			cp->un.ord = ad1848_get_rec_port(ac);
3294			error = 0;
3295		}
3296		break;
3297
3298	default:
3299		error = ENXIO;
3300		break;
3301	}
3302
3303	return(error);
3304}
3305
3306STATIC int
3307gus_mixer_get_port(addr, cp)
3308	void *addr;
3309	mixer_ctrl_t *cp;
3310{
3311	struct gus_softc *sc = addr;
3312	struct ics2101_softc *ic = &sc->sc_mixer;
3313	struct ad1848_volume vol;
3314	int error = EINVAL;
3315
3316	DPRINTF(("gus_mixer_get_port: dev=%d type=%d\n", cp->dev, cp->type));
3317
3318	if (!HAS_MIXER(sc) && cp->dev > GUSICS_MASTER_MUTE)
3319		return ENXIO;
3320
3321	switch (cp->dev) {
3322
3323	case GUSICS_MIC_IN_MUTE:	/* Microphone */
3324		if (cp->type == AUDIO_MIXER_ENUM) {
3325			if (HAS_MIXER(sc))
3326				cp->un.ord = ic->sc_mute[GUSMIX_CHAN_MIC][ICSMIX_LEFT];
3327			else
3328				cp->un.ord =
3329				    sc->sc_mixcontrol & GUSMASK_MIC_IN ? 0 : 1;
3330			error = 0;
3331		}
3332		break;
3333
3334	case GUSICS_LINE_IN_MUTE:
3335		if (cp->type == AUDIO_MIXER_ENUM) {
3336			if (HAS_MIXER(sc))
3337				cp->un.ord = ic->sc_mute[GUSMIX_CHAN_LINE][ICSMIX_LEFT];
3338			else
3339				cp->un.ord =
3340				    sc->sc_mixcontrol & GUSMASK_LINE_IN ? 1 : 0;
3341			error = 0;
3342		}
3343		break;
3344
3345	case GUSICS_MASTER_MUTE:
3346		if (cp->type == AUDIO_MIXER_ENUM) {
3347			if (HAS_MIXER(sc))
3348				cp->un.ord = ic->sc_mute[GUSMIX_CHAN_MASTER][ICSMIX_LEFT];
3349			else
3350				cp->un.ord =
3351				    sc->sc_mixcontrol & GUSMASK_LINE_OUT ? 1 : 0;
3352			error = 0;
3353		}
3354		break;
3355
3356	case GUSICS_DAC_MUTE:
3357		if (cp->type == AUDIO_MIXER_ENUM) {
3358			cp->un.ord = ic->sc_mute[GUSMIX_CHAN_DAC][ICSMIX_LEFT];
3359			error = 0;
3360		}
3361		break;
3362
3363	case GUSICS_CD_MUTE:
3364		if (cp->type == AUDIO_MIXER_ENUM) {
3365			cp->un.ord = ic->sc_mute[GUSMIX_CHAN_CD][ICSMIX_LEFT];
3366			error = 0;
3367		}
3368		break;
3369
3370	case GUSICS_MASTER_LVL:
3371		if (cp->type == AUDIO_MIXER_VALUE) {
3372			vol.left = ic->sc_setting[GUSMIX_CHAN_MASTER][ICSMIX_LEFT];
3373			vol.right = ic->sc_setting[GUSMIX_CHAN_MASTER][ICSMIX_RIGHT];
3374			if (gus_from_vol(cp, &vol))
3375				error = 0;
3376		}
3377		break;
3378
3379	case GUSICS_MIC_IN_LVL:	/* Microphone */
3380		if (cp->type == AUDIO_MIXER_VALUE) {
3381			vol.left = ic->sc_setting[GUSMIX_CHAN_MIC][ICSMIX_LEFT];
3382			vol.right = ic->sc_setting[GUSMIX_CHAN_MIC][ICSMIX_RIGHT];
3383			if (gus_from_vol(cp, &vol))
3384				error = 0;
3385		}
3386		break;
3387
3388	case GUSICS_LINE_IN_LVL:	/* line in */
3389		if (cp->type == AUDIO_MIXER_VALUE) {
3390			vol.left = ic->sc_setting[GUSMIX_CHAN_LINE][ICSMIX_LEFT];
3391			vol.right = ic->sc_setting[GUSMIX_CHAN_LINE][ICSMIX_RIGHT];
3392			if (gus_from_vol(cp, &vol))
3393				error = 0;
3394		}
3395		break;
3396
3397
3398	case GUSICS_CD_LVL:
3399		if (cp->type == AUDIO_MIXER_VALUE) {
3400			vol.left = ic->sc_setting[GUSMIX_CHAN_CD][ICSMIX_LEFT];
3401			vol.right = ic->sc_setting[GUSMIX_CHAN_CD][ICSMIX_RIGHT];
3402			if (gus_from_vol(cp, &vol))
3403				error = 0;
3404		}
3405		break;
3406
3407	case GUSICS_DAC_LVL:		/* dac out */
3408		if (cp->type == AUDIO_MIXER_VALUE) {
3409			vol.left = ic->sc_setting[GUSMIX_CHAN_DAC][ICSMIX_LEFT];
3410			vol.right = ic->sc_setting[GUSMIX_CHAN_DAC][ICSMIX_RIGHT];
3411			if (gus_from_vol(cp, &vol))
3412				error = 0;
3413		}
3414		break;
3415
3416
3417	case GUSICS_RECORD_SOURCE:
3418		if (cp->type == AUDIO_MIXER_ENUM) {
3419			/* Can't set anything else useful, sigh. */
3420			 cp->un.ord = 0;
3421		}
3422		break;
3423
3424	default:
3425		return ENXIO;
3426	    /*NOTREACHED*/
3427	}
3428	return error;
3429}
3430
3431STATIC void
3432gusics_master_mute(ic, mute)
3433	struct ics2101_softc *ic;
3434	int mute;
3435{
3436	ics2101_mix_mute(ic, GUSMIX_CHAN_MASTER, ICSMIX_LEFT, mute);
3437	ics2101_mix_mute(ic, GUSMIX_CHAN_MASTER, ICSMIX_RIGHT, mute);
3438}
3439
3440STATIC void
3441gusics_mic_mute(ic, mute)
3442	struct ics2101_softc *ic;
3443	int mute;
3444{
3445	ics2101_mix_mute(ic, GUSMIX_CHAN_MIC, ICSMIX_LEFT, mute);
3446	ics2101_mix_mute(ic, GUSMIX_CHAN_MIC, ICSMIX_RIGHT, mute);
3447}
3448
3449STATIC void
3450gusics_linein_mute(ic, mute)
3451	struct ics2101_softc *ic;
3452	int mute;
3453{
3454	ics2101_mix_mute(ic, GUSMIX_CHAN_LINE, ICSMIX_LEFT, mute);
3455	ics2101_mix_mute(ic, GUSMIX_CHAN_LINE, ICSMIX_RIGHT, mute);
3456}
3457
3458STATIC void
3459gusics_cd_mute(ic, mute)
3460	struct ics2101_softc *ic;
3461	int mute;
3462{
3463	ics2101_mix_mute(ic, GUSMIX_CHAN_CD, ICSMIX_LEFT, mute);
3464	ics2101_mix_mute(ic, GUSMIX_CHAN_CD, ICSMIX_RIGHT, mute);
3465}
3466
3467STATIC void
3468gusics_dac_mute(ic, mute)
3469	struct ics2101_softc *ic;
3470	int mute;
3471{
3472	ics2101_mix_mute(ic, GUSMIX_CHAN_DAC, ICSMIX_LEFT, mute);
3473	ics2101_mix_mute(ic, GUSMIX_CHAN_DAC, ICSMIX_RIGHT, mute);
3474}
3475
3476STATIC int
3477gusmax_mixer_set_port(addr, cp)
3478	void *addr;
3479	mixer_ctrl_t *cp;
3480{
3481	struct ad1848_softc *ac = addr;
3482	struct gus_softc *sc = ac->parent;
3483	struct ad1848_volume vol;
3484	int error = EINVAL;
3485
3486	DPRINTF(("gusmax_mixer_set_port: dev=%d type=%d\n", cp->dev, cp->type));
3487
3488	switch (cp->dev) {
3489#if 0
3490	case GUSMAX_MIC_IN_LVL:	/* Microphone */
3491		if (cp->type == AUDIO_MIXER_VALUE &&
3492		    cp->un.value.num_channels == 1) {
3493			/* XXX enable/disable pre-MUX fixed gain */
3494			if (gus_to_vol(cp, &vol))
3495				error = ad1848_set_mic_gain(ac, &vol);
3496		}
3497		break;
3498#endif
3499
3500	case GUSMAX_DAC_LVL:		/* dac out */
3501		if (cp->type == AUDIO_MIXER_VALUE) {
3502			if (gus_to_vol(cp, &vol))
3503				error = ad1848_set_aux1_gain(ac, &vol);
3504		}
3505		break;
3506
3507	case GUSMAX_LINE_IN_LVL:	/* line in */
3508		if (cp->type == AUDIO_MIXER_VALUE) {
3509			if (gus_to_vol(cp, &vol))
3510				error = cs4231_set_linein_gain(ac, &vol);
3511		}
3512		break;
3513
3514	case GUSMAX_MONO_LVL:	/* mic/mono in */
3515		if (cp->type == AUDIO_MIXER_VALUE &&
3516		    cp->un.value.num_channels == 1) {
3517			if (gus_to_vol(cp, &vol))
3518				error = cs4231_set_mono_gain(ac, &vol);
3519		}
3520		break;
3521
3522	case GUSMAX_CD_LVL:	/* CD: AUX2 */
3523		if (cp->type == AUDIO_MIXER_VALUE) {
3524			if (gus_to_vol(cp, &vol))
3525				error = ad1848_set_aux2_gain(ac, &vol);
3526		}
3527		break;
3528
3529	case GUSMAX_MONITOR_LVL:
3530		if (cp->type == AUDIO_MIXER_VALUE &&
3531		    cp->un.value.num_channels == 1) {
3532			vol.left  = cp->un.value.level[AUDIO_MIXER_LEVEL_MONO];
3533			error = ad1848_set_mon_gain(ac, &vol);
3534		}
3535		break;
3536
3537	case GUSMAX_OUT_LVL:	/* output volume */
3538		if (cp->type == AUDIO_MIXER_VALUE) {
3539			if (gus_to_vol(cp, &vol))
3540				error = ad1848_set_out_gain(ac, &vol);
3541		}
3542		break;
3543
3544	case GUSMAX_SPEAKER_LVL:
3545		if (cp->type == AUDIO_MIXER_VALUE &&
3546		    cp->un.value.num_channels == 1) {
3547			if (gus_to_vol(cp, &vol)) {
3548				gus_speaker_ctl(sc, vol.left > AUDIO_MIN_GAIN ?
3549						SPKR_ON : SPKR_OFF);
3550				error = 0;
3551			}
3552		}
3553		break;
3554
3555	case GUSMAX_LINE_IN_MUTE:
3556		if (cp->type == AUDIO_MIXER_ENUM) {
3557			ac->line_mute = cp->un.ord ? 1 : 0;
3558			DPRINTF(("line mute %d\n", cp->un.ord));
3559			cs4231_mute_line(ac, ac->line_mute);
3560			gus_linein_ctl(sc, ac->line_mute ? SPKR_OFF : SPKR_ON);
3561			error = 0;
3562		}
3563		break;
3564
3565	case GUSMAX_DAC_MUTE:
3566		if (cp->type == AUDIO_MIXER_ENUM) {
3567			ac->aux1_mute = cp->un.ord ? 1 : 0;
3568			DPRINTF(("dac mute %d\n", cp->un.ord));
3569			ad1848_mute_aux1(ac, ac->aux1_mute);
3570			error = 0;
3571		}
3572		break;
3573
3574	case GUSMAX_CD_MUTE:
3575		if (cp->type == AUDIO_MIXER_ENUM) {
3576			ac->aux2_mute = cp->un.ord ? 1 : 0;
3577			DPRINTF(("cd mute %d\n", cp->un.ord));
3578			ad1848_mute_aux2(ac, ac->aux2_mute);
3579			error = 0;
3580		}
3581		break;
3582
3583	case GUSMAX_MONO_MUTE:	/* Microphone */
3584		if (cp->type == AUDIO_MIXER_ENUM) {
3585			ac->mono_mute = cp->un.ord ? 1 : 0;
3586			DPRINTF(("mono mute %d\n", cp->un.ord));
3587			cs4231_mute_mono(ac, ac->mono_mute);
3588			gus_mic_ctl(sc, ac->mono_mute ? SPKR_OFF : SPKR_ON);
3589			error = 0;
3590		}
3591		break;
3592
3593	case GUSMAX_MONITOR_MUTE:
3594		if (cp->type == AUDIO_MIXER_ENUM) {
3595			ac->mon_mute = cp->un.ord ? 1 : 0;
3596			DPRINTF(("mono mute %d\n", cp->un.ord));
3597			cs4231_mute_monitor(ac, ac->mon_mute);
3598			error = 0;
3599		}
3600		break;
3601
3602	case GUSMAX_SPEAKER_MUTE:
3603		if (cp->type == AUDIO_MIXER_ENUM) {
3604			gus_speaker_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON);
3605			error = 0;
3606		}
3607		break;
3608
3609	case GUSMAX_REC_LVL:		/* record level */
3610		if (cp->type == AUDIO_MIXER_VALUE) {
3611			if (gus_to_vol(cp, &vol))
3612				error = ad1848_set_rec_gain(ac, &vol);
3613		}
3614		break;
3615
3616	case GUSMAX_RECORD_SOURCE:
3617		if (cp->type == AUDIO_MIXER_ENUM) {
3618			error = ad1848_set_rec_port(ac, cp->un.ord);
3619		}
3620		break;
3621
3622	default:
3623		return ENXIO;
3624	    /*NOTREACHED*/
3625    }
3626    return error;
3627}
3628
3629STATIC int
3630gus_mixer_set_port(addr, cp)
3631	void *addr;
3632	mixer_ctrl_t *cp;
3633{
3634	struct gus_softc *sc = addr;
3635	struct ics2101_softc *ic = &sc->sc_mixer;
3636	struct ad1848_volume vol;
3637	int error = EINVAL;
3638
3639	DPRINTF(("gus_mixer_set_port: dev=%d type=%d\n", cp->dev, cp->type));
3640
3641	if (!HAS_MIXER(sc) && cp->dev > GUSICS_MASTER_MUTE)
3642		return ENXIO;
3643
3644	switch (cp->dev) {
3645
3646	case GUSICS_MIC_IN_MUTE:	/* Microphone */
3647		if (cp->type == AUDIO_MIXER_ENUM) {
3648			DPRINTF(("mic mute %d\n", cp->un.ord));
3649			if (HAS_MIXER(sc)) {
3650				gusics_mic_mute(ic, cp->un.ord);
3651			}
3652			gus_mic_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON);
3653			error = 0;
3654		}
3655		break;
3656
3657	case GUSICS_LINE_IN_MUTE:
3658		if (cp->type == AUDIO_MIXER_ENUM) {
3659			DPRINTF(("linein mute %d\n", cp->un.ord));
3660			if (HAS_MIXER(sc)) {
3661				gusics_linein_mute(ic, cp->un.ord);
3662			}
3663			gus_linein_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON);
3664			error = 0;
3665		}
3666		break;
3667
3668	case GUSICS_MASTER_MUTE:
3669		if (cp->type == AUDIO_MIXER_ENUM) {
3670			DPRINTF(("master mute %d\n", cp->un.ord));
3671			if (HAS_MIXER(sc)) {
3672				gusics_master_mute(ic, cp->un.ord);
3673			}
3674			gus_speaker_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON);
3675			error = 0;
3676		}
3677		break;
3678
3679	case GUSICS_DAC_MUTE:
3680		if (cp->type == AUDIO_MIXER_ENUM) {
3681			gusics_dac_mute(ic, cp->un.ord);
3682			error = 0;
3683		}
3684		break;
3685
3686	case GUSICS_CD_MUTE:
3687		if (cp->type == AUDIO_MIXER_ENUM) {
3688			gusics_cd_mute(ic, cp->un.ord);
3689			error = 0;
3690		}
3691		break;
3692
3693	case GUSICS_MASTER_LVL:
3694		if (cp->type == AUDIO_MIXER_VALUE) {
3695			if (gus_to_vol(cp, &vol)) {
3696				ics2101_mix_attenuate(ic,
3697						      GUSMIX_CHAN_MASTER,
3698						      ICSMIX_LEFT,
3699						      vol.left);
3700				ics2101_mix_attenuate(ic,
3701						      GUSMIX_CHAN_MASTER,
3702						      ICSMIX_RIGHT,
3703						      vol.right);
3704				error = 0;
3705			}
3706		}
3707		break;
3708
3709	case GUSICS_MIC_IN_LVL:	/* Microphone */
3710		if (cp->type == AUDIO_MIXER_VALUE) {
3711			if (gus_to_vol(cp, &vol)) {
3712				ics2101_mix_attenuate(ic,
3713						      GUSMIX_CHAN_MIC,
3714						      ICSMIX_LEFT,
3715						      vol.left);
3716				ics2101_mix_attenuate(ic,
3717						      GUSMIX_CHAN_MIC,
3718						      ICSMIX_RIGHT,
3719						      vol.right);
3720				error = 0;
3721			}
3722		}
3723		break;
3724
3725	case GUSICS_LINE_IN_LVL:	/* line in */
3726		if (cp->type == AUDIO_MIXER_VALUE) {
3727			if (gus_to_vol(cp, &vol)) {
3728				ics2101_mix_attenuate(ic,
3729						      GUSMIX_CHAN_LINE,
3730						      ICSMIX_LEFT,
3731						      vol.left);
3732				ics2101_mix_attenuate(ic,
3733						      GUSMIX_CHAN_LINE,
3734						      ICSMIX_RIGHT,
3735						      vol.right);
3736				error = 0;
3737			}
3738		}
3739		break;
3740
3741
3742	case GUSICS_CD_LVL:
3743		if (cp->type == AUDIO_MIXER_VALUE) {
3744			if (gus_to_vol(cp, &vol)) {
3745				ics2101_mix_attenuate(ic,
3746						      GUSMIX_CHAN_CD,
3747						      ICSMIX_LEFT,
3748						      vol.left);
3749				ics2101_mix_attenuate(ic,
3750						      GUSMIX_CHAN_CD,
3751						      ICSMIX_RIGHT,
3752						      vol.right);
3753				error = 0;
3754			}
3755		}
3756		break;
3757
3758	case GUSICS_DAC_LVL:		/* dac out */
3759		if (cp->type == AUDIO_MIXER_VALUE) {
3760			if (gus_to_vol(cp, &vol)) {
3761				ics2101_mix_attenuate(ic,
3762						      GUSMIX_CHAN_DAC,
3763						      ICSMIX_LEFT,
3764						      vol.left);
3765				ics2101_mix_attenuate(ic,
3766						      GUSMIX_CHAN_DAC,
3767						      ICSMIX_RIGHT,
3768						      vol.right);
3769				error = 0;
3770			}
3771		}
3772		break;
3773
3774
3775	case GUSICS_RECORD_SOURCE:
3776		if (cp->type == AUDIO_MIXER_ENUM && cp->un.ord == 0) {
3777			/* Can't set anything else useful, sigh. */
3778			error = 0;
3779		}
3780		break;
3781
3782	default:
3783		return ENXIO;
3784	    /*NOTREACHED*/
3785	}
3786	return error;
3787}
3788
3789STATIC int
3790gus_get_props(addr)
3791	void *addr;
3792{
3793	struct gus_softc *sc = addr;
3794	return sc->sc_recdrq == sc->sc_drq ? 0 : AUDIO_PROP_FULLDUPLEX;
3795}
3796
3797STATIC int
3798gusmax_get_props(addr)
3799	void *addr;
3800{
3801	struct ad1848_softc *ac = addr;
3802	return gus_get_props(ac->parent);
3803}
3804
3805STATIC int
3806gusmax_mixer_query_devinfo(addr, dip)
3807	void *addr;
3808	mixer_devinfo_t *dip;
3809{
3810	DPRINTF(("gusmax_query_devinfo: index=%d\n", dip->index));
3811
3812	switch(dip->index) {
3813#if 0
3814    case GUSMAX_MIC_IN_LVL:	/* Microphone */
3815	dip->type = AUDIO_MIXER_VALUE;
3816	dip->mixer_class = GUSMAX_INPUT_CLASS;
3817	dip->prev = AUDIO_MIXER_LAST;
3818	dip->next = GUSMAX_MIC_IN_MUTE;
3819	strcpy(dip->label.name, AudioNmicrophone);
3820	dip->un.v.num_channels = 2;
3821	strcpy(dip->un.v.units.name, AudioNvolume);
3822	break;
3823#endif
3824
3825    case GUSMAX_MONO_LVL:	/* mono/microphone mixer */
3826	dip->type = AUDIO_MIXER_VALUE;
3827	dip->mixer_class = GUSMAX_INPUT_CLASS;
3828	dip->prev = AUDIO_MIXER_LAST;
3829	dip->next = GUSMAX_MONO_MUTE;
3830	strcpy(dip->label.name, AudioNmicrophone);
3831	dip->un.v.num_channels = 1;
3832	strcpy(dip->un.v.units.name, AudioNvolume);
3833	break;
3834
3835    case GUSMAX_DAC_LVL:		/*  dacout */
3836	dip->type = AUDIO_MIXER_VALUE;
3837	dip->mixer_class = GUSMAX_INPUT_CLASS;
3838	dip->prev = AUDIO_MIXER_LAST;
3839	dip->next = GUSMAX_DAC_MUTE;
3840	strcpy(dip->label.name, AudioNdac);
3841	dip->un.v.num_channels = 2;
3842	strcpy(dip->un.v.units.name, AudioNvolume);
3843	break;
3844
3845    case GUSMAX_LINE_IN_LVL:	/* line */
3846	dip->type = AUDIO_MIXER_VALUE;
3847	dip->mixer_class = GUSMAX_INPUT_CLASS;
3848	dip->prev = AUDIO_MIXER_LAST;
3849	dip->next = GUSMAX_LINE_IN_MUTE;
3850	strcpy(dip->label.name, AudioNline);
3851	dip->un.v.num_channels = 2;
3852	strcpy(dip->un.v.units.name, AudioNvolume);
3853	break;
3854
3855    case GUSMAX_CD_LVL:		/* cd */
3856	dip->type = AUDIO_MIXER_VALUE;
3857	dip->mixer_class = GUSMAX_INPUT_CLASS;
3858	dip->prev = AUDIO_MIXER_LAST;
3859	dip->next = GUSMAX_CD_MUTE;
3860	strcpy(dip->label.name, AudioNcd);
3861	dip->un.v.num_channels = 2;
3862	strcpy(dip->un.v.units.name, AudioNvolume);
3863	break;
3864
3865
3866    case GUSMAX_MONITOR_LVL:	/* monitor level */
3867	dip->type = AUDIO_MIXER_VALUE;
3868	dip->mixer_class = GUSMAX_MONITOR_CLASS;
3869	dip->next = GUSMAX_MONITOR_MUTE;
3870	dip->prev = AUDIO_MIXER_LAST;
3871	strcpy(dip->label.name, AudioNmonitor);
3872	dip->un.v.num_channels = 1;
3873	strcpy(dip->un.v.units.name, AudioNvolume);
3874	break;
3875
3876    case GUSMAX_OUT_LVL:		/* cs4231 output volume: not useful? */
3877	dip->type = AUDIO_MIXER_VALUE;
3878	dip->mixer_class = GUSMAX_MONITOR_CLASS;
3879	dip->prev = dip->next = AUDIO_MIXER_LAST;
3880	strcpy(dip->label.name, AudioNoutput);
3881	dip->un.v.num_channels = 2;
3882	strcpy(dip->un.v.units.name, AudioNvolume);
3883	break;
3884
3885    case GUSMAX_SPEAKER_LVL:		/* fake speaker volume */
3886	dip->type = AUDIO_MIXER_VALUE;
3887	dip->mixer_class = GUSMAX_MONITOR_CLASS;
3888	dip->prev = AUDIO_MIXER_LAST;
3889	dip->next = GUSMAX_SPEAKER_MUTE;
3890	strcpy(dip->label.name, AudioNmaster);
3891	dip->un.v.num_channels = 2;
3892	strcpy(dip->un.v.units.name, AudioNvolume);
3893	break;
3894
3895    case GUSMAX_LINE_IN_MUTE:
3896	dip->mixer_class = GUSMAX_INPUT_CLASS;
3897	dip->type = AUDIO_MIXER_ENUM;
3898	dip->prev = GUSMAX_LINE_IN_LVL;
3899	dip->next = AUDIO_MIXER_LAST;
3900	goto mute;
3901
3902    case GUSMAX_DAC_MUTE:
3903	dip->mixer_class = GUSMAX_INPUT_CLASS;
3904	dip->type = AUDIO_MIXER_ENUM;
3905	dip->prev = GUSMAX_DAC_LVL;
3906	dip->next = AUDIO_MIXER_LAST;
3907	goto mute;
3908
3909    case GUSMAX_CD_MUTE:
3910	dip->mixer_class = GUSMAX_INPUT_CLASS;
3911	dip->type = AUDIO_MIXER_ENUM;
3912	dip->prev = GUSMAX_CD_LVL;
3913	dip->next = AUDIO_MIXER_LAST;
3914	goto mute;
3915
3916    case GUSMAX_MONO_MUTE:
3917	dip->mixer_class = GUSMAX_INPUT_CLASS;
3918	dip->type = AUDIO_MIXER_ENUM;
3919	dip->prev = GUSMAX_MONO_LVL;
3920	dip->next = AUDIO_MIXER_LAST;
3921	goto mute;
3922
3923    case GUSMAX_MONITOR_MUTE:
3924	dip->mixer_class = GUSMAX_OUTPUT_CLASS;
3925	dip->type = AUDIO_MIXER_ENUM;
3926	dip->prev = GUSMAX_MONITOR_LVL;
3927	dip->next = AUDIO_MIXER_LAST;
3928	goto mute;
3929
3930    case GUSMAX_SPEAKER_MUTE:
3931	dip->mixer_class = GUSMAX_OUTPUT_CLASS;
3932	dip->type = AUDIO_MIXER_ENUM;
3933	dip->prev = GUSMAX_SPEAKER_LVL;
3934	dip->next = AUDIO_MIXER_LAST;
3935    mute:
3936	strcpy(dip->label.name, AudioNmute);
3937	dip->un.e.num_mem = 2;
3938	strcpy(dip->un.e.member[0].label.name, AudioNoff);
3939	dip->un.e.member[0].ord = 0;
3940	strcpy(dip->un.e.member[1].label.name, AudioNon);
3941	dip->un.e.member[1].ord = 1;
3942	break;
3943
3944    case GUSMAX_REC_LVL:	/* record level */
3945	dip->type = AUDIO_MIXER_VALUE;
3946	dip->mixer_class = GUSMAX_RECORD_CLASS;
3947	dip->prev = AUDIO_MIXER_LAST;
3948	dip->next = GUSMAX_RECORD_SOURCE;
3949	strcpy(dip->label.name, AudioNrecord);
3950	dip->un.v.num_channels = 2;
3951	strcpy(dip->un.v.units.name, AudioNvolume);
3952	break;
3953
3954    case GUSMAX_RECORD_SOURCE:
3955	dip->mixer_class = GUSMAX_RECORD_CLASS;
3956	dip->type = AUDIO_MIXER_ENUM;
3957	dip->prev = GUSMAX_REC_LVL;
3958	dip->next = AUDIO_MIXER_LAST;
3959	strcpy(dip->label.name, AudioNsource);
3960	dip->un.e.num_mem = 4;
3961	strcpy(dip->un.e.member[0].label.name, AudioNoutput);
3962	dip->un.e.member[0].ord = DAC_IN_PORT;
3963	strcpy(dip->un.e.member[1].label.name, AudioNmicrophone);
3964	dip->un.e.member[1].ord = MIC_IN_PORT;
3965	strcpy(dip->un.e.member[2].label.name, AudioNdac);
3966	dip->un.e.member[2].ord = AUX1_IN_PORT;
3967	strcpy(dip->un.e.member[3].label.name, AudioNline);
3968	dip->un.e.member[3].ord = LINE_IN_PORT;
3969	break;
3970
3971    case GUSMAX_INPUT_CLASS:			/* input class descriptor */
3972	dip->type = AUDIO_MIXER_CLASS;
3973	dip->mixer_class = GUSMAX_INPUT_CLASS;
3974	dip->next = dip->prev = AUDIO_MIXER_LAST;
3975	strcpy(dip->label.name, AudioCinputs);
3976	break;
3977
3978    case GUSMAX_OUTPUT_CLASS:			/* output class descriptor */
3979	dip->type = AUDIO_MIXER_CLASS;
3980	dip->mixer_class = GUSMAX_OUTPUT_CLASS;
3981	dip->next = dip->prev = AUDIO_MIXER_LAST;
3982	strcpy(dip->label.name, AudioCoutputs);
3983	break;
3984
3985    case GUSMAX_MONITOR_CLASS:			/* monitor class descriptor */
3986	dip->type = AUDIO_MIXER_CLASS;
3987	dip->mixer_class = GUSMAX_MONITOR_CLASS;
3988	dip->next = dip->prev = AUDIO_MIXER_LAST;
3989	strcpy(dip->label.name, AudioCmonitor);
3990	break;
3991
3992    case GUSMAX_RECORD_CLASS:			/* record source class */
3993	dip->type = AUDIO_MIXER_CLASS;
3994	dip->mixer_class = GUSMAX_RECORD_CLASS;
3995	dip->next = dip->prev = AUDIO_MIXER_LAST;
3996	strcpy(dip->label.name, AudioCrecord);
3997	break;
3998
3999    default:
4000	return ENXIO;
4001	/*NOTREACHED*/
4002    }
4003    DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name));
4004	return 0;
4005}
4006
4007STATIC int
4008gus_mixer_query_devinfo(addr, dip)
4009	void *addr;
4010	mixer_devinfo_t *dip;
4011{
4012	struct gus_softc *sc = addr;
4013
4014	DPRINTF(("gusmax_query_devinfo: index=%d\n", dip->index));
4015
4016	if (!HAS_MIXER(sc) && dip->index > GUSICS_MASTER_MUTE)
4017		return ENXIO;
4018
4019	switch(dip->index) {
4020
4021	case GUSICS_MIC_IN_LVL:	/* Microphone */
4022		dip->type = AUDIO_MIXER_VALUE;
4023		dip->mixer_class = GUSICS_INPUT_CLASS;
4024		dip->prev = AUDIO_MIXER_LAST;
4025		dip->next = GUSICS_MIC_IN_MUTE;
4026		strcpy(dip->label.name, AudioNmicrophone);
4027		dip->un.v.num_channels = 2;
4028		strcpy(dip->un.v.units.name, AudioNvolume);
4029		break;
4030
4031	case GUSICS_LINE_IN_LVL:	/* line */
4032		dip->type = AUDIO_MIXER_VALUE;
4033		dip->mixer_class = GUSICS_INPUT_CLASS;
4034		dip->prev = AUDIO_MIXER_LAST;
4035		dip->next = GUSICS_LINE_IN_MUTE;
4036		strcpy(dip->label.name, AudioNline);
4037		dip->un.v.num_channels = 2;
4038		strcpy(dip->un.v.units.name, AudioNvolume);
4039		break;
4040
4041	case GUSICS_CD_LVL:		/* cd */
4042		dip->type = AUDIO_MIXER_VALUE;
4043		dip->mixer_class = GUSICS_INPUT_CLASS;
4044		dip->prev = AUDIO_MIXER_LAST;
4045		dip->next = GUSICS_CD_MUTE;
4046		strcpy(dip->label.name, AudioNcd);
4047		dip->un.v.num_channels = 2;
4048		strcpy(dip->un.v.units.name, AudioNvolume);
4049		break;
4050
4051	case GUSICS_DAC_LVL:		/*  dacout */
4052		dip->type = AUDIO_MIXER_VALUE;
4053		dip->mixer_class = GUSICS_INPUT_CLASS;
4054		dip->prev = AUDIO_MIXER_LAST;
4055		dip->next = GUSICS_DAC_MUTE;
4056		strcpy(dip->label.name, AudioNdac);
4057		dip->un.v.num_channels = 2;
4058		strcpy(dip->un.v.units.name, AudioNvolume);
4059		break;
4060
4061	case GUSICS_MASTER_LVL:		/*  master output */
4062		dip->type = AUDIO_MIXER_VALUE;
4063		dip->mixer_class = GUSICS_OUTPUT_CLASS;
4064		dip->prev = AUDIO_MIXER_LAST;
4065		dip->next = GUSICS_MASTER_MUTE;
4066		strcpy(dip->label.name, AudioNmaster);
4067		dip->un.v.num_channels = 2;
4068		strcpy(dip->un.v.units.name, AudioNvolume);
4069		break;
4070
4071
4072	case GUSICS_LINE_IN_MUTE:
4073		dip->mixer_class = GUSICS_INPUT_CLASS;
4074		dip->type = AUDIO_MIXER_ENUM;
4075		dip->prev = GUSICS_LINE_IN_LVL;
4076		dip->next = AUDIO_MIXER_LAST;
4077		goto mute;
4078
4079	case GUSICS_DAC_MUTE:
4080		dip->mixer_class = GUSICS_INPUT_CLASS;
4081		dip->type = AUDIO_MIXER_ENUM;
4082		dip->prev = GUSICS_DAC_LVL;
4083		dip->next = AUDIO_MIXER_LAST;
4084		goto mute;
4085
4086	case GUSICS_CD_MUTE:
4087		dip->mixer_class = GUSICS_INPUT_CLASS;
4088		dip->type = AUDIO_MIXER_ENUM;
4089		dip->prev = GUSICS_CD_LVL;
4090		dip->next = AUDIO_MIXER_LAST;
4091		goto mute;
4092
4093	case GUSICS_MIC_IN_MUTE:
4094		dip->mixer_class = GUSICS_INPUT_CLASS;
4095		dip->type = AUDIO_MIXER_ENUM;
4096		dip->prev = GUSICS_MIC_IN_LVL;
4097		dip->next = AUDIO_MIXER_LAST;
4098		goto mute;
4099
4100	case GUSICS_MASTER_MUTE:
4101		dip->mixer_class = GUSICS_OUTPUT_CLASS;
4102		dip->type = AUDIO_MIXER_ENUM;
4103		dip->prev = GUSICS_MASTER_LVL;
4104		dip->next = AUDIO_MIXER_LAST;
4105mute:
4106		strcpy(dip->label.name, AudioNmute);
4107		dip->un.e.num_mem = 2;
4108		strcpy(dip->un.e.member[0].label.name, AudioNoff);
4109		dip->un.e.member[0].ord = 0;
4110		strcpy(dip->un.e.member[1].label.name, AudioNon);
4111		dip->un.e.member[1].ord = 1;
4112		break;
4113
4114	case GUSICS_RECORD_SOURCE:
4115		dip->mixer_class = GUSICS_RECORD_CLASS;
4116		dip->type = AUDIO_MIXER_ENUM;
4117		dip->prev = dip->next = AUDIO_MIXER_LAST;
4118		strcpy(dip->label.name, AudioNsource);
4119		dip->un.e.num_mem = 1;
4120		strcpy(dip->un.e.member[0].label.name, AudioNoutput);
4121		dip->un.e.member[0].ord = GUSICS_MASTER_LVL;
4122		break;
4123
4124	case GUSICS_INPUT_CLASS:
4125		dip->type = AUDIO_MIXER_CLASS;
4126		dip->mixer_class = GUSICS_INPUT_CLASS;
4127		dip->next = dip->prev = AUDIO_MIXER_LAST;
4128		strcpy(dip->label.name, AudioCinputs);
4129		break;
4130
4131	case GUSICS_OUTPUT_CLASS:
4132		dip->type = AUDIO_MIXER_CLASS;
4133		dip->mixer_class = GUSICS_OUTPUT_CLASS;
4134		dip->next = dip->prev = AUDIO_MIXER_LAST;
4135		strcpy(dip->label.name, AudioCoutputs);
4136		break;
4137
4138	case GUSICS_RECORD_CLASS:
4139		dip->type = AUDIO_MIXER_CLASS;
4140		dip->mixer_class = GUSICS_RECORD_CLASS;
4141		dip->next = dip->prev = AUDIO_MIXER_LAST;
4142		strcpy(dip->label.name, AudioCrecord);
4143		break;
4144
4145	default:
4146		return ENXIO;
4147	/*NOTREACHED*/
4148	}
4149	DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name));
4150	return 0;
4151}
4152
4153STATIC int
4154gus_query_encoding(addr, fp)
4155	void *addr;
4156	struct audio_encoding *fp;
4157{
4158	switch (fp->index) {
4159	case 0:
4160		strcpy(fp->name, AudioEmulaw);
4161		fp->encoding = AUDIO_ENCODING_ULAW;
4162		fp->precision = 8;
4163		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
4164		break;
4165	case 1:
4166		strcpy(fp->name, AudioEslinear);
4167		fp->encoding = AUDIO_ENCODING_SLINEAR;
4168		fp->precision = 8;
4169		fp->flags = 0;
4170		break;
4171	case 2:
4172		strcpy(fp->name, AudioEslinear_le);
4173		fp->encoding = AUDIO_ENCODING_SLINEAR_LE;
4174		fp->precision = 16;
4175		fp->flags = 0;
4176		break;
4177	case 3:
4178		strcpy(fp->name, AudioEulinear);
4179		fp->encoding = AUDIO_ENCODING_ULINEAR;
4180		fp->precision = 8;
4181		fp->flags = 0;
4182		break;
4183	case 4:
4184		strcpy(fp->name, AudioEulinear_le);
4185		fp->encoding = AUDIO_ENCODING_ULINEAR_LE;
4186		fp->precision = 16;
4187		fp->flags = 0;
4188		break;
4189	case 5:
4190		strcpy(fp->name, AudioEslinear_be);
4191		fp->encoding = AUDIO_ENCODING_SLINEAR_BE;
4192		fp->precision = 16;
4193		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
4194		break;
4195	case 6:
4196		strcpy(fp->name, AudioEulinear_be);
4197		fp->encoding = AUDIO_ENCODING_ULINEAR_BE;
4198		fp->precision = 16;
4199		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
4200		break;
4201	case 7:
4202		strcpy(fp->name, AudioEalaw);
4203		fp->encoding = AUDIO_ENCODING_ALAW;
4204		fp->precision = 8;
4205		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
4206		break;
4207
4208	default:
4209		return(EINVAL);
4210		/*NOTREACHED*/
4211	}
4212	return (0);
4213}
4214
4215/*
4216 * Setup the ICS mixer in "transparent" mode: reset everything to a sensible
4217 * level.  Levels as suggested by GUS SDK code.
4218 */
4219
4220STATIC void
4221gus_init_ics2101(sc)
4222	struct gus_softc *sc;
4223{
4224	struct ics2101_softc *ic = &sc->sc_mixer;
4225	sc->sc_mixer.sc_iot = sc->sc_iot;
4226	sc->sc_mixer.sc_selio = GUS_MIXER_SELECT;
4227	sc->sc_mixer.sc_selio_ioh = sc->sc_ioh3;
4228	sc->sc_mixer.sc_dataio = GUS_MIXER_DATA;
4229	sc->sc_mixer.sc_dataio_ioh = sc->sc_ioh2;
4230	sc->sc_mixer.sc_flags = (sc->sc_revision == 5) ? ICS_FLIP : 0;
4231
4232	ics2101_mix_attenuate(ic,
4233			      GUSMIX_CHAN_MIC,
4234			      ICSMIX_LEFT,
4235			      ICSMIX_MIN_ATTN);
4236	ics2101_mix_attenuate(ic,
4237			      GUSMIX_CHAN_MIC,
4238			      ICSMIX_RIGHT,
4239			      ICSMIX_MIN_ATTN);
4240	/*
4241	 * Start with microphone muted by the mixer...
4242	 */
4243	gusics_mic_mute(ic, 1);
4244
4245	/* ... and enabled by the GUS master mix control */
4246	gus_mic_ctl(sc, SPKR_ON);
4247
4248	ics2101_mix_attenuate(ic,
4249			      GUSMIX_CHAN_LINE,
4250			      ICSMIX_LEFT,
4251			      ICSMIX_MIN_ATTN);
4252	ics2101_mix_attenuate(ic,
4253			      GUSMIX_CHAN_LINE,
4254			      ICSMIX_RIGHT,
4255			      ICSMIX_MIN_ATTN);
4256
4257	ics2101_mix_attenuate(ic,
4258			      GUSMIX_CHAN_CD,
4259			      ICSMIX_LEFT,
4260			      ICSMIX_MIN_ATTN);
4261	ics2101_mix_attenuate(ic,
4262			      GUSMIX_CHAN_CD,
4263			      ICSMIX_RIGHT,
4264			      ICSMIX_MIN_ATTN);
4265
4266	ics2101_mix_attenuate(ic,
4267			      GUSMIX_CHAN_DAC,
4268			      ICSMIX_LEFT,
4269			      ICSMIX_MIN_ATTN);
4270	ics2101_mix_attenuate(ic,
4271			      GUSMIX_CHAN_DAC,
4272			      ICSMIX_RIGHT,
4273			      ICSMIX_MIN_ATTN);
4274
4275	ics2101_mix_attenuate(ic,
4276			      ICSMIX_CHAN_4,
4277			      ICSMIX_LEFT,
4278			      ICSMIX_MAX_ATTN);
4279	ics2101_mix_attenuate(ic,
4280			      ICSMIX_CHAN_4,
4281			      ICSMIX_RIGHT,
4282			      ICSMIX_MAX_ATTN);
4283
4284	ics2101_mix_attenuate(ic,
4285			      GUSMIX_CHAN_MASTER,
4286			      ICSMIX_LEFT,
4287			      ICSMIX_MIN_ATTN);
4288	ics2101_mix_attenuate(ic,
4289			      GUSMIX_CHAN_MASTER,
4290			      ICSMIX_RIGHT,
4291			      ICSMIX_MIN_ATTN);
4292	/* unmute other stuff: */
4293	gusics_cd_mute(ic, 0);
4294	gusics_dac_mute(ic, 0);
4295	gusics_linein_mute(ic, 0);
4296	return;
4297}
4298
4299
4300#endif /* NGUS */
4301