gus.c revision 1.32
1/*	$NetBSD: gus.c,v 1.32 1997/07/15 07:46:16 augustss Exp $	*/
2
3/*-
4 * Copyright (c) 1996 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Ken Hornstein and John Kohl.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 *    must display the following acknowledgement:
20 *        This product includes software developed by the NetBSD
21 *	  Foundation, Inc. and its contributors.
22 * 4. Neither the name of The NetBSD Foundation nor the names of its
23 *    contributors may be used to endorse or promote products derived
24 *    from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
30 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 */
38
39/*
40 *
41 * TODO:
42 *	. figure out why mixer activity while sound is playing causes problems
43 *	  (phantom interrupts?)
44 *  	. figure out a better deinterleave strategy that avoids sucking up
45 *	  CPU, memory and cache bandwidth.  (Maybe a special encoding?
46 *	  Maybe use the double-speed sampling/hardware deinterleave trick
47 *	  from the GUS SDK?)  A 486/33 isn't quite fast enough to keep
48 *	  up with 44.1kHz 16-bit stereo output without some drop-outs.
49 *	. use CS4231 for 16-bit sampling, for a-law and mu-law playback.
50 *	. actually test full-duplex sampling(recording) and playback.
51 */
52
53/*
54 * Gravis UltraSound driver
55 *
56 * For more detailed information, see the GUS developers' kit
57 * available on the net at:
58 *
59 * ftp://freedom.nmsu.edu/pub/ultrasound/gravis/util/
60 * 	gusdkXXX.zip (developers' kit--get rev 2.22 or later)
61 *		See ultrawrd.doc inside--it's MS Word (ick), but it's the bible
62 *
63 */
64
65/*
66 * The GUS Max has a slightly strange set of connections between the CS4231
67 * and the GF1 and the DMA interconnects.  It's set up so that the CS4231 can
68 * be playing while the GF1 is loading patches from the system.
69 *
70 * Here's a recreation of the DMA interconnect diagram:
71 *
72 *       GF1
73 *   +---------+				 digital
74 *   |         |  record			 ASIC
75 *   |         |--------------+
76 *   |         |              |		       +--------+
77 *   |         | play (dram)  |      +----+    |	|
78 *   |         |--------------(------|-\  |    |   +-+  |
79 *   +---------+              |      |  >-|----|---|C|--|------  dma chan 1
80 *                            |  +---|-/  |    |   +-+ 	|
81 *                            |  |   +----+    |    |   |
82 *                            |	 |   +----+    |    |   |
83 *   +---------+        +-+   +--(---|-\  |    |    |   |
84 *   |         | play   |8|      |   |  >-|----|----+---|------  dma chan 2
85 *   | ---C----|--------|/|------(---|-/  |    |        |
86 *   |    ^    |record  |1|      |   +----+    |	|
87 *   |    |    |   /----|6|------+   	       +--------+
88 *   | ---+----|--/     +-+
89 *   +---------+
90 *     CS4231   	8-to-16 bit bus conversion, if needed
91 *
92 *
93 * "C" is an optional combiner.
94 *
95 */
96
97#include "gus.h"
98#if NGUS > 0
99
100#include <sys/param.h>
101#include <sys/systm.h>
102#include <sys/errno.h>
103#include <sys/ioctl.h>
104#include <sys/syslog.h>
105#include <sys/device.h>
106#include <sys/proc.h>
107#include <sys/buf.h>
108#include <sys/fcntl.h>
109#include <sys/malloc.h>
110#include <sys/kernel.h>
111
112#include <machine/cpu.h>
113#include <machine/intr.h>
114#include <machine/bus.h>
115#include <machine/pio.h>
116#include <machine/cpufunc.h>
117#include <sys/audioio.h>
118#include <dev/audio_if.h>
119#include <dev/mulaw.h>
120
121#include <dev/isa/isavar.h>
122#include <dev/isa/isadmavar.h>
123#include <i386/isa/icu.h>
124
125#include <dev/ic/ics2101reg.h>
126#include <dev/ic/cs4231reg.h>
127#include <dev/ic/ad1848reg.h>
128#include <dev/isa/ics2101var.h>
129#include <dev/isa/ad1848var.h>
130#include <dev/isa/cs4231var.h>
131#include "gusreg.h"
132
133#ifdef AUDIO_DEBUG
134#define STATIC /* empty; for debugging symbols */
135#else
136#define STATIC static
137#endif
138
139/*
140 * Software state of a single "voice" on the GUS
141 */
142
143struct gus_voice {
144
145	/*
146	 * Various control bits
147	 */
148
149	unsigned char voccntl;	/* State of voice control register */
150	unsigned char volcntl;	/* State of volume control register */
151	unsigned char pan_pos;	/* Position of volume panning (4 bits) */
152	int rate;		/* Sample rate of voice being played back */
153
154	/*
155	 * Address of the voice data into the GUS's DRAM.  20 bits each
156	 */
157
158	u_long start_addr;	/* Starting address of voice data loop area */
159	u_long end_addr;	/* Ending address of voice data loop */
160	u_long current_addr;	/* Beginning address of voice data
161				   (start playing here) */
162
163	/*
164	 * linear volume values for the GUS's volume ramp.  0-511 (9 bits).
165	 * These values must be translated into the logarithmic values using
166	 * gus_log_volumes[]
167	 */
168
169	int start_volume;	/* Starting position of volume ramp */
170	int current_volume;	/* Current position of volume on volume ramp */
171	int end_volume;		/* Ending position of volume on volume ramp */
172};
173
174/*
175 * Software state of GUS
176 */
177
178struct gus_softc {
179	struct device sc_dev;		/* base device */
180	struct isadev sc_id;		/* ISA device */
181	void *sc_ih;			/* interrupt vector */
182	bus_space_tag_t sc_iot;		/* tag */
183	bus_space_handle_t sc_ioh;	/* handle */
184
185	int sc_iobase;			/* I/O base address */
186	int sc_irq;			/* IRQ used */
187	int sc_drq;			/* DMA channel for play */
188	int sc_recdrq;			/* DMA channel for recording */
189
190	int sc_flags;			/* Various flags about the GUS */
191#define GUS_MIXER_INSTALLED	0x01	/* An ICS mixer is installed */
192#define GUS_LOCKED		0x02	/* GUS is busy doing multi-phase DMA */
193#define GUS_CODEC_INSTALLED	0x04	/* CS4231 installed/MAX */
194#define GUS_PLAYING		0x08	/* GUS is playing a voice */
195#define GUS_DMAOUT_ACTIVE	0x10	/* GUS is busy doing audio DMA */
196#define GUS_DMAIN_ACTIVE	0x20	/* GUS is busy sampling  */
197#define GUS_OPEN		0x100	/* GUS is open */
198	int sc_dsize;			/* Size of GUS DRAM */
199	int sc_voices;			/* Number of active voices */
200	u_char sc_revision;		/* Board revision of GUS */
201	u_char sc_mixcontrol;		/* Value of GUS_MIX_CONTROL register */
202
203	u_long sc_orate;		/* Output sampling rate */
204	u_long sc_irate;		/* Input sampling rate */
205
206	int sc_encoding;		/* Current data encoding type */
207	int sc_precision;		/* # of bits of precision */
208	int sc_channels;		/* Number of active channels */
209	int sc_blocksize;		/* Current blocksize */
210	int sc_chanblocksize;		/* Current blocksize for each in-use
211					   channel */
212	short sc_nbufs;			/* how many on-GUS bufs per-channel */
213	short sc_bufcnt;		/* how many need to be played */
214	void *sc_deintr_buf;		/* deinterleave buffer for stereo */
215
216	int sc_ogain;			/* Output gain control */
217	u_char sc_out_port;		/* Current out port (generic only) */
218	u_char sc_in_port;		/* keep track of it when no codec */
219
220	void (*sc_dmaoutintr) __P((void*)); /* DMA completion intr handler */
221	void *sc_outarg;		/* argument for sc_dmaoutintr() */
222	u_char *sc_dmaoutaddr;		/* for isa_dmadone */
223	u_long sc_gusaddr;		/* where did we just put it? */
224	int sc_dmaoutcnt;		/* for isa_dmadone */
225
226	void (*sc_dmainintr) __P((void*)); /* DMA completion intr handler */
227	void *sc_inarg;			/* argument for sc_dmaoutintr() */
228	u_char *sc_dmainaddr;		/* for isa_dmadone */
229	int sc_dmaincnt;		/* for isa_dmadone */
230
231	struct stereo_dma_intr {
232		void (*intr)__P((void *));
233		void *arg;
234		u_char *buffer;
235		u_long dmabuf;
236		int size;
237		int flags;
238	} sc_stereo;
239
240	/*
241	 * State information for linear audio layer
242	 */
243
244	int sc_dmabuf;			/* Which ring buffer we're DMA'ing to */
245	int sc_playbuf;			/* Which ring buffer we're playing */
246
247	/*
248	 * Voice information array.  All voice-specific information is stored
249	 * here
250	 */
251
252	struct gus_voice sc_voc[32];	/* Voice data for each voice */
253	union {
254		struct ics2101_softc sc_mixer_u;
255		struct ad1848_softc sc_codec_u;
256	} u;
257#define sc_mixer u.sc_mixer_u
258#define sc_codec u.sc_codec_u
259};
260
261struct ics2101_volume {
262	u_char left;
263	u_char right;
264};
265
266#define HAS_CODEC(sc) ((sc)->sc_flags & GUS_CODEC_INSTALLED)
267#define HAS_MIXER(sc) ((sc)->sc_flags & GUS_MIXER_INSTALLED)
268
269/*
270 * Mixer devices for ICS2101
271 */
272/* MIC IN mute, line in mute, line out mute are first since they can be done
273   even if no ICS mixer. */
274#define GUSICS_MIC_IN_MUTE		0
275#define GUSICS_LINE_IN_MUTE		1
276#define GUSICS_MASTER_MUTE		2
277#define GUSICS_CD_MUTE			3
278#define GUSICS_DAC_MUTE			4
279#define GUSICS_MIC_IN_LVL		5
280#define GUSICS_LINE_IN_LVL		6
281#define GUSICS_CD_LVL			7
282#define GUSICS_DAC_LVL			8
283#define GUSICS_MASTER_LVL		9
284
285#define GUSICS_RECORD_SOURCE		10
286
287/* Classes */
288#define GUSICS_INPUT_CLASS		11
289#define GUSICS_OUTPUT_CLASS		12
290#define GUSICS_RECORD_CLASS		13
291
292/*
293 * Mixer & MUX devices for CS4231
294 */
295#define GUSMAX_MONO_LVL			0 /* mic input to MUX;
296					     also mono mixer input */
297#define GUSMAX_DAC_LVL			1 /* input to MUX; also mixer input */
298#define GUSMAX_LINE_IN_LVL		2 /* input to MUX; also mixer input */
299#define GUSMAX_CD_LVL			3 /* mixer input only */
300#define GUSMAX_MONITOR_LVL		4 /* digital mix (?) */
301#define GUSMAX_OUT_LVL			5 /* output level. (?) */
302#define GUSMAX_SPEAKER_LVL		6 /* pseudo-device for mute */
303#define GUSMAX_LINE_IN_MUTE		7 /* pre-mixer */
304#define GUSMAX_DAC_MUTE			8 /* pre-mixer */
305#define GUSMAX_CD_MUTE			9 /* pre-mixer */
306#define GUSMAX_MONO_MUTE		10 /* pre-mixer--microphone/mono */
307#define GUSMAX_MONITOR_MUTE		11 /* post-mixer level/mute */
308#define GUSMAX_SPEAKER_MUTE		12 /* speaker mute */
309
310#define GUSMAX_REC_LVL			13 /* post-MUX gain */
311
312#define GUSMAX_RECORD_SOURCE		14
313
314/* Classes */
315#define GUSMAX_INPUT_CLASS		15
316#define GUSMAX_RECORD_CLASS		16
317#define GUSMAX_MONITOR_CLASS		17
318#define GUSMAX_OUTPUT_CLASS		18
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	/* XXX WILL THIS ALWAYS WORK THE WAY THEY'RE OVERLAYED?! */
845	sc->sc_codec.sc_isa = sc->sc_dev.dv_parent;
846
847 	if (sc->sc_revision >= 5 && sc->sc_revision <= 9) {
848 		sc->sc_flags |= GUS_MIXER_INSTALLED;
849 		gus_init_ics2101(sc);
850	}
851	if (sc->sc_revision >= 0xa) {
852		gus_init_cs4231(sc);
853	}
854
855 	SELECT_GUS_REG(port, GUSREG_RESET);
856 	/*
857 	 * Check to see how much memory we have on this card; see if any
858 	 * "mirroring" occurs.  We're assuming at least 256K already exists
859 	 * on the card; otherwise the initial probe would have failed
860 	 */
861
862	guspoke(port, 0L, 0x00);
863	for(i = 1; i < 1024; i++) {
864		u_long loc;
865
866		/*
867		 * See if we've run into mirroring yet
868		 */
869
870		if (guspeek(port, 0L) != 0)
871			break;
872
873		loc = i << 10;
874
875		guspoke(port, loc, 0xaa);
876		if (guspeek(port, loc) != 0xaa)
877			break;
878	}
879
880	sc->sc_dsize = i;
881	sprintf(gus_device.version, "3.%d", sc->sc_revision);
882
883	printf("\n <Gravis UltraSound version 3.%d, %dKB DRAM, ",
884	       sc->sc_revision, sc->sc_dsize);
885	if (HAS_MIXER(sc))
886		printf("ICS2101 mixer, ");
887	if (HAS_CODEC(sc))
888		printf("%s codec/mixer, ", sc->sc_codec.chip_name);
889	if (sc->sc_recdrq == sc->sc_drq) {
890		printf("half-duplex");
891		gus_hw_if.full_duplex = 0;
892	} else {
893		printf("full-duplex, record drq %d", sc->sc_recdrq);
894		gus_hw_if.full_duplex = 1;
895	}
896
897	printf(">\n");
898
899	/*
900	 * Setup a default interrupt handler
901	 */
902
903	/* XXX we shouldn't have to use splgus == splclock, nor should
904	 * we use IPL_CLOCK.
905	 */
906	sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq, IST_EDGE,
907	    IPL_AUDIO, gusintr, sc /* sc->sc_gusdsp */);
908
909	/*
910	 * Set some default values
911	 */
912
913	sc->sc_irate = sc->sc_orate = 44100;
914	sc->sc_encoding = AUDIO_ENCODING_SLINEAR_LE;
915	sc->sc_precision = 16;
916	sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_DATA_SIZE16;
917	sc->sc_voc[GUS_VOICE_RIGHT].voccntl |= GUSMASK_DATA_SIZE16;
918	sc->sc_channels = 1;
919	sc->sc_ogain = 340;
920	gus_commit_settings(sc);
921
922	/*
923	 * We always put the left channel full left & right channel
924	 * full right.
925	 * For mono playback, we set up both voices playing the same buffer.
926	 */
927	outb(sc->sc_iobase+GUS_VOICE_SELECT, (unsigned char) GUS_VOICE_LEFT);
928	SELECT_GUS_REG(sc->sc_iobase, GUSREG_PAN_POS);
929	outb(sc->sc_iobase+GUS_DATA_HIGH, GUS_PAN_FULL_LEFT);
930
931	outb(sc->sc_iobase+GUS_VOICE_SELECT, (unsigned char) GUS_VOICE_RIGHT);
932	SELECT_GUS_REG(sc->sc_iobase, GUSREG_PAN_POS);
933	outb(sc->sc_iobase+GUS_DATA_HIGH, GUS_PAN_FULL_RIGHT);
934
935	/*
936	 * Attach to the generic audio layer
937	 */
938
939	if (audio_hardware_attach(&gus_hw_if, HAS_CODEC(sc) ? (void *)&sc->sc_codec : (void *)sc) != 0)
940		printf("gus: could not attach to audio pseudo-device driver\n");
941}
942
943int
944gusopen(dev, flags)
945	dev_t dev;
946	int flags;
947{
948	int unit = AUDIOUNIT(dev);
949	struct gus_softc *sc;
950
951	DPRINTF(("gusopen() called\n"));
952
953	if (unit >= gus_cd.cd_ndevs)
954		return ENXIO;
955	sc = gus_cd.cd_devs[unit];
956	if (!sc)
957		return ENXIO;
958
959	if (sc->sc_flags & GUS_OPEN)
960		return EBUSY;
961
962	/*
963	 * Some initialization
964	 */
965
966	sc->sc_flags |= GUS_OPEN;
967	sc->sc_dmabuf = 0;
968	sc->sc_playbuf = -1;
969	sc->sc_bufcnt = 0;
970	sc->sc_voc[GUS_VOICE_LEFT].start_addr = GUS_MEM_OFFSET - 1;
971	sc->sc_voc[GUS_VOICE_LEFT].current_addr = GUS_MEM_OFFSET;
972
973	if (HAS_CODEC(sc)) {
974		ad1848_open(&sc->sc_codec, dev, flags);
975		sc->sc_codec.aux1_mute = 0;
976		ad1848_mute_aux1(&sc->sc_codec, 0); /* turn on DAC output */
977		if (flags & FREAD) {
978			sc->sc_codec.mono_mute = 0;
979			cs4231_mute_mono(&sc->sc_codec, 0);
980		}
981	} else if (flags & FREAD) {
982		/* enable/unmute the microphone */
983		if (HAS_MIXER(sc)) {
984			gusics_mic_mute(&sc->sc_mixer, 0);
985		} else
986			gus_mic_ctl(sc, SPKR_ON);
987	}
988	if (sc->sc_nbufs == 0)
989	    gus_round_blocksize(sc, GUS_BUFFER_MULTIPLE); /* default blksiz */
990	return 0;
991}
992
993STATIC void
994gus_deinterleave(sc, buf, size)
995	register struct gus_softc *sc;
996	void *buf;
997	int size;
998{
999	/* deinterleave the stereo data.  We can use sc->sc_deintr_buf
1000	   for scratch space. */
1001	register int i;
1002
1003	if (size > sc->sc_blocksize) {
1004		printf("gus: deinterleave %d > %d\n", size, sc->sc_blocksize);
1005		return;
1006	} else if (size < sc->sc_blocksize) {
1007		DPRINTF(("gus: deinterleave %d < %d\n", size, sc->sc_blocksize));
1008	}
1009
1010	/*
1011	 * size is in bytes.
1012	 */
1013	if (sc->sc_precision == 16) {
1014		register u_short *dei = sc->sc_deintr_buf;
1015		register u_short *sbuf = buf;
1016		size >>= 1;		/* bytecnt to shortcnt */
1017		/* copy 2nd of each pair of samples to the staging area, while
1018		   compacting the 1st of each pair into the original area. */
1019		for (i = 0; i < size/2-1; i++)  {
1020			dei[i] = sbuf[i*2+1];
1021			sbuf[i+1] = sbuf[i*2+2];
1022		}
1023		/*
1024		 * this has copied one less sample than half of the
1025		 * buffer.  The first sample of the 1st stream was
1026		 * already in place and didn't need copying.
1027		 * Therefore, we've moved all of the 1st stream's
1028		 * samples into place.  We have one sample from 2nd
1029		 * stream in the last slot of original area, not
1030		 * copied to the staging area (But we don't need to!).
1031		 * Copy the remainder of the original stream into place.
1032		 */
1033		bcopy(dei, &sbuf[size/2], i * sizeof(short));
1034	} else {
1035		register u_char *dei = sc->sc_deintr_buf;
1036		register u_char *sbuf = buf;
1037		for (i = 0; i < size/2-1; i++)  {
1038			dei[i] = sbuf[i*2+1];
1039			sbuf[i+1] = sbuf[i*2+2];
1040		}
1041		bcopy(dei, &sbuf[size/2], i);
1042	}
1043}
1044
1045/*
1046 * Actually output a buffer to the DSP chip
1047 */
1048
1049int
1050gusmax_dma_output(addr, buf, size, intr, arg)
1051	void * addr;
1052	void *buf;
1053	int size;
1054	void (*intr) __P((void *));
1055	void *arg;
1056{
1057	register struct ad1848_softc *ac = addr;
1058	return gus_dma_output(ac->parent, buf, size, intr, arg);
1059}
1060
1061/*
1062 * called at splgus() from interrupt handler.
1063 */
1064void
1065stereo_dmaintr(arg)
1066	void *arg;
1067{
1068    struct gus_softc *sc = arg;
1069    struct stereo_dma_intr *sa = &sc->sc_stereo;
1070
1071    DMAPRINTF(("stereo_dmaintr"));
1072
1073    /*
1074     * Put other half in its place, then call the real interrupt routine :)
1075     */
1076
1077    sc->sc_dmaoutintr = sa->intr;
1078    sc->sc_outarg = sa->arg;
1079
1080#ifdef GUSPLAYDEBUG
1081    if (gusstats) {
1082      microtime(&dmarecords[dmarecord_index].tv);
1083      dmarecords[dmarecord_index].gusaddr = sa->dmabuf;
1084      dmarecords[dmarecord_index].bsdaddr = sa->buffer;
1085      dmarecords[dmarecord_index].count = sa->size;
1086      dmarecords[dmarecord_index].channel = 1;
1087      dmarecords[dmarecord_index].direction = 1;
1088      dmarecord_index = ++dmarecord_index % NDMARECS;
1089    }
1090#endif
1091
1092    gusdmaout(sc, sa->flags, sa->dmabuf, (caddr_t) sa->buffer, sa->size);
1093
1094    sa->flags = 0;
1095    sa->dmabuf = 0;
1096    sa->buffer = 0;
1097    sa->size = 0;
1098    sa->intr = 0;
1099    sa->arg = 0;
1100}
1101
1102/*
1103 * Start up DMA output to the card.
1104 * Called at splgus/splaudio already, either from intr handler or from
1105 * generic audio code.
1106 */
1107int
1108gus_dma_output(addr, buf, size, intr, arg)
1109	void * addr;
1110	void *buf;
1111	int size;
1112	void (*intr) __P((void *));
1113	void *arg;
1114{
1115	struct gus_softc *sc = addr;
1116	u_char *buffer = buf;
1117	u_long boarddma;
1118	int flags;
1119
1120	DMAPRINTF(("gus_dma_output %d @ %x\n", size, buf));
1121
1122	if (size != sc->sc_blocksize) {
1123	    DPRINTF(("gus_dma_output reqsize %d not sc_blocksize %d\n",
1124		     size, sc->sc_blocksize));
1125	    return EINVAL;
1126	}
1127
1128	flags = GUSMASK_DMA_WRITE;
1129	if (sc->sc_precision == 16)
1130	    flags |= GUSMASK_DMA_DATA_SIZE;
1131	if (sc->sc_encoding == AUDIO_ENCODING_ULAW ||
1132	    sc->sc_encoding == AUDIO_ENCODING_ULINEAR_BE ||
1133	    sc->sc_encoding == AUDIO_ENCODING_ULINEAR_LE)
1134	    flags |= GUSMASK_DMA_INVBIT;
1135
1136	if (sc->sc_channels == 2) {
1137		if (sc->sc_precision == 16) {
1138			if (size & 3) {
1139				DPRINTF(("gus_dma_output: unpaired 16bit samples"));
1140				size &= 3;
1141			}
1142		} else if (size & 1) {
1143			DPRINTF(("gus_dma_output: unpaired samples"));
1144			size &= 1;
1145		}
1146		if (size == 0)
1147			return 0;
1148
1149		gus_deinterleave(sc, (void *)buffer, size);
1150
1151		size >>= 1;
1152
1153 		boarddma = size * sc->sc_dmabuf + GUS_MEM_OFFSET;
1154
1155		sc->sc_stereo.intr = intr;
1156		sc->sc_stereo.arg = arg;
1157		sc->sc_stereo.size = size;
1158		sc->sc_stereo.dmabuf = boarddma + GUS_LEFT_RIGHT_OFFSET;
1159		sc->sc_stereo.buffer = buffer + size;
1160		sc->sc_stereo.flags = flags;
1161		if (gus_dostereo) {
1162		  intr = stereo_dmaintr;
1163		  arg = sc;
1164		}
1165	} else
1166		boarddma = size * sc->sc_dmabuf + GUS_MEM_OFFSET;
1167
1168
1169	sc->sc_flags |= GUS_LOCKED;
1170	sc->sc_dmaoutintr = intr;
1171	sc->sc_outarg = arg;
1172
1173#ifdef GUSPLAYDEBUG
1174	if (gusstats) {
1175	  microtime(&dmarecords[dmarecord_index].tv);
1176	  dmarecords[dmarecord_index].gusaddr = boarddma;
1177	  dmarecords[dmarecord_index].bsdaddr = buffer;
1178	  dmarecords[dmarecord_index].count = size;
1179	  dmarecords[dmarecord_index].channel = 0;
1180	  dmarecords[dmarecord_index].direction = 1;
1181	  dmarecord_index = ++dmarecord_index % NDMARECS;
1182	}
1183#endif
1184
1185	gusdmaout(sc, flags, boarddma, (caddr_t) buffer, size);
1186
1187	return 0;
1188}
1189
1190void
1191gusmax_close(addr)
1192	void *addr;
1193{
1194	register struct ad1848_softc *ac = addr;
1195	register struct gus_softc *sc = ac->parent;
1196#if 0
1197	ac->aux1_mute = 1;
1198	ad1848_mute_aux1(ac, 1);	/* turn off DAC output */
1199#endif
1200	ad1848_close(ac);
1201	gusclose(sc);
1202}
1203
1204/*
1205 * Close out device stuff.  Called at splgus() from generic audio layer.
1206 */
1207void
1208gusclose(addr)
1209	void *addr;
1210{
1211	struct gus_softc *sc = addr;
1212
1213        DPRINTF(("gus_close: sc=0x%x\n", sc));
1214
1215
1216/*	if (sc->sc_flags & GUS_DMAOUT_ACTIVE) */ {
1217		gus_halt_out_dma(sc);
1218	}
1219/*	if (sc->sc_flags & GUS_DMAIN_ACTIVE) */ {
1220		gus_halt_in_dma(sc);
1221	}
1222	sc->sc_flags &= ~(GUS_OPEN|GUS_LOCKED|GUS_DMAOUT_ACTIVE|GUS_DMAIN_ACTIVE);
1223
1224	if (sc->sc_deintr_buf) {
1225		FREE(sc->sc_deintr_buf, M_DEVBUF);
1226		sc->sc_deintr_buf = NULL;
1227	}
1228	/* turn off speaker, etc. */
1229
1230	/* make sure the voices shut up: */
1231	gus_stop_voice(sc, GUS_VOICE_LEFT, 1);
1232	gus_stop_voice(sc, GUS_VOICE_RIGHT, 0);
1233}
1234
1235/*
1236 * Service interrupts.  Farm them off to helper routines if we are using the
1237 * GUS for simple playback/record
1238 */
1239
1240#ifdef DIAGNOSTIC
1241int gusintrcnt;
1242int gusdmaintrcnt;
1243int gusvocintrcnt;
1244#endif
1245
1246int
1247gusintr(arg)
1248	void *arg;
1249{
1250	register struct gus_softc *sc = arg;
1251	unsigned char intr;
1252	register int port = sc->sc_iobase;
1253	int retval = 0;
1254
1255	DPRINTF(("gusintr\n"));
1256#ifdef DIAGNOSTIC
1257	gusintrcnt++;
1258#endif
1259	if (HAS_CODEC(sc))
1260		retval = ad1848_intr(&sc->sc_codec);
1261	if ((intr = inb(port+GUS_IRQ_STATUS)) & GUSMASK_IRQ_DMATC) {
1262		DMAPRINTF(("gusintr dma flags=%x\n", sc->sc_flags));
1263#ifdef DIAGNOSTIC
1264		gusdmaintrcnt++;
1265#endif
1266		retval += gus_dmaout_intr(sc);
1267		if (sc->sc_flags & GUS_DMAIN_ACTIVE) {
1268		    SELECT_GUS_REG(port, GUSREG_SAMPLE_CONTROL);
1269		    intr = inb(port+GUS_DATA_HIGH);
1270		    if (intr & GUSMASK_SAMPLE_DMATC) {
1271			retval += gus_dmain_intr(sc);
1272		    }
1273		}
1274	}
1275	if (intr & (GUSMASK_IRQ_VOICE | GUSMASK_IRQ_VOLUME)) {
1276		DMAPRINTF(("gusintr voice flags=%x\n", sc->sc_flags));
1277#ifdef DIAGNOSTIC
1278		gusvocintrcnt++;
1279#endif
1280		retval += gus_voice_intr(sc);
1281	}
1282	if (retval)
1283		return 1;
1284	return retval;
1285}
1286
1287int gus_bufcnt[GUS_MEM_FOR_BUFFERS / GUS_BUFFER_MULTIPLE];
1288int gus_restart;				/* how many restarts? */
1289int gus_stops;				/* how many times did voice stop? */
1290int gus_falsestops;			/* stopped but not done? */
1291int gus_continues;
1292
1293struct playcont {
1294	struct timeval tv;
1295	u_int playbuf;
1296	u_int dmabuf;
1297	u_char bufcnt;
1298	u_char vaction;
1299	u_char voccntl;
1300	u_char volcntl;
1301	u_long curaddr;
1302	u_long endaddr;
1303} playstats[NDMARECS];
1304
1305int playcntr;
1306
1307STATIC void
1308gus_dmaout_timeout(arg)
1309     void *arg;
1310{
1311    register struct gus_softc *sc = arg;
1312    register int port = sc->sc_iobase;
1313    int s;
1314
1315    printf("%s: dmaout timeout\n", sc->sc_dev.dv_xname);
1316    /*
1317     * Stop any DMA.
1318     */
1319
1320    s = splgus();
1321    SELECT_GUS_REG(port, GUSREG_DMA_CONTROL);
1322    outb(sc->sc_iobase+GUS_DATA_HIGH, 0);
1323
1324#if 0
1325    /* XXX we will dmadone below? */
1326    isa_dmaabort(sc->sc_dev.dv_parent, sc->sc_drq);
1327#endif
1328
1329    gus_dmaout_dointr(sc);
1330    splx(s);
1331}
1332
1333
1334/*
1335 * Service DMA interrupts.  This routine will only get called if we're doing
1336 * a DMA transfer for playback/record requests from the audio layer.
1337 */
1338
1339STATIC int
1340gus_dmaout_intr(sc)
1341	struct gus_softc *sc;
1342{
1343	register int port = sc->sc_iobase;
1344
1345	/*
1346	 * If we got a DMA transfer complete from the GUS DRAM, then deal
1347	 * with it.
1348	 */
1349
1350	SELECT_GUS_REG(port, GUSREG_DMA_CONTROL);
1351 	if (inb(port+GUS_DATA_HIGH) & GUSMASK_DMA_IRQPEND) {
1352	    untimeout(gus_dmaout_timeout, sc);
1353	    gus_dmaout_dointr(sc);
1354	    return 1;
1355	}
1356	return 0;
1357}
1358
1359STATIC void
1360gus_dmaout_dointr(sc)
1361	struct gus_softc *sc;
1362{
1363	register int port = sc->sc_iobase;
1364
1365	/* sc->sc_dmaoutcnt - 1 because DMA controller counts from zero?. */
1366	isa_dmadone(sc->sc_dev.dv_parent, 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_SLINEAR_LE:
1382	  case AUDIO_ENCODING_SLINEAR_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(sc->sc_dev.dv_parent, sc->sc_drq, buffaddr, length,
1882	    NULL, DMAMODE_WRITE, BUS_DMA_NOWAIT);
1883
1884	/*
1885	 * Set up DMA address - use the upper 16 bits ONLY
1886	 */
1887
1888	sc->sc_flags |= GUS_DMAOUT_ACTIVE;
1889
1890 	SELECT_GUS_REG(port, GUSREG_DMA_START);
1891 	outw(port+GUS_DATA_LOW, (int) (gusaddr >> 4));
1892
1893 	/*
1894 	 * Tell the GUS to start doing DMA
1895 	 */
1896
1897 	SELECT_GUS_REG(port, GUSREG_DMA_CONTROL);
1898	outb(port+GUS_DATA_HIGH, c);
1899
1900	/*
1901	 * XXX If we don't finish in one second, give up...
1902	 */
1903	untimeout(gus_dmaout_timeout, sc); /* flush old one, if there is one */
1904	timeout(gus_dmaout_timeout, sc, hz);
1905}
1906
1907/*
1908 * Start a voice playing on the GUS.  Called from interrupt handler at
1909 * splgus().
1910 */
1911
1912STATIC void
1913gus_start_voice(sc, voice, intrs)
1914	struct gus_softc *sc;
1915	int voice;
1916	int intrs;
1917{
1918	register int port = sc->sc_iobase;
1919	u_long start;
1920	u_long current;
1921	u_long end;
1922
1923	/*
1924	 * Pick all the values for the voice out of the gus_voice struct
1925	 * and use those to program the voice
1926	 */
1927
1928 	start = sc->sc_voc[voice].start_addr;
1929 	current = sc->sc_voc[voice].current_addr;
1930 	end = sc->sc_voc[voice].end_addr;
1931
1932 	/*
1933	 * If we're using 16 bit data, mangle the addresses a bit
1934	 */
1935
1936	if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16) {
1937	        /* -1 on start so that we get onto sample boundary--other
1938		   code always sets it for 1-byte rollover protection */
1939		start = convert_to_16bit(start-1);
1940		current = convert_to_16bit(current);
1941		end = convert_to_16bit(end);
1942	}
1943
1944	/*
1945	 * Select the voice we want to use, and program the data addresses
1946	 */
1947
1948	outb(port+GUS_VOICE_SELECT, (unsigned char) voice);
1949
1950	SELECT_GUS_REG(port, GUSREG_START_ADDR_HIGH);
1951	outw(port+GUS_DATA_LOW, ADDR_HIGH(start));
1952	SELECT_GUS_REG(port, GUSREG_START_ADDR_LOW);
1953	outw(port+GUS_DATA_LOW, ADDR_LOW(start));
1954
1955	SELECT_GUS_REG(port, GUSREG_CUR_ADDR_HIGH);
1956	outw(port+GUS_DATA_LOW, ADDR_HIGH(current));
1957	SELECT_GUS_REG(port, GUSREG_CUR_ADDR_LOW);
1958	outw(port+GUS_DATA_LOW, ADDR_LOW(current));
1959
1960	SELECT_GUS_REG(port, GUSREG_END_ADDR_HIGH);
1961	outw(port+GUS_DATA_LOW, ADDR_HIGH(end));
1962	SELECT_GUS_REG(port, GUSREG_END_ADDR_LOW);
1963	outw(port+GUS_DATA_LOW, ADDR_LOW(end));
1964
1965	/*
1966	 * (maybe) enable interrupts, disable voice stopping
1967	 */
1968
1969	if (intrs) {
1970		sc->sc_flags |= GUS_PLAYING; /* playing is about to start */
1971		sc->sc_voc[voice].voccntl |= GUSMASK_VOICE_IRQ;
1972		DMAPRINTF(("gus voice playing=%x\n", sc->sc_flags));
1973	} else
1974		sc->sc_voc[voice].voccntl &= ~GUSMASK_VOICE_IRQ;
1975	sc->sc_voc[voice].voccntl &= ~(GUSMASK_VOICE_STOPPED |
1976		GUSMASK_STOP_VOICE);
1977
1978	/*
1979	 * Tell the GUS about it.  Note that we're doing volume ramping here
1980	 * from 0 up to the set volume to help reduce clicks.
1981	 */
1982
1983	SELECT_GUS_REG(port, GUSREG_START_VOLUME);
1984	outb(port+GUS_DATA_HIGH, 0x00);
1985	SELECT_GUS_REG(port, GUSREG_END_VOLUME);
1986	outb(port+GUS_DATA_HIGH, sc->sc_voc[voice].current_volume >> 4);
1987	SELECT_GUS_REG(port, GUSREG_CUR_VOLUME);
1988	outw(port+GUS_DATA_LOW, 0x00);
1989	SELECT_GUS_REG(port, GUSREG_VOLUME_RATE);
1990	outb(port+GUS_DATA_HIGH, 63);
1991
1992	SELECT_GUS_REG(port, GUSREG_VOICE_CNTL);
1993	outb(port+GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
1994	SELECT_GUS_REG(port, GUSREG_VOLUME_CONTROL);
1995	outb(port+GUS_DATA_HIGH, 0x00);
1996	delay(50);
1997	SELECT_GUS_REG(port, GUSREG_VOICE_CNTL);
1998	outb(port+GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
1999	SELECT_GUS_REG(port, GUSREG_VOLUME_CONTROL);
2000	outb(port+GUS_DATA_HIGH, 0x00);
2001
2002}
2003
2004/*
2005 * Stop a given voice.  called at splgus()
2006 */
2007
2008STATIC void
2009gus_stop_voice(sc, voice, intrs_too)
2010	struct gus_softc *sc;
2011	int voice;
2012	int intrs_too;
2013{
2014	register int port = sc->sc_iobase;
2015
2016	sc->sc_voc[voice].voccntl |= GUSMASK_VOICE_STOPPED |
2017		GUSMASK_STOP_VOICE;
2018	if (intrs_too) {
2019	  sc->sc_voc[voice].voccntl &= ~(GUSMASK_VOICE_IRQ);
2020	  /* no more DMA to do */
2021	  sc->sc_flags &= ~GUS_PLAYING;
2022	}
2023	DMAPRINTF(("gusintr voice notplaying=%x\n", sc->sc_flags));
2024
2025	guspoke(port, 0L, 0);
2026
2027	outb(port+GUS_VOICE_SELECT, (unsigned char) voice);
2028
2029	SELECT_GUS_REG(port, GUSREG_CUR_VOLUME);
2030	outw(port+GUS_DATA_LOW, 0x0000);
2031	SELECT_GUS_REG(port, GUSREG_VOICE_CNTL);
2032	outb(port+GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
2033	delay(100);
2034	SELECT_GUS_REG(port, GUSREG_CUR_VOLUME);
2035	outw(port+GUS_DATA_LOW, 0x0000);
2036	SELECT_GUS_REG(port, GUSREG_VOICE_CNTL);
2037	outb(port+GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
2038
2039	SELECT_GUS_REG(port, GUSREG_CUR_ADDR_HIGH);
2040	outw(port+GUS_DATA_LOW, 0x0000);
2041	SELECT_GUS_REG(port, GUSREG_CUR_ADDR_LOW);
2042	outw(port+GUS_DATA_LOW, 0x0000);
2043
2044}
2045
2046
2047/*
2048 * Set the volume of a given voice.  Called at splgus().
2049 */
2050STATIC void
2051gus_set_volume(sc, voice, volume)
2052	struct gus_softc *sc;
2053	int voice, volume;
2054{
2055	register int port = sc->sc_iobase;
2056	unsigned int gusvol;
2057
2058	gusvol = gus_log_volumes[volume < 512 ? volume : 511];
2059
2060	sc->sc_voc[voice].current_volume = gusvol;
2061
2062	outb(port+GUS_VOICE_SELECT, (unsigned char) voice);
2063
2064	SELECT_GUS_REG(port, GUSREG_START_VOLUME);
2065	outb(port+GUS_DATA_HIGH, (unsigned char) (gusvol >> 4));
2066
2067	SELECT_GUS_REG(port, GUSREG_END_VOLUME);
2068	outb(port+GUS_DATA_HIGH, (unsigned char) (gusvol >> 4));
2069
2070	SELECT_GUS_REG(port, GUSREG_CUR_VOLUME);
2071	outw(port+GUS_DATA_LOW, gusvol << 4);
2072	delay(500);
2073	outw(port+GUS_DATA_LOW, gusvol << 4);
2074
2075}
2076
2077/*
2078 * Interface to the audio layer.
2079 */
2080
2081int
2082gusmax_set_params(addr, mode, p, q)
2083	void *addr;
2084	int mode;
2085	struct audio_params *p, *q;
2086{
2087	register struct ad1848_softc *ac = addr;
2088	register struct gus_softc *sc = ac->parent;
2089	int error;
2090
2091	error = ad1848_set_params(ac, mode, p, q);
2092	if (error)
2093		return error;
2094	error = gus_set_params(sc, mode, p, q);
2095	return error;
2096}
2097
2098int
2099gus_set_params(addr, mode, p, q)
2100	void *addr;
2101	int mode;
2102	struct audio_params *p, *q;
2103{
2104	register struct gus_softc *sc = addr;
2105	int s;
2106
2107	switch (p->encoding) {
2108	case AUDIO_ENCODING_ULAW:
2109	case AUDIO_ENCODING_SLINEAR_LE:
2110	case AUDIO_ENCODING_ULINEAR_LE:
2111	case AUDIO_ENCODING_SLINEAR_BE:
2112	case AUDIO_ENCODING_ULINEAR_BE:
2113		break;
2114	default:
2115		return (EINVAL);
2116	}
2117
2118	s = splaudio();
2119
2120	if (p->precision == 8) {
2121		sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~GUSMASK_DATA_SIZE16;
2122		sc->sc_voc[GUS_VOICE_RIGHT].voccntl &= ~GUSMASK_DATA_SIZE16;
2123	} else {
2124		sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_DATA_SIZE16;
2125		sc->sc_voc[GUS_VOICE_RIGHT].voccntl |= GUSMASK_DATA_SIZE16;
2126	}
2127
2128	sc->sc_encoding = p->encoding;
2129	sc->sc_precision = p->precision;
2130	sc->sc_channels = p->channels;
2131
2132	splx(s);
2133
2134	if (p->sample_rate > gus_max_frequency[sc->sc_voices - GUS_MIN_VOICES])
2135		p->sample_rate = gus_max_frequency[sc->sc_voices - GUS_MIN_VOICES];
2136	if (mode == AUMODE_RECORD)
2137		sc->sc_irate = p->sample_rate;
2138	else
2139		sc->sc_orate = p->sample_rate;
2140
2141	switch (p->encoding) {
2142	case AUDIO_ENCODING_ULAW:
2143		p->sw_code = mode == AUMODE_PLAY ?
2144			mulaw_to_ulinear8 : ulinear8_to_mulaw;
2145		break;
2146	case AUDIO_ENCODING_ULINEAR_BE:
2147	case AUDIO_ENCODING_SLINEAR_BE:
2148		p->sw_code = swap_bytes;
2149		break;
2150	default:
2151		p->sw_code = 0;
2152	}
2153
2154	/* Update setting for the other mode. */
2155	q->encoding = p->encoding;
2156	q->channels = p->channels;
2157	q->precision = p->precision;
2158	return 0;
2159}
2160
2161/*
2162 * Interface to the audio layer - set the blocksize to the correct number
2163 * of units
2164 */
2165
2166int
2167gusmax_round_blocksize(addr, blocksize)
2168	void * addr;
2169	int blocksize;
2170{
2171	register struct ad1848_softc *ac = addr;
2172	register struct gus_softc *sc = ac->parent;
2173
2174/*	blocksize = ad1848_round_blocksize(ac, blocksize);*/
2175	return gus_round_blocksize(sc, blocksize);
2176}
2177
2178int
2179gus_round_blocksize(addr, blocksize)
2180	void * addr;
2181	int blocksize;
2182{
2183	register struct gus_softc *sc = addr;
2184
2185	DPRINTF(("gus_round_blocksize called\n"));
2186
2187	if (sc->sc_encoding == AUDIO_ENCODING_ULAW && blocksize > 32768)
2188		blocksize = 32768;
2189	else if (blocksize > 65536)
2190		blocksize = 65536;
2191
2192	if ((blocksize % GUS_BUFFER_MULTIPLE) != 0)
2193		blocksize = (blocksize / GUS_BUFFER_MULTIPLE + 1) *
2194			GUS_BUFFER_MULTIPLE;
2195
2196	/* set up temporary buffer to hold the deinterleave, if necessary
2197	   for stereo output */
2198	if (sc->sc_deintr_buf) {
2199		FREE(sc->sc_deintr_buf, M_DEVBUF);
2200		sc->sc_deintr_buf = NULL;
2201	}
2202	MALLOC(sc->sc_deintr_buf, void *, blocksize>>1, M_DEVBUF, M_WAITOK);
2203
2204	sc->sc_blocksize = blocksize;
2205	/* multi-buffering not quite working yet. */
2206	sc->sc_nbufs = /*GUS_MEM_FOR_BUFFERS / blocksize*/ 2;
2207
2208	gus_set_chan_addrs(sc);
2209
2210	return blocksize;
2211}
2212
2213int
2214gus_get_out_gain(addr)
2215	caddr_t addr;
2216{
2217	register struct gus_softc *sc = (struct gus_softc *) addr;
2218
2219	DPRINTF(("gus_get_out_gain called\n"));
2220	return sc->sc_ogain / 2;
2221}
2222
2223STATIC inline void gus_set_voices(sc, voices)
2224struct gus_softc *sc;
2225int voices;
2226{
2227	register int port = sc->sc_iobase;
2228	/*
2229	 * Select the active number of voices
2230	 */
2231
2232	SELECT_GUS_REG(port, GUSREG_ACTIVE_VOICES);
2233	outb(port+GUS_DATA_HIGH, (voices-1) | 0xc0);
2234
2235	sc->sc_voices = voices;
2236}
2237
2238/*
2239 * Actually set the settings of various values on the card
2240 */
2241
2242int
2243gusmax_commit_settings(addr)
2244	void * addr;
2245{
2246	register struct ad1848_softc *ac = addr;
2247	register struct gus_softc *sc = ac->parent;
2248
2249	(void) ad1848_commit_settings(ac);
2250	return gus_commit_settings(sc);
2251}
2252
2253/*
2254 * Commit the settings.  Called at normal IPL.
2255 */
2256int
2257gus_commit_settings(addr)
2258	void * addr;
2259{
2260	register struct gus_softc *sc = addr;
2261	int s;
2262
2263	DPRINTF(("gus_commit_settings called (gain = %d)\n",sc->sc_ogain));
2264
2265
2266	s = splgus();
2267
2268	gus_set_recrate(sc, sc->sc_irate);
2269	gus_set_volume(sc, GUS_VOICE_LEFT, sc->sc_ogain);
2270	gus_set_volume(sc, GUS_VOICE_RIGHT, sc->sc_ogain);
2271	gus_set_samprate(sc, GUS_VOICE_LEFT, sc->sc_orate);
2272	gus_set_samprate(sc, GUS_VOICE_RIGHT, sc->sc_orate);
2273	splx(s);
2274	gus_set_chan_addrs(sc);
2275
2276	return 0;
2277}
2278
2279STATIC void
2280gus_set_chan_addrs(sc)
2281struct gus_softc *sc;
2282{
2283	/*
2284	 * We use sc_nbufs * blocksize bytes of storage in the on-board GUS
2285	 * ram.
2286	 * For mono, each of the sc_nbufs buffers is DMA'd to in one chunk,
2287	 * and both left & right channels play the same buffer.
2288	 *
2289	 * For stereo, each channel gets a contiguous half of the memory,
2290	 * and each has sc_nbufs buffers of size blocksize/2.
2291	 * Stereo data are deinterleaved in main memory before the DMA out
2292	 * routines are called to queue the output.
2293	 *
2294	 * The blocksize per channel is kept in sc_chanblocksize.
2295	 */
2296	if (sc->sc_channels == 2)
2297	    sc->sc_chanblocksize = sc->sc_blocksize/2;
2298	else
2299	    sc->sc_chanblocksize = sc->sc_blocksize;
2300
2301	sc->sc_voc[GUS_VOICE_LEFT].start_addr = GUS_MEM_OFFSET - 1;
2302	sc->sc_voc[GUS_VOICE_RIGHT].start_addr =
2303	    (gus_dostereo && sc->sc_channels == 2 ? GUS_LEFT_RIGHT_OFFSET : 0)
2304	      + GUS_MEM_OFFSET - 1;
2305	sc->sc_voc[GUS_VOICE_RIGHT].current_addr =
2306	    sc->sc_voc[GUS_VOICE_RIGHT].start_addr + 1;
2307	sc->sc_voc[GUS_VOICE_RIGHT].end_addr =
2308	    sc->sc_voc[GUS_VOICE_RIGHT].start_addr +
2309	    sc->sc_nbufs * sc->sc_chanblocksize;
2310
2311}
2312
2313/*
2314 * Set the sample rate of the given voice.  Called at splgus().
2315 */
2316
2317STATIC void
2318gus_set_samprate(sc, voice, freq)
2319	struct gus_softc *sc;
2320	int voice, freq;
2321{
2322	register int port = sc->sc_iobase;
2323	unsigned int fc;
2324	u_long temp, f = (u_long) freq;
2325
2326	/*
2327	 * calculate fc based on the number of active voices;
2328	 * we need to use longs to preserve enough bits
2329	 */
2330
2331	temp = (u_long) gus_max_frequency[sc->sc_voices-GUS_MIN_VOICES];
2332
2333 	fc = (unsigned int)(((f << 9L) + (temp >> 1L)) / temp);
2334
2335 	fc <<= 1;
2336
2337
2338	/*
2339	 * Program the voice frequency, and set it in the voice data record
2340	 */
2341
2342	outb(port+GUS_VOICE_SELECT, (unsigned char) voice);
2343	SELECT_GUS_REG(port, GUSREG_FREQ_CONTROL);
2344	outw(port+GUS_DATA_LOW, fc);
2345
2346	sc->sc_voc[voice].rate = freq;
2347
2348}
2349
2350/*
2351 * Set the sample rate of the recording frequency.  Formula is from the GUS
2352 * SDK.  Called at splgus().
2353 */
2354
2355STATIC void
2356gus_set_recrate(sc, rate)
2357	struct gus_softc *sc;
2358	u_long rate;
2359{
2360	register int port = sc->sc_iobase;
2361	u_char realrate;
2362	DPRINTF(("gus_set_recrate %lu\n", rate));
2363
2364#if 0
2365	realrate = 9878400/(16*(rate+2)); /* formula from GUS docs */
2366#endif
2367	realrate = (9878400 >> 4)/rate - 2; /* formula from code, sigh. */
2368
2369	SELECT_GUS_REG(port, GUSREG_SAMPLE_FREQ);
2370 	outb(port+GUS_DATA_HIGH, realrate);
2371}
2372
2373/*
2374 * Interface to the audio layer - turn the output on or off.  Note that some
2375 * of these bits are flipped in the register
2376 */
2377
2378int
2379gusmax_speaker_ctl(addr, newstate)
2380	void * addr;
2381	int newstate;
2382{
2383	register struct ad1848_softc *sc = addr;
2384	return gus_speaker_ctl(sc->parent, newstate);
2385}
2386
2387int
2388gus_speaker_ctl(addr, newstate)
2389	void * addr;
2390	int newstate;
2391{
2392	register struct gus_softc *sc = (struct gus_softc *) addr;
2393
2394	/* Line out bit is flipped: 0 enables, 1 disables */
2395	if ((newstate == SPKR_ON) &&
2396	    (sc->sc_mixcontrol & GUSMASK_LINE_OUT)) {
2397		sc->sc_mixcontrol &= ~GUSMASK_LINE_OUT;
2398		outb(sc->sc_iobase+GUS_MIX_CONTROL, sc->sc_mixcontrol);
2399	}
2400	if ((newstate == SPKR_OFF) &&
2401	    (sc->sc_mixcontrol & GUSMASK_LINE_OUT) == 0) {
2402		sc->sc_mixcontrol |= GUSMASK_LINE_OUT;
2403		outb(sc->sc_iobase+GUS_MIX_CONTROL, sc->sc_mixcontrol);
2404	}
2405
2406	return 0;
2407}
2408
2409STATIC int
2410gus_linein_ctl(addr, newstate)
2411	void * addr;
2412	int newstate;
2413{
2414	register struct gus_softc *sc = (struct gus_softc *) addr;
2415
2416	/* Line in bit is flipped: 0 enables, 1 disables */
2417	if ((newstate == SPKR_ON) &&
2418	    (sc->sc_mixcontrol & GUSMASK_LINE_IN)) {
2419		sc->sc_mixcontrol &= ~GUSMASK_LINE_IN;
2420		outb(sc->sc_iobase+GUS_MIX_CONTROL, sc->sc_mixcontrol);
2421	}
2422	if ((newstate == SPKR_OFF) &&
2423	    (sc->sc_mixcontrol & GUSMASK_LINE_IN) == 0) {
2424		sc->sc_mixcontrol |= GUSMASK_LINE_IN;
2425		outb(sc->sc_iobase+GUS_MIX_CONTROL, sc->sc_mixcontrol);
2426	}
2427
2428	return 0;
2429}
2430
2431STATIC int
2432gus_mic_ctl(addr, newstate)
2433	void * addr;
2434	int newstate;
2435{
2436	register struct gus_softc *sc = (struct gus_softc *) addr;
2437
2438	/* Mic bit is normal: 1 enables, 0 disables */
2439	if ((newstate == SPKR_ON) &&
2440	    (sc->sc_mixcontrol & GUSMASK_MIC_IN) == 0) {
2441		sc->sc_mixcontrol |= GUSMASK_MIC_IN;
2442		outb(sc->sc_iobase+GUS_MIX_CONTROL, sc->sc_mixcontrol);
2443	}
2444	if ((newstate == SPKR_OFF) &&
2445	    (sc->sc_mixcontrol & GUSMASK_MIC_IN)) {
2446		sc->sc_mixcontrol &= ~GUSMASK_MIC_IN;
2447		outb(sc->sc_iobase+GUS_MIX_CONTROL, sc->sc_mixcontrol);
2448	}
2449
2450	return 0;
2451}
2452
2453/*
2454 * Set the end address of a give voice.  Called at splgus()
2455 */
2456
2457STATIC void
2458gus_set_endaddr(sc, voice, addr)
2459	struct gus_softc *sc;
2460	int voice;
2461	u_long addr;
2462{
2463	register int port = sc->sc_iobase;
2464
2465	sc->sc_voc[voice].end_addr = addr;
2466
2467	if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16)
2468		addr = convert_to_16bit(addr);
2469
2470	SELECT_GUS_REG(port, GUSREG_END_ADDR_HIGH);
2471	outw(port+GUS_DATA_LOW, ADDR_HIGH(addr));
2472	SELECT_GUS_REG(port, GUSREG_END_ADDR_LOW);
2473	outw(port+GUS_DATA_LOW, ADDR_LOW(addr));
2474
2475}
2476
2477#ifdef GUSPLAYDEBUG
2478/*
2479 * Set current address.  called at splgus()
2480 */
2481STATIC void
2482gus_set_curaddr(sc, voice, addr)
2483	struct gus_softc *sc;
2484	int voice;
2485	u_long addr;
2486{
2487	register int port = sc->sc_iobase;
2488
2489	sc->sc_voc[voice].current_addr = addr;
2490
2491	if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16)
2492		addr = convert_to_16bit(addr);
2493
2494	outb(port+GUS_VOICE_SELECT, (unsigned char) voice);
2495
2496	SELECT_GUS_REG(port, GUSREG_CUR_ADDR_HIGH);
2497	outw(port+GUS_DATA_LOW, ADDR_HIGH(addr));
2498	SELECT_GUS_REG(port, GUSREG_CUR_ADDR_LOW);
2499	outw(port+GUS_DATA_LOW, ADDR_LOW(addr));
2500
2501}
2502
2503/*
2504 * Get current GUS playback address.  Called at splgus().
2505 */
2506STATIC u_long
2507gus_get_curaddr(sc, voice)
2508	struct gus_softc *sc;
2509	int voice;
2510{
2511	register int port = sc->sc_iobase;
2512	u_long addr;
2513
2514	outb(port+GUS_VOICE_SELECT, (unsigned char) voice);
2515	SELECT_GUS_REG(port, GUSREG_CUR_ADDR_HIGH|GUSREG_READ);
2516	addr = (inw(port+GUS_DATA_LOW) & 0x1fff) << 7;
2517	SELECT_GUS_REG(port, GUSREG_CUR_ADDR_LOW|GUSREG_READ);
2518	addr |= (inw(port+GUS_DATA_LOW) >> 9L) & 0x7f;
2519
2520	if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16)
2521	    addr = (addr & 0xc0000) | ((addr & 0x1ffff) << 1); /* undo 16-bit change */
2522	DPRINTF(("gus voice %d curaddr %d end_addr %d\n",
2523		 voice, addr, sc->sc_voc[voice].end_addr));
2524	/* XXX sanity check the address? */
2525
2526	return(addr);
2527}
2528#endif
2529
2530/*
2531 * Convert an address value to a "16 bit" value - why this is necessary I
2532 * have NO idea
2533 */
2534
2535STATIC u_long
2536convert_to_16bit(address)
2537	u_long address;
2538{
2539	u_long old_address;
2540
2541	old_address = address;
2542	address >>= 1;
2543	address &= 0x0001ffffL;
2544	address |= (old_address & 0x000c0000L);
2545
2546	return (address);
2547}
2548
2549/*
2550 * Write a value into the GUS's DRAM
2551 */
2552
2553STATIC void
2554guspoke(port, address, value)
2555	int port;
2556	long address;
2557	unsigned char value;
2558{
2559
2560	/*
2561	 * Select the DRAM address
2562	 */
2563
2564 	SELECT_GUS_REG(port, GUSREG_DRAM_ADDR_LOW);
2565 	outw(port+GUS_DATA_LOW, (unsigned int) (address & 0xffff));
2566 	SELECT_GUS_REG(port, GUSREG_DRAM_ADDR_HIGH);
2567 	outb(port+GUS_DATA_HIGH, (unsigned char) ((address >> 16) & 0xff));
2568
2569	/*
2570	 * Actually write the data
2571	 */
2572
2573	outb(port+GUS_DRAM_DATA, value);
2574}
2575
2576/*
2577 * Read a value from the GUS's DRAM
2578 */
2579
2580STATIC unsigned char
2581guspeek(port, address)
2582	int port;
2583	u_long address;
2584{
2585
2586	/*
2587	 * Select the DRAM address
2588	 */
2589
2590 	SELECT_GUS_REG(port, GUSREG_DRAM_ADDR_LOW);
2591 	outw(port+GUS_DATA_LOW, (unsigned int) (address & 0xffff));
2592 	SELECT_GUS_REG(port, GUSREG_DRAM_ADDR_HIGH);
2593 	outb(port+GUS_DATA_HIGH, (unsigned char) ((address >> 16) & 0xff));
2594
2595	/*
2596	 * Read in the data from the board
2597	 */
2598
2599	return (unsigned char) inb(port+GUS_DRAM_DATA);
2600}
2601
2602/*
2603 * Reset the Gravis UltraSound card, completely
2604 */
2605
2606STATIC void
2607gusreset(sc, voices)
2608	struct gus_softc *sc;
2609	int voices;
2610{
2611	register int port = sc->sc_iobase;
2612	int i,s;
2613
2614	s = splgus();
2615
2616	/*
2617	 * Reset the GF1 chip
2618	 */
2619
2620	SELECT_GUS_REG(port, GUSREG_RESET);
2621	outb(port+GUS_DATA_HIGH, 0x00);
2622
2623	delay(500);
2624
2625	/*
2626	 * Release reset
2627	 */
2628
2629	SELECT_GUS_REG(port, GUSREG_RESET);
2630	outb(port+GUS_DATA_HIGH, GUSMASK_MASTER_RESET);
2631
2632	delay(500);
2633
2634	/*
2635	 * Reset MIDI port as well
2636	 */
2637
2638	outb(GUS_MIDI_CONTROL,MIDI_RESET);
2639
2640	delay(500);
2641
2642	outb(GUS_MIDI_CONTROL,0x00);
2643
2644	/*
2645	 * Clear interrupts
2646	 */
2647
2648	SELECT_GUS_REG(port, GUSREG_DMA_CONTROL);
2649	outb(port+GUS_DATA_HIGH, 0x00);
2650	SELECT_GUS_REG(port, GUSREG_TIMER_CONTROL);
2651	outb(port+GUS_DATA_HIGH, 0x00);
2652	SELECT_GUS_REG(port, GUSREG_SAMPLE_CONTROL);
2653	outb(port+GUS_DATA_HIGH, 0x00);
2654
2655	gus_set_voices(sc, voices);
2656
2657	inb(port+GUS_IRQ_STATUS);
2658	SELECT_GUS_REG(port, GUSREG_DMA_CONTROL);
2659	inb(port+GUS_DATA_HIGH);
2660	SELECT_GUS_REG(port, GUSREG_SAMPLE_CONTROL);
2661	inb(port+GUS_DATA_HIGH);
2662	SELECT_GUS_REG(port, GUSREG_IRQ_STATUS);
2663	inb(port+GUS_DATA_HIGH);
2664
2665	/*
2666	 * Reset voice specific information
2667	 */
2668
2669	for(i = 0; i < voices; i++) {
2670		outb(port+GUS_VOICE_SELECT, (unsigned char) i);
2671
2672		SELECT_GUS_REG(port, GUSREG_VOICE_CNTL);
2673
2674		sc->sc_voc[i].voccntl = GUSMASK_VOICE_STOPPED |
2675			GUSMASK_STOP_VOICE;
2676
2677		outb(port+GUS_DATA_HIGH, sc->sc_voc[i].voccntl);
2678
2679		sc->sc_voc[i].volcntl = GUSMASK_VOLUME_STOPPED |
2680				GUSMASK_STOP_VOLUME;
2681
2682		SELECT_GUS_REG(port, GUSREG_VOLUME_CONTROL);
2683		outb(port+GUS_DATA_HIGH, sc->sc_voc[i].volcntl);
2684
2685		delay(100);
2686
2687		gus_set_samprate(sc, i, 8000);
2688		SELECT_GUS_REG(port, GUSREG_START_ADDR_HIGH);
2689		outw(port+GUS_DATA_LOW, 0x0000);
2690		SELECT_GUS_REG(port, GUSREG_START_ADDR_LOW);
2691		outw(port+GUS_DATA_LOW, 0x0000);
2692		SELECT_GUS_REG(port, GUSREG_END_ADDR_HIGH);
2693		outw(port+GUS_DATA_LOW, 0x0000);
2694		SELECT_GUS_REG(port, GUSREG_END_ADDR_LOW);
2695		outw(port+GUS_DATA_LOW, 0x0000);
2696		SELECT_GUS_REG(port, GUSREG_VOLUME_RATE);
2697		outb(port+GUS_DATA_HIGH, 0x01);
2698		SELECT_GUS_REG(port, GUSREG_START_VOLUME);
2699		outb(port+GUS_DATA_HIGH, 0x10);
2700		SELECT_GUS_REG(port, GUSREG_END_VOLUME);
2701		outb(port+GUS_DATA_HIGH, 0xe0);
2702		SELECT_GUS_REG(port, GUSREG_CUR_VOLUME);
2703		outw(port+GUS_DATA_LOW, 0x0000);
2704
2705		SELECT_GUS_REG(port, GUSREG_CUR_ADDR_HIGH);
2706		outw(port+GUS_DATA_LOW, 0x0000);
2707		SELECT_GUS_REG(port, GUSREG_CUR_ADDR_LOW);
2708		outw(port+GUS_DATA_LOW, 0x0000);
2709		SELECT_GUS_REG(port, GUSREG_PAN_POS);
2710		outb(port+GUS_DATA_HIGH, 0x07);
2711	}
2712
2713	/*
2714	 * Clear out any pending IRQs
2715	 */
2716
2717	inb(port+GUS_IRQ_STATUS);
2718	SELECT_GUS_REG(port, GUSREG_DMA_CONTROL);
2719	inb(port+GUS_DATA_HIGH);
2720	SELECT_GUS_REG(port, GUSREG_SAMPLE_CONTROL);
2721	inb(port+GUS_DATA_HIGH);
2722	SELECT_GUS_REG(port, GUSREG_IRQ_STATUS);
2723	inb(port+GUS_DATA_HIGH);
2724
2725	SELECT_GUS_REG(port, GUSREG_RESET);
2726	outb(port+GUS_DATA_HIGH, GUSMASK_MASTER_RESET | GUSMASK_DAC_ENABLE |
2727		GUSMASK_IRQ_ENABLE);
2728
2729	splx(s);
2730}
2731
2732
2733STATIC void
2734gus_init_cs4231(sc)
2735	struct gus_softc *sc;
2736{
2737	register int port = sc->sc_iobase;
2738	u_char ctrl;
2739
2740	ctrl = (port & 0xf0) >> 4;	/* set port address middle nibble */
2741	/*
2742	 * The codec is a bit weird--swapped dma channels.
2743	 */
2744	ctrl |= GUS_MAX_CODEC_ENABLE;
2745	if (sc->sc_drq >= 4)
2746		ctrl |= GUS_MAX_RECCHAN16;
2747	if (sc->sc_recdrq >= 4)
2748		ctrl |= GUS_MAX_PLAYCHAN16;
2749
2750	outb(port+GUS_MAX_CTRL, ctrl);
2751
2752	sc->sc_codec.sc_iot = sc->sc_iot;
2753	sc->sc_codec.sc_iobase = port+GUS_MAX_CODEC_BASE;
2754
2755	if (ad1848_probe(&sc->sc_codec) == 0) {
2756		sc->sc_flags &= ~GUS_CODEC_INSTALLED;
2757	} else {
2758		struct ad1848_volume vol = {AUDIO_MAX_GAIN, AUDIO_MAX_GAIN};
2759		struct audio_hw_if gusmax_hw_if = {
2760			gusopen,
2761			gusmax_close,
2762			NULL,				/* drain */
2763
2764			gus_query_encoding, /* query encoding */
2765
2766			gusmax_set_params,
2767
2768			gusmax_round_blocksize,
2769
2770			gusmax_set_out_port,
2771			gusmax_get_out_port,
2772			gusmax_set_in_port,
2773			gusmax_get_in_port,
2774
2775			gusmax_commit_settings,
2776
2777			gusmax_dma_output,
2778			gusmax_dma_input,
2779			gusmax_halt_out_dma,
2780			gusmax_halt_in_dma,
2781			gusmax_cont_out_dma,
2782			gusmax_cont_in_dma,
2783
2784			gusmax_speaker_ctl,
2785
2786			gus_getdev,
2787			gus_setfd,
2788			gusmax_mixer_set_port,
2789			gusmax_mixer_get_port,
2790			gusmax_mixer_query_devinfo,
2791			1,				/* full-duplex */
2792			0,
2793		};
2794		sc->sc_flags |= GUS_CODEC_INSTALLED;
2795		sc->sc_codec.parent = sc;
2796		sc->sc_codec.sc_drq = sc->sc_recdrq;
2797		sc->sc_codec.sc_recdrq = sc->sc_drq;
2798		gus_hw_if = gusmax_hw_if;
2799		/* enable line in and mic in the GUS mixer; the codec chip
2800		   will do the real mixing for them. */
2801		sc->sc_mixcontrol &= ~GUSMASK_LINE_IN; /* 0 enables. */
2802		sc->sc_mixcontrol |= GUSMASK_MIC_IN; /* 1 enables. */
2803		outb(sc->sc_iobase+GUS_MIX_CONTROL, sc->sc_mixcontrol);
2804
2805		ad1848_attach(&sc->sc_codec);
2806		/* turn on pre-MUX microphone gain. */
2807		ad1848_set_mic_gain(&sc->sc_codec, &vol);
2808	}
2809}
2810
2811
2812/*
2813 * Return info about the audio device, for the AUDIO_GETINFO ioctl
2814 */
2815
2816int
2817gus_getdev(addr, dev)
2818	void * addr;
2819	struct audio_device *dev;
2820{
2821	*dev = gus_device;
2822	return 0;
2823}
2824
2825/*
2826 * stubs (XXX)
2827 */
2828
2829int
2830gus_set_in_gain(addr, gain, balance)
2831	caddr_t addr;
2832	u_int gain;
2833	u_char balance;
2834{
2835	DPRINTF(("gus_set_in_gain called\n"));
2836	return 0;
2837}
2838
2839int
2840gus_get_in_gain(addr)
2841	caddr_t addr;
2842{
2843	DPRINTF(("gus_get_in_gain called\n"));
2844	return 0;
2845}
2846
2847int
2848gusmax_set_out_port(addr, port)
2849	void * addr;
2850	int port;
2851{
2852	register struct ad1848_softc *sc = addr;
2853	return gus_set_out_port(sc->parent, port);
2854}
2855
2856int
2857gus_set_out_port(addr, port)
2858	void * addr;
2859	int port;
2860{
2861	register struct gus_softc *sc = addr;
2862	DPRINTF(("gus_set_out_port called\n"));
2863	sc->sc_out_port = port;
2864
2865	return 0;
2866}
2867
2868int
2869gusmax_get_out_port(addr)
2870	void * addr;
2871{
2872	register struct ad1848_softc *sc = addr;
2873	return gus_get_out_port(sc->parent);
2874}
2875
2876int
2877gus_get_out_port(addr)
2878	void * addr;
2879{
2880	register struct gus_softc *sc = addr;
2881	DPRINTF(("gus_get_out_port() called\n"));
2882	return sc->sc_out_port;
2883}
2884
2885int
2886gusmax_set_in_port(addr, port)
2887	void * addr;
2888	int port;
2889{
2890	register struct ad1848_softc *sc = addr;
2891	DPRINTF(("gusmax_set_in_port: %d\n", port));
2892
2893	switch(port) {
2894	case MIC_IN_PORT:
2895	case LINE_IN_PORT:
2896	case AUX1_IN_PORT:
2897	case DAC_IN_PORT:
2898		break;
2899	default:
2900		return(EINVAL);
2901		/*NOTREACHED*/
2902	}
2903	return(ad1848_set_rec_port(sc, port));
2904}
2905
2906int
2907gusmax_get_in_port(addr)
2908	void * addr;
2909{
2910	register struct ad1848_softc *sc = addr;
2911	int port;
2912
2913	port = ad1848_get_rec_port(sc);
2914	DPRINTF(("gusmax_get_in_port: %d\n", port));
2915
2916	return(port);
2917}
2918
2919int
2920gus_set_in_port(addr, port)
2921	void * addr;
2922	int port;
2923{
2924	register struct gus_softc *sc = addr;
2925	DPRINTF(("gus_set_in_port called\n"));
2926	/*
2927	 * On the GUS with ICS mixer, the ADC input is after the mixer stage,
2928	 * so we can't set the input port.
2929	 *
2930	 * On the GUS with CS4231 codec/mixer, see gusmax_set_in_port().
2931	 */
2932	sc->sc_in_port = port;
2933
2934	return 0;
2935}
2936
2937
2938int
2939gus_get_in_port(addr)
2940	void * addr;
2941{
2942	register struct gus_softc *sc = addr;
2943	DPRINTF(("gus_get_in_port called\n"));
2944	return sc->sc_in_port;
2945}
2946
2947
2948int
2949gusmax_dma_input(addr, buf, size, callback, arg)
2950	void * addr;
2951	void *buf;
2952	int size;
2953	void (*callback) __P((void *));
2954	void *arg;
2955{
2956	register struct ad1848_softc *sc = addr;
2957	return gus_dma_input(sc->parent, buf, size, callback, arg);
2958}
2959
2960/*
2961 * Start sampling the input source into the requested DMA buffer.
2962 * Called at splgus(), either from top-half or from interrupt handler.
2963 */
2964int
2965gus_dma_input(addr, buf, size, callback, arg)
2966	void * addr;
2967	void *buf;
2968	int size;
2969	void (*callback) __P((void *));
2970	void *arg;
2971{
2972	register struct gus_softc *sc = addr;
2973	register int port = sc->sc_iobase;
2974	register u_char dmac;
2975	DMAPRINTF(("gus_dma_input called\n"));
2976
2977	/*
2978	 * Sample SIZE bytes of data from the card, into buffer at BUF.
2979	 */
2980
2981	if (sc->sc_precision == 16)
2982	    return EINVAL;		/* XXX */
2983
2984	/* set DMA modes */
2985	dmac = GUSMASK_SAMPLE_IRQ|GUSMASK_SAMPLE_START;
2986	if (sc->sc_recdrq >= 4)
2987		dmac |= GUSMASK_SAMPLE_DATA16;
2988	if (sc->sc_encoding == AUDIO_ENCODING_ULAW ||
2989	    sc->sc_encoding == AUDIO_ENCODING_ULINEAR_LE ||
2990	    sc->sc_encoding == AUDIO_ENCODING_ULINEAR_BE)
2991	    dmac |= GUSMASK_SAMPLE_INVBIT;
2992	if (sc->sc_channels == 2)
2993	    dmac |= GUSMASK_SAMPLE_STEREO;
2994	isa_dmastart(sc->sc_dev.dv_parent, sc->sc_recdrq, buf, size,
2995	    NULL, DMAMODE_READ, BUS_DMA_NOWAIT);
2996
2997	DMAPRINTF(("gus_dma_input isa_dmastarted\n"));
2998	sc->sc_flags |= GUS_DMAIN_ACTIVE;
2999	sc->sc_dmainintr = callback;
3000	sc->sc_inarg = arg;
3001	sc->sc_dmaincnt = size;
3002	sc->sc_dmainaddr = buf;
3003
3004	SELECT_GUS_REG(port, GUSREG_SAMPLE_CONTROL);
3005	outb(port+GUS_DATA_HIGH, dmac);	/* Go! */
3006
3007
3008	DMAPRINTF(("gus_dma_input returning\n"));
3009
3010	return 0;
3011}
3012
3013STATIC int
3014gus_dmain_intr(sc)
3015	struct gus_softc *sc;
3016{
3017        void (*callback) __P((void *));
3018	void *arg;
3019
3020	DMAPRINTF(("gus_dmain_intr called\n"));
3021	if (sc->sc_dmainintr) {
3022	    isa_dmadone(sc->sc_dev.dv_parent, sc->sc_recdrq);
3023	    callback = sc->sc_dmainintr;
3024	    arg = sc->sc_inarg;
3025
3026	    sc->sc_dmainaddr = 0;
3027	    sc->sc_dmaincnt = 0;
3028	    sc->sc_dmainintr = 0;
3029	    sc->sc_inarg = 0;
3030
3031	    sc->sc_flags &= ~GUS_DMAIN_ACTIVE;
3032	    DMAPRINTF(("calling dmain_intr callback %x(%x)\n", callback, arg));
3033	    (*callback)(arg);
3034	    return 1;
3035	} else {
3036	    DMAPRINTF(("gus_dmain_intr false?\n"));
3037	    return 0;			/* XXX ??? */
3038	}
3039}
3040
3041int
3042gusmax_halt_out_dma(addr)
3043	void * addr;
3044{
3045	register struct ad1848_softc *sc = addr;
3046	return gus_halt_out_dma(sc->parent);
3047}
3048
3049
3050int
3051gusmax_halt_in_dma(addr)
3052	void * addr;
3053{
3054	register struct ad1848_softc *sc = addr;
3055	return gus_halt_in_dma(sc->parent);
3056}
3057
3058int
3059gusmax_cont_out_dma(addr)
3060	void * addr;
3061{
3062	register struct ad1848_softc *sc = addr;
3063	return gus_cont_out_dma(sc->parent);
3064}
3065
3066int
3067gusmax_cont_in_dma(addr)
3068	void * addr;
3069{
3070	register struct ad1848_softc *sc = addr;
3071	return gus_cont_in_dma(sc->parent);
3072}
3073
3074/*
3075 * Stop any DMA output.  Called at splgus().
3076 */
3077int
3078gus_halt_out_dma(addr)
3079	void * addr;
3080{
3081	register struct gus_softc *sc = addr;
3082	register int port = sc->sc_iobase;
3083
3084	DMAPRINTF(("gus_halt_out_dma called\n"));
3085	/*
3086	 * Make sure the GUS _isn't_ setup for DMA
3087	 */
3088
3089 	SELECT_GUS_REG(port, GUSREG_DMA_CONTROL);
3090	outb(sc->sc_iobase+GUS_DATA_HIGH, 0);
3091
3092	untimeout(gus_dmaout_timeout, sc);
3093	isa_dmaabort(sc->sc_dev.dv_parent, sc->sc_drq);
3094	sc->sc_flags &= ~(GUS_DMAOUT_ACTIVE|GUS_LOCKED);
3095	sc->sc_dmaoutintr = 0;
3096	sc->sc_outarg = 0;
3097	sc->sc_dmaoutaddr = 0;
3098	sc->sc_dmaoutcnt = 0;
3099	sc->sc_dmabuf = 0;
3100	sc->sc_bufcnt = 0;
3101	sc->sc_playbuf = -1;
3102	/* also stop playing */
3103	gus_stop_voice(sc, GUS_VOICE_LEFT, 1);
3104	gus_stop_voice(sc, GUS_VOICE_RIGHT, 0);
3105
3106	return 0;
3107}
3108
3109/*
3110 * Stop any DMA output.  Called at splgus().
3111 */
3112int
3113gus_halt_in_dma(addr)
3114	void * addr;
3115{
3116	register struct gus_softc *sc = addr;
3117	register int port = sc->sc_iobase;
3118	DMAPRINTF(("gus_halt_in_dma called\n"));
3119
3120	/*
3121	 * Make sure the GUS _isn't_ setup for DMA
3122	 */
3123
3124 	SELECT_GUS_REG(port, GUSREG_SAMPLE_CONTROL);
3125	outb(port+GUS_DATA_HIGH,
3126	     inb(port+GUS_DATA_HIGH) & ~(GUSMASK_SAMPLE_START|GUSMASK_SAMPLE_IRQ));
3127
3128	isa_dmaabort(sc->sc_dev.dv_parent, sc->sc_recdrq);
3129	sc->sc_flags &= ~GUS_DMAIN_ACTIVE;
3130	sc->sc_dmainintr = 0;
3131	sc->sc_inarg = 0;
3132	sc->sc_dmainaddr = 0;
3133	sc->sc_dmaincnt = 0;
3134
3135	return 0;
3136}
3137
3138int
3139gus_cont_out_dma(addr)
3140	void * addr;
3141{
3142	DPRINTF(("gus_cont_out_dma called\n"));
3143	return EOPNOTSUPP;
3144}
3145
3146int
3147gus_cont_in_dma(addr)
3148	void * addr;
3149{
3150	DPRINTF(("gus_cont_in_dma called\n"));
3151	return EOPNOTSUPP;
3152}
3153
3154
3155STATIC int
3156gus_setfd(addr, flag)
3157	void *addr;
3158	int flag;
3159{
3160    if (gus_hw_if.full_duplex == 0)
3161	 return ENOTTY;
3162
3163    return(0);				/* nothing fancy to do. */
3164}
3165
3166STATIC __inline int
3167gus_to_vol(cp, vol)
3168	mixer_ctrl_t *cp;
3169	struct ad1848_volume *vol;
3170{
3171	if (cp->un.value.num_channels == 1) {
3172		vol->left = vol->right = cp->un.value.level[AUDIO_MIXER_LEVEL_MONO];
3173		return(1);
3174	}
3175	else if (cp->un.value.num_channels == 2) {
3176		vol->left  = cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT];
3177		vol->right = cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT];
3178		return(1);
3179	}
3180	return(0);
3181}
3182
3183STATIC __inline int
3184gus_from_vol(cp, vol)
3185	mixer_ctrl_t *cp;
3186	struct ad1848_volume *vol;
3187{
3188	if (cp->un.value.num_channels == 1) {
3189		cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = vol->left;
3190		return(1);
3191	}
3192	else if (cp->un.value.num_channels == 2) {
3193		cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = vol->left;
3194		cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = vol->right;
3195		return(1);
3196	}
3197	return(0);
3198}
3199
3200STATIC int
3201gusmax_mixer_get_port(addr, cp)
3202	void *addr;
3203	mixer_ctrl_t *cp;
3204{
3205	register struct ad1848_softc *ac = addr;
3206	register struct gus_softc *sc = ac->parent;
3207	struct ad1848_volume vol;
3208	int error = EINVAL;
3209
3210	DPRINTF(("gusmax_mixer_get_port: port=%d\n", cp->dev));
3211
3212	switch (cp->dev) {
3213#if 0 /* use mono level instead */
3214	case GUSMAX_MIC_IN_LVL:	/* Microphone */
3215		if (cp->type == AUDIO_MIXER_VALUE) {
3216			error = ad1848_get_mic_gain(ac, &vol);
3217			if (!error)
3218				gus_from_vol(cp, &vol);
3219		}
3220		break;
3221#endif
3222
3223	case GUSMAX_DAC_LVL:		/* dac out */
3224		if (cp->type == AUDIO_MIXER_VALUE) {
3225			error = ad1848_get_aux1_gain(ac, &vol);
3226			if (!error)
3227				gus_from_vol(cp, &vol);
3228		}
3229		break;
3230
3231	case GUSMAX_LINE_IN_LVL:	/* line in */
3232		if (cp->type == AUDIO_MIXER_VALUE) {
3233			error = cs4231_get_linein_gain(ac, &vol);
3234			if (!error)
3235				gus_from_vol(cp, &vol);
3236		}
3237		break;
3238
3239	case GUSMAX_MONO_LVL:	/* mono */
3240		if (cp->type == AUDIO_MIXER_VALUE &&
3241		    cp->un.value.num_channels == 1) {
3242			error = cs4231_get_mono_gain(ac, &vol);
3243			if (!error)
3244				gus_from_vol(cp, &vol);
3245		}
3246		break;
3247
3248	case GUSMAX_CD_LVL:	/* CD */
3249		if (cp->type == AUDIO_MIXER_VALUE) {
3250			error = ad1848_get_aux2_gain(ac, &vol);
3251			if (!error)
3252				gus_from_vol(cp, &vol);
3253		}
3254		break;
3255
3256	case GUSMAX_MONITOR_LVL:	/* monitor level */
3257		if (cp->type == AUDIO_MIXER_VALUE &&
3258		    cp->un.value.num_channels == 1) {
3259			error = ad1848_get_mon_gain(ac, &vol);
3260			if (!error)
3261				cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
3262					vol.left;
3263		}
3264		break;
3265
3266	case GUSMAX_OUT_LVL:	/* output level */
3267		if (cp->type == AUDIO_MIXER_VALUE) {
3268			error = ad1848_get_out_gain(ac, &vol);
3269			if (!error)
3270				gus_from_vol(cp, &vol);
3271		}
3272		break;
3273
3274	case GUSMAX_SPEAKER_LVL:	/* fake speaker for mute naming */
3275		if (cp->type == AUDIO_MIXER_VALUE) {
3276			if (sc->sc_mixcontrol & GUSMASK_LINE_OUT)
3277				vol.left = vol.right = AUDIO_MAX_GAIN;
3278			else
3279				vol.left = vol.right = AUDIO_MIN_GAIN;
3280			error = 0;
3281			gus_from_vol(cp, &vol);
3282		}
3283		break;
3284
3285	case GUSMAX_LINE_IN_MUTE:
3286		if (cp->type == AUDIO_MIXER_ENUM) {
3287			cp->un.ord = ac->line_mute;
3288			error = 0;
3289		}
3290		break;
3291
3292
3293	case GUSMAX_DAC_MUTE:
3294		if (cp->type == AUDIO_MIXER_ENUM) {
3295			cp->un.ord = ac->aux1_mute;
3296			error = 0;
3297		}
3298		break;
3299
3300	case GUSMAX_CD_MUTE:
3301		if (cp->type == AUDIO_MIXER_ENUM) {
3302			cp->un.ord = ac->aux2_mute;
3303			error = 0;
3304		}
3305		break;
3306
3307	case GUSMAX_MONO_MUTE:
3308		if (cp->type == AUDIO_MIXER_ENUM) {
3309			cp->un.ord = ac->mono_mute;
3310			error = 0;
3311		}
3312		break;
3313
3314	case GUSMAX_MONITOR_MUTE:
3315		if (cp->type == AUDIO_MIXER_ENUM) {
3316			cp->un.ord = ac->mon_mute;
3317			error = 0;
3318		}
3319		break;
3320
3321	case GUSMAX_SPEAKER_MUTE:
3322		if (cp->type == AUDIO_MIXER_ENUM) {
3323			cp->un.ord = sc->sc_mixcontrol & GUSMASK_LINE_OUT ? 1 : 0;
3324			error = 0;
3325		}
3326		break;
3327
3328	case GUSMAX_REC_LVL:		/* record level */
3329		if (cp->type == AUDIO_MIXER_VALUE) {
3330			error = ad1848_get_rec_gain(ac, &vol);
3331			if (!error)
3332				gus_from_vol(cp, &vol);
3333		}
3334		break;
3335
3336	case GUSMAX_RECORD_SOURCE:
3337		if (cp->type == AUDIO_MIXER_ENUM) {
3338			cp->un.ord = ad1848_get_rec_port(ac);
3339			error = 0;
3340		}
3341		break;
3342
3343	default:
3344		error = ENXIO;
3345		break;
3346	}
3347
3348	return(error);
3349}
3350
3351STATIC int
3352gus_mixer_get_port(addr, cp)
3353	void *addr;
3354	mixer_ctrl_t *cp;
3355{
3356	register struct gus_softc *sc = addr;
3357	register struct ics2101_softc *ic = &sc->sc_mixer;
3358	struct ad1848_volume vol;
3359	int error = EINVAL;
3360
3361	DPRINTF(("gus_mixer_get_port: dev=%d type=%d\n", cp->dev, cp->type));
3362
3363	if (!HAS_MIXER(sc) && cp->dev > GUSICS_MASTER_MUTE)
3364		return ENXIO;
3365
3366	switch (cp->dev) {
3367
3368	case GUSICS_MIC_IN_MUTE:	/* Microphone */
3369		if (cp->type == AUDIO_MIXER_ENUM) {
3370			if (HAS_MIXER(sc))
3371				cp->un.ord = ic->sc_mute[GUSMIX_CHAN_MIC][ICSMIX_LEFT];
3372			else
3373				cp->un.ord =
3374				    sc->sc_mixcontrol & GUSMASK_MIC_IN ? 0 : 1;
3375			error = 0;
3376		}
3377		break;
3378
3379	case GUSICS_LINE_IN_MUTE:
3380		if (cp->type == AUDIO_MIXER_ENUM) {
3381			if (HAS_MIXER(sc))
3382				cp->un.ord = ic->sc_mute[GUSMIX_CHAN_LINE][ICSMIX_LEFT];
3383			else
3384				cp->un.ord =
3385				    sc->sc_mixcontrol & GUSMASK_LINE_IN ? 1 : 0;
3386			error = 0;
3387		}
3388		break;
3389
3390	case GUSICS_MASTER_MUTE:
3391		if (cp->type == AUDIO_MIXER_ENUM) {
3392			if (HAS_MIXER(sc))
3393				cp->un.ord = ic->sc_mute[GUSMIX_CHAN_MASTER][ICSMIX_LEFT];
3394			else
3395				cp->un.ord =
3396				    sc->sc_mixcontrol & GUSMASK_LINE_OUT ? 1 : 0;
3397			error = 0;
3398		}
3399		break;
3400
3401	case GUSICS_DAC_MUTE:
3402		if (cp->type == AUDIO_MIXER_ENUM) {
3403			cp->un.ord = ic->sc_mute[GUSMIX_CHAN_DAC][ICSMIX_LEFT];
3404			error = 0;
3405		}
3406		break;
3407
3408	case GUSICS_CD_MUTE:
3409		if (cp->type == AUDIO_MIXER_ENUM) {
3410			cp->un.ord = ic->sc_mute[GUSMIX_CHAN_CD][ICSMIX_LEFT];
3411			error = 0;
3412		}
3413		break;
3414
3415	case GUSICS_MASTER_LVL:
3416		if (cp->type == AUDIO_MIXER_VALUE) {
3417			vol.left = ic->sc_setting[GUSMIX_CHAN_MASTER][ICSMIX_LEFT];
3418			vol.right = ic->sc_setting[GUSMIX_CHAN_MASTER][ICSMIX_RIGHT];
3419			if (gus_from_vol(cp, &vol))
3420				error = 0;
3421		}
3422		break;
3423
3424	case GUSICS_MIC_IN_LVL:	/* Microphone */
3425		if (cp->type == AUDIO_MIXER_VALUE) {
3426			vol.left = ic->sc_setting[GUSMIX_CHAN_MIC][ICSMIX_LEFT];
3427			vol.right = ic->sc_setting[GUSMIX_CHAN_MIC][ICSMIX_RIGHT];
3428			if (gus_from_vol(cp, &vol))
3429				error = 0;
3430		}
3431		break;
3432
3433	case GUSICS_LINE_IN_LVL:	/* line in */
3434		if (cp->type == AUDIO_MIXER_VALUE) {
3435			vol.left = ic->sc_setting[GUSMIX_CHAN_LINE][ICSMIX_LEFT];
3436			vol.right = ic->sc_setting[GUSMIX_CHAN_LINE][ICSMIX_RIGHT];
3437			if (gus_from_vol(cp, &vol))
3438				error = 0;
3439		}
3440		break;
3441
3442
3443	case GUSICS_CD_LVL:
3444		if (cp->type == AUDIO_MIXER_VALUE) {
3445			vol.left = ic->sc_setting[GUSMIX_CHAN_CD][ICSMIX_LEFT];
3446			vol.right = ic->sc_setting[GUSMIX_CHAN_CD][ICSMIX_RIGHT];
3447			if (gus_from_vol(cp, &vol))
3448				error = 0;
3449		}
3450		break;
3451
3452	case GUSICS_DAC_LVL:		/* dac out */
3453		if (cp->type == AUDIO_MIXER_VALUE) {
3454			vol.left = ic->sc_setting[GUSMIX_CHAN_DAC][ICSMIX_LEFT];
3455			vol.right = ic->sc_setting[GUSMIX_CHAN_DAC][ICSMIX_RIGHT];
3456			if (gus_from_vol(cp, &vol))
3457				error = 0;
3458		}
3459		break;
3460
3461
3462	case GUSICS_RECORD_SOURCE:
3463		if (cp->type == AUDIO_MIXER_ENUM) {
3464			/* Can't set anything else useful, sigh. */
3465			 cp->un.ord = 0;
3466		}
3467		break;
3468
3469	default:
3470		return ENXIO;
3471	    /*NOTREACHED*/
3472	}
3473	return error;
3474}
3475
3476STATIC void
3477gusics_master_mute(ic, mute)
3478	struct ics2101_softc *ic;
3479	int mute;
3480{
3481	ics2101_mix_mute(ic, GUSMIX_CHAN_MASTER, ICSMIX_LEFT, mute);
3482	ics2101_mix_mute(ic, GUSMIX_CHAN_MASTER, ICSMIX_RIGHT, mute);
3483}
3484
3485STATIC void
3486gusics_mic_mute(ic, mute)
3487	struct ics2101_softc *ic;
3488	int mute;
3489{
3490	ics2101_mix_mute(ic, GUSMIX_CHAN_MIC, ICSMIX_LEFT, mute);
3491	ics2101_mix_mute(ic, GUSMIX_CHAN_MIC, ICSMIX_RIGHT, mute);
3492}
3493
3494STATIC void
3495gusics_linein_mute(ic, mute)
3496	struct ics2101_softc *ic;
3497	int mute;
3498{
3499	ics2101_mix_mute(ic, GUSMIX_CHAN_LINE, ICSMIX_LEFT, mute);
3500	ics2101_mix_mute(ic, GUSMIX_CHAN_LINE, ICSMIX_RIGHT, mute);
3501}
3502
3503STATIC void
3504gusics_cd_mute(ic, mute)
3505	struct ics2101_softc *ic;
3506	int mute;
3507{
3508	ics2101_mix_mute(ic, GUSMIX_CHAN_CD, ICSMIX_LEFT, mute);
3509	ics2101_mix_mute(ic, GUSMIX_CHAN_CD, ICSMIX_RIGHT, mute);
3510}
3511
3512STATIC void
3513gusics_dac_mute(ic, mute)
3514	struct ics2101_softc *ic;
3515	int mute;
3516{
3517	ics2101_mix_mute(ic, GUSMIX_CHAN_DAC, ICSMIX_LEFT, mute);
3518	ics2101_mix_mute(ic, GUSMIX_CHAN_DAC, ICSMIX_RIGHT, mute);
3519}
3520
3521STATIC int
3522gusmax_mixer_set_port(addr, cp)
3523	void *addr;
3524	mixer_ctrl_t *cp;
3525{
3526	register struct ad1848_softc *ac = addr;
3527	register struct gus_softc *sc = ac->parent;
3528	struct ad1848_volume vol;
3529	int error = EINVAL;
3530
3531	DPRINTF(("gusmax_mixer_set_port: dev=%d type=%d\n", cp->dev, cp->type));
3532
3533	switch (cp->dev) {
3534#if 0
3535	case GUSMAX_MIC_IN_LVL:	/* Microphone */
3536		if (cp->type == AUDIO_MIXER_VALUE &&
3537		    cp->un.value.num_channels == 1) {
3538			/* XXX enable/disable pre-MUX fixed gain */
3539			if (gus_to_vol(cp, &vol))
3540				error = ad1848_set_mic_gain(ac, &vol);
3541		}
3542		break;
3543#endif
3544
3545	case GUSMAX_DAC_LVL:		/* dac out */
3546		if (cp->type == AUDIO_MIXER_VALUE) {
3547			if (gus_to_vol(cp, &vol))
3548				error = ad1848_set_aux1_gain(ac, &vol);
3549		}
3550		break;
3551
3552	case GUSMAX_LINE_IN_LVL:	/* line in */
3553		if (cp->type == AUDIO_MIXER_VALUE) {
3554			if (gus_to_vol(cp, &vol))
3555				error = cs4231_set_linein_gain(ac, &vol);
3556		}
3557		break;
3558
3559	case GUSMAX_MONO_LVL:	/* mic/mono in */
3560		if (cp->type == AUDIO_MIXER_VALUE &&
3561		    cp->un.value.num_channels == 1) {
3562			if (gus_to_vol(cp, &vol))
3563				error = cs4231_set_mono_gain(ac, &vol);
3564		}
3565		break;
3566
3567	case GUSMAX_CD_LVL:	/* CD: AUX2 */
3568		if (cp->type == AUDIO_MIXER_VALUE) {
3569			if (gus_to_vol(cp, &vol))
3570				error = ad1848_set_aux2_gain(ac, &vol);
3571		}
3572		break;
3573
3574	case GUSMAX_MONITOR_LVL:
3575		if (cp->type == AUDIO_MIXER_VALUE &&
3576		    cp->un.value.num_channels == 1) {
3577			vol.left  = cp->un.value.level[AUDIO_MIXER_LEVEL_MONO];
3578			error = ad1848_set_mon_gain(ac, &vol);
3579		}
3580		break;
3581
3582	case GUSMAX_OUT_LVL:	/* output volume */
3583		if (cp->type == AUDIO_MIXER_VALUE) {
3584			if (gus_to_vol(cp, &vol))
3585				error = ad1848_set_out_gain(ac, &vol);
3586		}
3587		break;
3588
3589	case GUSMAX_SPEAKER_LVL:
3590		if (cp->type == AUDIO_MIXER_VALUE &&
3591		    cp->un.value.num_channels == 1) {
3592			if (gus_to_vol(cp, &vol)) {
3593				gus_speaker_ctl(sc, vol.left > AUDIO_MIN_GAIN ?
3594						SPKR_ON : SPKR_OFF);
3595				error = 0;
3596			}
3597		}
3598		break;
3599
3600	case GUSMAX_LINE_IN_MUTE:
3601		if (cp->type == AUDIO_MIXER_ENUM) {
3602			ac->line_mute = cp->un.ord ? 1 : 0;
3603			DPRINTF(("line mute %d\n", cp->un.ord));
3604			cs4231_mute_line(ac, ac->line_mute);
3605			gus_linein_ctl(sc, ac->line_mute ? SPKR_OFF : SPKR_ON);
3606			error = 0;
3607		}
3608		break;
3609
3610	case GUSMAX_DAC_MUTE:
3611		if (cp->type == AUDIO_MIXER_ENUM) {
3612			ac->aux1_mute = cp->un.ord ? 1 : 0;
3613			DPRINTF(("dac mute %d\n", cp->un.ord));
3614			ad1848_mute_aux1(ac, ac->aux1_mute);
3615			error = 0;
3616		}
3617		break;
3618
3619	case GUSMAX_CD_MUTE:
3620		if (cp->type == AUDIO_MIXER_ENUM) {
3621			ac->aux2_mute = cp->un.ord ? 1 : 0;
3622			DPRINTF(("cd mute %d\n", cp->un.ord));
3623			ad1848_mute_aux2(ac, ac->aux2_mute);
3624			error = 0;
3625		}
3626		break;
3627
3628	case GUSMAX_MONO_MUTE:	/* Microphone */
3629		if (cp->type == AUDIO_MIXER_ENUM) {
3630			ac->mono_mute = cp->un.ord ? 1 : 0;
3631			DPRINTF(("mono mute %d\n", cp->un.ord));
3632			cs4231_mute_mono(ac, ac->mono_mute);
3633			gus_mic_ctl(sc, ac->mono_mute ? SPKR_OFF : SPKR_ON);
3634			error = 0;
3635		}
3636		break;
3637
3638	case GUSMAX_MONITOR_MUTE:
3639		if (cp->type == AUDIO_MIXER_ENUM) {
3640			ac->mon_mute = cp->un.ord ? 1 : 0;
3641			DPRINTF(("mono mute %d\n", cp->un.ord));
3642			cs4231_mute_monitor(ac, ac->mon_mute);
3643			error = 0;
3644		}
3645		break;
3646
3647	case GUSMAX_SPEAKER_MUTE:
3648		if (cp->type == AUDIO_MIXER_ENUM) {
3649			gus_speaker_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON);
3650			error = 0;
3651		}
3652		break;
3653
3654	case GUSMAX_REC_LVL:		/* record level */
3655		if (cp->type == AUDIO_MIXER_VALUE) {
3656			if (gus_to_vol(cp, &vol))
3657				error = ad1848_set_rec_gain(ac, &vol);
3658		}
3659		break;
3660
3661	case GUSMAX_RECORD_SOURCE:
3662		if (cp->type == AUDIO_MIXER_ENUM) {
3663			error = ad1848_set_rec_port(ac, cp->un.ord);
3664		}
3665		break;
3666
3667	default:
3668		return ENXIO;
3669	    /*NOTREACHED*/
3670    }
3671    return error;
3672}
3673
3674STATIC int
3675gus_mixer_set_port(addr, cp)
3676	void *addr;
3677	mixer_ctrl_t *cp;
3678{
3679	register struct gus_softc *sc = addr;
3680	register struct ics2101_softc *ic = &sc->sc_mixer;
3681	struct ad1848_volume vol;
3682	int error = EINVAL;
3683
3684	DPRINTF(("gus_mixer_set_port: dev=%d type=%d\n", cp->dev, cp->type));
3685
3686	if (!HAS_MIXER(sc) && cp->dev > GUSICS_MASTER_MUTE)
3687		return ENXIO;
3688
3689	switch (cp->dev) {
3690
3691	case GUSICS_MIC_IN_MUTE:	/* Microphone */
3692		if (cp->type == AUDIO_MIXER_ENUM) {
3693			DPRINTF(("mic mute %d\n", cp->un.ord));
3694			if (HAS_MIXER(sc)) {
3695				gusics_mic_mute(ic, cp->un.ord);
3696			}
3697			gus_mic_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON);
3698			error = 0;
3699		}
3700		break;
3701
3702	case GUSICS_LINE_IN_MUTE:
3703		if (cp->type == AUDIO_MIXER_ENUM) {
3704			DPRINTF(("linein mute %d\n", cp->un.ord));
3705			if (HAS_MIXER(sc)) {
3706				gusics_linein_mute(ic, cp->un.ord);
3707			}
3708			gus_linein_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON);
3709			error = 0;
3710		}
3711		break;
3712
3713	case GUSICS_MASTER_MUTE:
3714		if (cp->type == AUDIO_MIXER_ENUM) {
3715			DPRINTF(("master mute %d\n", cp->un.ord));
3716			if (HAS_MIXER(sc)) {
3717				gusics_master_mute(ic, cp->un.ord);
3718			}
3719			gus_speaker_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON);
3720			error = 0;
3721		}
3722		break;
3723
3724	case GUSICS_DAC_MUTE:
3725		if (cp->type == AUDIO_MIXER_ENUM) {
3726			gusics_dac_mute(ic, cp->un.ord);
3727			error = 0;
3728		}
3729		break;
3730
3731	case GUSICS_CD_MUTE:
3732		if (cp->type == AUDIO_MIXER_ENUM) {
3733			gusics_cd_mute(ic, cp->un.ord);
3734			error = 0;
3735		}
3736		break;
3737
3738	case GUSICS_MASTER_LVL:
3739		if (cp->type == AUDIO_MIXER_VALUE) {
3740			if (gus_to_vol(cp, &vol)) {
3741				ics2101_mix_attenuate(ic,
3742						      GUSMIX_CHAN_MASTER,
3743						      ICSMIX_LEFT,
3744						      vol.left);
3745				ics2101_mix_attenuate(ic,
3746						      GUSMIX_CHAN_MASTER,
3747						      ICSMIX_RIGHT,
3748						      vol.right);
3749				error = 0;
3750			}
3751		}
3752		break;
3753
3754	case GUSICS_MIC_IN_LVL:	/* Microphone */
3755		if (cp->type == AUDIO_MIXER_VALUE) {
3756			if (gus_to_vol(cp, &vol)) {
3757				ics2101_mix_attenuate(ic,
3758						      GUSMIX_CHAN_MIC,
3759						      ICSMIX_LEFT,
3760						      vol.left);
3761				ics2101_mix_attenuate(ic,
3762						      GUSMIX_CHAN_MIC,
3763						      ICSMIX_RIGHT,
3764						      vol.right);
3765				error = 0;
3766			}
3767		}
3768		break;
3769
3770	case GUSICS_LINE_IN_LVL:	/* line in */
3771		if (cp->type == AUDIO_MIXER_VALUE) {
3772			if (gus_to_vol(cp, &vol)) {
3773				ics2101_mix_attenuate(ic,
3774						      GUSMIX_CHAN_LINE,
3775						      ICSMIX_LEFT,
3776						      vol.left);
3777				ics2101_mix_attenuate(ic,
3778						      GUSMIX_CHAN_LINE,
3779						      ICSMIX_RIGHT,
3780						      vol.right);
3781				error = 0;
3782			}
3783		}
3784		break;
3785
3786
3787	case GUSICS_CD_LVL:
3788		if (cp->type == AUDIO_MIXER_VALUE) {
3789			if (gus_to_vol(cp, &vol)) {
3790				ics2101_mix_attenuate(ic,
3791						      GUSMIX_CHAN_CD,
3792						      ICSMIX_LEFT,
3793						      vol.left);
3794				ics2101_mix_attenuate(ic,
3795						      GUSMIX_CHAN_CD,
3796						      ICSMIX_RIGHT,
3797						      vol.right);
3798				error = 0;
3799			}
3800		}
3801		break;
3802
3803	case GUSICS_DAC_LVL:		/* dac out */
3804		if (cp->type == AUDIO_MIXER_VALUE) {
3805			if (gus_to_vol(cp, &vol)) {
3806				ics2101_mix_attenuate(ic,
3807						      GUSMIX_CHAN_DAC,
3808						      ICSMIX_LEFT,
3809						      vol.left);
3810				ics2101_mix_attenuate(ic,
3811						      GUSMIX_CHAN_DAC,
3812						      ICSMIX_RIGHT,
3813						      vol.right);
3814				error = 0;
3815			}
3816		}
3817		break;
3818
3819
3820	case GUSICS_RECORD_SOURCE:
3821		if (cp->type == AUDIO_MIXER_ENUM && cp->un.ord == 0) {
3822			/* Can't set anything else useful, sigh. */
3823			error = 0;
3824		}
3825		break;
3826
3827	default:
3828		return ENXIO;
3829	    /*NOTREACHED*/
3830	}
3831	return error;
3832}
3833
3834STATIC int
3835gusmax_mixer_query_devinfo(addr, dip)
3836	void *addr;
3837	register mixer_devinfo_t *dip;
3838{
3839	DPRINTF(("gusmax_query_devinfo: index=%d\n", dip->index));
3840
3841	switch(dip->index) {
3842#if 0
3843    case GUSMAX_MIC_IN_LVL:	/* Microphone */
3844	dip->type = AUDIO_MIXER_VALUE;
3845	dip->mixer_class = GUSMAX_INPUT_CLASS;
3846	dip->prev = AUDIO_MIXER_LAST;
3847	dip->next = GUSMAX_MIC_IN_MUTE;
3848	strcpy(dip->label.name, AudioNmicrophone);
3849	dip->un.v.num_channels = 2;
3850	strcpy(dip->un.v.units.name, AudioNvolume);
3851	break;
3852#endif
3853
3854    case GUSMAX_MONO_LVL:	/* mono/microphone mixer */
3855	dip->type = AUDIO_MIXER_VALUE;
3856	dip->mixer_class = GUSMAX_INPUT_CLASS;
3857	dip->prev = AUDIO_MIXER_LAST;
3858	dip->next = GUSMAX_MONO_MUTE;
3859	strcpy(dip->label.name, AudioNmicrophone);
3860	dip->un.v.num_channels = 1;
3861	strcpy(dip->un.v.units.name, AudioNvolume);
3862	break;
3863
3864    case GUSMAX_DAC_LVL:		/*  dacout */
3865	dip->type = AUDIO_MIXER_VALUE;
3866	dip->mixer_class = GUSMAX_INPUT_CLASS;
3867	dip->prev = AUDIO_MIXER_LAST;
3868	dip->next = GUSMAX_DAC_MUTE;
3869	strcpy(dip->label.name, AudioNdac);
3870	dip->un.v.num_channels = 2;
3871	strcpy(dip->un.v.units.name, AudioNvolume);
3872	break;
3873
3874    case GUSMAX_LINE_IN_LVL:	/* line */
3875	dip->type = AUDIO_MIXER_VALUE;
3876	dip->mixer_class = GUSMAX_INPUT_CLASS;
3877	dip->prev = AUDIO_MIXER_LAST;
3878	dip->next = GUSMAX_LINE_IN_MUTE;
3879	strcpy(dip->label.name, AudioNline);
3880	dip->un.v.num_channels = 2;
3881	strcpy(dip->un.v.units.name, AudioNvolume);
3882	break;
3883
3884    case GUSMAX_CD_LVL:		/* cd */
3885	dip->type = AUDIO_MIXER_VALUE;
3886	dip->mixer_class = GUSMAX_INPUT_CLASS;
3887	dip->prev = AUDIO_MIXER_LAST;
3888	dip->next = GUSMAX_CD_MUTE;
3889	strcpy(dip->label.name, AudioNcd);
3890	dip->un.v.num_channels = 2;
3891	strcpy(dip->un.v.units.name, AudioNvolume);
3892	break;
3893
3894
3895    case GUSMAX_MONITOR_LVL:	/* monitor level */
3896	dip->type = AUDIO_MIXER_VALUE;
3897	dip->mixer_class = GUSMAX_MONITOR_CLASS;
3898	dip->next = GUSMAX_MONITOR_MUTE;
3899	dip->prev = AUDIO_MIXER_LAST;
3900	strcpy(dip->label.name, AudioNmonitor);
3901	dip->un.v.num_channels = 1;
3902	strcpy(dip->un.v.units.name, AudioNvolume);
3903	break;
3904
3905    case GUSMAX_OUT_LVL:		/* cs4231 output volume: not useful? */
3906	dip->type = AUDIO_MIXER_VALUE;
3907	dip->mixer_class = GUSMAX_MONITOR_CLASS;
3908	dip->prev = dip->next = AUDIO_MIXER_LAST;
3909	strcpy(dip->label.name, AudioNoutput);
3910	dip->un.v.num_channels = 2;
3911	strcpy(dip->un.v.units.name, AudioNvolume);
3912	break;
3913
3914    case GUSMAX_SPEAKER_LVL:		/* fake speaker volume */
3915	dip->type = AUDIO_MIXER_VALUE;
3916	dip->mixer_class = GUSMAX_MONITOR_CLASS;
3917	dip->prev = AUDIO_MIXER_LAST;
3918	dip->next = GUSMAX_SPEAKER_MUTE;
3919	strcpy(dip->label.name, AudioNspeaker);
3920	dip->un.v.num_channels = 2;
3921	strcpy(dip->un.v.units.name, AudioNvolume);
3922	break;
3923
3924    case GUSMAX_LINE_IN_MUTE:
3925	dip->mixer_class = GUSMAX_INPUT_CLASS;
3926	dip->type = AUDIO_MIXER_ENUM;
3927	dip->prev = GUSMAX_LINE_IN_LVL;
3928	dip->next = AUDIO_MIXER_LAST;
3929	goto mute;
3930
3931    case GUSMAX_DAC_MUTE:
3932	dip->mixer_class = GUSMAX_INPUT_CLASS;
3933	dip->type = AUDIO_MIXER_ENUM;
3934	dip->prev = GUSMAX_DAC_LVL;
3935	dip->next = AUDIO_MIXER_LAST;
3936	goto mute;
3937
3938    case GUSMAX_CD_MUTE:
3939	dip->mixer_class = GUSMAX_INPUT_CLASS;
3940	dip->type = AUDIO_MIXER_ENUM;
3941	dip->prev = GUSMAX_CD_LVL;
3942	dip->next = AUDIO_MIXER_LAST;
3943	goto mute;
3944
3945    case GUSMAX_MONO_MUTE:
3946	dip->mixer_class = GUSMAX_INPUT_CLASS;
3947	dip->type = AUDIO_MIXER_ENUM;
3948	dip->prev = GUSMAX_MONO_LVL;
3949	dip->next = AUDIO_MIXER_LAST;
3950	goto mute;
3951
3952    case GUSMAX_MONITOR_MUTE:
3953	dip->mixer_class = GUSMAX_OUTPUT_CLASS;
3954	dip->type = AUDIO_MIXER_ENUM;
3955	dip->prev = GUSMAX_MONITOR_LVL;
3956	dip->next = AUDIO_MIXER_LAST;
3957	goto mute;
3958
3959    case GUSMAX_SPEAKER_MUTE:
3960	dip->mixer_class = GUSMAX_OUTPUT_CLASS;
3961	dip->type = AUDIO_MIXER_ENUM;
3962	dip->prev = GUSMAX_SPEAKER_LVL;
3963	dip->next = AUDIO_MIXER_LAST;
3964    mute:
3965	strcpy(dip->label.name, AudioNmute);
3966	dip->un.e.num_mem = 2;
3967	strcpy(dip->un.e.member[0].label.name, AudioNoff);
3968	dip->un.e.member[0].ord = 0;
3969	strcpy(dip->un.e.member[1].label.name, AudioNon);
3970	dip->un.e.member[1].ord = 1;
3971	break;
3972
3973    case GUSMAX_REC_LVL:	/* record level */
3974	dip->type = AUDIO_MIXER_VALUE;
3975	dip->mixer_class = GUSMAX_RECORD_CLASS;
3976	dip->prev = AUDIO_MIXER_LAST;
3977	dip->next = GUSMAX_RECORD_SOURCE;
3978	strcpy(dip->label.name, AudioNrecord);
3979	dip->un.v.num_channels = 2;
3980	strcpy(dip->un.v.units.name, AudioNvolume);
3981	break;
3982
3983    case GUSMAX_RECORD_SOURCE:
3984	dip->mixer_class = GUSMAX_RECORD_CLASS;
3985	dip->type = AUDIO_MIXER_ENUM;
3986	dip->prev = GUSMAX_REC_LVL;
3987	dip->next = AUDIO_MIXER_LAST;
3988	strcpy(dip->label.name, AudioNsource);
3989	dip->un.e.num_mem = 4;
3990	strcpy(dip->un.e.member[0].label.name, AudioNoutput);
3991	dip->un.e.member[0].ord = DAC_IN_PORT;
3992	strcpy(dip->un.e.member[1].label.name, AudioNmicrophone);
3993	dip->un.e.member[1].ord = MIC_IN_PORT;
3994	strcpy(dip->un.e.member[2].label.name, AudioNdac);
3995	dip->un.e.member[2].ord = AUX1_IN_PORT;
3996	strcpy(dip->un.e.member[3].label.name, AudioNline);
3997	dip->un.e.member[3].ord = LINE_IN_PORT;
3998	break;
3999
4000    case GUSMAX_INPUT_CLASS:			/* input class descriptor */
4001	dip->type = AUDIO_MIXER_CLASS;
4002	dip->mixer_class = GUSMAX_INPUT_CLASS;
4003	dip->next = dip->prev = AUDIO_MIXER_LAST;
4004	strcpy(dip->label.name, AudioCInputs);
4005	break;
4006
4007    case GUSMAX_OUTPUT_CLASS:			/* output class descriptor */
4008	dip->type = AUDIO_MIXER_CLASS;
4009	dip->mixer_class = GUSMAX_OUTPUT_CLASS;
4010	dip->next = dip->prev = AUDIO_MIXER_LAST;
4011	strcpy(dip->label.name, AudioCOutputs);
4012	break;
4013
4014    case GUSMAX_MONITOR_CLASS:			/* monitor class descriptor */
4015	dip->type = AUDIO_MIXER_CLASS;
4016	dip->mixer_class = GUSMAX_MONITOR_CLASS;
4017	dip->next = dip->prev = AUDIO_MIXER_LAST;
4018	strcpy(dip->label.name, AudioCMonitor);
4019	break;
4020
4021    case GUSMAX_RECORD_CLASS:			/* record source class */
4022	dip->type = AUDIO_MIXER_CLASS;
4023	dip->mixer_class = GUSMAX_RECORD_CLASS;
4024	dip->next = dip->prev = AUDIO_MIXER_LAST;
4025	strcpy(dip->label.name, AudioCRecord);
4026	break;
4027
4028    default:
4029	return ENXIO;
4030	/*NOTREACHED*/
4031    }
4032    DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name));
4033	return 0;
4034}
4035
4036STATIC int
4037gus_mixer_query_devinfo(addr, dip)
4038	void *addr;
4039	register mixer_devinfo_t *dip;
4040{
4041	register struct gus_softc *sc = addr;
4042
4043	DPRINTF(("gusmax_query_devinfo: index=%d\n", dip->index));
4044
4045	if (!HAS_MIXER(sc) && dip->index > GUSICS_MASTER_MUTE)
4046		return ENXIO;
4047
4048	switch(dip->index) {
4049
4050	case GUSICS_MIC_IN_LVL:	/* Microphone */
4051		dip->type = AUDIO_MIXER_VALUE;
4052		dip->mixer_class = GUSICS_INPUT_CLASS;
4053		dip->prev = AUDIO_MIXER_LAST;
4054		dip->next = GUSICS_MIC_IN_MUTE;
4055		strcpy(dip->label.name, AudioNmicrophone);
4056		dip->un.v.num_channels = 2;
4057		strcpy(dip->un.v.units.name, AudioNvolume);
4058		break;
4059
4060	case GUSICS_LINE_IN_LVL:	/* line */
4061		dip->type = AUDIO_MIXER_VALUE;
4062		dip->mixer_class = GUSICS_INPUT_CLASS;
4063		dip->prev = AUDIO_MIXER_LAST;
4064		dip->next = GUSICS_LINE_IN_MUTE;
4065		strcpy(dip->label.name, AudioNline);
4066		dip->un.v.num_channels = 2;
4067		strcpy(dip->un.v.units.name, AudioNvolume);
4068		break;
4069
4070	case GUSICS_CD_LVL:		/* cd */
4071		dip->type = AUDIO_MIXER_VALUE;
4072		dip->mixer_class = GUSICS_INPUT_CLASS;
4073		dip->prev = AUDIO_MIXER_LAST;
4074		dip->next = GUSICS_CD_MUTE;
4075		strcpy(dip->label.name, AudioNcd);
4076		dip->un.v.num_channels = 2;
4077		strcpy(dip->un.v.units.name, AudioNvolume);
4078		break;
4079
4080	case GUSICS_DAC_LVL:		/*  dacout */
4081		dip->type = AUDIO_MIXER_VALUE;
4082		dip->mixer_class = GUSICS_INPUT_CLASS;
4083		dip->prev = AUDIO_MIXER_LAST;
4084		dip->next = GUSICS_DAC_MUTE;
4085		strcpy(dip->label.name, AudioNdac);
4086		dip->un.v.num_channels = 2;
4087		strcpy(dip->un.v.units.name, AudioNvolume);
4088		break;
4089
4090	case GUSICS_MASTER_LVL:		/*  master output */
4091		dip->type = AUDIO_MIXER_VALUE;
4092		dip->mixer_class = GUSICS_OUTPUT_CLASS;
4093		dip->prev = AUDIO_MIXER_LAST;
4094		dip->next = GUSICS_MASTER_MUTE;
4095		strcpy(dip->label.name, AudioNvolume);
4096		dip->un.v.num_channels = 2;
4097		strcpy(dip->un.v.units.name, AudioNvolume);
4098		break;
4099
4100
4101	case GUSICS_LINE_IN_MUTE:
4102		dip->mixer_class = GUSICS_INPUT_CLASS;
4103		dip->type = AUDIO_MIXER_ENUM;
4104		dip->prev = GUSICS_LINE_IN_LVL;
4105		dip->next = AUDIO_MIXER_LAST;
4106		goto mute;
4107
4108	case GUSICS_DAC_MUTE:
4109		dip->mixer_class = GUSICS_INPUT_CLASS;
4110		dip->type = AUDIO_MIXER_ENUM;
4111		dip->prev = GUSICS_DAC_LVL;
4112		dip->next = AUDIO_MIXER_LAST;
4113		goto mute;
4114
4115	case GUSICS_CD_MUTE:
4116		dip->mixer_class = GUSICS_INPUT_CLASS;
4117		dip->type = AUDIO_MIXER_ENUM;
4118		dip->prev = GUSICS_CD_LVL;
4119		dip->next = AUDIO_MIXER_LAST;
4120		goto mute;
4121
4122	case GUSICS_MIC_IN_MUTE:
4123		dip->mixer_class = GUSICS_INPUT_CLASS;
4124		dip->type = AUDIO_MIXER_ENUM;
4125		dip->prev = GUSICS_MIC_IN_LVL;
4126		dip->next = AUDIO_MIXER_LAST;
4127		goto mute;
4128
4129	case GUSICS_MASTER_MUTE:
4130		dip->mixer_class = GUSICS_OUTPUT_CLASS;
4131		dip->type = AUDIO_MIXER_ENUM;
4132		dip->prev = GUSICS_MASTER_LVL;
4133		dip->next = AUDIO_MIXER_LAST;
4134mute:
4135		strcpy(dip->label.name, AudioNmute);
4136		dip->un.e.num_mem = 2;
4137		strcpy(dip->un.e.member[0].label.name, AudioNoff);
4138		dip->un.e.member[0].ord = 0;
4139		strcpy(dip->un.e.member[1].label.name, AudioNon);
4140		dip->un.e.member[1].ord = 1;
4141		break;
4142
4143	case GUSICS_RECORD_SOURCE:
4144		dip->mixer_class = GUSICS_RECORD_CLASS;
4145		dip->type = AUDIO_MIXER_ENUM;
4146		dip->prev = dip->next = AUDIO_MIXER_LAST;
4147		strcpy(dip->label.name, AudioNsource);
4148		dip->un.e.num_mem = 1;
4149		strcpy(dip->un.e.member[0].label.name, AudioNoutput);
4150		dip->un.e.member[0].ord = GUSICS_MASTER_LVL;
4151		break;
4152
4153	case GUSICS_INPUT_CLASS:
4154		dip->type = AUDIO_MIXER_CLASS;
4155		dip->mixer_class = GUSICS_INPUT_CLASS;
4156		dip->next = dip->prev = AUDIO_MIXER_LAST;
4157		strcpy(dip->label.name, AudioCInputs);
4158		break;
4159
4160	case GUSICS_OUTPUT_CLASS:
4161		dip->type = AUDIO_MIXER_CLASS;
4162		dip->mixer_class = GUSICS_OUTPUT_CLASS;
4163		dip->next = dip->prev = AUDIO_MIXER_LAST;
4164		strcpy(dip->label.name, AudioCOutputs);
4165		break;
4166
4167	case GUSICS_RECORD_CLASS:
4168		dip->type = AUDIO_MIXER_CLASS;
4169		dip->mixer_class = GUSICS_RECORD_CLASS;
4170		dip->next = dip->prev = AUDIO_MIXER_LAST;
4171		strcpy(dip->label.name, AudioCRecord);
4172		break;
4173
4174	default:
4175		return ENXIO;
4176	/*NOTREACHED*/
4177	}
4178	DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name));
4179	return 0;
4180}
4181
4182STATIC int
4183gus_query_encoding(addr, fp)
4184	void *addr;
4185	struct audio_encoding *fp;
4186{
4187	switch (fp->index) {
4188	case 0:
4189		strcpy(fp->name, AudioEmulaw);
4190		fp->encoding = AUDIO_ENCODING_ULAW;
4191		fp->precision = 8;
4192		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
4193		break;
4194	case 1:
4195		strcpy(fp->name, AudioElinear);
4196		fp->encoding = AUDIO_ENCODING_SLINEAR;
4197		fp->precision = 8;
4198		fp->flags = 0;
4199		break;
4200	case 2:
4201		strcpy(fp->name, AudioElinear_le);
4202		fp->encoding = AUDIO_ENCODING_SLINEAR_LE;
4203		fp->precision = 16;
4204		fp->flags = 0;
4205		break;
4206	case 3:
4207		strcpy(fp->name, AudioEulinear);
4208		fp->encoding = AUDIO_ENCODING_ULINEAR;
4209		fp->precision = 8;
4210		fp->flags = 0;
4211		break;
4212	case 4:
4213		strcpy(fp->name, AudioEulinear_le);
4214		fp->encoding = AUDIO_ENCODING_ULINEAR_LE;
4215		fp->precision = 16;
4216		fp->flags = 0;
4217		break;
4218	case 5:
4219		strcpy(fp->name, AudioElinear_be);
4220		fp->encoding = AUDIO_ENCODING_SLINEAR_BE;
4221		fp->precision = 16;
4222		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
4223		break;
4224	case 6:
4225		strcpy(fp->name, AudioEulinear_be);
4226		fp->encoding = AUDIO_ENCODING_ULINEAR_BE;
4227		fp->precision = 16;
4228		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
4229		break;
4230	default:
4231		return(EINVAL);
4232		/*NOTREACHED*/
4233	}
4234	return (0);
4235}
4236
4237/*
4238 * Setup the ICS mixer in "transparent" mode: reset everything to a sensible
4239 * level.  Levels as suggested by GUS SDK code.
4240 */
4241
4242STATIC void
4243gus_init_ics2101(sc)
4244	struct gus_softc *sc;
4245{
4246	register int port = sc->sc_iobase;
4247	register struct ics2101_softc *ic = &sc->sc_mixer;
4248	sc->sc_mixer.sc_selio = port+GUS_MIXER_SELECT;
4249	sc->sc_mixer.sc_dataio = port+GUS_MIXER_DATA;
4250	sc->sc_mixer.sc_flags = (sc->sc_revision == 5) ? ICS_FLIP : 0;
4251
4252	ics2101_mix_attenuate(ic,
4253			      GUSMIX_CHAN_MIC,
4254			      ICSMIX_LEFT,
4255			      ICSMIX_MIN_ATTN);
4256	ics2101_mix_attenuate(ic,
4257			      GUSMIX_CHAN_MIC,
4258			      ICSMIX_RIGHT,
4259			      ICSMIX_MIN_ATTN);
4260	/*
4261	 * Start with microphone muted by the mixer...
4262	 */
4263	gusics_mic_mute(ic, 1);
4264
4265	/* ... and enabled by the GUS master mix control */
4266	gus_mic_ctl(sc, SPKR_ON);
4267
4268	ics2101_mix_attenuate(ic,
4269			      GUSMIX_CHAN_LINE,
4270			      ICSMIX_LEFT,
4271			      ICSMIX_MIN_ATTN);
4272	ics2101_mix_attenuate(ic,
4273			      GUSMIX_CHAN_LINE,
4274			      ICSMIX_RIGHT,
4275			      ICSMIX_MIN_ATTN);
4276
4277	ics2101_mix_attenuate(ic,
4278			      GUSMIX_CHAN_CD,
4279			      ICSMIX_LEFT,
4280			      ICSMIX_MIN_ATTN);
4281	ics2101_mix_attenuate(ic,
4282			      GUSMIX_CHAN_CD,
4283			      ICSMIX_RIGHT,
4284			      ICSMIX_MIN_ATTN);
4285
4286	ics2101_mix_attenuate(ic,
4287			      GUSMIX_CHAN_DAC,
4288			      ICSMIX_LEFT,
4289			      ICSMIX_MIN_ATTN);
4290	ics2101_mix_attenuate(ic,
4291			      GUSMIX_CHAN_DAC,
4292			      ICSMIX_RIGHT,
4293			      ICSMIX_MIN_ATTN);
4294
4295	ics2101_mix_attenuate(ic,
4296			      ICSMIX_CHAN_4,
4297			      ICSMIX_LEFT,
4298			      ICSMIX_MAX_ATTN);
4299	ics2101_mix_attenuate(ic,
4300			      ICSMIX_CHAN_4,
4301			      ICSMIX_RIGHT,
4302			      ICSMIX_MAX_ATTN);
4303
4304	ics2101_mix_attenuate(ic,
4305			      GUSMIX_CHAN_MASTER,
4306			      ICSMIX_LEFT,
4307			      ICSMIX_MIN_ATTN);
4308	ics2101_mix_attenuate(ic,
4309			      GUSMIX_CHAN_MASTER,
4310			      ICSMIX_RIGHT,
4311			      ICSMIX_MIN_ATTN);
4312	/* unmute other stuff: */
4313	gusics_cd_mute(ic, 0);
4314	gusics_dac_mute(ic, 0);
4315	gusics_linein_mute(ic, 0);
4316	return;
4317}
4318
4319
4320#endif /* NGUS */
4321