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