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