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