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