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