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