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