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