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