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