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