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