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