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