gus.c revision 1.58
1/*	$NetBSD: gus.c,v 1.58 1998/07/02 14:39:51 mycroft 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_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, 0, 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.mute[AD1848_AUX1_CHANNEL] = 0;
1061		ad1848_mute_channel(&sc->sc_codec, AD1848_AUX1_CHANNEL, 0); /* turn on DAC output */
1062		if (flags & FREAD) {
1063			sc->sc_codec.mute[AD1848_MONO_CHANNEL] = 0;
1064			ad1848_mute_channel(&sc->sc_codec, AD1848_MONO_CHANNEL, 0);
1065		}
1066	} else if (flags & FREAD) {
1067		/* enable/unmute the microphone */
1068		if (HAS_MIXER(sc)) {
1069			gusics_mic_mute(&sc->sc_mixer, 0);
1070		} else
1071			gus_mic_ctl(sc, SPKR_ON);
1072	}
1073	if (sc->sc_nbufs == 0)
1074	    gus_round_blocksize(sc, GUS_BUFFER_MULTIPLE); /* default blksiz */
1075	return 0;
1076}
1077
1078int
1079gusmaxopen(addr, flags)
1080	void *addr;
1081	int flags;
1082{
1083	struct ad1848_softc *ac = addr;
1084	return gusopen(ac->parent, flags);
1085}
1086
1087STATIC void
1088gus_deinterleave(sc, buf, size)
1089	struct gus_softc *sc;
1090	void *buf;
1091	int size;
1092{
1093	/* deinterleave the stereo data.  We can use sc->sc_deintr_buf
1094	   for scratch space. */
1095	int i;
1096
1097	if (size > sc->sc_blocksize) {
1098		printf("gus: deinterleave %d > %d\n", size, sc->sc_blocksize);
1099		return;
1100	} else if (size < sc->sc_blocksize) {
1101		DPRINTF(("gus: deinterleave %d < %d\n", size, sc->sc_blocksize));
1102	}
1103
1104	/*
1105	 * size is in bytes.
1106	 */
1107	if (sc->sc_precision == 16) {
1108		u_short *dei = sc->sc_deintr_buf;
1109		u_short *sbuf = buf;
1110		size >>= 1;		/* bytecnt to shortcnt */
1111		/* copy 2nd of each pair of samples to the staging area, while
1112		   compacting the 1st of each pair into the original area. */
1113		for (i = 0; i < size/2-1; i++)  {
1114			dei[i] = sbuf[i*2+1];
1115			sbuf[i+1] = sbuf[i*2+2];
1116		}
1117		/*
1118		 * this has copied one less sample than half of the
1119		 * buffer.  The first sample of the 1st stream was
1120		 * already in place and didn't need copying.
1121		 * Therefore, we've moved all of the 1st stream's
1122		 * samples into place.  We have one sample from 2nd
1123		 * stream in the last slot of original area, not
1124		 * copied to the staging area (But we don't need to!).
1125		 * Copy the remainder of the original stream into place.
1126		 */
1127		bcopy(dei, &sbuf[size/2], i * sizeof(short));
1128	} else {
1129		u_char *dei = sc->sc_deintr_buf;
1130		u_char *sbuf = buf;
1131		for (i = 0; i < size/2-1; i++)  {
1132			dei[i] = sbuf[i*2+1];
1133			sbuf[i+1] = sbuf[i*2+2];
1134		}
1135		bcopy(dei, &sbuf[size/2], i);
1136	}
1137}
1138
1139/*
1140 * Actually output a buffer to the DSP chip
1141 */
1142
1143int
1144gusmax_dma_output(addr, buf, size, intr, arg)
1145	void * addr;
1146	void *buf;
1147	int size;
1148	void (*intr) __P((void *));
1149	void *arg;
1150{
1151	struct ad1848_softc *ac = addr;
1152	return gus_dma_output(ac->parent, buf, size, intr, arg);
1153}
1154
1155/*
1156 * called at splgus() from interrupt handler.
1157 */
1158void
1159stereo_dmaintr(arg)
1160	void *arg;
1161{
1162    struct gus_softc *sc = arg;
1163    struct stereo_dma_intr *sa = &sc->sc_stereo;
1164
1165    DMAPRINTF(("stereo_dmaintr"));
1166
1167    /*
1168     * Put other half in its place, then call the real interrupt routine :)
1169     */
1170
1171    sc->sc_dmaoutintr = sa->intr;
1172    sc->sc_outarg = sa->arg;
1173
1174#ifdef GUSPLAYDEBUG
1175    if (gusstats) {
1176      microtime(&dmarecords[dmarecord_index].tv);
1177      dmarecords[dmarecord_index].gusaddr = sa->dmabuf;
1178      dmarecords[dmarecord_index].bsdaddr = sa->buffer;
1179      dmarecords[dmarecord_index].count = sa->size;
1180      dmarecords[dmarecord_index].channel = 1;
1181      dmarecords[dmarecord_index].direction = 1;
1182      dmarecord_index = ++dmarecord_index % NDMARECS;
1183    }
1184#endif
1185
1186    gusdmaout(sc, sa->flags, sa->dmabuf, (caddr_t) sa->buffer, sa->size);
1187
1188    sa->flags = 0;
1189    sa->dmabuf = 0;
1190    sa->buffer = 0;
1191    sa->size = 0;
1192    sa->intr = 0;
1193    sa->arg = 0;
1194}
1195
1196/*
1197 * Start up DMA output to the card.
1198 * Called at splgus/splaudio already, either from intr handler or from
1199 * generic audio code.
1200 */
1201int
1202gus_dma_output(addr, buf, size, intr, arg)
1203	void * addr;
1204	void *buf;
1205	int size;
1206	void (*intr) __P((void *));
1207	void *arg;
1208{
1209	struct gus_softc *sc = addr;
1210	u_char *buffer = buf;
1211	u_long boarddma;
1212	int flags;
1213
1214	DMAPRINTF(("gus_dma_output %d @ %p\n", size, buf));
1215
1216	if (size != sc->sc_blocksize) {
1217	    DPRINTF(("gus_dma_output reqsize %d not sc_blocksize %d\n",
1218		     size, sc->sc_blocksize));
1219	    return EINVAL;
1220	}
1221
1222	flags = GUSMASK_DMA_WRITE;
1223	if (sc->sc_precision == 16)
1224	    flags |= GUSMASK_DMA_DATA_SIZE;
1225	if (sc->sc_encoding == AUDIO_ENCODING_ULAW ||
1226	    sc->sc_encoding == AUDIO_ENCODING_ALAW ||
1227	    sc->sc_encoding == AUDIO_ENCODING_ULINEAR_BE ||
1228	    sc->sc_encoding == AUDIO_ENCODING_ULINEAR_LE)
1229	    flags |= GUSMASK_DMA_INVBIT;
1230
1231	if (sc->sc_channels == 2) {
1232		if (sc->sc_precision == 16) {
1233			if (size & 3) {
1234				DPRINTF(("gus_dma_output: unpaired 16bit samples"));
1235				size &= 3;
1236			}
1237		} else if (size & 1) {
1238			DPRINTF(("gus_dma_output: unpaired samples"));
1239			size &= 1;
1240		}
1241		if (size == 0)
1242			return 0;
1243
1244		gus_deinterleave(sc, (void *)buffer, size);
1245
1246		size >>= 1;
1247
1248 		boarddma = size * sc->sc_dmabuf + GUS_MEM_OFFSET;
1249
1250		sc->sc_stereo.intr = intr;
1251		sc->sc_stereo.arg = arg;
1252		sc->sc_stereo.size = size;
1253		sc->sc_stereo.dmabuf = boarddma + GUS_LEFT_RIGHT_OFFSET;
1254		sc->sc_stereo.buffer = buffer + size;
1255		sc->sc_stereo.flags = flags;
1256		if (gus_dostereo) {
1257		  intr = stereo_dmaintr;
1258		  arg = sc;
1259		}
1260	} else
1261		boarddma = size * sc->sc_dmabuf + GUS_MEM_OFFSET;
1262
1263
1264	sc->sc_flags |= GUS_LOCKED;
1265	sc->sc_dmaoutintr = intr;
1266	sc->sc_outarg = arg;
1267
1268#ifdef GUSPLAYDEBUG
1269	if (gusstats) {
1270	  microtime(&dmarecords[dmarecord_index].tv);
1271	  dmarecords[dmarecord_index].gusaddr = boarddma;
1272	  dmarecords[dmarecord_index].bsdaddr = buffer;
1273	  dmarecords[dmarecord_index].count = size;
1274	  dmarecords[dmarecord_index].channel = 0;
1275	  dmarecords[dmarecord_index].direction = 1;
1276	  dmarecord_index = ++dmarecord_index % NDMARECS;
1277	}
1278#endif
1279
1280	gusdmaout(sc, flags, boarddma, (caddr_t) buffer, size);
1281
1282	return 0;
1283}
1284
1285void
1286gusmax_close(addr)
1287	void *addr;
1288{
1289	struct ad1848_softc *ac = addr;
1290	struct gus_softc *sc = ac->parent;
1291#if 0
1292	ac->mute[AD1848_AUX1_CHANNEL] = MUTE_ALL;
1293	ad1848_mute_channel(ac, MUTE_ALL); /* turn off DAC output */
1294#endif
1295	ad1848_close(ac);
1296	gusclose(sc);
1297}
1298
1299/*
1300 * Close out device stuff.  Called at splgus() from generic audio layer.
1301 */
1302void
1303gusclose(addr)
1304	void *addr;
1305{
1306	struct gus_softc *sc = addr;
1307
1308        DPRINTF(("gus_close: sc=%p\n", sc));
1309
1310
1311/*	if (sc->sc_flags & GUS_DMAOUT_ACTIVE) */ {
1312		gus_halt_out_dma(sc);
1313	}
1314/*	if (sc->sc_flags & GUS_DMAIN_ACTIVE) */ {
1315		gus_halt_in_dma(sc);
1316	}
1317	sc->sc_flags &= ~(GUS_OPEN|GUS_LOCKED|GUS_DMAOUT_ACTIVE|GUS_DMAIN_ACTIVE);
1318
1319	if (sc->sc_deintr_buf) {
1320		FREE(sc->sc_deintr_buf, M_DEVBUF);
1321		sc->sc_deintr_buf = NULL;
1322	}
1323	/* turn off speaker, etc. */
1324
1325	/* make sure the voices shut up: */
1326	gus_stop_voice(sc, GUS_VOICE_LEFT, 1);
1327	gus_stop_voice(sc, GUS_VOICE_RIGHT, 0);
1328}
1329
1330/*
1331 * Service interrupts.  Farm them off to helper routines if we are using the
1332 * GUS for simple playback/record
1333 */
1334
1335#ifdef DIAGNOSTIC
1336int gusintrcnt;
1337int gusdmaintrcnt;
1338int gusvocintrcnt;
1339#endif
1340
1341int
1342gusintr(arg)
1343	void *arg;
1344{
1345	struct gus_softc *sc = arg;
1346	bus_space_tag_t iot = sc->sc_iot;
1347	bus_space_handle_t ioh1 = sc->sc_ioh1;
1348	bus_space_handle_t ioh2 = sc->sc_ioh2;
1349	unsigned char intr;
1350
1351	int retval = 0;
1352
1353	DPRINTF(("gusintr\n"));
1354#ifdef DIAGNOSTIC
1355	gusintrcnt++;
1356#endif
1357	if (HAS_CODEC(sc))
1358		retval = ad1848_intr(&sc->sc_codec);
1359	if ((intr = bus_space_read_1(iot, ioh1, GUS_IRQ_STATUS)) & GUSMASK_IRQ_DMATC) {
1360		DMAPRINTF(("gusintr dma flags=%x\n", sc->sc_flags));
1361#ifdef DIAGNOSTIC
1362		gusdmaintrcnt++;
1363#endif
1364		retval += gus_dmaout_intr(sc);
1365		if (sc->sc_flags & GUS_DMAIN_ACTIVE) {
1366		    SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
1367		    intr = bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
1368		    if (intr & GUSMASK_SAMPLE_DMATC) {
1369			retval += gus_dmain_intr(sc);
1370		    }
1371		}
1372	}
1373	if (intr & (GUSMASK_IRQ_VOICE | GUSMASK_IRQ_VOLUME)) {
1374		DMAPRINTF(("gusintr voice flags=%x\n", sc->sc_flags));
1375#ifdef DIAGNOSTIC
1376		gusvocintrcnt++;
1377#endif
1378		retval += gus_voice_intr(sc);
1379	}
1380	if (retval)
1381		return 1;
1382	return retval;
1383}
1384
1385int gus_bufcnt[GUS_MEM_FOR_BUFFERS / GUS_BUFFER_MULTIPLE];
1386int gus_restart;				/* how many restarts? */
1387int gus_stops;				/* how many times did voice stop? */
1388int gus_falsestops;			/* stopped but not done? */
1389int gus_continues;
1390
1391struct playcont {
1392	struct timeval tv;
1393	u_int playbuf;
1394	u_int dmabuf;
1395	u_char bufcnt;
1396	u_char vaction;
1397	u_char voccntl;
1398	u_char volcntl;
1399	u_long curaddr;
1400	u_long endaddr;
1401} playstats[NDMARECS];
1402
1403int playcntr;
1404
1405STATIC void
1406gus_dmaout_timeout(arg)
1407 	void *arg;
1408{
1409 	struct gus_softc *sc = arg;
1410 	bus_space_tag_t iot = sc->sc_iot;
1411 	bus_space_handle_t ioh2 = sc->sc_ioh2;
1412 	int s;
1413
1414 	printf("%s: dmaout timeout\n", sc->sc_dev.dv_xname);
1415 	/*
1416 	 * Stop any DMA.
1417 	 */
1418
1419 	s = splgus();
1420 	SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
1421 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0);
1422
1423#if 0
1424 	/* XXX we will dmadone below? */
1425 	isa_dmaabort(sc->sc_dev.dv_parent, sc->sc_drq);
1426#endif
1427
1428 	gus_dmaout_dointr(sc);
1429 	splx(s);
1430}
1431
1432
1433/*
1434 * Service DMA interrupts.  This routine will only get called if we're doing
1435 * a DMA transfer for playback/record requests from the audio layer.
1436 */
1437
1438STATIC int
1439gus_dmaout_intr(sc)
1440	struct gus_softc *sc;
1441{
1442	bus_space_tag_t iot = sc->sc_iot;
1443	bus_space_handle_t ioh2 = sc->sc_ioh2;
1444
1445	/*
1446	 * If we got a DMA transfer complete from the GUS DRAM, then deal
1447	 * with it.
1448	 */
1449
1450	SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
1451 	if (bus_space_read_1(iot, ioh2, GUS_DATA_HIGH) & GUSMASK_DMA_IRQPEND) {
1452	    untimeout(gus_dmaout_timeout, sc);
1453	    gus_dmaout_dointr(sc);
1454	    return 1;
1455	}
1456	return 0;
1457}
1458
1459STATIC void
1460gus_dmaout_dointr(sc)
1461	struct gus_softc *sc;
1462{
1463 	bus_space_tag_t iot = sc->sc_iot;
1464 	bus_space_handle_t ioh2 = sc->sc_ioh2;
1465
1466	/* sc->sc_dmaoutcnt - 1 because DMA controller counts from zero?. */
1467 	isa_dmadone(sc->sc_ic, sc->sc_drq);
1468	sc->sc_flags &= ~GUS_DMAOUT_ACTIVE;  /* pending DMA is done */
1469 	DMAPRINTF(("gus_dmaout_dointr %d @ %p\n", sc->sc_dmaoutcnt,
1470		   sc->sc_dmaoutaddr));
1471
1472	/*
1473	 * to prevent clicking, we need to copy last sample
1474	 * from last buffer to scratch area just before beginning of
1475	 * buffer.  However, if we're doing formats that are converted by
1476	 * the card during the DMA process, we need to pick up the converted
1477	 * byte rather than the one we have in memory.
1478	 */
1479	if (sc->sc_dmabuf == sc->sc_nbufs - 1) {
1480	  int i;
1481	  switch (sc->sc_encoding) {
1482	  case AUDIO_ENCODING_SLINEAR_LE:
1483	  case AUDIO_ENCODING_SLINEAR_BE:
1484	    if (sc->sc_precision == 8)
1485	      goto byte;
1486	    /* we have the native format */
1487	    for (i = 1; i <= 2; i++)
1488	      guspoke(iot, ioh2, sc->sc_gusaddr -
1489		      (sc->sc_nbufs - 1) * sc->sc_chanblocksize - i,
1490		      sc->sc_dmaoutaddr[sc->sc_dmaoutcnt-i]);
1491	    break;
1492	  case AUDIO_ENCODING_ULINEAR_LE:
1493	  case AUDIO_ENCODING_ULINEAR_BE:
1494	    guspoke(iot, ioh2, sc->sc_gusaddr -
1495		    (sc->sc_nbufs - 1) * sc->sc_chanblocksize - 2,
1496		    guspeek(iot, ioh2,
1497			    sc->sc_gusaddr + sc->sc_chanblocksize - 2));
1498	  case AUDIO_ENCODING_ALAW:
1499	  case AUDIO_ENCODING_ULAW:
1500	  byte:
1501	    /* we need to fetch the translated byte, then stuff it. */
1502	    guspoke(iot, ioh2, sc->sc_gusaddr -
1503		    (sc->sc_nbufs - 1) * sc->sc_chanblocksize - 1,
1504		    guspeek(iot, ioh2,
1505			    sc->sc_gusaddr + sc->sc_chanblocksize - 1));
1506	    break;
1507	  }
1508	}
1509	/*
1510	 * If this is the first half of stereo, "ignore" this one
1511	 * and copy out the second half.
1512	 */
1513	if (sc->sc_dmaoutintr == stereo_dmaintr) {
1514	    (*sc->sc_dmaoutintr)(sc->sc_outarg);
1515	    return;
1516	}
1517	/*
1518	 * If the voice is stopped, then start it.  Reset the loop
1519	 * and roll bits.  Call the audio layer routine, since if
1520	 * we're starting a stopped voice, that means that the next
1521	 * buffer can be filled
1522	 */
1523
1524	sc->sc_flags &= ~GUS_LOCKED;
1525	if (sc->sc_voc[GUS_VOICE_LEFT].voccntl &
1526	    GUSMASK_VOICE_STOPPED) {
1527	    if (sc->sc_flags & GUS_PLAYING) {
1528		printf("%s: playing yet stopped?\n", sc->sc_dev.dv_xname);
1529	    }
1530	    sc->sc_bufcnt++; /* another yet to be played */
1531	    gus_start_playing(sc, sc->sc_dmabuf);
1532	    gus_restart++;
1533	} else {
1534	    /*
1535	     * set the sound action based on which buffer we
1536	     * just transferred.  If we just transferred buffer 0
1537	     * we want the sound to loop when it gets to the nth
1538	     * buffer; if we just transferred
1539	     * any other buffer, we want the sound to roll over
1540	     * at least one more time.  The voice interrupt
1541	     * handlers will take care of accounting &
1542	     * setting control bits if it's not caught up to us
1543	     * yet.
1544	     */
1545	    if (++sc->sc_bufcnt == 2) {
1546		/*
1547		 * XXX
1548		 * If we're too slow in reaction here,
1549		 * the voice could be just approaching the
1550		 * end of its run.  It should be set to stop,
1551		 * so these adjustments might not DTRT.
1552		 */
1553		if (sc->sc_dmabuf == 0 &&
1554		    sc->sc_playbuf == sc->sc_nbufs - 1) {
1555		    /* player is just at the last buf, we're at the
1556		       first.  Turn on looping, turn off rolling. */
1557		    sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_LOOP_ENABLE;
1558		    sc->sc_voc[GUS_VOICE_LEFT].volcntl &= ~GUSMASK_VOICE_ROLL;
1559		    playstats[playcntr].vaction = 3;
1560		} else {
1561		    /* player is at previous buf:
1562		       turn on rolling, turn off looping */
1563		    sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~GUSMASK_LOOP_ENABLE;
1564		    sc->sc_voc[GUS_VOICE_LEFT].volcntl |= GUSMASK_VOICE_ROLL;
1565		    playstats[playcntr].vaction = 4;
1566		}
1567#ifdef GUSPLAYDEBUG
1568		if (gusstats) {
1569		  microtime(&playstats[playcntr].tv);
1570		  playstats[playcntr].endaddr = sc->sc_voc[GUS_VOICE_LEFT].end_addr;
1571		  playstats[playcntr].voccntl = sc->sc_voc[GUS_VOICE_LEFT].voccntl;
1572		  playstats[playcntr].volcntl = sc->sc_voc[GUS_VOICE_LEFT].volcntl;
1573		  playstats[playcntr].playbuf = sc->sc_playbuf;
1574		  playstats[playcntr].dmabuf = sc->sc_dmabuf;
1575		  playstats[playcntr].bufcnt = sc->sc_bufcnt;
1576		  playstats[playcntr].curaddr = gus_get_curaddr(sc, GUS_VOICE_LEFT);
1577		  playcntr = ++playcntr % NDMARECS;
1578		}
1579#endif
1580		bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, GUS_VOICE_LEFT);
1581		SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
1582		bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_LEFT].voccntl);
1583		SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
1584		bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_LEFT].volcntl);
1585	    }
1586	}
1587	gus_bufcnt[sc->sc_bufcnt-1]++;
1588	/*
1589	 * flip to the next DMA buffer
1590	 */
1591
1592	sc->sc_dmabuf = ++sc->sc_dmabuf % sc->sc_nbufs;
1593	/*
1594	 * See comments below about DMA admission control strategy.
1595	 * We can call the upper level here if we have an
1596	 * idle buffer (not currently playing) to DMA into.
1597	 */
1598	if (sc->sc_dmaoutintr && sc->sc_bufcnt < sc->sc_nbufs) {
1599	    /* clean out to prevent double calls */
1600	    void (*pfunc) __P((void *)) = sc->sc_dmaoutintr;
1601	    void *arg = sc->sc_outarg;
1602
1603	    sc->sc_outarg = 0;
1604	    sc->sc_dmaoutintr = 0;
1605	    (*pfunc)(arg);
1606	}
1607}
1608
1609/*
1610 * Service voice interrupts
1611 */
1612
1613STATIC int
1614gus_voice_intr(sc)
1615	struct gus_softc *sc;
1616{
1617	bus_space_tag_t iot = sc->sc_iot;
1618	bus_space_handle_t ioh2 = sc->sc_ioh2;
1619	int ignore = 0, voice, rval = 0;
1620	unsigned char intr, status;
1621
1622	/*
1623	 * The point of this may not be obvious at first.  A voice can
1624	 * interrupt more than once; according to the GUS SDK we are supposed
1625	 * to ignore multiple interrupts for the same voice.
1626	 */
1627
1628	while(1) {
1629		SELECT_GUS_REG(iot, ioh2, GUSREG_IRQ_STATUS);
1630		intr = bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
1631
1632		if ((intr & (GUSMASK_WIRQ_VOLUME | GUSMASK_WIRQ_VOICE))
1633			== (GUSMASK_WIRQ_VOLUME | GUSMASK_WIRQ_VOICE))
1634			/*
1635			 * No more interrupts, time to return
1636			 */
1637		 	return rval;
1638
1639		if ((intr & GUSMASK_WIRQ_VOICE) == 0) {
1640
1641		    /*
1642		     * We've got a voice interrupt.  Ignore previous
1643		     * interrupts by the same voice.
1644		     */
1645
1646		    rval = 1;
1647		    voice = intr & GUSMASK_WIRQ_VOICEMASK;
1648
1649		    if ((1 << voice) & ignore)
1650			break;
1651
1652		    ignore |= 1 << voice;
1653
1654		    /*
1655		     * If the voice is stopped, then force it to stop
1656		     * (this stops it from continuously generating IRQs)
1657		     */
1658
1659		    SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL+0x80);
1660		    status = bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
1661		    if (status & GUSMASK_VOICE_STOPPED) {
1662			if (voice != GUS_VOICE_LEFT) {
1663			    DMAPRINTF(("%s: spurious voice %d stop?\n",
1664				       sc->sc_dev.dv_xname, voice));
1665			    gus_stop_voice(sc, voice, 0);
1666			    continue;
1667			}
1668			gus_stop_voice(sc, voice, 1);
1669			/* also kill right voice */
1670			gus_stop_voice(sc, GUS_VOICE_RIGHT, 0);
1671			sc->sc_bufcnt--; /* it finished a buffer */
1672			if (sc->sc_bufcnt > 0) {
1673			    /*
1674			     * probably a race to get here: the voice
1675			     * stopped while the DMA code was just trying to
1676			     * get the next buffer in place.
1677			     * Start the voice again.
1678			     */
1679			    printf("%s: stopped voice not drained? (%x)\n",
1680				   sc->sc_dev.dv_xname, sc->sc_bufcnt);
1681			    gus_falsestops++;
1682
1683			    sc->sc_playbuf = ++sc->sc_playbuf % sc->sc_nbufs;
1684			    gus_start_playing(sc, sc->sc_playbuf);
1685			} else if (sc->sc_bufcnt < 0) {
1686			    panic("%s: negative bufcnt in stopped voice",
1687				  sc->sc_dev.dv_xname);
1688			} else {
1689			    sc->sc_playbuf = -1; /* none are active */
1690			    gus_stops++;
1691			}
1692			/* fall through to callback and admit another
1693			   buffer.... */
1694		    } else if (sc->sc_bufcnt != 0) {
1695			/*
1696			 * This should always be taken if the voice
1697			 * is not stopped.
1698			 */
1699			gus_continues++;
1700			if (gus_continue_playing(sc, voice)) {
1701				/*
1702				 * we shouldn't have continued--active DMA
1703				 * is in the way in the ring, for
1704				 * some as-yet undebugged reason.
1705				 */
1706				gus_stop_voice(sc, GUS_VOICE_LEFT, 1);
1707				/* also kill right voice */
1708				gus_stop_voice(sc, GUS_VOICE_RIGHT, 0);
1709				sc->sc_playbuf = -1;
1710				gus_stops++;
1711			}
1712		    }
1713		    /*
1714		     * call the upper level to send on down another
1715		     * block. We do admission rate control as follows:
1716		     *
1717		     * When starting up output (in the first N
1718		     * blocks), call the upper layer after the DMA is
1719		     * complete (see above in gus_dmaout_intr()).
1720		     *
1721		     * When output is already in progress and we have
1722		     * no more GUS buffers to use for DMA, the DMA
1723		     * output routines do not call the upper layer.
1724		     * Instead, we call the DMA completion routine
1725		     * here, after the voice interrupts indicating
1726		     * that it's finished with a buffer.
1727		     *
1728		     * However, don't call anything here if the DMA
1729		     * output flag is set, (which shouldn't happen)
1730		     * because we'll squish somebody else's DMA if
1731		     * that's the case.  When DMA is done, it will
1732		     * call back if there is a spare buffer.
1733		     */
1734		    if (sc->sc_dmaoutintr && !(sc->sc_flags & GUS_LOCKED)) {
1735			if (sc->sc_dmaoutintr == stereo_dmaintr)
1736			    printf("gusdmaout botch?\n");
1737			else {
1738			    /* clean out to avoid double calls */
1739			    void (*pfunc) __P((void *)) = sc->sc_dmaoutintr;
1740			    void *arg = sc->sc_outarg;
1741
1742			    sc->sc_outarg = 0;
1743			    sc->sc_dmaoutintr = 0;
1744			    (*pfunc)(arg);
1745			}
1746		    }
1747		}
1748
1749		/*
1750		 * Ignore other interrupts for now
1751		 */
1752	}
1753	return 0;
1754}
1755
1756STATIC void
1757gus_start_playing(sc, bufno)
1758	struct gus_softc *sc;
1759	int bufno;
1760{
1761	bus_space_tag_t iot = sc->sc_iot;
1762	bus_space_handle_t ioh2 = sc->sc_ioh2;
1763	/*
1764	 * Start the voices playing, with buffer BUFNO.
1765	 */
1766
1767	/*
1768	 * Loop or roll if we have buffers ready.
1769	 */
1770
1771	if (sc->sc_bufcnt == 1) {
1772		sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~(GUSMASK_LOOP_ENABLE);
1773		sc->sc_voc[GUS_VOICE_LEFT].volcntl &= ~(GUSMASK_VOICE_ROLL);
1774	} else {
1775		if (bufno == sc->sc_nbufs - 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			sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~GUSMASK_LOOP_ENABLE;
1780			sc->sc_voc[GUS_VOICE_LEFT].volcntl |= GUSMASK_VOICE_ROLL;
1781		}
1782	}
1783
1784	bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, GUS_VOICE_LEFT);
1785
1786	SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
1787	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_LEFT].voccntl);
1788
1789	SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
1790	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_LEFT].volcntl);
1791
1792	sc->sc_voc[GUS_VOICE_LEFT].current_addr =
1793		GUS_MEM_OFFSET + sc->sc_chanblocksize * bufno;
1794	sc->sc_voc[GUS_VOICE_LEFT].end_addr =
1795		sc->sc_voc[GUS_VOICE_LEFT].current_addr + sc->sc_chanblocksize - 1;
1796	sc->sc_voc[GUS_VOICE_RIGHT].current_addr =
1797		sc->sc_voc[GUS_VOICE_LEFT].current_addr +
1798		(gus_dostereo && sc->sc_channels == 2 ? GUS_LEFT_RIGHT_OFFSET : 0);
1799	/*
1800	 * set up right channel to just loop forever, no interrupts,
1801	 * starting at the buffer we just filled.  We'll feed it data
1802	 * at the same time as left channel.
1803	 */
1804	sc->sc_voc[GUS_VOICE_RIGHT].voccntl |= GUSMASK_LOOP_ENABLE;
1805	sc->sc_voc[GUS_VOICE_RIGHT].volcntl &= ~(GUSMASK_VOICE_ROLL);
1806
1807#ifdef GUSPLAYDEBUG
1808	if (gusstats) {
1809		microtime(&playstats[playcntr].tv);
1810		playstats[playcntr].curaddr = sc->sc_voc[GUS_VOICE_LEFT].current_addr;
1811
1812		playstats[playcntr].voccntl = sc->sc_voc[GUS_VOICE_LEFT].voccntl;
1813		playstats[playcntr].volcntl = sc->sc_voc[GUS_VOICE_LEFT].volcntl;
1814		playstats[playcntr].endaddr = sc->sc_voc[GUS_VOICE_LEFT].end_addr;
1815		playstats[playcntr].playbuf = bufno;
1816		playstats[playcntr].dmabuf = sc->sc_dmabuf;
1817		playstats[playcntr].bufcnt = sc->sc_bufcnt;
1818		playstats[playcntr].vaction = 5;
1819		playcntr = ++playcntr % NDMARECS;
1820	}
1821#endif
1822
1823	bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, GUS_VOICE_RIGHT);
1824	SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
1825	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_RIGHT].voccntl);
1826	SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
1827	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_RIGHT].volcntl);
1828
1829	gus_start_voice(sc, GUS_VOICE_RIGHT, 0);
1830	gus_start_voice(sc, GUS_VOICE_LEFT, 1);
1831	if (sc->sc_playbuf == -1)
1832		/* mark start of playing */
1833		sc->sc_playbuf = bufno;
1834}
1835
1836STATIC int
1837gus_continue_playing(sc, voice)
1838	struct gus_softc *sc;
1839	int voice;
1840{
1841	bus_space_tag_t iot = sc->sc_iot;
1842	bus_space_handle_t ioh2 = sc->sc_ioh2;
1843
1844	/*
1845	 * stop this voice from interrupting while we work.
1846	 */
1847
1848	SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
1849	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl & ~(GUSMASK_VOICE_IRQ));
1850
1851	/*
1852	 * update playbuf to point to the buffer the hardware just started
1853	 * playing
1854	 */
1855	sc->sc_playbuf = ++sc->sc_playbuf % sc->sc_nbufs;
1856
1857	/*
1858	 * account for buffer just finished
1859	 */
1860	if (--sc->sc_bufcnt == 0) {
1861		DPRINTF(("gus: bufcnt 0 on continuing voice?\n"));
1862	}
1863	if (sc->sc_playbuf == sc->sc_dmabuf && (sc->sc_flags & GUS_LOCKED)) {
1864		printf("%s: continue into active dmabuf?\n", sc->sc_dev.dv_xname);
1865		return 1;
1866	}
1867
1868	/*
1869	 * Select the end of the buffer based on the currently active
1870	 * buffer, [plus extra contiguous buffers (if ready)].
1871	 */
1872
1873	/*
1874	 * set endpoint at end of buffer we just started playing.
1875	 *
1876	 * The total gets -1 because end addrs are one less than you might
1877	 * think (the end_addr is the address of the last sample to play)
1878	 */
1879	gus_set_endaddr(sc, voice, GUS_MEM_OFFSET +
1880			sc->sc_chanblocksize * (sc->sc_playbuf + 1) - 1);
1881
1882	if (sc->sc_bufcnt < 2) {
1883		/*
1884		 * Clear out the loop and roll flags, and rotate the currently
1885		 * playing buffer.  That way, if we don't manage to get more
1886		 * data before this buffer finishes, we'll just stop.
1887		 */
1888		sc->sc_voc[voice].voccntl &= ~GUSMASK_LOOP_ENABLE;
1889		sc->sc_voc[voice].volcntl &= ~GUSMASK_VOICE_ROLL;
1890		playstats[playcntr].vaction = 0;
1891	} else {
1892		/*
1893		 * We have some buffers to play.  set LOOP if we're on the
1894		 * last buffer in the ring, otherwise set ROLL.
1895		 */
1896		if (sc->sc_playbuf == sc->sc_nbufs - 1) {
1897			sc->sc_voc[voice].voccntl |= GUSMASK_LOOP_ENABLE;
1898			sc->sc_voc[voice].volcntl &= ~GUSMASK_VOICE_ROLL;
1899			playstats[playcntr].vaction = 1;
1900		} else {
1901			sc->sc_voc[voice].voccntl &= ~GUSMASK_LOOP_ENABLE;
1902			sc->sc_voc[voice].volcntl |= GUSMASK_VOICE_ROLL;
1903			playstats[playcntr].vaction = 2;
1904		}
1905	}
1906#ifdef GUSPLAYDEBUG
1907	if (gusstats) {
1908		microtime(&playstats[playcntr].tv);
1909		playstats[playcntr].curaddr = gus_get_curaddr(sc, voice);
1910
1911		playstats[playcntr].voccntl = sc->sc_voc[voice].voccntl;
1912		playstats[playcntr].volcntl = sc->sc_voc[voice].volcntl;
1913		playstats[playcntr].endaddr = sc->sc_voc[voice].end_addr;
1914		playstats[playcntr].playbuf = sc->sc_playbuf;
1915		playstats[playcntr].dmabuf = sc->sc_dmabuf;
1916		playstats[playcntr].bufcnt = sc->sc_bufcnt;
1917		playcntr = ++playcntr % NDMARECS;
1918	}
1919#endif
1920
1921	/*
1922	 * (re-)set voice parameters.  This will reenable interrupts from this
1923	 * voice.
1924	 */
1925
1926	SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
1927	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
1928	SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
1929	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].volcntl);
1930	return 0;
1931}
1932
1933/*
1934 * Send/receive data into GUS's DRAM using DMA.  Called at splgus()
1935 */
1936
1937STATIC void
1938gusdmaout(sc, flags, gusaddr, buffaddr, length)
1939	struct gus_softc *sc;
1940	int flags, length;
1941	u_long gusaddr;
1942	caddr_t buffaddr;
1943{
1944	unsigned char c = (unsigned char) flags;
1945	bus_space_tag_t iot = sc->sc_iot;
1946	bus_space_handle_t ioh2 = sc->sc_ioh2;
1947
1948	DMAPRINTF(("gusdmaout flags=%x scflags=%x\n", flags, sc->sc_flags));
1949
1950	sc->sc_gusaddr = gusaddr;
1951
1952	/*
1953	 * If we're using a 16 bit DMA channel, we have to jump through some
1954	 * extra hoops; this includes translating the DRAM address a bit
1955	 */
1956
1957	if (sc->sc_drq >= 4) {
1958		c |= GUSMASK_DMA_WIDTH;
1959		gusaddr = convert_to_16bit(gusaddr);
1960	}
1961
1962	/*
1963	 * Add flag bits that we always set - fast DMA, enable IRQ
1964	 */
1965
1966	c |= GUSMASK_DMA_ENABLE | GUSMASK_DMA_R0 | GUSMASK_DMA_IRQ;
1967
1968	/*
1969	 * Make sure the GUS _isn't_ setup for DMA
1970	 */
1971
1972 	SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
1973	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0);
1974
1975	/*
1976	 * Tell the PC DMA controller to start doing DMA
1977	 */
1978
1979	sc->sc_dmaoutaddr = (u_char *) buffaddr;
1980	sc->sc_dmaoutcnt = length;
1981 	isa_dmastart(sc->sc_ic, sc->sc_drq, buffaddr, length,
1982 	    NULL, DMAMODE_WRITE, BUS_DMA_NOWAIT);
1983
1984	/*
1985	 * Set up DMA address - use the upper 16 bits ONLY
1986	 */
1987
1988	sc->sc_flags |= GUS_DMAOUT_ACTIVE;
1989
1990 	SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_START);
1991 	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, (int) (gusaddr >> 4));
1992
1993 	/*
1994 	 * Tell the GUS to start doing DMA
1995 	 */
1996
1997 	SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
1998	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, c);
1999
2000	/*
2001	 * XXX If we don't finish in one second, give up...
2002	 */
2003	untimeout(gus_dmaout_timeout, sc); /* flush old one, if there is one */
2004	timeout(gus_dmaout_timeout, sc, hz);
2005}
2006
2007/*
2008 * Start a voice playing on the GUS.  Called from interrupt handler at
2009 * splgus().
2010 */
2011
2012STATIC void
2013gus_start_voice(sc, voice, intrs)
2014	struct gus_softc *sc;
2015	int voice;
2016	int intrs;
2017{
2018	bus_space_tag_t iot = sc->sc_iot;
2019	bus_space_handle_t ioh2 = sc->sc_ioh2;
2020	u_long start;
2021	u_long current;
2022	u_long end;
2023
2024	/*
2025	 * Pick all the values for the voice out of the gus_voice struct
2026	 * and use those to program the voice
2027	 */
2028
2029 	start = sc->sc_voc[voice].start_addr;
2030 	current = sc->sc_voc[voice].current_addr;
2031 	end = sc->sc_voc[voice].end_addr;
2032
2033 	/*
2034	 * If we're using 16 bit data, mangle the addresses a bit
2035	 */
2036
2037	if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16) {
2038	        /* -1 on start so that we get onto sample boundary--other
2039		   code always sets it for 1-byte rollover protection */
2040		start = convert_to_16bit(start-1);
2041		current = convert_to_16bit(current);
2042		end = convert_to_16bit(end);
2043	}
2044
2045	/*
2046	 * Select the voice we want to use, and program the data addresses
2047	 */
2048
2049	bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
2050
2051	SELECT_GUS_REG(iot, ioh2, GUSREG_START_ADDR_HIGH);
2052	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(start));
2053	SELECT_GUS_REG(iot, ioh2, GUSREG_START_ADDR_LOW);
2054	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(start));
2055
2056	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH);
2057	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(current));
2058	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW);
2059	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(current));
2060
2061	SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_HIGH);
2062	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(end));
2063	SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_LOW);
2064	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(end));
2065
2066	/*
2067	 * (maybe) enable interrupts, disable voice stopping
2068	 */
2069
2070	if (intrs) {
2071		sc->sc_flags |= GUS_PLAYING; /* playing is about to start */
2072		sc->sc_voc[voice].voccntl |= GUSMASK_VOICE_IRQ;
2073		DMAPRINTF(("gus voice playing=%x\n", sc->sc_flags));
2074	} else
2075		sc->sc_voc[voice].voccntl &= ~GUSMASK_VOICE_IRQ;
2076	sc->sc_voc[voice].voccntl &= ~(GUSMASK_VOICE_STOPPED |
2077		GUSMASK_STOP_VOICE);
2078
2079	/*
2080	 * Tell the GUS about it.  Note that we're doing volume ramping here
2081	 * from 0 up to the set volume to help reduce clicks.
2082	 */
2083
2084	SELECT_GUS_REG(iot, ioh2, GUSREG_START_VOLUME);
2085	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
2086	SELECT_GUS_REG(iot, ioh2, GUSREG_END_VOLUME);
2087	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].current_volume >> 4);
2088	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME);
2089	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x00);
2090	SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_RATE);
2091	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 63);
2092
2093	SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
2094	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
2095	SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
2096	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
2097	delay(50);
2098	SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
2099	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
2100	SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
2101	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
2102
2103}
2104
2105/*
2106 * Stop a given voice.  called at splgus()
2107 */
2108
2109STATIC void
2110gus_stop_voice(sc, voice, intrs_too)
2111	struct gus_softc *sc;
2112	int voice;
2113	int intrs_too;
2114{
2115	bus_space_tag_t iot = sc->sc_iot;
2116	bus_space_handle_t ioh2 = sc->sc_ioh2;
2117
2118	sc->sc_voc[voice].voccntl |= GUSMASK_VOICE_STOPPED |
2119		GUSMASK_STOP_VOICE;
2120	if (intrs_too) {
2121	  sc->sc_voc[voice].voccntl &= ~(GUSMASK_VOICE_IRQ);
2122	  /* no more DMA to do */
2123	  sc->sc_flags &= ~GUS_PLAYING;
2124	}
2125	DMAPRINTF(("gusintr voice notplaying=%x\n", sc->sc_flags));
2126
2127	guspoke(iot, ioh2, 0L, 0);
2128
2129	bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
2130
2131	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME);
2132	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2133	SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
2134	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
2135	delay(100);
2136	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME);
2137	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2138	SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
2139	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
2140
2141	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH);
2142	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2143	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW);
2144	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2145
2146}
2147
2148
2149/*
2150 * Set the volume of a given voice.  Called at splgus().
2151 */
2152STATIC void
2153gus_set_volume(sc, voice, volume)
2154	struct gus_softc *sc;
2155	int voice, volume;
2156{
2157	bus_space_tag_t iot = sc->sc_iot;
2158	bus_space_handle_t ioh2 = sc->sc_ioh2;
2159	unsigned int gusvol;
2160
2161	gusvol = gus_log_volumes[volume < 512 ? volume : 511];
2162
2163	sc->sc_voc[voice].current_volume = gusvol;
2164
2165	bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
2166
2167	SELECT_GUS_REG(iot, ioh2, GUSREG_START_VOLUME);
2168	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (unsigned char) (gusvol >> 4));
2169
2170	SELECT_GUS_REG(iot, ioh2, GUSREG_END_VOLUME);
2171	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (unsigned char) (gusvol >> 4));
2172
2173	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME);
2174	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, gusvol << 4);
2175	delay(500);
2176	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, gusvol << 4);
2177
2178}
2179
2180/*
2181 * Interface to the audio layer.
2182 */
2183
2184int
2185gusmax_set_params(addr, setmode, usemode, p, r)
2186	void *addr;
2187	int setmode, usemode;
2188	struct audio_params *p, *r;
2189{
2190	struct ad1848_softc *ac = addr;
2191	struct gus_softc *sc = ac->parent;
2192	int error;
2193
2194	error = ad1848_set_params(ac, setmode, usemode, p, r);
2195	if (error)
2196		return error;
2197	error = gus_set_params(sc, setmode, usemode, p, r);
2198	return error;
2199}
2200
2201int
2202gus_set_params(addr, setmode, usemode, p, r)
2203	void *addr;
2204	int setmode, usemode;
2205	struct audio_params *p, *r;
2206{
2207	struct gus_softc *sc = addr;
2208	int s;
2209
2210	switch (p->encoding) {
2211	case AUDIO_ENCODING_ULAW:
2212	case AUDIO_ENCODING_ALAW:
2213	case AUDIO_ENCODING_SLINEAR_LE:
2214	case AUDIO_ENCODING_ULINEAR_LE:
2215	case AUDIO_ENCODING_SLINEAR_BE:
2216	case AUDIO_ENCODING_ULINEAR_BE:
2217		break;
2218	default:
2219		return (EINVAL);
2220	}
2221
2222	s = splaudio();
2223
2224	if (p->precision == 8) {
2225		sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~GUSMASK_DATA_SIZE16;
2226		sc->sc_voc[GUS_VOICE_RIGHT].voccntl &= ~GUSMASK_DATA_SIZE16;
2227	} else {
2228		sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_DATA_SIZE16;
2229		sc->sc_voc[GUS_VOICE_RIGHT].voccntl |= GUSMASK_DATA_SIZE16;
2230	}
2231
2232	sc->sc_encoding = p->encoding;
2233	sc->sc_precision = p->precision;
2234	sc->sc_channels = p->channels;
2235
2236	splx(s);
2237
2238	if (p->sample_rate > gus_max_frequency[sc->sc_voices - GUS_MIN_VOICES])
2239		p->sample_rate = gus_max_frequency[sc->sc_voices - GUS_MIN_VOICES];
2240	if (setmode & AUMODE_RECORD)
2241		sc->sc_irate = p->sample_rate;
2242	if (setmode & AUMODE_PLAY)
2243		sc->sc_orate = p->sample_rate;
2244
2245	switch (p->encoding) {
2246	case AUDIO_ENCODING_ULAW:
2247		p->sw_code = mulaw_to_ulinear8;
2248		r->sw_code = ulinear8_to_mulaw;
2249		break;
2250	case AUDIO_ENCODING_ALAW:
2251		p->sw_code = alaw_to_ulinear8;
2252		r->sw_code = ulinear8_to_alaw;
2253		break;
2254	case AUDIO_ENCODING_ULINEAR_BE:
2255	case AUDIO_ENCODING_SLINEAR_BE:
2256		r->sw_code = p->sw_code = swap_bytes;
2257		break;
2258	}
2259
2260	return 0;
2261}
2262
2263/*
2264 * Interface to the audio layer - set the blocksize to the correct number
2265 * of units
2266 */
2267
2268int
2269gusmax_round_blocksize(addr, blocksize)
2270	void * addr;
2271	int blocksize;
2272{
2273	struct ad1848_softc *ac = addr;
2274	struct gus_softc *sc = ac->parent;
2275
2276/*	blocksize = ad1848_round_blocksize(ac, blocksize);*/
2277	return gus_round_blocksize(sc, blocksize);
2278}
2279
2280int
2281gus_round_blocksize(addr, blocksize)
2282	void * addr;
2283	int blocksize;
2284{
2285	struct gus_softc *sc = addr;
2286
2287	DPRINTF(("gus_round_blocksize called\n"));
2288
2289	if ((sc->sc_encoding == AUDIO_ENCODING_ULAW ||
2290	     sc->sc_encoding == AUDIO_ENCODING_ALAW) && blocksize > 32768)
2291		blocksize = 32768;
2292	else if (blocksize > 65536)
2293		blocksize = 65536;
2294
2295	if ((blocksize % GUS_BUFFER_MULTIPLE) != 0)
2296		blocksize = (blocksize / GUS_BUFFER_MULTIPLE + 1) *
2297			GUS_BUFFER_MULTIPLE;
2298
2299	/* set up temporary buffer to hold the deinterleave, if necessary
2300	   for stereo output */
2301	if (sc->sc_deintr_buf) {
2302		FREE(sc->sc_deintr_buf, M_DEVBUF);
2303		sc->sc_deintr_buf = NULL;
2304	}
2305	MALLOC(sc->sc_deintr_buf, void *, blocksize>>1, M_DEVBUF, M_WAITOK);
2306
2307	sc->sc_blocksize = blocksize;
2308	/* multi-buffering not quite working yet. */
2309	sc->sc_nbufs = /*GUS_MEM_FOR_BUFFERS / blocksize*/ 2;
2310
2311	gus_set_chan_addrs(sc);
2312
2313	return blocksize;
2314}
2315
2316int
2317gus_get_out_gain(addr)
2318	caddr_t addr;
2319{
2320	struct gus_softc *sc = (struct gus_softc *) addr;
2321
2322	DPRINTF(("gus_get_out_gain called\n"));
2323	return sc->sc_ogain / 2;
2324}
2325
2326STATIC inline void gus_set_voices(sc, voices)
2327struct gus_softc *sc;
2328int voices;
2329{
2330	bus_space_tag_t iot = sc->sc_iot;
2331	bus_space_handle_t ioh2 = sc->sc_ioh2;
2332	/*
2333	 * Select the active number of voices
2334	 */
2335
2336	SELECT_GUS_REG(iot, ioh2, GUSREG_ACTIVE_VOICES);
2337	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (voices-1) | 0xc0);
2338
2339	sc->sc_voices = voices;
2340}
2341
2342/*
2343 * Actually set the settings of various values on the card
2344 */
2345
2346int
2347gusmax_commit_settings(addr)
2348	void * addr;
2349{
2350	struct ad1848_softc *ac = addr;
2351	struct gus_softc *sc = ac->parent;
2352	int error;
2353
2354	error = ad1848_commit_settings(ac);
2355	if (error)
2356		return error;
2357	return gus_commit_settings(sc);
2358}
2359
2360/*
2361 * Commit the settings.  Called at normal IPL.
2362 */
2363int
2364gus_commit_settings(addr)
2365	void * addr;
2366{
2367	struct gus_softc *sc = addr;
2368	int s;
2369
2370	DPRINTF(("gus_commit_settings called (gain = %d)\n",sc->sc_ogain));
2371
2372
2373	s = splgus();
2374
2375	gus_set_recrate(sc, sc->sc_irate);
2376	gus_set_volume(sc, GUS_VOICE_LEFT, sc->sc_ogain);
2377	gus_set_volume(sc, GUS_VOICE_RIGHT, sc->sc_ogain);
2378	gus_set_samprate(sc, GUS_VOICE_LEFT, sc->sc_orate);
2379	gus_set_samprate(sc, GUS_VOICE_RIGHT, sc->sc_orate);
2380	splx(s);
2381	gus_set_chan_addrs(sc);
2382
2383	return 0;
2384}
2385
2386STATIC void
2387gus_set_chan_addrs(sc)
2388struct gus_softc *sc;
2389{
2390	/*
2391	 * We use sc_nbufs * blocksize bytes of storage in the on-board GUS
2392	 * ram.
2393	 * For mono, each of the sc_nbufs buffers is DMA'd to in one chunk,
2394	 * and both left & right channels play the same buffer.
2395	 *
2396	 * For stereo, each channel gets a contiguous half of the memory,
2397	 * and each has sc_nbufs buffers of size blocksize/2.
2398	 * Stereo data are deinterleaved in main memory before the DMA out
2399	 * routines are called to queue the output.
2400	 *
2401	 * The blocksize per channel is kept in sc_chanblocksize.
2402	 */
2403	if (sc->sc_channels == 2)
2404	    sc->sc_chanblocksize = sc->sc_blocksize/2;
2405	else
2406	    sc->sc_chanblocksize = sc->sc_blocksize;
2407
2408	sc->sc_voc[GUS_VOICE_LEFT].start_addr = GUS_MEM_OFFSET - 1;
2409	sc->sc_voc[GUS_VOICE_RIGHT].start_addr =
2410	    (gus_dostereo && sc->sc_channels == 2 ? GUS_LEFT_RIGHT_OFFSET : 0)
2411	      + GUS_MEM_OFFSET - 1;
2412	sc->sc_voc[GUS_VOICE_RIGHT].current_addr =
2413	    sc->sc_voc[GUS_VOICE_RIGHT].start_addr + 1;
2414	sc->sc_voc[GUS_VOICE_RIGHT].end_addr =
2415	    sc->sc_voc[GUS_VOICE_RIGHT].start_addr +
2416	    sc->sc_nbufs * sc->sc_chanblocksize;
2417
2418}
2419
2420/*
2421 * Set the sample rate of the given voice.  Called at splgus().
2422 */
2423
2424STATIC void
2425gus_set_samprate(sc, voice, freq)
2426	struct gus_softc *sc;
2427	int voice, freq;
2428{
2429	bus_space_tag_t iot = sc->sc_iot;
2430	bus_space_handle_t ioh2 = sc->sc_ioh2;
2431	unsigned int fc;
2432	u_long temp, f = (u_long) freq;
2433
2434	/*
2435	 * calculate fc based on the number of active voices;
2436	 * we need to use longs to preserve enough bits
2437	 */
2438
2439	temp = (u_long) gus_max_frequency[sc->sc_voices-GUS_MIN_VOICES];
2440
2441 	fc = (unsigned int)(((f << 9L) + (temp >> 1L)) / temp);
2442
2443 	fc <<= 1;
2444
2445
2446	/*
2447	 * Program the voice frequency, and set it in the voice data record
2448	 */
2449
2450	bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
2451	SELECT_GUS_REG(iot, ioh2, GUSREG_FREQ_CONTROL);
2452	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, fc);
2453
2454	sc->sc_voc[voice].rate = freq;
2455
2456}
2457
2458/*
2459 * Set the sample rate of the recording frequency.  Formula is from the GUS
2460 * SDK.  Called at splgus().
2461 */
2462
2463STATIC void
2464gus_set_recrate(sc, rate)
2465	struct gus_softc *sc;
2466	u_long rate;
2467{
2468	bus_space_tag_t iot = sc->sc_iot;
2469	bus_space_handle_t ioh2 = sc->sc_ioh2;
2470	u_char realrate;
2471	DPRINTF(("gus_set_recrate %lu\n", rate));
2472
2473#if 0
2474	realrate = 9878400/(16*(rate+2)); /* formula from GUS docs */
2475#endif
2476	realrate = (9878400 >> 4)/rate - 2; /* formula from code, sigh. */
2477
2478	SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_FREQ);
2479 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, realrate);
2480}
2481
2482/*
2483 * Interface to the audio layer - turn the output on or off.  Note that some
2484 * of these bits are flipped in the register
2485 */
2486
2487int
2488gusmax_speaker_ctl(addr, newstate)
2489	void * addr;
2490	int newstate;
2491{
2492	struct ad1848_softc *sc = addr;
2493	return gus_speaker_ctl(sc->parent, newstate);
2494}
2495
2496int
2497gus_speaker_ctl(addr, newstate)
2498	void * addr;
2499	int newstate;
2500{
2501	struct gus_softc *sc = (struct gus_softc *) addr;
2502	bus_space_tag_t iot = sc->sc_iot;
2503	bus_space_handle_t ioh1 = sc->sc_ioh1;
2504
2505	/* Line out bit is flipped: 0 enables, 1 disables */
2506	if ((newstate == SPKR_ON) &&
2507	    (sc->sc_mixcontrol & GUSMASK_LINE_OUT)) {
2508		sc->sc_mixcontrol &= ~GUSMASK_LINE_OUT;
2509		bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
2510	}
2511	if ((newstate == SPKR_OFF) &&
2512	    (sc->sc_mixcontrol & GUSMASK_LINE_OUT) == 0) {
2513		sc->sc_mixcontrol |= GUSMASK_LINE_OUT;
2514		bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
2515	}
2516
2517	return 0;
2518}
2519
2520STATIC int
2521gus_linein_ctl(addr, newstate)
2522	void * addr;
2523	int newstate;
2524{
2525	struct gus_softc *sc = (struct gus_softc *) addr;
2526	bus_space_tag_t iot = sc->sc_iot;
2527	bus_space_handle_t ioh1 = sc->sc_ioh1;
2528
2529	/* Line in bit is flipped: 0 enables, 1 disables */
2530	if ((newstate == SPKR_ON) &&
2531	    (sc->sc_mixcontrol & GUSMASK_LINE_IN)) {
2532		sc->sc_mixcontrol &= ~GUSMASK_LINE_IN;
2533		bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
2534	}
2535	if ((newstate == SPKR_OFF) &&
2536	    (sc->sc_mixcontrol & GUSMASK_LINE_IN) == 0) {
2537		sc->sc_mixcontrol |= GUSMASK_LINE_IN;
2538		bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
2539	}
2540
2541	return 0;
2542}
2543
2544STATIC int
2545gus_mic_ctl(addr, newstate)
2546	void * addr;
2547	int newstate;
2548{
2549	struct gus_softc *sc = (struct gus_softc *) addr;
2550	bus_space_tag_t iot = sc->sc_iot;
2551	bus_space_handle_t ioh1 = sc->sc_ioh1;
2552
2553	/* Mic bit is normal: 1 enables, 0 disables */
2554	if ((newstate == SPKR_ON) &&
2555	    (sc->sc_mixcontrol & GUSMASK_MIC_IN) == 0) {
2556		sc->sc_mixcontrol |= GUSMASK_MIC_IN;
2557		bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
2558	}
2559	if ((newstate == SPKR_OFF) &&
2560	    (sc->sc_mixcontrol & GUSMASK_MIC_IN)) {
2561		sc->sc_mixcontrol &= ~GUSMASK_MIC_IN;
2562		bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
2563	}
2564
2565	return 0;
2566}
2567
2568/*
2569 * Set the end address of a give voice.  Called at splgus()
2570 */
2571
2572STATIC void
2573gus_set_endaddr(sc, voice, addr)
2574	struct gus_softc *sc;
2575	int voice;
2576	u_long addr;
2577{
2578	bus_space_tag_t iot = sc->sc_iot;
2579	bus_space_handle_t ioh2 = sc->sc_ioh2;
2580
2581	sc->sc_voc[voice].end_addr = addr;
2582
2583	if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16)
2584		addr = convert_to_16bit(addr);
2585
2586	SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_HIGH);
2587	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(addr));
2588	SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_LOW);
2589	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(addr));
2590
2591}
2592
2593#ifdef GUSPLAYDEBUG
2594/*
2595 * Set current address.  called at splgus()
2596 */
2597STATIC void
2598gus_set_curaddr(sc, voice, addr)
2599	struct gus_softc *sc;
2600	int voice;
2601	u_long addr;
2602{
2603	bus_space_tag_t iot = sc->sc_iot;
2604	bus_space_handle_t ioh2 = sc->sc_ioh2;
2605
2606	sc->sc_voc[voice].current_addr = addr;
2607
2608	if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16)
2609		addr = convert_to_16bit(addr);
2610
2611	bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
2612
2613	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH);
2614	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(addr));
2615	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW);
2616	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(addr));
2617
2618}
2619
2620/*
2621 * Get current GUS playback address.  Called at splgus().
2622 */
2623STATIC u_long
2624gus_get_curaddr(sc, voice)
2625	struct gus_softc *sc;
2626	int voice;
2627{
2628	bus_space_tag_t iot = sc->sc_iot;
2629	bus_space_handle_t ioh2 = sc->sc_ioh2;
2630	u_long addr;
2631
2632	bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
2633	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH|GUSREG_READ);
2634	addr = (bus_space_read_2(iot, ioh2, GUS_DATA_LOW) & 0x1fff) << 7;
2635	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW|GUSREG_READ);
2636	addr |= (bus_space_read_2(iot, ioh2, GUS_DATA_LOW) >> 9L) & 0x7f;
2637
2638	if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16)
2639	    addr = (addr & 0xc0000) | ((addr & 0x1ffff) << 1); /* undo 16-bit change */
2640	DPRINTF(("gus voice %d curaddr %ld end_addr %ld\n",
2641		 voice, addr, sc->sc_voc[voice].end_addr));
2642	/* XXX sanity check the address? */
2643
2644	return(addr);
2645}
2646#endif
2647
2648/*
2649 * Convert an address value to a "16 bit" value - why this is necessary I
2650 * have NO idea
2651 */
2652
2653STATIC u_long
2654convert_to_16bit(address)
2655	u_long address;
2656{
2657	u_long old_address;
2658
2659	old_address = address;
2660	address >>= 1;
2661	address &= 0x0001ffffL;
2662	address |= (old_address & 0x000c0000L);
2663
2664	return (address);
2665}
2666
2667/*
2668 * Write a value into the GUS's DRAM
2669 */
2670
2671STATIC void
2672guspoke(iot, ioh2, address, value)
2673	bus_space_tag_t iot;
2674	bus_space_handle_t ioh2;
2675	long address;
2676	unsigned char value;
2677{
2678
2679	/*
2680	 * Select the DRAM address
2681	 */
2682
2683 	SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_LOW);
2684 	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, (unsigned int) (address & 0xffff));
2685 	SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_HIGH);
2686 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (unsigned char) ((address >> 16) & 0xff));
2687
2688	/*
2689	 * Actually write the data
2690	 */
2691
2692	bus_space_write_1(iot, ioh2, GUS_DRAM_DATA, value);
2693}
2694
2695/*
2696 * Read a value from the GUS's DRAM
2697 */
2698
2699STATIC unsigned char
2700guspeek(iot, ioh2, address)
2701	bus_space_tag_t iot;
2702	bus_space_handle_t ioh2;
2703	u_long address;
2704{
2705
2706	/*
2707	 * Select the DRAM address
2708	 */
2709
2710 	SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_LOW);
2711 	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, (unsigned int) (address & 0xffff));
2712 	SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_HIGH);
2713 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (unsigned char) ((address >> 16) & 0xff));
2714
2715	/*
2716	 * Read in the data from the board
2717	 */
2718
2719	return (unsigned char) bus_space_read_1(iot, ioh2, GUS_DRAM_DATA);
2720}
2721
2722/*
2723 * Reset the Gravis UltraSound card, completely
2724 */
2725
2726STATIC void
2727gusreset(sc, voices)
2728	struct gus_softc *sc;
2729	int voices;
2730{
2731	bus_space_tag_t iot = sc->sc_iot;
2732	bus_space_handle_t ioh1 = sc->sc_ioh1;
2733	bus_space_handle_t ioh2 = sc->sc_ioh2;
2734	bus_space_handle_t ioh4 = sc->sc_ioh4;
2735	int i,s;
2736
2737	s = splgus();
2738
2739	/*
2740	 * Reset the GF1 chip
2741	 */
2742
2743	SELECT_GUS_REG(iot, ioh2, GUSREG_RESET);
2744	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
2745
2746	delay(500);
2747
2748	/*
2749	 * Release reset
2750	 */
2751
2752	SELECT_GUS_REG(iot, ioh2, GUSREG_RESET);
2753	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, GUSMASK_MASTER_RESET);
2754
2755	delay(500);
2756
2757	/*
2758	 * Reset MIDI port as well
2759	 */
2760
2761	bus_space_write_1(iot, ioh4, GUS_MIDI_CONTROL, MIDI_RESET);
2762
2763	delay(500);
2764
2765	bus_space_write_1(iot, ioh4, GUS_MIDI_CONTROL, 0x00);
2766
2767	/*
2768	 * Clear interrupts
2769	 */
2770
2771	SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
2772	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
2773	SELECT_GUS_REG(iot, ioh2, GUSREG_TIMER_CONTROL);
2774	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
2775	SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
2776	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
2777
2778	gus_set_voices(sc, voices);
2779
2780	bus_space_read_1(iot, ioh1, GUS_IRQ_STATUS);
2781	SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
2782	bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
2783	SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
2784	bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
2785	SELECT_GUS_REG(iot, ioh2, GUSREG_IRQ_STATUS);
2786	bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
2787
2788	/*
2789	 * Reset voice specific information
2790	 */
2791
2792	for(i = 0; i < voices; i++) {
2793		bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) i);
2794
2795		SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
2796
2797		sc->sc_voc[i].voccntl = GUSMASK_VOICE_STOPPED |
2798			GUSMASK_STOP_VOICE;
2799
2800		bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[i].voccntl);
2801
2802		sc->sc_voc[i].volcntl = GUSMASK_VOLUME_STOPPED |
2803				GUSMASK_STOP_VOLUME;
2804
2805		SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
2806		bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[i].volcntl);
2807
2808		delay(100);
2809
2810		gus_set_samprate(sc, i, 8000);
2811		SELECT_GUS_REG(iot, ioh2, GUSREG_START_ADDR_HIGH);
2812		bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2813		SELECT_GUS_REG(iot, ioh2, GUSREG_START_ADDR_LOW);
2814		bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2815		SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_HIGH);
2816		bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2817		SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_LOW);
2818		bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2819		SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_RATE);
2820		bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x01);
2821		SELECT_GUS_REG(iot, ioh2, GUSREG_START_VOLUME);
2822		bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x10);
2823		SELECT_GUS_REG(iot, ioh2, GUSREG_END_VOLUME);
2824		bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0xe0);
2825		SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME);
2826		bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2827
2828		SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH);
2829		bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2830		SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW);
2831		bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2832		SELECT_GUS_REG(iot, ioh2, GUSREG_PAN_POS);
2833		bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x07);
2834	}
2835
2836	/*
2837	 * Clear out any pending IRQs
2838	 */
2839
2840	bus_space_read_1(iot, ioh1, GUS_IRQ_STATUS);
2841	SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
2842	bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
2843	SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
2844	bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
2845	SELECT_GUS_REG(iot, ioh2, GUSREG_IRQ_STATUS);
2846	bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
2847
2848	SELECT_GUS_REG(iot, ioh2, GUSREG_RESET);
2849	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, GUSMASK_MASTER_RESET | GUSMASK_DAC_ENABLE |
2850		GUSMASK_IRQ_ENABLE);
2851
2852	splx(s);
2853}
2854
2855
2856STATIC int
2857gus_init_cs4231(sc)
2858	struct gus_softc *sc;
2859{
2860	bus_space_tag_t iot = sc->sc_iot;
2861	bus_space_handle_t ioh1 = sc->sc_ioh1;
2862	int port = sc->sc_iobase;
2863	u_char ctrl;
2864
2865	ctrl = (port & 0xf0) >> 4;	/* set port address middle nibble */
2866	/*
2867	 * The codec is a bit weird--swapped dma channels.
2868	 */
2869	ctrl |= GUS_MAX_CODEC_ENABLE;
2870	if (sc->sc_drq >= 4)
2871		ctrl |= GUS_MAX_RECCHAN16;
2872	if (sc->sc_recdrq >= 4)
2873		ctrl |= GUS_MAX_PLAYCHAN16;
2874
2875	bus_space_write_1(iot, ioh1, GUS_MAX_CTRL, ctrl);
2876
2877	sc->sc_codec.sc_iot = sc->sc_iot;
2878	sc->sc_codec.sc_iobase = port+GUS_MAX_CODEC_BASE;
2879
2880	if (ad1848_mapprobe(&sc->sc_codec, sc->sc_codec.sc_iobase) == 0) {
2881		sc->sc_flags &= ~GUS_CODEC_INSTALLED;
2882		return (0);
2883	} else {
2884		struct ad1848_volume vol = {AUDIO_MAX_GAIN, AUDIO_MAX_GAIN};
2885		sc->sc_flags |= GUS_CODEC_INSTALLED;
2886		sc->sc_codec.parent = sc;
2887		sc->sc_codec.sc_drq = sc->sc_recdrq;
2888		sc->sc_codec.sc_recdrq = sc->sc_drq;
2889		gus_hw_if = gusmax_hw_if;
2890		/* enable line in and mic in the GUS mixer; the codec chip
2891		   will do the real mixing for them. */
2892		sc->sc_mixcontrol &= ~GUSMASK_LINE_IN; /* 0 enables. */
2893		sc->sc_mixcontrol |= GUSMASK_MIC_IN; /* 1 enables. */
2894		bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
2895
2896		ad1848_attach(&sc->sc_codec);
2897		/* turn on pre-MUX microphone gain. */
2898		ad1848_set_mic_gain(&sc->sc_codec, &vol);
2899
2900		return (1);
2901	}
2902}
2903
2904
2905/*
2906 * Return info about the audio device, for the AUDIO_GETINFO ioctl
2907 */
2908
2909int
2910gus_getdev(addr, dev)
2911	void * addr;
2912	struct audio_device *dev;
2913{
2914	*dev = gus_device;
2915	return 0;
2916}
2917
2918/*
2919 * stubs (XXX)
2920 */
2921
2922int
2923gus_set_in_gain(addr, gain, balance)
2924	caddr_t addr;
2925	u_int gain;
2926	u_char balance;
2927{
2928	DPRINTF(("gus_set_in_gain called\n"));
2929	return 0;
2930}
2931
2932int
2933gus_get_in_gain(addr)
2934	caddr_t addr;
2935{
2936	DPRINTF(("gus_get_in_gain called\n"));
2937	return 0;
2938}
2939
2940int
2941gusmax_dma_input(addr, buf, size, callback, arg)
2942	void * addr;
2943	void *buf;
2944	int size;
2945	void (*callback) __P((void *));
2946	void *arg;
2947{
2948	struct ad1848_softc *sc = addr;
2949	return gus_dma_input(sc->parent, buf, size, callback, arg);
2950}
2951
2952/*
2953 * Start sampling the input source into the requested DMA buffer.
2954 * Called at splgus(), either from top-half or from interrupt handler.
2955 */
2956int
2957gus_dma_input(addr, buf, size, callback, arg)
2958	void * addr;
2959	void *buf;
2960	int size;
2961	void (*callback) __P((void *));
2962	void *arg;
2963{
2964	struct gus_softc *sc = addr;
2965	bus_space_tag_t iot = sc->sc_iot;
2966	bus_space_handle_t ioh2 = sc->sc_ioh2;
2967	u_char dmac;
2968	DMAPRINTF(("gus_dma_input called\n"));
2969
2970	/*
2971	 * Sample SIZE bytes of data from the card, into buffer at BUF.
2972	 */
2973
2974	if (sc->sc_precision == 16)
2975	    return EINVAL;		/* XXX */
2976
2977	/* set DMA modes */
2978	dmac = GUSMASK_SAMPLE_IRQ|GUSMASK_SAMPLE_START;
2979	if (sc->sc_recdrq >= 4)
2980		dmac |= GUSMASK_SAMPLE_DATA16;
2981	if (sc->sc_encoding == AUDIO_ENCODING_ULAW ||
2982 	    sc->sc_encoding == AUDIO_ENCODING_ALAW ||
2983 	    sc->sc_encoding == AUDIO_ENCODING_ULINEAR_LE ||
2984 	    sc->sc_encoding == AUDIO_ENCODING_ULINEAR_BE)
2985	    dmac |= GUSMASK_SAMPLE_INVBIT;
2986	if (sc->sc_channels == 2)
2987	    dmac |= GUSMASK_SAMPLE_STEREO;
2988 	isa_dmastart(sc->sc_ic, sc->sc_recdrq, buf, size,
2989 	    NULL, DMAMODE_READ, BUS_DMA_NOWAIT);
2990
2991	DMAPRINTF(("gus_dma_input isa_dmastarted\n"));
2992	sc->sc_flags |= GUS_DMAIN_ACTIVE;
2993	sc->sc_dmainintr = callback;
2994	sc->sc_inarg = arg;
2995	sc->sc_dmaincnt = size;
2996	sc->sc_dmainaddr = buf;
2997
2998	SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
2999	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, dmac);	/* Go! */
3000
3001
3002	DMAPRINTF(("gus_dma_input returning\n"));
3003
3004	return 0;
3005}
3006
3007STATIC int
3008gus_dmain_intr(sc)
3009	struct gus_softc *sc;
3010{
3011        void (*callback) __P((void *));
3012	void *arg;
3013
3014	DMAPRINTF(("gus_dmain_intr called\n"));
3015	if (sc->sc_dmainintr) {
3016 	    isa_dmadone(sc->sc_ic, sc->sc_recdrq);
3017	    callback = sc->sc_dmainintr;
3018	    arg = sc->sc_inarg;
3019
3020	    sc->sc_dmainaddr = 0;
3021	    sc->sc_dmaincnt = 0;
3022	    sc->sc_dmainintr = 0;
3023	    sc->sc_inarg = 0;
3024
3025	    sc->sc_flags &= ~GUS_DMAIN_ACTIVE;
3026	    DMAPRINTF(("calling dmain_intr callback %p(%p)\n", callback, arg));
3027	    (*callback)(arg);
3028	    return 1;
3029	} else {
3030	    DMAPRINTF(("gus_dmain_intr false?\n"));
3031	    return 0;			/* XXX ??? */
3032	}
3033}
3034
3035int
3036gusmax_halt_out_dma(addr)
3037	void * addr;
3038{
3039	struct ad1848_softc *sc = addr;
3040	return gus_halt_out_dma(sc->parent);
3041}
3042
3043
3044int
3045gusmax_halt_in_dma(addr)
3046	void * addr;
3047{
3048	struct ad1848_softc *sc = addr;
3049	return gus_halt_in_dma(sc->parent);
3050}
3051
3052/*
3053 * Stop any DMA output.  Called at splgus().
3054 */
3055int
3056gus_halt_out_dma(addr)
3057	void * addr;
3058{
3059 	struct gus_softc *sc = addr;
3060 	bus_space_tag_t iot = sc->sc_iot;
3061 	bus_space_handle_t ioh2 = sc->sc_ioh2;
3062
3063	DMAPRINTF(("gus_halt_out_dma called\n"));
3064	/*
3065	 * Make sure the GUS _isn't_ setup for DMA
3066	 */
3067
3068  	SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
3069 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0);
3070
3071	untimeout(gus_dmaout_timeout, sc);
3072 	isa_dmaabort(sc->sc_ic, sc->sc_drq);
3073	sc->sc_flags &= ~(GUS_DMAOUT_ACTIVE|GUS_LOCKED);
3074	sc->sc_dmaoutintr = 0;
3075	sc->sc_outarg = 0;
3076	sc->sc_dmaoutaddr = 0;
3077	sc->sc_dmaoutcnt = 0;
3078	sc->sc_dmabuf = 0;
3079	sc->sc_bufcnt = 0;
3080	sc->sc_playbuf = -1;
3081	/* also stop playing */
3082	gus_stop_voice(sc, GUS_VOICE_LEFT, 1);
3083	gus_stop_voice(sc, GUS_VOICE_RIGHT, 0);
3084
3085	return 0;
3086}
3087
3088/*
3089 * Stop any DMA output.  Called at splgus().
3090 */
3091int
3092gus_halt_in_dma(addr)
3093	void * addr;
3094{
3095 	struct gus_softc *sc = addr;
3096 	bus_space_tag_t iot = sc->sc_iot;
3097 	bus_space_handle_t ioh2 = sc->sc_ioh2;
3098	DMAPRINTF(("gus_halt_in_dma called\n"));
3099
3100	/*
3101	 * Make sure the GUS _isn't_ setup for DMA
3102	 */
3103
3104  	SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
3105 	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH,
3106 	     bus_space_read_1(iot, ioh2, GUS_DATA_HIGH) & ~(GUSMASK_SAMPLE_START|GUSMASK_SAMPLE_IRQ));
3107
3108 	isa_dmaabort(sc->sc_ic, sc->sc_recdrq);
3109	sc->sc_flags &= ~GUS_DMAIN_ACTIVE;
3110	sc->sc_dmainintr = 0;
3111	sc->sc_inarg = 0;
3112	sc->sc_dmainaddr = 0;
3113	sc->sc_dmaincnt = 0;
3114
3115	return 0;
3116}
3117
3118
3119static ad1848_devmap_t gusmapping[] = {
3120	{ GUSMAX_DAC_LVL, AD1848_KIND_LVL, AD1848_AUX1_CHANNEL },
3121	{ GUSMAX_LINE_IN_LVL, AD1848_KIND_LVL, AD1848_LINE_CHANNEL },
3122	{ GUSMAX_MONO_LVL, AD1848_KIND_LVL, AD1848_MONO_CHANNEL },
3123	{ GUSMAX_CD_LVL, AD1848_KIND_LVL, AD1848_AUX2_CHANNEL },
3124	{ GUSMAX_MONITOR_LVL, AD1848_KIND_LVL, AD1848_MONITOR_CHANNEL },
3125	{ GUSMAX_OUT_LVL, AD1848_KIND_LVL, AD1848_DAC_CHANNEL },
3126	{ GUSMAX_DAC_MUTE, AD1848_KIND_MUTE, AD1848_AUX1_CHANNEL },
3127	{ GUSMAX_LINE_IN_MUTE, AD1848_KIND_MUTE, AD1848_LINE_CHANNEL },
3128	{ GUSMAX_MONO_MUTE, AD1848_KIND_MUTE, AD1848_MONO_CHANNEL },
3129	{ GUSMAX_CD_MUTE, AD1848_KIND_MUTE, AD1848_AUX2_CHANNEL },
3130	{ GUSMAX_MONITOR_MUTE, AD1848_KIND_MUTE, AD1848_MONITOR_CHANNEL },
3131	{ GUSMAX_REC_LVL, AD1848_KIND_RECORDGAIN, -1 },
3132	{ GUSMAX_RECORD_SOURCE, AD1848_KIND_RECORDSOURCE, -1 }
3133};
3134
3135static int nummap = sizeof(gusmapping) / sizeof(gusmapping[0]);
3136
3137STATIC int
3138gusmax_mixer_get_port(addr, cp)
3139	void *addr;
3140	mixer_ctrl_t *cp;
3141{
3142	struct ad1848_softc *ac = addr;
3143	struct gus_softc *sc = ac->parent;
3144	struct ad1848_volume vol;
3145	int error = ad1848_mixer_get_port(ac, gusmapping, nummap, cp);
3146
3147	if (error != ENXIO)
3148	  return (error);
3149
3150	error = EINVAL;
3151
3152	switch (cp->dev) {
3153	case GUSMAX_SPEAKER_LVL:	/* fake speaker for mute naming */
3154		if (cp->type == AUDIO_MIXER_VALUE) {
3155			if (sc->sc_mixcontrol & GUSMASK_LINE_OUT)
3156				vol.left = vol.right = AUDIO_MAX_GAIN;
3157			else
3158				vol.left = vol.right = AUDIO_MIN_GAIN;
3159			error = 0;
3160			ad1848_from_vol(cp, &vol);
3161		}
3162		break;
3163
3164	case GUSMAX_SPEAKER_MUTE:
3165		if (cp->type == AUDIO_MIXER_ENUM) {
3166			cp->un.ord = sc->sc_mixcontrol & GUSMASK_LINE_OUT ? 1 : 0;
3167			error = 0;
3168		}
3169		break;
3170	default:
3171		error = ENXIO;
3172		break;
3173	}
3174
3175	return(error);
3176}
3177
3178STATIC int
3179gus_mixer_get_port(addr, cp)
3180	void *addr;
3181	mixer_ctrl_t *cp;
3182{
3183	struct gus_softc *sc = addr;
3184	struct ics2101_softc *ic = &sc->sc_mixer;
3185	struct ad1848_volume vol;
3186	int error = EINVAL;
3187
3188	DPRINTF(("gus_mixer_get_port: dev=%d type=%d\n", cp->dev, cp->type));
3189
3190	if (!HAS_MIXER(sc) && cp->dev > GUSICS_MASTER_MUTE)
3191		return ENXIO;
3192
3193	switch (cp->dev) {
3194
3195	case GUSICS_MIC_IN_MUTE:	/* Microphone */
3196		if (cp->type == AUDIO_MIXER_ENUM) {
3197			if (HAS_MIXER(sc))
3198				cp->un.ord = ic->sc_mute[GUSMIX_CHAN_MIC][ICSMIX_LEFT];
3199			else
3200				cp->un.ord =
3201				    sc->sc_mixcontrol & GUSMASK_MIC_IN ? 0 : 1;
3202			error = 0;
3203		}
3204		break;
3205
3206	case GUSICS_LINE_IN_MUTE:
3207		if (cp->type == AUDIO_MIXER_ENUM) {
3208			if (HAS_MIXER(sc))
3209				cp->un.ord = ic->sc_mute[GUSMIX_CHAN_LINE][ICSMIX_LEFT];
3210			else
3211				cp->un.ord =
3212				    sc->sc_mixcontrol & GUSMASK_LINE_IN ? 1 : 0;
3213			error = 0;
3214		}
3215		break;
3216
3217	case GUSICS_MASTER_MUTE:
3218		if (cp->type == AUDIO_MIXER_ENUM) {
3219			if (HAS_MIXER(sc))
3220				cp->un.ord = ic->sc_mute[GUSMIX_CHAN_MASTER][ICSMIX_LEFT];
3221			else
3222				cp->un.ord =
3223				    sc->sc_mixcontrol & GUSMASK_LINE_OUT ? 1 : 0;
3224			error = 0;
3225		}
3226		break;
3227
3228	case GUSICS_DAC_MUTE:
3229		if (cp->type == AUDIO_MIXER_ENUM) {
3230			cp->un.ord = ic->sc_mute[GUSMIX_CHAN_DAC][ICSMIX_LEFT];
3231			error = 0;
3232		}
3233		break;
3234
3235	case GUSICS_CD_MUTE:
3236		if (cp->type == AUDIO_MIXER_ENUM) {
3237			cp->un.ord = ic->sc_mute[GUSMIX_CHAN_CD][ICSMIX_LEFT];
3238			error = 0;
3239		}
3240		break;
3241
3242	case GUSICS_MASTER_LVL:
3243		if (cp->type == AUDIO_MIXER_VALUE) {
3244			vol.left = ic->sc_setting[GUSMIX_CHAN_MASTER][ICSMIX_LEFT];
3245			vol.right = ic->sc_setting[GUSMIX_CHAN_MASTER][ICSMIX_RIGHT];
3246			if (ad1848_from_vol(cp, &vol))
3247				error = 0;
3248		}
3249		break;
3250
3251	case GUSICS_MIC_IN_LVL:	/* Microphone */
3252		if (cp->type == AUDIO_MIXER_VALUE) {
3253			vol.left = ic->sc_setting[GUSMIX_CHAN_MIC][ICSMIX_LEFT];
3254			vol.right = ic->sc_setting[GUSMIX_CHAN_MIC][ICSMIX_RIGHT];
3255			if (ad1848_from_vol(cp, &vol))
3256				error = 0;
3257		}
3258		break;
3259
3260	case GUSICS_LINE_IN_LVL:	/* line in */
3261		if (cp->type == AUDIO_MIXER_VALUE) {
3262			vol.left = ic->sc_setting[GUSMIX_CHAN_LINE][ICSMIX_LEFT];
3263			vol.right = ic->sc_setting[GUSMIX_CHAN_LINE][ICSMIX_RIGHT];
3264			if (ad1848_from_vol(cp, &vol))
3265				error = 0;
3266		}
3267		break;
3268
3269
3270	case GUSICS_CD_LVL:
3271		if (cp->type == AUDIO_MIXER_VALUE) {
3272			vol.left = ic->sc_setting[GUSMIX_CHAN_CD][ICSMIX_LEFT];
3273			vol.right = ic->sc_setting[GUSMIX_CHAN_CD][ICSMIX_RIGHT];
3274			if (ad1848_from_vol(cp, &vol))
3275				error = 0;
3276		}
3277		break;
3278
3279	case GUSICS_DAC_LVL:		/* dac out */
3280		if (cp->type == AUDIO_MIXER_VALUE) {
3281			vol.left = ic->sc_setting[GUSMIX_CHAN_DAC][ICSMIX_LEFT];
3282			vol.right = ic->sc_setting[GUSMIX_CHAN_DAC][ICSMIX_RIGHT];
3283			if (ad1848_from_vol(cp, &vol))
3284				error = 0;
3285		}
3286		break;
3287
3288
3289	case GUSICS_RECORD_SOURCE:
3290		if (cp->type == AUDIO_MIXER_ENUM) {
3291			/* Can't set anything else useful, sigh. */
3292			 cp->un.ord = 0;
3293		}
3294		break;
3295
3296	default:
3297		return ENXIO;
3298	    /*NOTREACHED*/
3299	}
3300	return error;
3301}
3302
3303STATIC void
3304gusics_master_mute(ic, mute)
3305	struct ics2101_softc *ic;
3306	int mute;
3307{
3308	ics2101_mix_mute(ic, GUSMIX_CHAN_MASTER, ICSMIX_LEFT, mute);
3309	ics2101_mix_mute(ic, GUSMIX_CHAN_MASTER, ICSMIX_RIGHT, mute);
3310}
3311
3312STATIC void
3313gusics_mic_mute(ic, mute)
3314	struct ics2101_softc *ic;
3315	int mute;
3316{
3317	ics2101_mix_mute(ic, GUSMIX_CHAN_MIC, ICSMIX_LEFT, mute);
3318	ics2101_mix_mute(ic, GUSMIX_CHAN_MIC, ICSMIX_RIGHT, mute);
3319}
3320
3321STATIC void
3322gusics_linein_mute(ic, mute)
3323	struct ics2101_softc *ic;
3324	int mute;
3325{
3326	ics2101_mix_mute(ic, GUSMIX_CHAN_LINE, ICSMIX_LEFT, mute);
3327	ics2101_mix_mute(ic, GUSMIX_CHAN_LINE, ICSMIX_RIGHT, mute);
3328}
3329
3330STATIC void
3331gusics_cd_mute(ic, mute)
3332	struct ics2101_softc *ic;
3333	int mute;
3334{
3335	ics2101_mix_mute(ic, GUSMIX_CHAN_CD, ICSMIX_LEFT, mute);
3336	ics2101_mix_mute(ic, GUSMIX_CHAN_CD, ICSMIX_RIGHT, mute);
3337}
3338
3339STATIC void
3340gusics_dac_mute(ic, mute)
3341	struct ics2101_softc *ic;
3342	int mute;
3343{
3344	ics2101_mix_mute(ic, GUSMIX_CHAN_DAC, ICSMIX_LEFT, mute);
3345	ics2101_mix_mute(ic, GUSMIX_CHAN_DAC, ICSMIX_RIGHT, mute);
3346}
3347
3348STATIC int
3349gusmax_mixer_set_port(addr, cp)
3350	void *addr;
3351	mixer_ctrl_t *cp;
3352{
3353	struct ad1848_softc *ac = addr;
3354	struct gus_softc *sc = ac->parent;
3355	struct ad1848_volume vol;
3356	int error = ad1848_mixer_set_port(ac, gusmapping, nummap, cp);
3357
3358	if (error != ENXIO)
3359	  return (error);
3360
3361	DPRINTF(("gusmax_mixer_set_port: dev=%d type=%d\n", cp->dev, cp->type));
3362
3363	switch (cp->dev) {
3364	case GUSMAX_SPEAKER_LVL:
3365		if (cp->type == AUDIO_MIXER_VALUE &&
3366		    cp->un.value.num_channels == 1) {
3367			if (ad1848_to_vol(cp, &vol)) {
3368				gus_speaker_ctl(sc, vol.left > AUDIO_MIN_GAIN ?
3369						SPKR_ON : SPKR_OFF);
3370				error = 0;
3371			}
3372		}
3373		break;
3374
3375	case GUSMAX_SPEAKER_MUTE:
3376		if (cp->type == AUDIO_MIXER_ENUM) {
3377			gus_speaker_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON);
3378			error = 0;
3379		}
3380		break;
3381
3382	default:
3383		return ENXIO;
3384	    /*NOTREACHED*/
3385    }
3386    return error;
3387}
3388
3389STATIC int
3390gus_mixer_set_port(addr, cp)
3391	void *addr;
3392	mixer_ctrl_t *cp;
3393{
3394	struct gus_softc *sc = addr;
3395	struct ics2101_softc *ic = &sc->sc_mixer;
3396	struct ad1848_volume vol;
3397	int error = EINVAL;
3398
3399	DPRINTF(("gus_mixer_set_port: dev=%d type=%d\n", cp->dev, cp->type));
3400
3401	if (!HAS_MIXER(sc) && cp->dev > GUSICS_MASTER_MUTE)
3402		return ENXIO;
3403
3404	switch (cp->dev) {
3405
3406	case GUSICS_MIC_IN_MUTE:	/* Microphone */
3407		if (cp->type == AUDIO_MIXER_ENUM) {
3408			DPRINTF(("mic mute %d\n", cp->un.ord));
3409			if (HAS_MIXER(sc)) {
3410				gusics_mic_mute(ic, cp->un.ord);
3411			}
3412			gus_mic_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON);
3413			error = 0;
3414		}
3415		break;
3416
3417	case GUSICS_LINE_IN_MUTE:
3418		if (cp->type == AUDIO_MIXER_ENUM) {
3419			DPRINTF(("linein mute %d\n", cp->un.ord));
3420			if (HAS_MIXER(sc)) {
3421				gusics_linein_mute(ic, cp->un.ord);
3422			}
3423			gus_linein_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON);
3424			error = 0;
3425		}
3426		break;
3427
3428	case GUSICS_MASTER_MUTE:
3429		if (cp->type == AUDIO_MIXER_ENUM) {
3430			DPRINTF(("master mute %d\n", cp->un.ord));
3431			if (HAS_MIXER(sc)) {
3432				gusics_master_mute(ic, cp->un.ord);
3433			}
3434			gus_speaker_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON);
3435			error = 0;
3436		}
3437		break;
3438
3439	case GUSICS_DAC_MUTE:
3440		if (cp->type == AUDIO_MIXER_ENUM) {
3441			gusics_dac_mute(ic, cp->un.ord);
3442			error = 0;
3443		}
3444		break;
3445
3446	case GUSICS_CD_MUTE:
3447		if (cp->type == AUDIO_MIXER_ENUM) {
3448			gusics_cd_mute(ic, cp->un.ord);
3449			error = 0;
3450		}
3451		break;
3452
3453	case GUSICS_MASTER_LVL:
3454		if (cp->type == AUDIO_MIXER_VALUE) {
3455			if (ad1848_to_vol(cp, &vol)) {
3456				ics2101_mix_attenuate(ic,
3457						      GUSMIX_CHAN_MASTER,
3458						      ICSMIX_LEFT,
3459						      vol.left);
3460				ics2101_mix_attenuate(ic,
3461						      GUSMIX_CHAN_MASTER,
3462						      ICSMIX_RIGHT,
3463						      vol.right);
3464				error = 0;
3465			}
3466		}
3467		break;
3468
3469	case GUSICS_MIC_IN_LVL:	/* Microphone */
3470		if (cp->type == AUDIO_MIXER_VALUE) {
3471			if (ad1848_to_vol(cp, &vol)) {
3472				ics2101_mix_attenuate(ic,
3473						      GUSMIX_CHAN_MIC,
3474						      ICSMIX_LEFT,
3475						      vol.left);
3476				ics2101_mix_attenuate(ic,
3477						      GUSMIX_CHAN_MIC,
3478						      ICSMIX_RIGHT,
3479						      vol.right);
3480				error = 0;
3481			}
3482		}
3483		break;
3484
3485	case GUSICS_LINE_IN_LVL:	/* line in */
3486		if (cp->type == AUDIO_MIXER_VALUE) {
3487			if (ad1848_to_vol(cp, &vol)) {
3488				ics2101_mix_attenuate(ic,
3489						      GUSMIX_CHAN_LINE,
3490						      ICSMIX_LEFT,
3491						      vol.left);
3492				ics2101_mix_attenuate(ic,
3493						      GUSMIX_CHAN_LINE,
3494						      ICSMIX_RIGHT,
3495						      vol.right);
3496				error = 0;
3497			}
3498		}
3499		break;
3500
3501
3502	case GUSICS_CD_LVL:
3503		if (cp->type == AUDIO_MIXER_VALUE) {
3504			if (ad1848_to_vol(cp, &vol)) {
3505				ics2101_mix_attenuate(ic,
3506						      GUSMIX_CHAN_CD,
3507						      ICSMIX_LEFT,
3508						      vol.left);
3509				ics2101_mix_attenuate(ic,
3510						      GUSMIX_CHAN_CD,
3511						      ICSMIX_RIGHT,
3512						      vol.right);
3513				error = 0;
3514			}
3515		}
3516		break;
3517
3518	case GUSICS_DAC_LVL:		/* dac out */
3519		if (cp->type == AUDIO_MIXER_VALUE) {
3520			if (ad1848_to_vol(cp, &vol)) {
3521				ics2101_mix_attenuate(ic,
3522						      GUSMIX_CHAN_DAC,
3523						      ICSMIX_LEFT,
3524						      vol.left);
3525				ics2101_mix_attenuate(ic,
3526						      GUSMIX_CHAN_DAC,
3527						      ICSMIX_RIGHT,
3528						      vol.right);
3529				error = 0;
3530			}
3531		}
3532		break;
3533
3534
3535	case GUSICS_RECORD_SOURCE:
3536		if (cp->type == AUDIO_MIXER_ENUM && cp->un.ord == 0) {
3537			/* Can't set anything else useful, sigh. */
3538			error = 0;
3539		}
3540		break;
3541
3542	default:
3543		return ENXIO;
3544	    /*NOTREACHED*/
3545	}
3546	return error;
3547}
3548
3549STATIC int
3550gus_get_props(addr)
3551	void *addr;
3552{
3553	struct gus_softc *sc = addr;
3554	return sc->sc_recdrq == sc->sc_drq ? 0 : AUDIO_PROP_FULLDUPLEX;
3555}
3556
3557STATIC int
3558gusmax_get_props(addr)
3559	void *addr;
3560{
3561	struct ad1848_softc *ac = addr;
3562	return gus_get_props(ac->parent);
3563}
3564
3565STATIC int
3566gusmax_mixer_query_devinfo(addr, dip)
3567	void *addr;
3568	mixer_devinfo_t *dip;
3569{
3570	DPRINTF(("gusmax_query_devinfo: index=%d\n", dip->index));
3571
3572	switch(dip->index) {
3573#if 0
3574    case GUSMAX_MIC_IN_LVL:	/* Microphone */
3575	dip->type = AUDIO_MIXER_VALUE;
3576	dip->mixer_class = GUSMAX_INPUT_CLASS;
3577	dip->prev = AUDIO_MIXER_LAST;
3578	dip->next = GUSMAX_MIC_IN_MUTE;
3579	strcpy(dip->label.name, AudioNmicrophone);
3580	dip->un.v.num_channels = 2;
3581	strcpy(dip->un.v.units.name, AudioNvolume);
3582	break;
3583#endif
3584
3585    case GUSMAX_MONO_LVL:	/* mono/microphone mixer */
3586	dip->type = AUDIO_MIXER_VALUE;
3587	dip->mixer_class = GUSMAX_INPUT_CLASS;
3588	dip->prev = AUDIO_MIXER_LAST;
3589	dip->next = GUSMAX_MONO_MUTE;
3590	strcpy(dip->label.name, AudioNmicrophone);
3591	dip->un.v.num_channels = 1;
3592	strcpy(dip->un.v.units.name, AudioNvolume);
3593	break;
3594
3595    case GUSMAX_DAC_LVL:		/*  dacout */
3596	dip->type = AUDIO_MIXER_VALUE;
3597	dip->mixer_class = GUSMAX_INPUT_CLASS;
3598	dip->prev = AUDIO_MIXER_LAST;
3599	dip->next = GUSMAX_DAC_MUTE;
3600	strcpy(dip->label.name, AudioNdac);
3601	dip->un.v.num_channels = 2;
3602	strcpy(dip->un.v.units.name, AudioNvolume);
3603	break;
3604
3605    case GUSMAX_LINE_IN_LVL:	/* line */
3606	dip->type = AUDIO_MIXER_VALUE;
3607	dip->mixer_class = GUSMAX_INPUT_CLASS;
3608	dip->prev = AUDIO_MIXER_LAST;
3609	dip->next = GUSMAX_LINE_IN_MUTE;
3610	strcpy(dip->label.name, AudioNline);
3611	dip->un.v.num_channels = 2;
3612	strcpy(dip->un.v.units.name, AudioNvolume);
3613	break;
3614
3615    case GUSMAX_CD_LVL:		/* cd */
3616	dip->type = AUDIO_MIXER_VALUE;
3617	dip->mixer_class = GUSMAX_INPUT_CLASS;
3618	dip->prev = AUDIO_MIXER_LAST;
3619	dip->next = GUSMAX_CD_MUTE;
3620	strcpy(dip->label.name, AudioNcd);
3621	dip->un.v.num_channels = 2;
3622	strcpy(dip->un.v.units.name, AudioNvolume);
3623	break;
3624
3625
3626    case GUSMAX_MONITOR_LVL:	/* monitor level */
3627	dip->type = AUDIO_MIXER_VALUE;
3628	dip->mixer_class = GUSMAX_MONITOR_CLASS;
3629	dip->next = GUSMAX_MONITOR_MUTE;
3630	dip->prev = AUDIO_MIXER_LAST;
3631	strcpy(dip->label.name, AudioNmonitor);
3632	dip->un.v.num_channels = 1;
3633	strcpy(dip->un.v.units.name, AudioNvolume);
3634	break;
3635
3636    case GUSMAX_OUT_LVL:		/* cs4231 output volume: not useful? */
3637	dip->type = AUDIO_MIXER_VALUE;
3638	dip->mixer_class = GUSMAX_MONITOR_CLASS;
3639	dip->prev = dip->next = AUDIO_MIXER_LAST;
3640	strcpy(dip->label.name, AudioNoutput);
3641	dip->un.v.num_channels = 2;
3642	strcpy(dip->un.v.units.name, AudioNvolume);
3643	break;
3644
3645    case GUSMAX_SPEAKER_LVL:		/* fake speaker volume */
3646	dip->type = AUDIO_MIXER_VALUE;
3647	dip->mixer_class = GUSMAX_MONITOR_CLASS;
3648	dip->prev = AUDIO_MIXER_LAST;
3649	dip->next = GUSMAX_SPEAKER_MUTE;
3650	strcpy(dip->label.name, AudioNmaster);
3651	dip->un.v.num_channels = 2;
3652	strcpy(dip->un.v.units.name, AudioNvolume);
3653	break;
3654
3655    case GUSMAX_LINE_IN_MUTE:
3656	dip->mixer_class = GUSMAX_INPUT_CLASS;
3657	dip->type = AUDIO_MIXER_ENUM;
3658	dip->prev = GUSMAX_LINE_IN_LVL;
3659	dip->next = AUDIO_MIXER_LAST;
3660	goto mute;
3661
3662    case GUSMAX_DAC_MUTE:
3663	dip->mixer_class = GUSMAX_INPUT_CLASS;
3664	dip->type = AUDIO_MIXER_ENUM;
3665	dip->prev = GUSMAX_DAC_LVL;
3666	dip->next = AUDIO_MIXER_LAST;
3667	goto mute;
3668
3669    case GUSMAX_CD_MUTE:
3670	dip->mixer_class = GUSMAX_INPUT_CLASS;
3671	dip->type = AUDIO_MIXER_ENUM;
3672	dip->prev = GUSMAX_CD_LVL;
3673	dip->next = AUDIO_MIXER_LAST;
3674	goto mute;
3675
3676    case GUSMAX_MONO_MUTE:
3677	dip->mixer_class = GUSMAX_INPUT_CLASS;
3678	dip->type = AUDIO_MIXER_ENUM;
3679	dip->prev = GUSMAX_MONO_LVL;
3680	dip->next = AUDIO_MIXER_LAST;
3681	goto mute;
3682
3683    case GUSMAX_MONITOR_MUTE:
3684	dip->mixer_class = GUSMAX_OUTPUT_CLASS;
3685	dip->type = AUDIO_MIXER_ENUM;
3686	dip->prev = GUSMAX_MONITOR_LVL;
3687	dip->next = AUDIO_MIXER_LAST;
3688	goto mute;
3689
3690    case GUSMAX_SPEAKER_MUTE:
3691	dip->mixer_class = GUSMAX_OUTPUT_CLASS;
3692	dip->type = AUDIO_MIXER_ENUM;
3693	dip->prev = GUSMAX_SPEAKER_LVL;
3694	dip->next = AUDIO_MIXER_LAST;
3695    mute:
3696	strcpy(dip->label.name, AudioNmute);
3697	dip->un.e.num_mem = 2;
3698	strcpy(dip->un.e.member[0].label.name, AudioNoff);
3699	dip->un.e.member[0].ord = 0;
3700	strcpy(dip->un.e.member[1].label.name, AudioNon);
3701	dip->un.e.member[1].ord = 1;
3702	break;
3703
3704    case GUSMAX_REC_LVL:	/* record level */
3705	dip->type = AUDIO_MIXER_VALUE;
3706	dip->mixer_class = GUSMAX_RECORD_CLASS;
3707	dip->prev = AUDIO_MIXER_LAST;
3708	dip->next = GUSMAX_RECORD_SOURCE;
3709	strcpy(dip->label.name, AudioNrecord);
3710	dip->un.v.num_channels = 2;
3711	strcpy(dip->un.v.units.name, AudioNvolume);
3712	break;
3713
3714    case GUSMAX_RECORD_SOURCE:
3715	dip->mixer_class = GUSMAX_RECORD_CLASS;
3716	dip->type = AUDIO_MIXER_ENUM;
3717	dip->prev = GUSMAX_REC_LVL;
3718	dip->next = AUDIO_MIXER_LAST;
3719	strcpy(dip->label.name, AudioNsource);
3720	dip->un.e.num_mem = 4;
3721	strcpy(dip->un.e.member[0].label.name, AudioNoutput);
3722	dip->un.e.member[0].ord = DAC_IN_PORT;
3723	strcpy(dip->un.e.member[1].label.name, AudioNmicrophone);
3724	dip->un.e.member[1].ord = MIC_IN_PORT;
3725	strcpy(dip->un.e.member[2].label.name, AudioNdac);
3726	dip->un.e.member[2].ord = AUX1_IN_PORT;
3727	strcpy(dip->un.e.member[3].label.name, AudioNline);
3728	dip->un.e.member[3].ord = LINE_IN_PORT;
3729	break;
3730
3731    case GUSMAX_INPUT_CLASS:			/* input class descriptor */
3732	dip->type = AUDIO_MIXER_CLASS;
3733	dip->mixer_class = GUSMAX_INPUT_CLASS;
3734	dip->next = dip->prev = AUDIO_MIXER_LAST;
3735	strcpy(dip->label.name, AudioCinputs);
3736	break;
3737
3738    case GUSMAX_OUTPUT_CLASS:			/* output class descriptor */
3739	dip->type = AUDIO_MIXER_CLASS;
3740	dip->mixer_class = GUSMAX_OUTPUT_CLASS;
3741	dip->next = dip->prev = AUDIO_MIXER_LAST;
3742	strcpy(dip->label.name, AudioCoutputs);
3743	break;
3744
3745    case GUSMAX_MONITOR_CLASS:			/* monitor class descriptor */
3746	dip->type = AUDIO_MIXER_CLASS;
3747	dip->mixer_class = GUSMAX_MONITOR_CLASS;
3748	dip->next = dip->prev = AUDIO_MIXER_LAST;
3749	strcpy(dip->label.name, AudioCmonitor);
3750	break;
3751
3752    case GUSMAX_RECORD_CLASS:			/* record source class */
3753	dip->type = AUDIO_MIXER_CLASS;
3754	dip->mixer_class = GUSMAX_RECORD_CLASS;
3755	dip->next = dip->prev = AUDIO_MIXER_LAST;
3756	strcpy(dip->label.name, AudioCrecord);
3757	break;
3758
3759    default:
3760	return ENXIO;
3761	/*NOTREACHED*/
3762    }
3763    DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name));
3764	return 0;
3765}
3766
3767STATIC int
3768gus_mixer_query_devinfo(addr, dip)
3769	void *addr;
3770	mixer_devinfo_t *dip;
3771{
3772	struct gus_softc *sc = addr;
3773
3774	DPRINTF(("gusmax_query_devinfo: index=%d\n", dip->index));
3775
3776	if (!HAS_MIXER(sc) && dip->index > GUSICS_MASTER_MUTE)
3777		return ENXIO;
3778
3779	switch(dip->index) {
3780
3781	case GUSICS_MIC_IN_LVL:	/* Microphone */
3782		dip->type = AUDIO_MIXER_VALUE;
3783		dip->mixer_class = GUSICS_INPUT_CLASS;
3784		dip->prev = AUDIO_MIXER_LAST;
3785		dip->next = GUSICS_MIC_IN_MUTE;
3786		strcpy(dip->label.name, AudioNmicrophone);
3787		dip->un.v.num_channels = 2;
3788		strcpy(dip->un.v.units.name, AudioNvolume);
3789		break;
3790
3791	case GUSICS_LINE_IN_LVL:	/* line */
3792		dip->type = AUDIO_MIXER_VALUE;
3793		dip->mixer_class = GUSICS_INPUT_CLASS;
3794		dip->prev = AUDIO_MIXER_LAST;
3795		dip->next = GUSICS_LINE_IN_MUTE;
3796		strcpy(dip->label.name, AudioNline);
3797		dip->un.v.num_channels = 2;
3798		strcpy(dip->un.v.units.name, AudioNvolume);
3799		break;
3800
3801	case GUSICS_CD_LVL:		/* cd */
3802		dip->type = AUDIO_MIXER_VALUE;
3803		dip->mixer_class = GUSICS_INPUT_CLASS;
3804		dip->prev = AUDIO_MIXER_LAST;
3805		dip->next = GUSICS_CD_MUTE;
3806		strcpy(dip->label.name, AudioNcd);
3807		dip->un.v.num_channels = 2;
3808		strcpy(dip->un.v.units.name, AudioNvolume);
3809		break;
3810
3811	case GUSICS_DAC_LVL:		/*  dacout */
3812		dip->type = AUDIO_MIXER_VALUE;
3813		dip->mixer_class = GUSICS_INPUT_CLASS;
3814		dip->prev = AUDIO_MIXER_LAST;
3815		dip->next = GUSICS_DAC_MUTE;
3816		strcpy(dip->label.name, AudioNdac);
3817		dip->un.v.num_channels = 2;
3818		strcpy(dip->un.v.units.name, AudioNvolume);
3819		break;
3820
3821	case GUSICS_MASTER_LVL:		/*  master output */
3822		dip->type = AUDIO_MIXER_VALUE;
3823		dip->mixer_class = GUSICS_OUTPUT_CLASS;
3824		dip->prev = AUDIO_MIXER_LAST;
3825		dip->next = GUSICS_MASTER_MUTE;
3826		strcpy(dip->label.name, AudioNmaster);
3827		dip->un.v.num_channels = 2;
3828		strcpy(dip->un.v.units.name, AudioNvolume);
3829		break;
3830
3831
3832	case GUSICS_LINE_IN_MUTE:
3833		dip->mixer_class = GUSICS_INPUT_CLASS;
3834		dip->type = AUDIO_MIXER_ENUM;
3835		dip->prev = GUSICS_LINE_IN_LVL;
3836		dip->next = AUDIO_MIXER_LAST;
3837		goto mute;
3838
3839	case GUSICS_DAC_MUTE:
3840		dip->mixer_class = GUSICS_INPUT_CLASS;
3841		dip->type = AUDIO_MIXER_ENUM;
3842		dip->prev = GUSICS_DAC_LVL;
3843		dip->next = AUDIO_MIXER_LAST;
3844		goto mute;
3845
3846	case GUSICS_CD_MUTE:
3847		dip->mixer_class = GUSICS_INPUT_CLASS;
3848		dip->type = AUDIO_MIXER_ENUM;
3849		dip->prev = GUSICS_CD_LVL;
3850		dip->next = AUDIO_MIXER_LAST;
3851		goto mute;
3852
3853	case GUSICS_MIC_IN_MUTE:
3854		dip->mixer_class = GUSICS_INPUT_CLASS;
3855		dip->type = AUDIO_MIXER_ENUM;
3856		dip->prev = GUSICS_MIC_IN_LVL;
3857		dip->next = AUDIO_MIXER_LAST;
3858		goto mute;
3859
3860	case GUSICS_MASTER_MUTE:
3861		dip->mixer_class = GUSICS_OUTPUT_CLASS;
3862		dip->type = AUDIO_MIXER_ENUM;
3863		dip->prev = GUSICS_MASTER_LVL;
3864		dip->next = AUDIO_MIXER_LAST;
3865mute:
3866		strcpy(dip->label.name, AudioNmute);
3867		dip->un.e.num_mem = 2;
3868		strcpy(dip->un.e.member[0].label.name, AudioNoff);
3869		dip->un.e.member[0].ord = 0;
3870		strcpy(dip->un.e.member[1].label.name, AudioNon);
3871		dip->un.e.member[1].ord = 1;
3872		break;
3873
3874	case GUSICS_RECORD_SOURCE:
3875		dip->mixer_class = GUSICS_RECORD_CLASS;
3876		dip->type = AUDIO_MIXER_ENUM;
3877		dip->prev = dip->next = AUDIO_MIXER_LAST;
3878		strcpy(dip->label.name, AudioNsource);
3879		dip->un.e.num_mem = 1;
3880		strcpy(dip->un.e.member[0].label.name, AudioNoutput);
3881		dip->un.e.member[0].ord = GUSICS_MASTER_LVL;
3882		break;
3883
3884	case GUSICS_INPUT_CLASS:
3885		dip->type = AUDIO_MIXER_CLASS;
3886		dip->mixer_class = GUSICS_INPUT_CLASS;
3887		dip->next = dip->prev = AUDIO_MIXER_LAST;
3888		strcpy(dip->label.name, AudioCinputs);
3889		break;
3890
3891	case GUSICS_OUTPUT_CLASS:
3892		dip->type = AUDIO_MIXER_CLASS;
3893		dip->mixer_class = GUSICS_OUTPUT_CLASS;
3894		dip->next = dip->prev = AUDIO_MIXER_LAST;
3895		strcpy(dip->label.name, AudioCoutputs);
3896		break;
3897
3898	case GUSICS_RECORD_CLASS:
3899		dip->type = AUDIO_MIXER_CLASS;
3900		dip->mixer_class = GUSICS_RECORD_CLASS;
3901		dip->next = dip->prev = AUDIO_MIXER_LAST;
3902		strcpy(dip->label.name, AudioCrecord);
3903		break;
3904
3905	default:
3906		return ENXIO;
3907	/*NOTREACHED*/
3908	}
3909	DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name));
3910	return 0;
3911}
3912
3913STATIC int
3914gus_query_encoding(addr, fp)
3915	void *addr;
3916	struct audio_encoding *fp;
3917{
3918	switch (fp->index) {
3919	case 0:
3920		strcpy(fp->name, AudioEmulaw);
3921		fp->encoding = AUDIO_ENCODING_ULAW;
3922		fp->precision = 8;
3923		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
3924		break;
3925	case 1:
3926		strcpy(fp->name, AudioEslinear);
3927		fp->encoding = AUDIO_ENCODING_SLINEAR;
3928		fp->precision = 8;
3929		fp->flags = 0;
3930		break;
3931	case 2:
3932		strcpy(fp->name, AudioEslinear_le);
3933		fp->encoding = AUDIO_ENCODING_SLINEAR_LE;
3934		fp->precision = 16;
3935		fp->flags = 0;
3936		break;
3937	case 3:
3938		strcpy(fp->name, AudioEulinear);
3939		fp->encoding = AUDIO_ENCODING_ULINEAR;
3940		fp->precision = 8;
3941		fp->flags = 0;
3942		break;
3943	case 4:
3944		strcpy(fp->name, AudioEulinear_le);
3945		fp->encoding = AUDIO_ENCODING_ULINEAR_LE;
3946		fp->precision = 16;
3947		fp->flags = 0;
3948		break;
3949	case 5:
3950		strcpy(fp->name, AudioEslinear_be);
3951		fp->encoding = AUDIO_ENCODING_SLINEAR_BE;
3952		fp->precision = 16;
3953		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
3954		break;
3955	case 6:
3956		strcpy(fp->name, AudioEulinear_be);
3957		fp->encoding = AUDIO_ENCODING_ULINEAR_BE;
3958		fp->precision = 16;
3959		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
3960		break;
3961	case 7:
3962		strcpy(fp->name, AudioEalaw);
3963		fp->encoding = AUDIO_ENCODING_ALAW;
3964		fp->precision = 8;
3965		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
3966		break;
3967
3968	default:
3969		return(EINVAL);
3970		/*NOTREACHED*/
3971	}
3972	return (0);
3973}
3974
3975/*
3976 * Setup the ICS mixer in "transparent" mode: reset everything to a sensible
3977 * level.  Levels as suggested by GUS SDK code.
3978 */
3979
3980STATIC void
3981gus_init_ics2101(sc)
3982	struct gus_softc *sc;
3983{
3984	struct ics2101_softc *ic = &sc->sc_mixer;
3985	sc->sc_mixer.sc_iot = sc->sc_iot;
3986	sc->sc_mixer.sc_selio = GUS_MIXER_SELECT;
3987	sc->sc_mixer.sc_selio_ioh = sc->sc_ioh3;
3988	sc->sc_mixer.sc_dataio = GUS_MIXER_DATA;
3989	sc->sc_mixer.sc_dataio_ioh = sc->sc_ioh2;
3990	sc->sc_mixer.sc_flags = (sc->sc_revision == 5) ? ICS_FLIP : 0;
3991
3992	ics2101_mix_attenuate(ic,
3993			      GUSMIX_CHAN_MIC,
3994			      ICSMIX_LEFT,
3995			      ICSMIX_MIN_ATTN);
3996	ics2101_mix_attenuate(ic,
3997			      GUSMIX_CHAN_MIC,
3998			      ICSMIX_RIGHT,
3999			      ICSMIX_MIN_ATTN);
4000	/*
4001	 * Start with microphone muted by the mixer...
4002	 */
4003	gusics_mic_mute(ic, 1);
4004
4005	/* ... and enabled by the GUS master mix control */
4006	gus_mic_ctl(sc, SPKR_ON);
4007
4008	ics2101_mix_attenuate(ic,
4009			      GUSMIX_CHAN_LINE,
4010			      ICSMIX_LEFT,
4011			      ICSMIX_MIN_ATTN);
4012	ics2101_mix_attenuate(ic,
4013			      GUSMIX_CHAN_LINE,
4014			      ICSMIX_RIGHT,
4015			      ICSMIX_MIN_ATTN);
4016
4017	ics2101_mix_attenuate(ic,
4018			      GUSMIX_CHAN_CD,
4019			      ICSMIX_LEFT,
4020			      ICSMIX_MIN_ATTN);
4021	ics2101_mix_attenuate(ic,
4022			      GUSMIX_CHAN_CD,
4023			      ICSMIX_RIGHT,
4024			      ICSMIX_MIN_ATTN);
4025
4026	ics2101_mix_attenuate(ic,
4027			      GUSMIX_CHAN_DAC,
4028			      ICSMIX_LEFT,
4029			      ICSMIX_MIN_ATTN);
4030	ics2101_mix_attenuate(ic,
4031			      GUSMIX_CHAN_DAC,
4032			      ICSMIX_RIGHT,
4033			      ICSMIX_MIN_ATTN);
4034
4035	ics2101_mix_attenuate(ic,
4036			      ICSMIX_CHAN_4,
4037			      ICSMIX_LEFT,
4038			      ICSMIX_MAX_ATTN);
4039	ics2101_mix_attenuate(ic,
4040			      ICSMIX_CHAN_4,
4041			      ICSMIX_RIGHT,
4042			      ICSMIX_MAX_ATTN);
4043
4044	ics2101_mix_attenuate(ic,
4045			      GUSMIX_CHAN_MASTER,
4046			      ICSMIX_LEFT,
4047			      ICSMIX_MIN_ATTN);
4048	ics2101_mix_attenuate(ic,
4049			      GUSMIX_CHAN_MASTER,
4050			      ICSMIX_RIGHT,
4051			      ICSMIX_MIN_ATTN);
4052	/* unmute other stuff: */
4053	gusics_cd_mute(ic, 0);
4054	gusics_dac_mute(ic, 0);
4055	gusics_linein_mute(ic, 0);
4056	return;
4057}
4058
4059
4060#endif /* NGUS */
4061