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