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