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