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