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