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