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