1/*	$NetBSD: gus.c,v 1.107 2011/11/23 23:07:32 jmcneill 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.107 2011/11/23 23:07:32 jmcneill 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	struct device 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(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 not "
697			    "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 = (void *) 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, "can't create map for drq %d\n",
948			       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, "can't create map for drq %d\n",
965			       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, (unsigned char) GUS_VOICE_LEFT);
1061	SELECT_GUS_REG(iot, ioh2, GUSREG_PAN_POS);
1062	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, GUS_PAN_FULL_LEFT);
1063
1064	bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) GUS_VOICE_RIGHT);
1065	SELECT_GUS_REG(iot, ioh2, GUSREG_PAN_POS);
1066	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, GUS_PAN_FULL_RIGHT);
1067
1068	/* set up buffer to hold the deinterleave, if necessary
1069	   for stereo output */
1070	sc->sc_deintr_buf = kmem_alloc(GUS_MAX_BLOCKSIZE>>1, KM_SLEEP);
1071
1072	/*
1073	 * Attach to the generic audio layer
1074	 */
1075
1076	audio_attach_mi(hwif,
1077	    HAS_CODEC(sc) ? (void *)&sc->sc_codec : (void *)sc, &sc->sc_dev);
1078}
1079
1080int
1081gusopen(void *addr, int flags)
1082{
1083	struct gus_softc *sc;
1084
1085	sc = addr;
1086	DPRINTF(("gusopen() called\n"));
1087
1088	if (sc->sc_flags & GUS_OPEN)
1089		return EBUSY;
1090
1091	/*
1092	 * Some initialization
1093	 */
1094
1095	sc->sc_flags |= GUS_OPEN;
1096	sc->sc_dmabuf = 0;
1097	sc->sc_playbuf = -1;
1098	sc->sc_bufcnt = 0;
1099	sc->sc_voc[GUS_VOICE_LEFT].start_addr = GUS_MEM_OFFSET - 1;
1100	sc->sc_voc[GUS_VOICE_LEFT].current_addr = GUS_MEM_OFFSET;
1101
1102	if (HAS_CODEC(sc)) {
1103		ad1848_open(&sc->sc_codec.sc_ad1848, flags);
1104		sc->sc_codec.sc_ad1848.mute[AD1848_AUX1_CHANNEL] = 0;
1105
1106		/* turn on DAC output */
1107		ad1848_mute_channel(&sc->sc_codec.sc_ad1848,
1108				    AD1848_AUX1_CHANNEL, 0);
1109		if (flags & FREAD) {
1110			sc->sc_codec.sc_ad1848.mute[AD1848_MONO_CHANNEL] = 0;
1111			ad1848_mute_channel(&sc->sc_codec.sc_ad1848,
1112					    AD1848_MONO_CHANNEL, 0);
1113		}
1114	} else if (flags & FREAD) {
1115		/* enable/unmute the microphone */
1116		if (HAS_MIXER(sc)) {
1117			gusics_mic_mute(&sc->sc_mixer, 0);
1118		} else
1119			gus_mic_ctl(sc, SPKR_ON);
1120	}
1121	if (sc->sc_nbufs == 0)
1122	    gus_round_blocksize(sc, GUS_BUFFER_MULTIPLE, /* default blksiz */
1123				0, NULL); /* XXX */
1124	return 0;
1125}
1126
1127int
1128gusmaxopen(void *addr, int flags)
1129{
1130	struct ad1848_isa_softc *ac;
1131
1132	ac = addr;
1133	return gusopen(ac->sc_ad1848.parent, flags);
1134}
1135
1136STATIC void
1137gus_deinterleave(struct gus_softc *sc, void *tbuf, int size)
1138{
1139	/* deinterleave the stereo data.  We can use sc->sc_deintr_buf
1140	   for scratch space. */
1141	int i;
1142
1143	if (size > sc->sc_blocksize) {
1144		printf("gus: deinterleave %d > %d\n", size, sc->sc_blocksize);
1145		return;
1146	} else if (size < sc->sc_blocksize) {
1147		DPRINTF(("gus: deinterleave %d < %d\n", size, sc->sc_blocksize));
1148	}
1149
1150	/*
1151	 * size is in bytes.
1152	 */
1153	if (sc->sc_precision == 16) {
1154		u_short *dei = sc->sc_deintr_buf;
1155		u_short *sbuf = tbuf;
1156		size >>= 1;		/* bytecnt to shortcnt */
1157		/* copy 2nd of each pair of samples to the staging area, while
1158		   compacting the 1st of each pair into the original area. */
1159		for (i = 0; i < size/2-1; i++)  {
1160			dei[i] = sbuf[i*2+1];
1161			sbuf[i+1] = sbuf[i*2+2];
1162		}
1163		/*
1164		 * this has copied one less sample than half of the
1165		 * buffer.  The first sample of the 1st stream was
1166		 * already in place and didn't need copying.
1167		 * Therefore, we've moved all of the 1st stream's
1168		 * samples into place.  We have one sample from 2nd
1169		 * stream in the last slot of original area, not
1170		 * copied to the staging area (But we don't need to!).
1171		 * Copy the remainder of the original stream into place.
1172		 */
1173		memcpy(&sbuf[size/2], dei, i * sizeof(short));
1174	} else {
1175		u_char *dei = sc->sc_deintr_buf;
1176		u_char *sbuf = tbuf;
1177		for (i = 0; i < size/2-1; i++)  {
1178			dei[i] = sbuf[i*2+1];
1179			sbuf[i+1] = sbuf[i*2+2];
1180		}
1181		memcpy(&sbuf[size/2], dei, i);
1182	}
1183}
1184
1185/*
1186 * Actually output a buffer to the DSP chip
1187 */
1188
1189int
1190gusmax_dma_output(void *addr, void *tbuf, int size,
1191		  void (*intr)(void *), void *arg)
1192{
1193	struct ad1848_isa_softc *ac;
1194
1195	ac = addr;
1196	return gus_dma_output(ac->sc_ad1848.parent, tbuf, size, intr, arg);
1197}
1198
1199/*
1200 * called from interrupt handler.
1201 */
1202void
1203stereo_dmaintr(void *arg)
1204{
1205	struct gus_softc *sc;
1206	struct stereo_dma_intr *sa;
1207
1208	DMAPRINTF(("stereo_dmaintr"));
1209	sc = arg;
1210	sa = &sc->sc_stereo;
1211
1212	KASSERT(mutex_owned(&sc->sc_codec.sc_ad1848.sc_intr_lock));
1213
1214	/*
1215	 * Put other half in its place, then call the real interrupt routine :)
1216	 */
1217
1218	sc->sc_dmaoutintr = sa->intr;
1219	sc->sc_outarg = sa->arg;
1220
1221#ifdef GUSPLAYDEBUG
1222	if (gusstats) {
1223		microtime(&dmarecords[dmarecord_index].tv);
1224		dmarecords[dmarecord_index].gusaddr = sa->dmabuf;
1225		dmarecords[dmarecord_index].bsdaddr = sa->buffer;
1226		dmarecords[dmarecord_index].count = sa->size;
1227		dmarecords[dmarecord_index].channel = 1;
1228		dmarecords[dmarecord_index].direction = 1;
1229		dmarecord_index = (dmarecord_index + 1) % NDMARECS;
1230	}
1231#endif
1232
1233	gusdmaout(sc, sa->flags, sa->dmabuf, (void *) sa->buffer, sa->size);
1234
1235	sa->flags = 0;
1236	sa->dmabuf = 0;
1237	sa->buffer = 0;
1238	sa->size = 0;
1239	sa->intr = 0;
1240	sa->arg = 0;
1241}
1242
1243/*
1244 * Start up DMA output to the card.
1245 */
1246int
1247gus_dma_output(void *addr, void *tbuf, int size,
1248	       void (*intr)(void *), void *arg)
1249{
1250	struct gus_softc *sc;
1251	u_char *buffer;
1252	u_long boarddma;
1253	int flags;
1254
1255	DMAPRINTF(("gus_dma_output %d @ %p\n", size, tbuf));
1256	sc = addr;
1257	buffer = tbuf;
1258
1259	if (size != sc->sc_blocksize) {
1260		DPRINTF(("gus_dma_output reqsize %d not sc_blocksize %d\n",
1261		     size, sc->sc_blocksize));
1262		return EINVAL;
1263	}
1264
1265	flags = GUSMASK_DMA_WRITE;
1266	if (sc->sc_precision == 16)
1267		flags |= GUSMASK_DMA_DATA_SIZE;
1268	if (sc->sc_encoding == AUDIO_ENCODING_ULAW ||
1269	    sc->sc_encoding == AUDIO_ENCODING_ALAW ||
1270	    sc->sc_encoding == AUDIO_ENCODING_ULINEAR_BE ||
1271	    sc->sc_encoding == AUDIO_ENCODING_ULINEAR_LE)
1272		flags |= GUSMASK_DMA_INVBIT;
1273
1274	if (sc->sc_channels == 2) {
1275		if (sc->sc_precision == 16) {
1276			if (size & 3) {
1277				DPRINTF(("gus_dma_output: unpaired 16bit samples"));
1278				size &= 3;
1279			}
1280		} else if (size & 1) {
1281			DPRINTF(("gus_dma_output: unpaired samples"));
1282			size &= 1;
1283		}
1284		if (size == 0)
1285			return 0;
1286
1287		gus_deinterleave(sc, (void *)buffer, size);
1288
1289		size >>= 1;
1290
1291		boarddma = size * sc->sc_dmabuf + GUS_MEM_OFFSET;
1292
1293		sc->sc_stereo.intr = intr;
1294		sc->sc_stereo.arg = arg;
1295		sc->sc_stereo.size = size;
1296		sc->sc_stereo.dmabuf = boarddma + GUS_LEFT_RIGHT_OFFSET;
1297		sc->sc_stereo.buffer = buffer + size;
1298		sc->sc_stereo.flags = flags;
1299		if (gus_dostereo) {
1300			intr = stereo_dmaintr;
1301			arg = sc;
1302		}
1303	} else
1304		boarddma = size * sc->sc_dmabuf + GUS_MEM_OFFSET;
1305
1306
1307	sc->sc_flags |= GUS_LOCKED;
1308	sc->sc_dmaoutintr = intr;
1309	sc->sc_outarg = arg;
1310
1311#ifdef GUSPLAYDEBUG
1312	if (gusstats) {
1313		microtime(&dmarecords[dmarecord_index].tv);
1314		dmarecords[dmarecord_index].gusaddr = boarddma;
1315		dmarecords[dmarecord_index].bsdaddr = buffer;
1316		dmarecords[dmarecord_index].count = size;
1317		dmarecords[dmarecord_index].channel = 0;
1318		dmarecords[dmarecord_index].direction = 1;
1319		dmarecord_index = (dmarecord_index + 1) % NDMARECS;
1320	}
1321#endif
1322
1323	gusdmaout(sc, flags, boarddma, (void *) buffer, size);
1324
1325	return 0;
1326}
1327
1328void
1329gusmax_close(void *addr)
1330{
1331	struct ad1848_isa_softc *ac;
1332	struct gus_softc *sc;
1333
1334	ac = addr;
1335	sc = ac->sc_ad1848.parent;
1336#if 0
1337	ac->mute[AD1848_AUX1_CHANNEL] = MUTE_ALL;
1338	ad1848_mute_channel(ac, MUTE_ALL); /* turn off DAC output */
1339#endif
1340	ad1848_close(&ac->sc_ad1848);
1341	gusclose(sc);
1342}
1343
1344/*
1345 * Close out device stuff.
1346 */
1347void
1348gusclose(void *addr)
1349{
1350	struct gus_softc *sc;
1351
1352	sc = addr;
1353	DPRINTF(("gus_close: sc=%p\n", sc));
1354
1355
1356/*	if (sc->sc_flags & GUS_DMAOUT_ACTIVE) */ {
1357		gus_halt_out_dma(sc);
1358	}
1359/*	if (sc->sc_flags & GUS_DMAIN_ACTIVE) */ {
1360		gus_halt_in_dma(sc);
1361	}
1362	sc->sc_flags &= ~(GUS_OPEN|GUS_LOCKED|GUS_DMAOUT_ACTIVE|GUS_DMAIN_ACTIVE);
1363
1364	/* turn off speaker, etc. */
1365
1366	/* make sure the voices shut up: */
1367	gus_stop_voice(sc, GUS_VOICE_LEFT, 1);
1368	gus_stop_voice(sc, GUS_VOICE_RIGHT, 0);
1369}
1370
1371/*
1372 * Service interrupts.  Farm them off to helper routines if we are using the
1373 * GUS for simple playback/record
1374 */
1375
1376#ifdef DIAGNOSTIC
1377int gusintrcnt;
1378int gusdmaintrcnt;
1379int gusvocintrcnt;
1380#endif
1381
1382int
1383gusintr(void *arg)
1384{
1385	struct gus_softc *sc;
1386	bus_space_tag_t iot;
1387	bus_space_handle_t ioh1;
1388	bus_space_handle_t ioh2;
1389	unsigned char intr;
1390	int retval;
1391
1392	DPRINTF(("gusintr\n"));
1393	sc = arg;
1394	iot = sc->sc_iot;
1395	ioh1 = sc->sc_ioh1;
1396	ioh2 = sc->sc_ioh2;
1397	retval = 0;
1398#ifdef DIAGNOSTIC
1399	gusintrcnt++;
1400#endif
1401
1402	mutex_spin_enter(&sc->sc_codec.sc_ad1848.sc_intr_lock);
1403
1404	if (HAS_CODEC(sc))
1405		retval = ad1848_isa_intr(&sc->sc_codec);
1406	if ((intr = bus_space_read_1(iot, ioh1, GUS_IRQ_STATUS)) & GUSMASK_IRQ_DMATC) {
1407		DMAPRINTF(("gusintr DMA flags=%x\n", sc->sc_flags));
1408#ifdef DIAGNOSTIC
1409		gusdmaintrcnt++;
1410#endif
1411		retval += gus_dmaout_intr(sc);
1412		if (sc->sc_flags & GUS_DMAIN_ACTIVE) {
1413			SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
1414			intr = bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
1415			if (intr & GUSMASK_SAMPLE_DMATC) {
1416				retval += gus_dmain_intr(sc);
1417			}
1418		}
1419	}
1420	if (intr & (GUSMASK_IRQ_VOICE | GUSMASK_IRQ_VOLUME)) {
1421		DMAPRINTF(("gusintr voice flags=%x\n", sc->sc_flags));
1422#ifdef DIAGNOSTIC
1423		gusvocintrcnt++;
1424#endif
1425		retval += gus_voice_intr(sc);
1426	}
1427
1428	mutex_spin_exit(&sc->sc_codec.sc_ad1848.sc_intr_lock);
1429
1430	return retval;
1431}
1432
1433int gus_bufcnt[GUS_MEM_FOR_BUFFERS / GUS_BUFFER_MULTIPLE];
1434int gus_restart;				/* how many restarts? */
1435int gus_stops;				/* how many times did voice stop? */
1436int gus_falsestops;			/* stopped but not done? */
1437int gus_continues;
1438
1439struct playcont {
1440	struct timeval tv;
1441	u_int playbuf;
1442	u_int dmabuf;
1443	u_char bufcnt;
1444	u_char vaction;
1445	u_char voccntl;
1446	u_char volcntl;
1447	u_long curaddr;
1448	u_long endaddr;
1449} playstats[NDMARECS];
1450
1451int playcntr;
1452
1453STATIC void
1454gus_dmaout_timeout(void *arg)
1455{
1456	struct gus_softc *sc;
1457	bus_space_tag_t iot;
1458	bus_space_handle_t ioh2;
1459
1460	sc = arg;
1461	iot = sc->sc_iot;
1462	ioh2 = sc->sc_ioh2;
1463	printf("%s: dmaout timeout\n", device_xname(&sc->sc_dev));
1464
1465	/*
1466	 * Stop any DMA.
1467	 */
1468	mutex_spin_enter(&sc->sc_codec.sc_ad1848.sc_intr_lock);
1469	SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
1470	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0);
1471#if 0
1472	/* XXX we will dmadone below? */
1473	isa_dmaabort(device_parent(&sc->sc_dev), sc->sc_playdrq);
1474#endif
1475
1476	gus_dmaout_dointr(sc);
1477	mutex_spin_exit(&sc->sc_codec.sc_ad1848.sc_intr_lock);
1478}
1479
1480
1481/*
1482 * Service DMA interrupts.  This routine will only get called if we're doing
1483 * a DMA transfer for playback/record requests from the audio layer.
1484 */
1485
1486STATIC int
1487gus_dmaout_intr(struct gus_softc *sc)
1488{
1489	bus_space_tag_t iot;
1490	bus_space_handle_t ioh2;
1491
1492	KASSERT(mutex_owned(&sc->sc_codec.sc_ad1848.sc_intr_lock));
1493
1494	iot = sc->sc_iot;
1495	ioh2 = sc->sc_ioh2;
1496	/*
1497	 * If we got a DMA transfer complete from the GUS DRAM, then deal
1498	 * with it.
1499	 */
1500
1501	SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
1502	if (bus_space_read_1(iot, ioh2, GUS_DATA_HIGH) & GUSMASK_DMA_IRQPEND) {
1503		callout_stop(&sc->sc_dmaout_ch);
1504		gus_dmaout_dointr(sc);
1505		return 1;
1506	}
1507	return 0;
1508}
1509
1510STATIC void
1511gus_dmaout_dointr(struct gus_softc *sc)
1512{
1513	bus_space_tag_t iot;
1514	bus_space_handle_t ioh2;
1515
1516	KASSERT(mutex_owned(&sc->sc_codec.sc_ad1848.sc_intr_lock));
1517
1518	iot = sc->sc_iot;
1519	ioh2 = sc->sc_ioh2;
1520	/* sc->sc_dmaoutcnt - 1 because DMA controller counts from zero?. */
1521	isa_dmadone(sc->sc_ic, sc->sc_playdrq);
1522	sc->sc_flags &= ~GUS_DMAOUT_ACTIVE;  /* pending DMA is done */
1523	DMAPRINTF(("gus_dmaout_dointr %d @ %p\n", sc->sc_dmaoutcnt,
1524		   sc->sc_dmaoutaddr));
1525
1526	/*
1527	 * to prevent clicking, we need to copy last sample
1528	 * from last buffer to scratch area just before beginning of
1529	 * buffer.  However, if we're doing formats that are converted by
1530	 * the card during the DMA process, we need to pick up the converted
1531	 * byte rather than the one we have in memory.
1532	 */
1533	if (sc->sc_dmabuf == sc->sc_nbufs - 1) {
1534		int i;
1535		switch (sc->sc_encoding) {
1536		case AUDIO_ENCODING_SLINEAR_LE:
1537		case AUDIO_ENCODING_SLINEAR_BE:
1538			if (sc->sc_precision == 8)
1539				goto byte;
1540			/* we have the native format */
1541			for (i = 1; i <= 2; i++)
1542				guspoke(iot, ioh2, sc->sc_gusaddr -
1543					(sc->sc_nbufs - 1) * sc->sc_chanblocksize - i,
1544					sc->sc_dmaoutaddr[sc->sc_dmaoutcnt-i]);
1545			break;
1546		case AUDIO_ENCODING_ULINEAR_LE:
1547		case AUDIO_ENCODING_ULINEAR_BE:
1548			guspoke(iot, ioh2, sc->sc_gusaddr -
1549				(sc->sc_nbufs - 1) * sc->sc_chanblocksize - 2,
1550				guspeek(iot, ioh2,
1551					sc->sc_gusaddr + sc->sc_chanblocksize - 2));
1552		case AUDIO_ENCODING_ALAW:
1553		case AUDIO_ENCODING_ULAW:
1554		byte:
1555			/* we need to fetch the translated byte, then stuff it. */
1556			guspoke(iot, ioh2, sc->sc_gusaddr -
1557				(sc->sc_nbufs - 1) * sc->sc_chanblocksize - 1,
1558				guspeek(iot, ioh2,
1559					sc->sc_gusaddr + sc->sc_chanblocksize - 1));
1560			break;
1561		}
1562	}
1563	/*
1564	 * If this is the first half of stereo, "ignore" this one
1565	 * and copy out the second half.
1566	 */
1567	if (sc->sc_dmaoutintr == stereo_dmaintr) {
1568		(*sc->sc_dmaoutintr)(sc->sc_outarg);
1569		return;
1570	}
1571	/*
1572	 * If the voice is stopped, then start it.  Reset the loop
1573	 * and roll bits.  Call the audio layer routine, since if
1574	 * we're starting a stopped voice, that means that the next
1575	 * buffer can be filled
1576	 */
1577
1578	sc->sc_flags &= ~GUS_LOCKED;
1579	if (sc->sc_voc[GUS_VOICE_LEFT].voccntl &
1580	    GUSMASK_VOICE_STOPPED) {
1581		if (sc->sc_flags & GUS_PLAYING) {
1582			printf("%s: playing yet stopped?\n", device_xname(&sc->sc_dev));
1583		}
1584		sc->sc_bufcnt++; /* another yet to be played */
1585		gus_start_playing(sc, sc->sc_dmabuf);
1586		gus_restart++;
1587	} else {
1588		/*
1589		 * set the sound action based on which buffer we
1590		 * just transferred.  If we just transferred buffer 0
1591		 * we want the sound to loop when it gets to the nth
1592		 * buffer; if we just transferred
1593		 * any other buffer, we want the sound to roll over
1594		 * at least one more time.  The voice interrupt
1595		 * handlers will take care of accounting &
1596		 * setting control bits if it's not caught up to us
1597		 * yet.
1598		 */
1599		if (++sc->sc_bufcnt == 2) {
1600			/*
1601			 * XXX
1602			 * If we're too slow in reaction here,
1603			 * the voice could be just approaching the
1604			 * end of its run.  It should be set to stop,
1605			 * so these adjustments might not DTRT.
1606			 */
1607			if (sc->sc_dmabuf == 0 &&
1608			    sc->sc_playbuf == sc->sc_nbufs - 1) {
1609				/* player is just at the last tbuf, we're at the
1610				   first.  Turn on looping, turn off rolling. */
1611				sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_LOOP_ENABLE;
1612				sc->sc_voc[GUS_VOICE_LEFT].volcntl &= ~GUSMASK_VOICE_ROLL;
1613				playstats[playcntr].vaction = 3;
1614			} else {
1615				/* player is at previous tbuf:
1616				   turn on rolling, turn off looping */
1617				sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~GUSMASK_LOOP_ENABLE;
1618				sc->sc_voc[GUS_VOICE_LEFT].volcntl |= GUSMASK_VOICE_ROLL;
1619				playstats[playcntr].vaction = 4;
1620			}
1621#ifdef GUSPLAYDEBUG
1622			if (gusstats) {
1623				microtime(&playstats[playcntr].tv);
1624				playstats[playcntr].endaddr
1625				    = sc->sc_voc[GUS_VOICE_LEFT].end_addr;
1626				playstats[playcntr].voccntl
1627				    = sc->sc_voc[GUS_VOICE_LEFT].voccntl;
1628				playstats[playcntr].volcntl
1629				    = sc->sc_voc[GUS_VOICE_LEFT].volcntl;
1630				playstats[playcntr].playbuf = sc->sc_playbuf;
1631				playstats[playcntr].dmabuf = sc->sc_dmabuf;
1632				playstats[playcntr].bufcnt = sc->sc_bufcnt;
1633				playstats[playcntr].curaddr
1634				    = gus_get_curaddr(sc, GUS_VOICE_LEFT);
1635				playcntr = (playcntr + 1) % NDMARECS;
1636			}
1637#endif
1638			bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, GUS_VOICE_LEFT);
1639			SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
1640			bus_space_write_1(iot, ioh2, GUS_DATA_HIGH,
1641					  sc->sc_voc[GUS_VOICE_LEFT].voccntl);
1642			SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
1643			bus_space_write_1(iot, ioh2, GUS_DATA_HIGH,
1644					  sc->sc_voc[GUS_VOICE_LEFT].volcntl);
1645		}
1646	}
1647	gus_bufcnt[sc->sc_bufcnt-1]++;
1648	/*
1649	 * flip to the next DMA buffer
1650	 */
1651
1652	sc->sc_dmabuf = (sc->sc_dmabuf + 1) % sc->sc_nbufs;
1653	/*
1654	 * See comments below about DMA admission control strategy.
1655	 * We can call the upper level here if we have an
1656	 * idle buffer (not currently playing) to DMA into.
1657	 */
1658	if (sc->sc_dmaoutintr && sc->sc_bufcnt < sc->sc_nbufs) {
1659		/* clean out to prevent double calls */
1660		void (*pfunc)(void *);
1661		void *arg;
1662
1663		pfunc = sc->sc_dmaoutintr;
1664		arg = sc->sc_outarg;
1665		sc->sc_outarg = 0;
1666		sc->sc_dmaoutintr = 0;
1667		(*pfunc)(arg);
1668	}
1669}
1670
1671/*
1672 * Service voice interrupts
1673 */
1674
1675STATIC int
1676gus_voice_intr(struct gus_softc *sc)
1677{
1678	bus_space_tag_t iot;
1679	bus_space_handle_t ioh2;
1680	int ignore, voice, rval;
1681	unsigned char intr, status;
1682
1683	KASSERT(mutex_owned(&sc->sc_codec.sc_ad1848.sc_intr_lock));
1684
1685	iot = sc->sc_iot;
1686	ioh2 = sc->sc_ioh2;
1687	ignore = 0;
1688	rval = 0;
1689	/*
1690	 * The point of this may not be obvious at first.  A voice can
1691	 * interrupt more than once; according to the GUS SDK we are supposed
1692	 * to ignore multiple interrupts for the same voice.
1693	 */
1694
1695	while (1) {
1696		SELECT_GUS_REG(iot, ioh2, GUSREG_IRQ_STATUS);
1697		intr = bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
1698
1699		if ((intr & (GUSMASK_WIRQ_VOLUME | GUSMASK_WIRQ_VOICE))
1700			== (GUSMASK_WIRQ_VOLUME | GUSMASK_WIRQ_VOICE))
1701			/*
1702			 * No more interrupts, time to return
1703			 */
1704			return rval;
1705
1706		if ((intr & GUSMASK_WIRQ_VOICE) == 0) {
1707
1708			/*
1709			 * We've got a voice interrupt.  Ignore previous
1710			 * interrupts by the same voice.
1711			 */
1712
1713			rval = 1;
1714			voice = intr & GUSMASK_WIRQ_VOICEMASK;
1715
1716			if ((1 << voice) & ignore)
1717				break;
1718
1719			ignore |= 1 << voice;
1720
1721			/*
1722			 * If the voice is stopped, then force it to stop
1723			 * (this stops it from continuously generating IRQs)
1724			 */
1725
1726			SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL+0x80);
1727			status = bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
1728			if (status & GUSMASK_VOICE_STOPPED) {
1729				if (voice != GUS_VOICE_LEFT) {
1730					DMAPRINTF(("%s: spurious voice %d stop?\n",
1731						   device_xname(&sc->sc_dev), voice));
1732					gus_stop_voice(sc, voice, 0);
1733					continue;
1734				}
1735				gus_stop_voice(sc, voice, 1);
1736				/* also kill right voice */
1737				gus_stop_voice(sc, GUS_VOICE_RIGHT, 0);
1738				sc->sc_bufcnt--; /* it finished a buffer */
1739				if (sc->sc_bufcnt > 0) {
1740					/*
1741					 * probably a race to get here: the
1742					 * voice stopped while the DMA code was
1743					 * just trying to get the next buffer
1744					 * in place.  Start the voice again.
1745					 */
1746					printf("%s: stopped voice not drained? (%x)\n",
1747					       device_xname(&sc->sc_dev), sc->sc_bufcnt);
1748					gus_falsestops++;
1749
1750					sc->sc_playbuf = (sc->sc_playbuf + 1) % sc->sc_nbufs;
1751					gus_start_playing(sc, sc->sc_playbuf);
1752				} else if (sc->sc_bufcnt < 0) {
1753					panic("%s: negative bufcnt in stopped voice",
1754					      device_xname(&sc->sc_dev));
1755				} else {
1756					sc->sc_playbuf = -1; /* none are active */
1757					gus_stops++;
1758				}
1759				/* fall through to callback and admit another
1760				   buffer.... */
1761			} else if (sc->sc_bufcnt != 0) {
1762				/*
1763				 * This should always be taken if the voice
1764				 * is not stopped.
1765				 */
1766				gus_continues++;
1767				if (gus_continue_playing(sc, voice)) {
1768					/*
1769					 * we shouldn't have continued--active
1770					 * DMA is in the way in the ring, for
1771					 * some as-yet undebugged reason.
1772					 */
1773					gus_stop_voice(sc, GUS_VOICE_LEFT, 1);
1774					/* also kill right voice */
1775					gus_stop_voice(sc, GUS_VOICE_RIGHT, 0);
1776					sc->sc_playbuf = -1;
1777					gus_stops++;
1778				}
1779			}
1780			/*
1781			 * call the upper level to send on down another
1782			 * block. We do admission rate control as follows:
1783			 *
1784			 * When starting up output (in the first N
1785			 * blocks), call the upper layer after the DMA is
1786			 * complete (see above in gus_dmaout_intr()).
1787			 *
1788			 * When output is already in progress and we have
1789			 * no more GUS buffers to use for DMA, the DMA
1790			 * output routines do not call the upper layer.
1791			 * Instead, we call the DMA completion routine
1792			 * here, after the voice interrupts indicating
1793			 * that it's finished with a buffer.
1794			 *
1795			 * However, don't call anything here if the DMA
1796			 * output flag is set, (which shouldn't happen)
1797			 * because we'll squish somebody else's DMA if
1798			 * that's the case.  When DMA is done, it will
1799			 * call back if there is a spare buffer.
1800			 */
1801			if (sc->sc_dmaoutintr && !(sc->sc_flags & GUS_LOCKED)) {
1802				if (sc->sc_dmaoutintr == stereo_dmaintr)
1803					printf("gusdmaout botch?\n");
1804				else {
1805					/* clean out to avoid double calls */
1806					void (*pfunc)(void *);
1807					void *arg;
1808
1809					pfunc = sc->sc_dmaoutintr;
1810					arg = sc->sc_outarg;
1811					sc->sc_outarg = 0;
1812					sc->sc_dmaoutintr = 0;
1813					(*pfunc)(arg);
1814				}
1815			}
1816		}
1817
1818		/*
1819		 * Ignore other interrupts for now
1820		 */
1821	}
1822	return 0;
1823}
1824
1825/*
1826 * Start the voices playing, with buffer BUFNO.
1827 */
1828STATIC void
1829gus_start_playing(struct gus_softc *sc, int bufno)
1830{
1831	bus_space_tag_t iot;
1832	bus_space_handle_t ioh2;
1833
1834	iot = sc->sc_iot;
1835	ioh2 = sc->sc_ioh2;
1836	/*
1837	 * Loop or roll if we have buffers ready.
1838	 */
1839
1840	if (sc->sc_bufcnt == 1) {
1841		sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~(GUSMASK_LOOP_ENABLE);
1842		sc->sc_voc[GUS_VOICE_LEFT].volcntl &= ~(GUSMASK_VOICE_ROLL);
1843	} else {
1844		if (bufno == sc->sc_nbufs - 1) {
1845			sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_LOOP_ENABLE;
1846			sc->sc_voc[GUS_VOICE_LEFT].volcntl &= ~(GUSMASK_VOICE_ROLL);
1847		} else {
1848			sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~GUSMASK_LOOP_ENABLE;
1849			sc->sc_voc[GUS_VOICE_LEFT].volcntl |= GUSMASK_VOICE_ROLL;
1850		}
1851	}
1852
1853	bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, GUS_VOICE_LEFT);
1854
1855	SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
1856	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_LEFT].voccntl);
1857
1858	SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
1859	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_LEFT].volcntl);
1860
1861	sc->sc_voc[GUS_VOICE_LEFT].current_addr =
1862	    GUS_MEM_OFFSET + sc->sc_chanblocksize * bufno;
1863	sc->sc_voc[GUS_VOICE_LEFT].end_addr =
1864	    sc->sc_voc[GUS_VOICE_LEFT].current_addr + sc->sc_chanblocksize - 1;
1865	sc->sc_voc[GUS_VOICE_RIGHT].current_addr =
1866	    sc->sc_voc[GUS_VOICE_LEFT].current_addr +
1867	    (gus_dostereo && sc->sc_channels == 2 ? GUS_LEFT_RIGHT_OFFSET : 0);
1868	/*
1869	 * set up right channel to just loop forever, no interrupts,
1870	 * starting at the buffer we just filled.  We'll feed it data
1871	 * at the same time as left channel.
1872	 */
1873	sc->sc_voc[GUS_VOICE_RIGHT].voccntl |= GUSMASK_LOOP_ENABLE;
1874	sc->sc_voc[GUS_VOICE_RIGHT].volcntl &= ~(GUSMASK_VOICE_ROLL);
1875
1876#ifdef GUSPLAYDEBUG
1877	if (gusstats) {
1878		microtime(&playstats[playcntr].tv);
1879		playstats[playcntr].curaddr = sc->sc_voc[GUS_VOICE_LEFT].current_addr;
1880
1881		playstats[playcntr].voccntl = sc->sc_voc[GUS_VOICE_LEFT].voccntl;
1882		playstats[playcntr].volcntl = sc->sc_voc[GUS_VOICE_LEFT].volcntl;
1883		playstats[playcntr].endaddr = sc->sc_voc[GUS_VOICE_LEFT].end_addr;
1884		playstats[playcntr].playbuf = bufno;
1885		playstats[playcntr].dmabuf = sc->sc_dmabuf;
1886		playstats[playcntr].bufcnt = sc->sc_bufcnt;
1887		playstats[playcntr].vaction = 5;
1888		playcntr = (playcntr + 1) % NDMARECS;
1889	}
1890#endif
1891
1892	bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, GUS_VOICE_RIGHT);
1893	SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
1894	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_RIGHT].voccntl);
1895	SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
1896	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_RIGHT].volcntl);
1897
1898	gus_start_voice(sc, GUS_VOICE_RIGHT, 0);
1899	gus_start_voice(sc, GUS_VOICE_LEFT, 1);
1900	if (sc->sc_playbuf == -1)
1901		/* mark start of playing */
1902		sc->sc_playbuf = bufno;
1903}
1904
1905STATIC int
1906gus_continue_playing(struct gus_softc *sc, int voice)
1907{
1908	bus_space_tag_t iot;
1909	bus_space_handle_t ioh2;
1910
1911	KASSERT(mutex_owned(&sc->sc_codec.sc_ad1848.sc_intr_lock));
1912
1913	/*
1914	 * stop this voice from interrupting while we work.
1915	 */
1916	iot = sc->sc_iot;
1917	ioh2 = sc->sc_ioh2;
1918
1919	SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
1920	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH,
1921	    sc->sc_voc[voice].voccntl & ~(GUSMASK_VOICE_IRQ));
1922
1923	/*
1924	 * update playbuf to point to the buffer the hardware just started
1925	 * playing
1926	 */
1927	sc->sc_playbuf = (sc->sc_playbuf + 1) % sc->sc_nbufs;
1928
1929	/*
1930	 * account for buffer just finished
1931	 */
1932	if (--sc->sc_bufcnt == 0) {
1933		DPRINTF(("gus: bufcnt 0 on continuing voice?\n"));
1934	}
1935	if (sc->sc_playbuf == sc->sc_dmabuf && (sc->sc_flags & GUS_LOCKED)) {
1936		aprint_error_dev(&sc->sc_dev, "continue into active dmabuf?\n");
1937		return 1;
1938	}
1939
1940	/*
1941	 * Select the end of the buffer based on the currently active
1942	 * buffer, [plus extra contiguous buffers (if ready)].
1943	 */
1944
1945	/*
1946	 * set endpoint at end of buffer we just started playing.
1947	 *
1948	 * The total gets -1 because end addrs are one less than you might
1949	 * think (the end_addr is the address of the last sample to play)
1950	 */
1951	gus_set_endaddr(sc, voice, GUS_MEM_OFFSET +
1952			sc->sc_chanblocksize * (sc->sc_playbuf + 1) - 1);
1953
1954	if (sc->sc_bufcnt < 2) {
1955		/*
1956		 * Clear out the loop and roll flags, and rotate the currently
1957		 * playing buffer.  That way, if we don't manage to get more
1958		 * data before this buffer finishes, we'll just stop.
1959		 */
1960		sc->sc_voc[voice].voccntl &= ~GUSMASK_LOOP_ENABLE;
1961		sc->sc_voc[voice].volcntl &= ~GUSMASK_VOICE_ROLL;
1962		playstats[playcntr].vaction = 0;
1963	} else {
1964		/*
1965		 * We have some buffers to play.  set LOOP if we're on the
1966		 * last buffer in the ring, otherwise set ROLL.
1967		 */
1968		if (sc->sc_playbuf == sc->sc_nbufs - 1) {
1969			sc->sc_voc[voice].voccntl |= GUSMASK_LOOP_ENABLE;
1970			sc->sc_voc[voice].volcntl &= ~GUSMASK_VOICE_ROLL;
1971			playstats[playcntr].vaction = 1;
1972		} else {
1973			sc->sc_voc[voice].voccntl &= ~GUSMASK_LOOP_ENABLE;
1974			sc->sc_voc[voice].volcntl |= GUSMASK_VOICE_ROLL;
1975			playstats[playcntr].vaction = 2;
1976		}
1977	}
1978#ifdef GUSPLAYDEBUG
1979	if (gusstats) {
1980		microtime(&playstats[playcntr].tv);
1981		playstats[playcntr].curaddr = gus_get_curaddr(sc, voice);
1982
1983		playstats[playcntr].voccntl = sc->sc_voc[voice].voccntl;
1984		playstats[playcntr].volcntl = sc->sc_voc[voice].volcntl;
1985		playstats[playcntr].endaddr = sc->sc_voc[voice].end_addr;
1986		playstats[playcntr].playbuf = sc->sc_playbuf;
1987		playstats[playcntr].dmabuf = sc->sc_dmabuf;
1988		playstats[playcntr].bufcnt = sc->sc_bufcnt;
1989		playcntr = (playcntr + 1) % NDMARECS;
1990	}
1991#endif
1992
1993	/*
1994	 * (re-)set voice parameters.  This will reenable interrupts from this
1995	 * voice.
1996	 */
1997
1998	SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
1999	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
2000	SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
2001	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].volcntl);
2002	return 0;
2003}
2004
2005/*
2006 * Send/receive data into GUS's DRAM using DMA.
2007 */
2008STATIC void
2009gusdmaout(struct gus_softc *sc, int flags,
2010	  u_long gusaddr, void *buffaddr, int length)
2011{
2012	unsigned char c;
2013	bus_space_tag_t iot;
2014	bus_space_handle_t ioh2;
2015
2016	KASSERT(mutex_owned(&sc->sc_codec.sc_ad1848.sc_intr_lock));
2017
2018	DMAPRINTF(("gusdmaout flags=%x scflags=%x\n", flags, sc->sc_flags));
2019	c = (unsigned char) flags;
2020	iot = sc->sc_iot;
2021	ioh2 = sc->sc_ioh2;
2022
2023	sc->sc_gusaddr = gusaddr;
2024
2025	/*
2026	 * If we're using a 16 bit DMA channel, we have to jump through some
2027	 * extra hoops; this includes translating the DRAM address a bit
2028	 */
2029
2030	if (sc->sc_playdrq >= 4) {
2031		c |= GUSMASK_DMA_WIDTH;
2032		gusaddr = convert_to_16bit(gusaddr);
2033	}
2034
2035	/*
2036	 * Add flag bits that we always set - fast DMA, enable IRQ
2037	 */
2038
2039	c |= GUSMASK_DMA_ENABLE | GUSMASK_DMA_R0 | GUSMASK_DMA_IRQ;
2040
2041	/*
2042	 * Make sure the GUS _isn't_ setup for DMA
2043	 */
2044
2045	SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
2046	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0);
2047
2048	/*
2049	 * Tell the PC DMA controller to start doing DMA
2050	 */
2051
2052	sc->sc_dmaoutaddr = (u_char *) buffaddr;
2053	sc->sc_dmaoutcnt = length;
2054	isa_dmastart(sc->sc_ic, sc->sc_playdrq, buffaddr, length,
2055	    NULL, DMAMODE_WRITE, BUS_DMA_NOWAIT);
2056
2057	/*
2058	 * Set up DMA address - use the upper 16 bits ONLY
2059	 */
2060
2061	sc->sc_flags |= GUS_DMAOUT_ACTIVE;
2062
2063	SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_START);
2064	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, (int) (gusaddr >> 4));
2065
2066	/*
2067	 * Tell the GUS to start doing DMA
2068	 */
2069
2070	SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
2071	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, c);
2072
2073	/*
2074	 * XXX If we don't finish in one second, give up...
2075	 */
2076	callout_reset(&sc->sc_dmaout_ch, hz, gus_dmaout_timeout, sc);
2077}
2078
2079/*
2080 * Start a voice playing on the GUS.
2081 */
2082
2083STATIC void
2084gus_start_voice(struct gus_softc *sc, int voice, int intrs)
2085{
2086	bus_space_tag_t iot;
2087	bus_space_handle_t ioh2;
2088	u_long start;
2089	u_long current;
2090	u_long end;
2091
2092	KASSERT(mutex_owned(&sc->sc_codec.sc_ad1848.sc_intr_lock));
2093
2094	iot = sc->sc_iot;
2095	ioh2 = sc->sc_ioh2;
2096	/*
2097	 * Pick all the values for the voice out of the gus_voice struct
2098	 * and use those to program the voice
2099	 */
2100
2101	start = sc->sc_voc[voice].start_addr;
2102	current = sc->sc_voc[voice].current_addr;
2103	end = sc->sc_voc[voice].end_addr;
2104
2105	/*
2106	 * If we're using 16 bit data, mangle the addresses a bit
2107	 */
2108
2109	if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16) {
2110		/* -1 on start so that we get onto sample boundary--other
2111		 * code always sets it for 1-byte rollover protection */
2112		start = convert_to_16bit(start-1);
2113		current = convert_to_16bit(current);
2114		end = convert_to_16bit(end);
2115	}
2116
2117	/*
2118	 * Select the voice we want to use, and program the data addresses
2119	 */
2120
2121	bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
2122
2123	SELECT_GUS_REG(iot, ioh2, GUSREG_START_ADDR_HIGH);
2124	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(start));
2125	SELECT_GUS_REG(iot, ioh2, GUSREG_START_ADDR_LOW);
2126	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(start));
2127
2128	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH);
2129	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(current));
2130	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW);
2131	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(current));
2132
2133	SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_HIGH);
2134	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(end));
2135	SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_LOW);
2136	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(end));
2137
2138	/*
2139	 * (maybe) enable interrupts, disable voice stopping
2140	 */
2141
2142	if (intrs) {
2143		sc->sc_flags |= GUS_PLAYING; /* playing is about to start */
2144		sc->sc_voc[voice].voccntl |= GUSMASK_VOICE_IRQ;
2145		DMAPRINTF(("gus voice playing=%x\n", sc->sc_flags));
2146	} else
2147		sc->sc_voc[voice].voccntl &= ~GUSMASK_VOICE_IRQ;
2148	sc->sc_voc[voice].voccntl &= ~(GUSMASK_VOICE_STOPPED |
2149	    GUSMASK_STOP_VOICE);
2150
2151	/*
2152	 * Tell the GUS about it.  Note that we're doing volume ramping here
2153	 * from 0 up to the set volume to help reduce clicks.
2154	 */
2155
2156	SELECT_GUS_REG(iot, ioh2, GUSREG_START_VOLUME);
2157	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
2158	SELECT_GUS_REG(iot, ioh2, GUSREG_END_VOLUME);
2159	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH,
2160	    sc->sc_voc[voice].current_volume >> 4);
2161	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME);
2162	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x00);
2163	SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_RATE);
2164	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 63);
2165
2166	SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
2167	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
2168	SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
2169	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
2170	delay(50);
2171	SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
2172	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
2173	SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
2174	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
2175
2176}
2177
2178/*
2179 * Stop a given voice.
2180 */
2181STATIC void
2182gus_stop_voice(struct gus_softc *sc, int voice, int intrs_too)
2183{
2184	bus_space_tag_t iot;
2185	bus_space_handle_t ioh2;
2186
2187	KASSERT(mutex_owned(&sc->sc_codec.sc_ad1848.sc_intr_lock));
2188
2189	iot = sc->sc_iot;
2190	ioh2 = sc->sc_ioh2;
2191	sc->sc_voc[voice].voccntl |= GUSMASK_VOICE_STOPPED |
2192	    GUSMASK_STOP_VOICE;
2193	if (intrs_too) {
2194		sc->sc_voc[voice].voccntl &= ~(GUSMASK_VOICE_IRQ);
2195		/* no more DMA to do */
2196		sc->sc_flags &= ~GUS_PLAYING;
2197	}
2198	DMAPRINTF(("gusintr voice notplaying=%x\n", sc->sc_flags));
2199
2200	guspoke(iot, ioh2, 0L, 0);
2201
2202	bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
2203
2204	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME);
2205	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2206	SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
2207	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
2208	delay(100);
2209	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME);
2210	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2211	SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
2212	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
2213
2214	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH);
2215	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2216	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW);
2217	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2218
2219}
2220
2221
2222/*
2223 * Set the volume of a given voice.
2224 */
2225STATIC void
2226gus_set_volume(struct gus_softc *sc, int voice, int volume)
2227{
2228	bus_space_tag_t iot;
2229	bus_space_handle_t ioh2;
2230	unsigned int gusvol;
2231
2232	KASSERT(mutex_owned(&sc->sc_codec.sc_ad1848.sc_intr_lock));
2233
2234	iot = sc->sc_iot;
2235	ioh2 = sc->sc_ioh2;
2236	gusvol = gus_log_volumes[volume < 512 ? volume : 511];
2237
2238	sc->sc_voc[voice].current_volume = gusvol;
2239
2240	bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
2241
2242	SELECT_GUS_REG(iot, ioh2, GUSREG_START_VOLUME);
2243	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (unsigned char) (gusvol >> 4));
2244
2245	SELECT_GUS_REG(iot, ioh2, GUSREG_END_VOLUME);
2246	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (unsigned char) (gusvol >> 4));
2247
2248	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME);
2249	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, gusvol << 4);
2250	delay(500);
2251	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, gusvol << 4);
2252
2253}
2254
2255/*
2256 * Interface to the audio layer.
2257 */
2258
2259int
2260gusmax_set_params(void *addr, int setmode, int usemode, audio_params_t *p,
2261		  audio_params_t *r, stream_filter_list_t *pfil,
2262		  stream_filter_list_t *rfil)
2263{
2264	struct ad1848_isa_softc *ac;
2265	struct gus_softc *sc;
2266	int error;
2267
2268	ac = addr;
2269	sc = ac->sc_ad1848.parent;
2270	error = ad1848_set_params(ac, setmode, usemode, p, r, pfil, rfil);
2271	if (error)
2272		return error;
2273	/*
2274	 * ad1848_set_params() sets a filter for
2275	 *  SLINEAR_LE 8, SLINEAR_BE 16, ULINEAR_LE 16, ULINEAR_BE 16.
2276	 * gus_set_params() sets a filter for
2277	 *  ULAW, ALAW, ULINEAR_BE (16), SLINEAR_BE (16)
2278	 */
2279	error = gus_set_params(sc, setmode, usemode, p, r, pfil, rfil);
2280	return error;
2281}
2282
2283int
2284gus_set_params(void *addr,int setmode, int usemode, audio_params_t *p,
2285	       audio_params_t *r, stream_filter_list_t *pfil,
2286	       stream_filter_list_t *rfil)
2287{
2288	audio_params_t hw;
2289	struct gus_softc *sc;
2290
2291	sc = addr;
2292	switch (p->encoding) {
2293	case AUDIO_ENCODING_ULAW:
2294	case AUDIO_ENCODING_ALAW:
2295	case AUDIO_ENCODING_SLINEAR_LE:
2296	case AUDIO_ENCODING_ULINEAR_LE:
2297	case AUDIO_ENCODING_SLINEAR_BE:
2298	case AUDIO_ENCODING_ULINEAR_BE:
2299		break;
2300	default:
2301		return EINVAL;
2302	}
2303
2304	mutex_spin_enter(&sc->sc_intr_lock);
2305
2306	if (p->precision == 8) {
2307		sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~GUSMASK_DATA_SIZE16;
2308		sc->sc_voc[GUS_VOICE_RIGHT].voccntl &= ~GUSMASK_DATA_SIZE16;
2309	} else {
2310		sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_DATA_SIZE16;
2311		sc->sc_voc[GUS_VOICE_RIGHT].voccntl |= GUSMASK_DATA_SIZE16;
2312	}
2313
2314	sc->sc_encoding = p->encoding;
2315	sc->sc_precision = p->precision;
2316	sc->sc_channels = p->channels;
2317
2318	if (p->sample_rate > gus_max_frequency[sc->sc_voices - GUS_MIN_VOICES])
2319		p->sample_rate = gus_max_frequency[sc->sc_voices - GUS_MIN_VOICES];
2320	if (setmode & AUMODE_RECORD)
2321		sc->sc_irate = p->sample_rate;
2322	if (setmode & AUMODE_PLAY)
2323		sc->sc_orate = p->sample_rate;
2324
2325	mutex_spin_exit(&sc->sc_intr_lock);
2326
2327	hw = *p;
2328	/* clear req_size before setting a filter to avoid confliction
2329	 * in gusmax_set_params() */
2330	switch (p->encoding) {
2331	case AUDIO_ENCODING_ULAW:
2332		hw.encoding = AUDIO_ENCODING_ULINEAR_LE;
2333		pfil->req_size = rfil->req_size = 0;
2334		pfil->append(pfil, mulaw_to_linear8, &hw);
2335		rfil->append(rfil, linear8_to_mulaw, &hw);
2336		break;
2337	case AUDIO_ENCODING_ALAW:
2338		hw.encoding = AUDIO_ENCODING_ULINEAR_LE;
2339		pfil->req_size = rfil->req_size = 0;
2340		pfil->append(pfil, alaw_to_linear8, &hw);
2341		rfil->append(rfil, linear8_to_alaw, &hw);
2342		break;
2343	case AUDIO_ENCODING_ULINEAR_BE:
2344		hw.encoding = AUDIO_ENCODING_ULINEAR_LE;
2345		pfil->req_size = rfil->req_size = 0;
2346		pfil->append(pfil, swap_bytes, &hw);
2347		rfil->append(rfil, swap_bytes, &hw);
2348		break;
2349	case AUDIO_ENCODING_SLINEAR_BE:
2350		hw.encoding = AUDIO_ENCODING_SLINEAR_LE;
2351		pfil->req_size = rfil->req_size = 0;
2352		pfil->append(pfil, swap_bytes, &hw);
2353		rfil->append(rfil, swap_bytes, &hw);
2354		break;
2355	}
2356
2357	return 0;
2358}
2359
2360/*
2361 * Interface to the audio layer - set the blocksize to the correct number
2362 * of units
2363 */
2364
2365int
2366gusmax_round_blocksize(void *addr, int blocksize,
2367		       int mode, const audio_params_t *param)
2368{
2369	struct ad1848_isa_softc *ac;
2370	struct gus_softc *sc;
2371
2372	ac = addr;
2373	sc = ac->sc_ad1848.parent;
2374/*	blocksize = ad1848_round_blocksize(ac, blocksize, mode, param);*/
2375	return gus_round_blocksize(sc, blocksize, mode, param);
2376}
2377
2378int
2379gus_round_blocksize(void *addr, int blocksize,
2380    int mode, const audio_params_t *param)
2381{
2382	struct gus_softc *sc;
2383
2384	DPRINTF(("gus_round_blocksize called\n"));
2385	sc = addr;
2386
2387	if ((sc->sc_encoding == AUDIO_ENCODING_ULAW ||
2388	     sc->sc_encoding == AUDIO_ENCODING_ALAW) && blocksize > 32768)
2389		blocksize = 32768;
2390	else if (blocksize > 65536)
2391		blocksize = 65536;
2392
2393	if ((blocksize % GUS_BUFFER_MULTIPLE) != 0)
2394		blocksize = (blocksize / GUS_BUFFER_MULTIPLE + 1) *
2395			GUS_BUFFER_MULTIPLE;
2396
2397	sc->sc_blocksize = blocksize;
2398	/* multi-buffering not quite working yet. */
2399	sc->sc_nbufs = /*GUS_MEM_FOR_BUFFERS / blocksize*/ 2;
2400
2401	gus_set_chan_addrs(sc);
2402
2403	return blocksize;
2404}
2405
2406int
2407gus_get_out_gain(void *addr)
2408{
2409	struct gus_softc *sc;
2410
2411	DPRINTF(("gus_get_out_gain called\n"));
2412	sc = (struct gus_softc *) addr;
2413	return sc->sc_ogain / 2;
2414}
2415
2416STATIC inline void
2417gus_set_voices(struct gus_softc *sc, int voices)
2418{
2419	bus_space_tag_t iot;
2420	bus_space_handle_t ioh2;
2421
2422	iot = sc->sc_iot;
2423	ioh2 = sc->sc_ioh2;
2424	/*
2425	 * Select the active number of voices
2426	 */
2427	SELECT_GUS_REG(iot, ioh2, GUSREG_ACTIVE_VOICES);
2428	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (voices-1) | 0xc0);
2429
2430	sc->sc_voices = voices;
2431}
2432
2433/*
2434 * Actually set the settings of various values on the card
2435 */
2436int
2437gusmax_commit_settings(void *addr)
2438{
2439	struct ad1848_isa_softc *ac;
2440	struct gus_softc *sc;
2441	int error;
2442
2443	ac = addr;
2444	sc = ac->sc_ad1848.parent;
2445	error = ad1848_commit_settings(ac);
2446	if (error)
2447		return error;
2448	return gus_commit_settings(sc);
2449}
2450
2451/*
2452 * Commit the settings.
2453 */
2454int
2455gus_commit_settings(void *addr)
2456{
2457	struct gus_softc *sc;
2458
2459	sc = addr;
2460	DPRINTF(("gus_commit_settings called (gain = %d)\n",sc->sc_ogain));
2461
2462	mutex_spin_enter(&sc->sc_codec.sc_ad1848.sc_intr_lock);
2463	gus_set_recrate(sc, sc->sc_irate);
2464	gus_set_volume(sc, GUS_VOICE_LEFT, sc->sc_ogain);
2465	gus_set_volume(sc, GUS_VOICE_RIGHT, sc->sc_ogain);
2466	gus_set_samprate(sc, GUS_VOICE_LEFT, sc->sc_orate);
2467	gus_set_samprate(sc, GUS_VOICE_RIGHT, sc->sc_orate);
2468	mutex_spin_exit(&sc->sc_codec.sc_ad1848.sc_intr_lock);
2469
2470	gus_set_chan_addrs(sc);
2471
2472	return 0;
2473}
2474
2475STATIC void
2476gus_set_chan_addrs(struct gus_softc *sc)
2477{
2478
2479	/*
2480	 * We use sc_nbufs * blocksize bytes of storage in the on-board GUS
2481	 * ram.
2482	 * For mono, each of the sc_nbufs buffers is DMA'd to in one chunk,
2483	 * and both left & right channels play the same buffer.
2484	 *
2485	 * For stereo, each channel gets a contiguous half of the memory,
2486	 * and each has sc_nbufs buffers of size blocksize/2.
2487	 * Stereo data are deinterleaved in main memory before the DMA out
2488	 * routines are called to queue the output.
2489	 *
2490	 * The blocksize per channel is kept in sc_chanblocksize.
2491	 */
2492	if (sc->sc_channels == 2)
2493	    sc->sc_chanblocksize = sc->sc_blocksize/2;
2494	else
2495	    sc->sc_chanblocksize = sc->sc_blocksize;
2496
2497	sc->sc_voc[GUS_VOICE_LEFT].start_addr = GUS_MEM_OFFSET - 1;
2498	sc->sc_voc[GUS_VOICE_RIGHT].start_addr =
2499	    (gus_dostereo && sc->sc_channels == 2 ? GUS_LEFT_RIGHT_OFFSET : 0)
2500	      + GUS_MEM_OFFSET - 1;
2501	sc->sc_voc[GUS_VOICE_RIGHT].current_addr =
2502	    sc->sc_voc[GUS_VOICE_RIGHT].start_addr + 1;
2503	sc->sc_voc[GUS_VOICE_RIGHT].end_addr =
2504	    sc->sc_voc[GUS_VOICE_RIGHT].start_addr +
2505	    sc->sc_nbufs * sc->sc_chanblocksize;
2506
2507}
2508
2509/*
2510 * Set the sample rate of the given voice.
2511 */
2512STATIC void
2513gus_set_samprate(struct gus_softc *sc, int voice, int freq)
2514{
2515	bus_space_tag_t iot;
2516	bus_space_handle_t ioh2;
2517	unsigned int fc;
2518	u_long temp, f;
2519
2520	KASSERT(mutex_owned(&sc->sc_codec.sc_ad1848.sc_intr_lock));
2521
2522	iot = sc->sc_iot;
2523	ioh2 = sc->sc_ioh2;
2524	f = (u_long) freq;
2525	/*
2526	 * calculate fc based on the number of active voices;
2527	 * we need to use longs to preserve enough bits
2528	 */
2529
2530	temp = (u_long) gus_max_frequency[sc->sc_voices-GUS_MIN_VOICES];
2531
2532	fc = (unsigned int)(((f << 9L) + (temp >> 1L)) / temp);
2533	fc <<= 1;
2534
2535	/*
2536	 * Program the voice frequency, and set it in the voice data record
2537	 */
2538
2539	bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
2540	SELECT_GUS_REG(iot, ioh2, GUSREG_FREQ_CONTROL);
2541	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, fc);
2542
2543	sc->sc_voc[voice].rate = freq;
2544
2545}
2546
2547/*
2548 * Set the sample rate of the recording frequency.  Formula is from the GUS
2549 * SDK.
2550 */
2551STATIC void
2552gus_set_recrate(struct gus_softc *sc, u_long rate)
2553{
2554	bus_space_tag_t iot;
2555	bus_space_handle_t ioh2;
2556	u_char realrate;
2557
2558	KASSERT(mutex_owned(&sc->sc_codec.sc_ad1848.sc_intr_lock));
2559
2560	DPRINTF(("gus_set_recrate %lu\n", rate));
2561	iot = sc->sc_iot;
2562	ioh2 = sc->sc_ioh2;
2563
2564#if 0
2565	realrate = 9878400/(16*(rate+2)); /* formula from GUS docs */
2566#endif
2567	realrate = (9878400 >> 4)/rate - 2; /* formula from code, sigh. */
2568
2569	SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_FREQ);
2570	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, realrate);
2571}
2572
2573/*
2574 * Interface to the audio layer - turn the output on or off.  Note that some
2575 * of these bits are flipped in the register
2576 */
2577
2578int
2579gusmax_speaker_ctl(void *addr, int newstate)
2580{
2581	struct ad1848_isa_softc *sc;
2582
2583	sc = addr;
2584	return gus_speaker_ctl(sc->sc_ad1848.parent, newstate);
2585}
2586
2587int
2588gus_speaker_ctl(void *addr, int newstate)
2589{
2590	struct gus_softc *sc;
2591	bus_space_tag_t iot;
2592	bus_space_handle_t ioh1;
2593
2594	sc = (struct gus_softc *) addr;
2595	iot = sc->sc_iot;
2596	ioh1 = sc->sc_ioh1;
2597	/* Line out bit is flipped: 0 enables, 1 disables */
2598	if ((newstate == SPKR_ON) &&
2599	    (sc->sc_mixcontrol & GUSMASK_LINE_OUT)) {
2600		sc->sc_mixcontrol &= ~GUSMASK_LINE_OUT;
2601		bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
2602	}
2603	if ((newstate == SPKR_OFF) &&
2604	    (sc->sc_mixcontrol & GUSMASK_LINE_OUT) == 0) {
2605		sc->sc_mixcontrol |= GUSMASK_LINE_OUT;
2606		bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
2607	}
2608
2609	return 0;
2610}
2611
2612STATIC int
2613gus_linein_ctl(void *addr, int newstate)
2614{
2615	struct gus_softc *sc;
2616	bus_space_tag_t iot;
2617	bus_space_handle_t ioh1;
2618
2619	sc = (struct gus_softc *) addr;
2620	iot = sc->sc_iot;
2621	ioh1 = sc->sc_ioh1;
2622	/* Line in bit is flipped: 0 enables, 1 disables */
2623	if ((newstate == SPKR_ON) &&
2624	    (sc->sc_mixcontrol & GUSMASK_LINE_IN)) {
2625		sc->sc_mixcontrol &= ~GUSMASK_LINE_IN;
2626		bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
2627	}
2628	if ((newstate == SPKR_OFF) &&
2629	    (sc->sc_mixcontrol & GUSMASK_LINE_IN) == 0) {
2630		sc->sc_mixcontrol |= GUSMASK_LINE_IN;
2631		bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
2632	}
2633
2634	return 0;
2635}
2636
2637STATIC int
2638gus_mic_ctl(void *addr, int newstate)
2639{
2640	struct gus_softc *sc;
2641	bus_space_tag_t iot;
2642	bus_space_handle_t ioh1;
2643
2644	sc = (struct gus_softc *) addr;
2645	iot = sc->sc_iot;
2646	ioh1 = sc->sc_ioh1;
2647	/* Mic bit is normal: 1 enables, 0 disables */
2648	if ((newstate == SPKR_ON) &&
2649	    (sc->sc_mixcontrol & GUSMASK_MIC_IN) == 0) {
2650		sc->sc_mixcontrol |= GUSMASK_MIC_IN;
2651		bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
2652	}
2653	if ((newstate == SPKR_OFF) &&
2654	    (sc->sc_mixcontrol & GUSMASK_MIC_IN)) {
2655		sc->sc_mixcontrol &= ~GUSMASK_MIC_IN;
2656		bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
2657	}
2658
2659	return 0;
2660}
2661
2662/*
2663 * Set the end address of a give voice.
2664 */
2665STATIC void
2666gus_set_endaddr(struct gus_softc *sc, int voice, u_long addr)
2667{
2668	bus_space_tag_t iot;
2669	bus_space_handle_t ioh2;
2670
2671	KASSERT(mutex_owned(&sc->sc_codec.sc_ad1848.sc_intr_lock));
2672
2673	iot = sc->sc_iot;
2674	ioh2 = sc->sc_ioh2;
2675	sc->sc_voc[voice].end_addr = addr;
2676
2677	if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16)
2678		addr = convert_to_16bit(addr);
2679
2680	SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_HIGH);
2681	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(addr));
2682	SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_LOW);
2683	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(addr));
2684
2685}
2686
2687#ifdef GUSPLAYDEBUG
2688/*
2689 * Set current address.
2690 */
2691STATIC void
2692gus_set_curaddr(struct gus_softc *sc, int voice, u_long addr)
2693{
2694	bus_space_tag_t iot;
2695	bus_space_handle_t ioh2;
2696
2697	KASSERT(mutex_owned(&sc->sc_codec.sc_ad1848.sc_intr_lock));
2698
2699	iot = sc->sc_iot;
2700	ioh2 = sc->sc_ioh2;
2701	sc->sc_voc[voice].current_addr = addr;
2702
2703	if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16)
2704		addr = convert_to_16bit(addr);
2705
2706	bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
2707
2708	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH);
2709	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(addr));
2710	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW);
2711	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(addr));
2712
2713}
2714
2715/*
2716 * Get current GUS playback address.
2717 */
2718STATIC u_long
2719gus_get_curaddr(struct gus_softc *sc, int voice)
2720{
2721	bus_space_tag_t iot;
2722	bus_space_handle_t ioh2;
2723	u_long addr;
2724
2725	KASSERT(mutex_owned(&sc->sc_codec.sc_ad1848.sc_intr_lock));
2726
2727	iot = sc->sc_iot;
2728	ioh2 = sc->sc_ioh2;
2729	bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
2730	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH|GUSREG_READ);
2731	addr = (bus_space_read_2(iot, ioh2, GUS_DATA_LOW) & 0x1fff) << 7;
2732	SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW|GUSREG_READ);
2733	addr |= (bus_space_read_2(iot, ioh2, GUS_DATA_LOW) >> 9L) & 0x7f;
2734
2735	if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16)
2736	    addr = (addr & 0xc0000) | ((addr & 0x1ffff) << 1); /* undo 16-bit change */
2737	DPRINTF(("gus voice %d curaddr %ld end_addr %ld\n",
2738		 voice, addr, sc->sc_voc[voice].end_addr));
2739	/* XXX sanity check the address? */
2740
2741	return addr;
2742}
2743#endif
2744
2745/*
2746 * Convert an address value to a "16 bit" value - why this is necessary I
2747 * have NO idea
2748 */
2749
2750STATIC u_long
2751convert_to_16bit(u_long address)
2752{
2753	u_long old_address;
2754
2755	old_address = address;
2756	address >>= 1;
2757	address &= 0x0001ffffL;
2758	address |= (old_address & 0x000c0000L);
2759
2760	return address;
2761}
2762
2763/*
2764 * Write a value into the GUS's DRAM
2765 */
2766STATIC void
2767guspoke(bus_space_tag_t iot, bus_space_handle_t ioh2,
2768	long address, unsigned char value)
2769{
2770
2771	/*
2772	 * Select the DRAM address
2773	 */
2774
2775	SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_LOW);
2776	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, (unsigned int) (address & 0xffff));
2777	SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_HIGH);
2778	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (unsigned char) ((address >> 16) & 0xff));
2779
2780	/*
2781	 * Actually write the data
2782	 */
2783
2784	bus_space_write_1(iot, ioh2, GUS_DRAM_DATA, value);
2785}
2786
2787/*
2788 * Read a value from the GUS's DRAM
2789 */
2790STATIC unsigned char
2791guspeek(bus_space_tag_t iot, bus_space_handle_t ioh2, u_long address)
2792{
2793
2794	/*
2795	 * Select the DRAM address
2796	 */
2797
2798	SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_LOW);
2799	bus_space_write_2(iot, ioh2, GUS_DATA_LOW, (unsigned int) (address & 0xffff));
2800	SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_HIGH);
2801	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (unsigned char) ((address >> 16) & 0xff));
2802
2803	/*
2804	 * Read in the data from the board
2805	 */
2806
2807	return (unsigned char) bus_space_read_1(iot, ioh2, GUS_DRAM_DATA);
2808}
2809
2810/*
2811 * Reset the Gravis UltraSound card, completely
2812 */
2813STATIC void
2814gusreset(struct gus_softc *sc, int voices)
2815{
2816	bus_space_tag_t iot;
2817	bus_space_handle_t ioh1;
2818	bus_space_handle_t ioh2;
2819	bus_space_handle_t ioh4;
2820	int i;
2821
2822	KASSERT(mutex_owned(&sc->sc_codec.sc_ad1848.sc_intr_lock));
2823
2824	iot = sc->sc_iot;
2825	ioh1 = sc->sc_ioh1;
2826	ioh2 = sc->sc_ioh2;
2827	ioh4 = sc->sc_ioh4;
2828
2829	/*
2830	 * Reset the GF1 chip
2831	 */
2832
2833	SELECT_GUS_REG(iot, ioh2, GUSREG_RESET);
2834	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
2835
2836	delay(500);
2837
2838	/*
2839	 * Release reset
2840	 */
2841
2842	SELECT_GUS_REG(iot, ioh2, GUSREG_RESET);
2843	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, GUSMASK_MASTER_RESET);
2844
2845	delay(500);
2846
2847	/*
2848	 * Reset MIDI port as well
2849	 */
2850
2851	bus_space_write_1(iot, ioh4, GUS_MIDI_CONTROL, MIDI_RESET);
2852
2853	delay(500);
2854
2855	bus_space_write_1(iot, ioh4, GUS_MIDI_CONTROL, 0x00);
2856
2857	/*
2858	 * Clear interrupts
2859	 */
2860
2861	SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
2862	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
2863	SELECT_GUS_REG(iot, ioh2, GUSREG_TIMER_CONTROL);
2864	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
2865	SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
2866	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
2867
2868	gus_set_voices(sc, voices);
2869
2870	bus_space_read_1(iot, ioh1, GUS_IRQ_STATUS);
2871	SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
2872	bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
2873	SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
2874	bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
2875	SELECT_GUS_REG(iot, ioh2, GUSREG_IRQ_STATUS);
2876	bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
2877
2878	/*
2879	 * Reset voice specific information
2880	 */
2881
2882	for(i = 0; i < voices; i++) {
2883		bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) i);
2884
2885		SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
2886
2887		sc->sc_voc[i].voccntl = GUSMASK_VOICE_STOPPED |
2888			GUSMASK_STOP_VOICE;
2889
2890		bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[i].voccntl);
2891
2892		sc->sc_voc[i].volcntl = GUSMASK_VOLUME_STOPPED |
2893				GUSMASK_STOP_VOLUME;
2894
2895		SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
2896		bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[i].volcntl);
2897
2898		delay(100);
2899
2900		gus_set_samprate(sc, i, 8000);
2901		SELECT_GUS_REG(iot, ioh2, GUSREG_START_ADDR_HIGH);
2902		bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2903		SELECT_GUS_REG(iot, ioh2, GUSREG_START_ADDR_LOW);
2904		bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2905		SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_HIGH);
2906		bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2907		SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_LOW);
2908		bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2909		SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_RATE);
2910		bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x01);
2911		SELECT_GUS_REG(iot, ioh2, GUSREG_START_VOLUME);
2912		bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x10);
2913		SELECT_GUS_REG(iot, ioh2, GUSREG_END_VOLUME);
2914		bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0xe0);
2915		SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME);
2916		bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2917
2918		SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH);
2919		bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2920		SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW);
2921		bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2922		SELECT_GUS_REG(iot, ioh2, GUSREG_PAN_POS);
2923		bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x07);
2924	}
2925
2926	/*
2927	 * Clear out any pending IRQs
2928	 */
2929
2930	bus_space_read_1(iot, ioh1, GUS_IRQ_STATUS);
2931	SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
2932	bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
2933	SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
2934	bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
2935	SELECT_GUS_REG(iot, ioh2, GUSREG_IRQ_STATUS);
2936	bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
2937
2938	SELECT_GUS_REG(iot, ioh2, GUSREG_RESET);
2939	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, GUSMASK_MASTER_RESET | GUSMASK_DAC_ENABLE |
2940		GUSMASK_IRQ_ENABLE);
2941}
2942
2943
2944STATIC int
2945gus_init_cs4231(struct gus_softc *sc)
2946{
2947	bus_space_tag_t iot;
2948	bus_space_handle_t ioh1;
2949	int port;
2950	u_char ctrl;
2951
2952	iot = sc->sc_iot;
2953	ioh1 = sc->sc_ioh1;
2954	port = sc->sc_iobase;
2955	ctrl = (port & 0xf0) >> 4;	/* set port address middle nibble */
2956	/*
2957	 * The codec is a bit weird--swapped DMA channels.
2958	 */
2959	ctrl |= GUS_MAX_CODEC_ENABLE;
2960	if (sc->sc_playdrq >= 4)
2961		ctrl |= GUS_MAX_RECCHAN16;
2962	if (sc->sc_recdrq >= 4)
2963		ctrl |= GUS_MAX_PLAYCHAN16;
2964
2965	bus_space_write_1(iot, ioh1, GUS_MAX_CTRL, ctrl);
2966
2967	sc->sc_codec.sc_ad1848.sc_iot = sc->sc_iot;
2968	sc->sc_codec.sc_iobase = port+GUS_MAX_CODEC_BASE;
2969
2970	if (ad1848_isa_mapprobe(&sc->sc_codec, sc->sc_codec.sc_iobase) == 0) {
2971		sc->sc_flags &= ~GUS_CODEC_INSTALLED;
2972		return 0;
2973	} else {
2974		struct ad1848_volume vol = {AUDIO_MAX_GAIN, AUDIO_MAX_GAIN};
2975		sc->sc_flags |= GUS_CODEC_INSTALLED;
2976		sc->sc_codec.sc_ad1848.parent = sc;
2977		sc->sc_codec.sc_playdrq = sc->sc_recdrq;
2978		sc->sc_codec.sc_play_maxsize = sc->sc_req_maxsize;
2979		sc->sc_codec.sc_recdrq = sc->sc_playdrq;
2980		sc->sc_codec.sc_rec_maxsize = sc->sc_play_maxsize;
2981		/* enable line in and mic in the GUS mixer; the codec chip
2982		   will do the real mixing for them. */
2983		sc->sc_mixcontrol &= ~GUSMASK_LINE_IN; /* 0 enables. */
2984		sc->sc_mixcontrol |= GUSMASK_MIC_IN; /* 1 enables. */
2985		bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
2986
2987		ad1848_isa_attach(&sc->sc_codec);
2988		/* turn on pre-MUX microphone gain. */
2989		ad1848_set_mic_gain(&sc->sc_codec.sc_ad1848, &vol);
2990
2991		return 1;
2992	}
2993}
2994
2995
2996/*
2997 * Return info about the audio device, for the AUDIO_GETINFO ioctl
2998 */
2999int
3000gus_getdev(void *addr, struct audio_device *dev)
3001{
3002
3003	*dev = gus_device;
3004	return 0;
3005}
3006
3007/*
3008 * stubs (XXX)
3009 */
3010
3011int
3012gus_set_in_gain(void *addr, u_int gain,
3013    u_char balance)
3014{
3015
3016	DPRINTF(("gus_set_in_gain called\n"));
3017	return 0;
3018}
3019
3020int
3021gus_get_in_gain(void *addr)
3022{
3023
3024	DPRINTF(("gus_get_in_gain called\n"));
3025	return 0;
3026}
3027
3028int
3029gusmax_dma_input(void *addr, void *tbuf, int size,
3030		 void (*callback)(void *), void *arg)
3031{
3032	struct ad1848_isa_softc *sc;
3033
3034	sc = addr;
3035	return gus_dma_input(sc->sc_ad1848.parent, tbuf, size, callback, arg);
3036}
3037
3038/*
3039 * Start sampling the input source into the requested DMA buffer.
3040 * Called from top-half or from interrupt handler.
3041 */
3042int
3043gus_dma_input(void *addr, void *tbuf, int size,
3044	      void (*callback)(void *), void *arg)
3045{
3046	struct gus_softc *sc;
3047	bus_space_tag_t iot;
3048	bus_space_handle_t ioh2;
3049	u_char dmac;
3050
3051	DMAPRINTF(("gus_dma_input called\n"));
3052	sc = addr;
3053	iot = sc->sc_iot;
3054	ioh2 = sc->sc_ioh2;
3055
3056	KASSERT(mutex_owned(&sc->sc_codec.sc_ad1848.sc_intr_lock));
3057
3058	/*
3059	 * Sample SIZE bytes of data from the card, into buffer at BUF.
3060	 */
3061
3062	if (sc->sc_precision == 16)
3063		return EINVAL;		/* XXX */
3064
3065	/* set DMA modes */
3066	dmac = GUSMASK_SAMPLE_IRQ|GUSMASK_SAMPLE_START;
3067	if (sc->sc_recdrq >= 4)
3068		dmac |= GUSMASK_SAMPLE_DATA16;
3069	if (sc->sc_encoding == AUDIO_ENCODING_ULAW ||
3070	    sc->sc_encoding == AUDIO_ENCODING_ALAW ||
3071	    sc->sc_encoding == AUDIO_ENCODING_ULINEAR_LE ||
3072	    sc->sc_encoding == AUDIO_ENCODING_ULINEAR_BE)
3073		dmac |= GUSMASK_SAMPLE_INVBIT;
3074	if (sc->sc_channels == 2)
3075		dmac |= GUSMASK_SAMPLE_STEREO;
3076	isa_dmastart(sc->sc_ic, sc->sc_recdrq, tbuf, size,
3077	    NULL, DMAMODE_READ, BUS_DMA_NOWAIT);
3078
3079	DMAPRINTF(("gus_dma_input isa_dmastarted\n"));
3080	sc->sc_flags |= GUS_DMAIN_ACTIVE;
3081	sc->sc_dmainintr = callback;
3082	sc->sc_inarg = arg;
3083	sc->sc_dmaincnt = size;
3084	sc->sc_dmainaddr = tbuf;
3085
3086	SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
3087	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, dmac);	/* Go! */
3088
3089
3090	DMAPRINTF(("gus_dma_input returning\n"));
3091
3092	return 0;
3093}
3094
3095STATIC int
3096gus_dmain_intr(struct gus_softc *sc)
3097{
3098	void (*callback)(void *);
3099	void *arg;
3100
3101	KASSERT(mutex_owned(&sc->sc_codec.sc_ad1848.sc_intr_lock));
3102
3103	DMAPRINTF(("gus_dmain_intr called\n"));
3104	if (sc->sc_dmainintr) {
3105		isa_dmadone(sc->sc_ic, sc->sc_recdrq);
3106		callback = sc->sc_dmainintr;
3107		arg = sc->sc_inarg;
3108
3109		sc->sc_dmainaddr = 0;
3110		sc->sc_dmaincnt = 0;
3111		sc->sc_dmainintr = 0;
3112		sc->sc_inarg = 0;
3113
3114		sc->sc_flags &= ~GUS_DMAIN_ACTIVE;
3115		DMAPRINTF(("calling dmain_intr callback %p(%p)\n", callback, arg));
3116		(*callback)(arg);
3117		return 1;
3118	} else {
3119		DMAPRINTF(("gus_dmain_intr false?\n"));
3120		return 0;			/* XXX ??? */
3121	}
3122}
3123
3124int
3125gusmax_halt_out_dma(void *addr)
3126{
3127	struct ad1848_isa_softc *sc;
3128
3129	sc = addr;
3130	return gus_halt_out_dma(sc->sc_ad1848.parent);
3131}
3132
3133
3134int
3135gusmax_halt_in_dma(void *addr)
3136{
3137	struct ad1848_isa_softc *sc;
3138
3139	sc = addr;
3140	return gus_halt_in_dma(sc->sc_ad1848.parent);
3141}
3142
3143/*
3144 * Stop any DMA output.
3145 */
3146int
3147gus_halt_out_dma(void *addr)
3148{
3149	struct gus_softc *sc;
3150	bus_space_tag_t iot;
3151	bus_space_handle_t ioh2;
3152
3153	DMAPRINTF(("gus_halt_out_dma called\n"));
3154	sc = addr;
3155	iot = sc->sc_iot;
3156	ioh2 = sc->sc_ioh2;
3157
3158	KASSERT(mutex_owned(&sc->sc_codec.sc_ad1848.sc_intr_lock));
3159
3160	/*
3161	 * Make sure the GUS _isn't_ setup for DMA
3162	 */
3163
3164	SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
3165	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0);
3166
3167	callout_stop(&sc->sc_dmaout_ch);
3168	isa_dmaabort(sc->sc_ic, sc->sc_playdrq);
3169	sc->sc_flags &= ~(GUS_DMAOUT_ACTIVE|GUS_LOCKED);
3170	sc->sc_dmaoutintr = 0;
3171	sc->sc_outarg = 0;
3172	sc->sc_dmaoutaddr = 0;
3173	sc->sc_dmaoutcnt = 0;
3174	sc->sc_dmabuf = 0;
3175	sc->sc_bufcnt = 0;
3176	sc->sc_playbuf = -1;
3177	/* also stop playing */
3178	gus_stop_voice(sc, GUS_VOICE_LEFT, 1);
3179	gus_stop_voice(sc, GUS_VOICE_RIGHT, 0);
3180
3181	return 0;
3182}
3183
3184/*
3185 * Stop any DMA output.
3186 */
3187int
3188gus_halt_in_dma(void *addr)
3189{
3190	struct gus_softc *sc;
3191	bus_space_tag_t iot;
3192	bus_space_handle_t ioh2;
3193
3194	DMAPRINTF(("gus_halt_in_dma called\n"));
3195	sc = addr;
3196	iot = sc->sc_iot;
3197	ioh2 = sc->sc_ioh2;
3198
3199	KASSERT(mutex_owned(&sc->sc_codec.sc_ad1848.sc_intr_lock));
3200
3201	/*
3202	 * Make sure the GUS _isn't_ setup for DMA
3203	 */
3204
3205	SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
3206	bus_space_write_1(iot, ioh2, GUS_DATA_HIGH,
3207	    bus_space_read_1(iot, ioh2, GUS_DATA_HIGH)
3208	    & ~(GUSMASK_SAMPLE_START|GUSMASK_SAMPLE_IRQ));
3209
3210	isa_dmaabort(sc->sc_ic, sc->sc_recdrq);
3211	sc->sc_flags &= ~GUS_DMAIN_ACTIVE;
3212	sc->sc_dmainintr = 0;
3213	sc->sc_inarg = 0;
3214	sc->sc_dmainaddr = 0;
3215	sc->sc_dmaincnt = 0;
3216
3217	return 0;
3218}
3219
3220
3221static ad1848_devmap_t gusmapping[] = {
3222	{ GUSMAX_DAC_LVL, AD1848_KIND_LVL, AD1848_AUX1_CHANNEL },
3223	{ GUSMAX_LINE_IN_LVL, AD1848_KIND_LVL, AD1848_LINE_CHANNEL },
3224	{ GUSMAX_MONO_LVL, AD1848_KIND_LVL, AD1848_MONO_CHANNEL },
3225	{ GUSMAX_CD_LVL, AD1848_KIND_LVL, AD1848_AUX2_CHANNEL },
3226	{ GUSMAX_MONITOR_LVL, AD1848_KIND_LVL, AD1848_MONITOR_CHANNEL },
3227	{ GUSMAX_OUT_LVL, AD1848_KIND_LVL, AD1848_DAC_CHANNEL },
3228	{ GUSMAX_DAC_MUTE, AD1848_KIND_MUTE, AD1848_AUX1_CHANNEL },
3229	{ GUSMAX_LINE_IN_MUTE, AD1848_KIND_MUTE, AD1848_LINE_CHANNEL },
3230	{ GUSMAX_MONO_MUTE, AD1848_KIND_MUTE, AD1848_MONO_CHANNEL },
3231	{ GUSMAX_CD_MUTE, AD1848_KIND_MUTE, AD1848_AUX2_CHANNEL },
3232	{ GUSMAX_MONITOR_MUTE, AD1848_KIND_MUTE, AD1848_MONITOR_CHANNEL },
3233	{ GUSMAX_REC_LVL, AD1848_KIND_RECORDGAIN, -1 },
3234	{ GUSMAX_RECORD_SOURCE, AD1848_KIND_RECORDSOURCE, -1 }
3235};
3236
3237static int nummap = sizeof(gusmapping) / sizeof(gusmapping[0]);
3238
3239STATIC int
3240gusmax_mixer_get_port(void *addr, mixer_ctrl_t *cp)
3241{
3242	struct ad1848_isa_softc *ac;
3243	struct gus_softc *sc;
3244	struct ad1848_volume vol;
3245	int error;
3246
3247	ac = addr;
3248	sc = ac->sc_ad1848.parent;
3249	error = ad1848_mixer_get_port(&ac->sc_ad1848, gusmapping, nummap, cp);
3250	if (error != ENXIO)
3251		return error;
3252
3253	error = EINVAL;
3254
3255	switch (cp->dev) {
3256	case GUSMAX_SPEAKER_LVL:	/* fake speaker for mute naming */
3257		if (cp->type == AUDIO_MIXER_VALUE) {
3258			if (sc->sc_mixcontrol & GUSMASK_LINE_OUT)
3259				vol.left = vol.right = AUDIO_MAX_GAIN;
3260			else
3261				vol.left = vol.right = AUDIO_MIN_GAIN;
3262			error = 0;
3263			ad1848_from_vol(cp, &vol);
3264		}
3265		break;
3266
3267	case GUSMAX_SPEAKER_MUTE:
3268		if (cp->type == AUDIO_MIXER_ENUM) {
3269			cp->un.ord = sc->sc_mixcontrol & GUSMASK_LINE_OUT ? 1 : 0;
3270			error = 0;
3271		}
3272		break;
3273	default:
3274		error = ENXIO;
3275		break;
3276	}
3277
3278	return error;
3279}
3280
3281STATIC int
3282gus_mixer_get_port(void *addr, mixer_ctrl_t *cp)
3283{
3284	struct gus_softc *sc;
3285	struct ics2101_softc *ic;
3286	struct ad1848_volume vol;
3287	int error;
3288
3289	DPRINTF(("gus_mixer_get_port: dev=%d type=%d\n", cp->dev, cp->type));
3290	sc = addr;
3291	ic = &sc->sc_mixer;
3292	error = EINVAL;
3293
3294	if (!HAS_MIXER(sc) && cp->dev > GUSICS_MASTER_MUTE)
3295		return ENXIO;
3296
3297	switch (cp->dev) {
3298
3299	case GUSICS_MIC_IN_MUTE:	/* Microphone */
3300		if (cp->type == AUDIO_MIXER_ENUM) {
3301			if (HAS_MIXER(sc))
3302				cp->un.ord = ic->sc_mute[GUSMIX_CHAN_MIC][ICSMIX_LEFT];
3303			else
3304				cp->un.ord =
3305				    sc->sc_mixcontrol & GUSMASK_MIC_IN ? 0 : 1;
3306			error = 0;
3307		}
3308		break;
3309
3310	case GUSICS_LINE_IN_MUTE:
3311		if (cp->type == AUDIO_MIXER_ENUM) {
3312			if (HAS_MIXER(sc))
3313				cp->un.ord = ic->sc_mute[GUSMIX_CHAN_LINE][ICSMIX_LEFT];
3314			else
3315				cp->un.ord =
3316				    sc->sc_mixcontrol & GUSMASK_LINE_IN ? 1 : 0;
3317			error = 0;
3318		}
3319		break;
3320
3321	case GUSICS_MASTER_MUTE:
3322		if (cp->type == AUDIO_MIXER_ENUM) {
3323			if (HAS_MIXER(sc))
3324				cp->un.ord = ic->sc_mute[GUSMIX_CHAN_MASTER][ICSMIX_LEFT];
3325			else
3326				cp->un.ord =
3327				    sc->sc_mixcontrol & GUSMASK_LINE_OUT ? 1 : 0;
3328			error = 0;
3329		}
3330		break;
3331
3332	case GUSICS_DAC_MUTE:
3333		if (cp->type == AUDIO_MIXER_ENUM) {
3334			cp->un.ord = ic->sc_mute[GUSMIX_CHAN_DAC][ICSMIX_LEFT];
3335			error = 0;
3336		}
3337		break;
3338
3339	case GUSICS_CD_MUTE:
3340		if (cp->type == AUDIO_MIXER_ENUM) {
3341			cp->un.ord = ic->sc_mute[GUSMIX_CHAN_CD][ICSMIX_LEFT];
3342			error = 0;
3343		}
3344		break;
3345
3346	case GUSICS_MASTER_LVL:
3347		if (cp->type == AUDIO_MIXER_VALUE) {
3348			vol.left = ic->sc_setting[GUSMIX_CHAN_MASTER][ICSMIX_LEFT];
3349			vol.right = ic->sc_setting[GUSMIX_CHAN_MASTER][ICSMIX_RIGHT];
3350			if (ad1848_from_vol(cp, &vol))
3351				error = 0;
3352		}
3353		break;
3354
3355	case GUSICS_MIC_IN_LVL:	/* Microphone */
3356		if (cp->type == AUDIO_MIXER_VALUE) {
3357			vol.left = ic->sc_setting[GUSMIX_CHAN_MIC][ICSMIX_LEFT];
3358			vol.right = ic->sc_setting[GUSMIX_CHAN_MIC][ICSMIX_RIGHT];
3359			if (ad1848_from_vol(cp, &vol))
3360				error = 0;
3361		}
3362		break;
3363
3364	case GUSICS_LINE_IN_LVL:	/* line in */
3365		if (cp->type == AUDIO_MIXER_VALUE) {
3366			vol.left = ic->sc_setting[GUSMIX_CHAN_LINE][ICSMIX_LEFT];
3367			vol.right = ic->sc_setting[GUSMIX_CHAN_LINE][ICSMIX_RIGHT];
3368			if (ad1848_from_vol(cp, &vol))
3369				error = 0;
3370		}
3371		break;
3372
3373
3374	case GUSICS_CD_LVL:
3375		if (cp->type == AUDIO_MIXER_VALUE) {
3376			vol.left = ic->sc_setting[GUSMIX_CHAN_CD][ICSMIX_LEFT];
3377			vol.right = ic->sc_setting[GUSMIX_CHAN_CD][ICSMIX_RIGHT];
3378			if (ad1848_from_vol(cp, &vol))
3379				error = 0;
3380		}
3381		break;
3382
3383	case GUSICS_DAC_LVL:		/* dac out */
3384		if (cp->type == AUDIO_MIXER_VALUE) {
3385			vol.left = ic->sc_setting[GUSMIX_CHAN_DAC][ICSMIX_LEFT];
3386			vol.right = ic->sc_setting[GUSMIX_CHAN_DAC][ICSMIX_RIGHT];
3387			if (ad1848_from_vol(cp, &vol))
3388				error = 0;
3389		}
3390		break;
3391
3392
3393	case GUSICS_RECORD_SOURCE:
3394		if (cp->type == AUDIO_MIXER_ENUM) {
3395			/* Can't set anything else useful, sigh. */
3396			 cp->un.ord = 0;
3397		}
3398		break;
3399
3400	default:
3401		return ENXIO;
3402		/*NOTREACHED*/
3403	}
3404	return error;
3405}
3406
3407STATIC void
3408gusics_master_mute(struct ics2101_softc *ic, int mute)
3409{
3410
3411	ics2101_mix_mute(ic, GUSMIX_CHAN_MASTER, ICSMIX_LEFT, mute);
3412	ics2101_mix_mute(ic, GUSMIX_CHAN_MASTER, ICSMIX_RIGHT, mute);
3413}
3414
3415STATIC void
3416gusics_mic_mute(struct ics2101_softc *ic, int mute)
3417{
3418
3419	ics2101_mix_mute(ic, GUSMIX_CHAN_MIC, ICSMIX_LEFT, mute);
3420	ics2101_mix_mute(ic, GUSMIX_CHAN_MIC, ICSMIX_RIGHT, mute);
3421}
3422
3423STATIC void
3424gusics_linein_mute(struct ics2101_softc *ic, int mute)
3425{
3426
3427	ics2101_mix_mute(ic, GUSMIX_CHAN_LINE, ICSMIX_LEFT, mute);
3428	ics2101_mix_mute(ic, GUSMIX_CHAN_LINE, ICSMIX_RIGHT, mute);
3429}
3430
3431STATIC void
3432gusics_cd_mute(struct ics2101_softc *ic, int mute)
3433{
3434
3435	ics2101_mix_mute(ic, GUSMIX_CHAN_CD, ICSMIX_LEFT, mute);
3436	ics2101_mix_mute(ic, GUSMIX_CHAN_CD, ICSMIX_RIGHT, mute);
3437}
3438
3439STATIC void
3440gusics_dac_mute(struct ics2101_softc *ic, int mute)
3441{
3442
3443	ics2101_mix_mute(ic, GUSMIX_CHAN_DAC, ICSMIX_LEFT, mute);
3444	ics2101_mix_mute(ic, GUSMIX_CHAN_DAC, ICSMIX_RIGHT, mute);
3445}
3446
3447STATIC int
3448gusmax_mixer_set_port(void *addr, mixer_ctrl_t *cp)
3449{
3450	struct ad1848_isa_softc *ac;
3451	struct gus_softc *sc;
3452	struct ad1848_volume vol;
3453	int error;
3454
3455	ac = addr;
3456	sc = ac->sc_ad1848.parent;
3457	error = ad1848_mixer_set_port(&ac->sc_ad1848, gusmapping, nummap, cp);
3458	if (error != ENXIO)
3459		return error;
3460
3461	DPRINTF(("gusmax_mixer_set_port: dev=%d type=%d\n", cp->dev, cp->type));
3462
3463	switch (cp->dev) {
3464	case GUSMAX_SPEAKER_LVL:
3465		if (cp->type == AUDIO_MIXER_VALUE &&
3466		    cp->un.value.num_channels == 1) {
3467			if (ad1848_to_vol(cp, &vol)) {
3468				gus_speaker_ctl(sc, vol.left > AUDIO_MIN_GAIN ?
3469						SPKR_ON : SPKR_OFF);
3470				error = 0;
3471			}
3472		}
3473		break;
3474
3475	case GUSMAX_SPEAKER_MUTE:
3476		if (cp->type == AUDIO_MIXER_ENUM) {
3477			gus_speaker_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON);
3478			error = 0;
3479		}
3480		break;
3481
3482	default:
3483		return ENXIO;
3484		/*NOTREACHED*/
3485	}
3486	return error;
3487}
3488
3489STATIC int
3490gus_mixer_set_port(void *addr, mixer_ctrl_t *cp)
3491{
3492	struct gus_softc *sc;
3493	struct ics2101_softc *ic;
3494	struct ad1848_volume vol;
3495	int error;
3496
3497	DPRINTF(("gus_mixer_set_port: dev=%d type=%d\n", cp->dev, cp->type));
3498	sc = addr;
3499	ic = &sc->sc_mixer;
3500	error = EINVAL;
3501
3502	if (!HAS_MIXER(sc) && cp->dev > GUSICS_MASTER_MUTE)
3503		return ENXIO;
3504
3505	switch (cp->dev) {
3506
3507	case GUSICS_MIC_IN_MUTE:	/* Microphone */
3508		if (cp->type == AUDIO_MIXER_ENUM) {
3509			DPRINTF(("mic mute %d\n", cp->un.ord));
3510			if (HAS_MIXER(sc)) {
3511				gusics_mic_mute(ic, cp->un.ord);
3512			}
3513			gus_mic_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON);
3514			error = 0;
3515		}
3516		break;
3517
3518	case GUSICS_LINE_IN_MUTE:
3519		if (cp->type == AUDIO_MIXER_ENUM) {
3520			DPRINTF(("linein mute %d\n", cp->un.ord));
3521			if (HAS_MIXER(sc)) {
3522				gusics_linein_mute(ic, cp->un.ord);
3523			}
3524			gus_linein_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON);
3525			error = 0;
3526		}
3527		break;
3528
3529	case GUSICS_MASTER_MUTE:
3530		if (cp->type == AUDIO_MIXER_ENUM) {
3531			DPRINTF(("master mute %d\n", cp->un.ord));
3532			if (HAS_MIXER(sc)) {
3533				gusics_master_mute(ic, cp->un.ord);
3534			}
3535			gus_speaker_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON);
3536			error = 0;
3537		}
3538		break;
3539
3540	case GUSICS_DAC_MUTE:
3541		if (cp->type == AUDIO_MIXER_ENUM) {
3542			gusics_dac_mute(ic, cp->un.ord);
3543			error = 0;
3544		}
3545		break;
3546
3547	case GUSICS_CD_MUTE:
3548		if (cp->type == AUDIO_MIXER_ENUM) {
3549			gusics_cd_mute(ic, cp->un.ord);
3550			error = 0;
3551		}
3552		break;
3553
3554	case GUSICS_MASTER_LVL:
3555		if (cp->type == AUDIO_MIXER_VALUE) {
3556			if (ad1848_to_vol(cp, &vol)) {
3557				ics2101_mix_attenuate(ic,
3558						      GUSMIX_CHAN_MASTER,
3559						      ICSMIX_LEFT,
3560						      vol.left);
3561				ics2101_mix_attenuate(ic,
3562						      GUSMIX_CHAN_MASTER,
3563						      ICSMIX_RIGHT,
3564						      vol.right);
3565				error = 0;
3566			}
3567		}
3568		break;
3569
3570	case GUSICS_MIC_IN_LVL:	/* Microphone */
3571		if (cp->type == AUDIO_MIXER_VALUE) {
3572			if (ad1848_to_vol(cp, &vol)) {
3573				ics2101_mix_attenuate(ic,
3574						      GUSMIX_CHAN_MIC,
3575						      ICSMIX_LEFT,
3576						      vol.left);
3577				ics2101_mix_attenuate(ic,
3578						      GUSMIX_CHAN_MIC,
3579						      ICSMIX_RIGHT,
3580						      vol.right);
3581				error = 0;
3582			}
3583		}
3584		break;
3585
3586	case GUSICS_LINE_IN_LVL:	/* line in */
3587		if (cp->type == AUDIO_MIXER_VALUE) {
3588			if (ad1848_to_vol(cp, &vol)) {
3589				ics2101_mix_attenuate(ic,
3590						      GUSMIX_CHAN_LINE,
3591						      ICSMIX_LEFT,
3592						      vol.left);
3593				ics2101_mix_attenuate(ic,
3594						      GUSMIX_CHAN_LINE,
3595						      ICSMIX_RIGHT,
3596						      vol.right);
3597				error = 0;
3598			}
3599		}
3600		break;
3601
3602
3603	case GUSICS_CD_LVL:
3604		if (cp->type == AUDIO_MIXER_VALUE) {
3605			if (ad1848_to_vol(cp, &vol)) {
3606				ics2101_mix_attenuate(ic,
3607						      GUSMIX_CHAN_CD,
3608						      ICSMIX_LEFT,
3609						      vol.left);
3610				ics2101_mix_attenuate(ic,
3611						      GUSMIX_CHAN_CD,
3612						      ICSMIX_RIGHT,
3613						      vol.right);
3614				error = 0;
3615			}
3616		}
3617		break;
3618
3619	case GUSICS_DAC_LVL:		/* dac out */
3620		if (cp->type == AUDIO_MIXER_VALUE) {
3621			if (ad1848_to_vol(cp, &vol)) {
3622				ics2101_mix_attenuate(ic,
3623						      GUSMIX_CHAN_DAC,
3624						      ICSMIX_LEFT,
3625						      vol.left);
3626				ics2101_mix_attenuate(ic,
3627						      GUSMIX_CHAN_DAC,
3628						      ICSMIX_RIGHT,
3629						      vol.right);
3630				error = 0;
3631			}
3632		}
3633		break;
3634
3635
3636	case GUSICS_RECORD_SOURCE:
3637		if (cp->type == AUDIO_MIXER_ENUM && cp->un.ord == 0) {
3638			/* Can't set anything else useful, sigh. */
3639			error = 0;
3640		}
3641		break;
3642
3643	default:
3644		return ENXIO;
3645		/*NOTREACHED*/
3646	}
3647	return error;
3648}
3649
3650STATIC int
3651gus_get_props(void *addr)
3652{
3653	struct gus_softc *sc;
3654
3655	sc = addr;
3656	return AUDIO_PROP_MMAP |
3657	    (sc->sc_recdrq == sc->sc_playdrq ? 0 : AUDIO_PROP_FULLDUPLEX);
3658}
3659
3660STATIC int
3661gusmax_get_props(void *addr)
3662{
3663	struct ad1848_isa_softc *ac;
3664
3665	ac = addr;
3666	return gus_get_props(ac->sc_ad1848.parent);
3667}
3668
3669STATIC int
3670gusmax_mixer_query_devinfo(void *addr, mixer_devinfo_t *dip)
3671{
3672
3673	DPRINTF(("gusmax_query_devinfo: index=%d\n", dip->index));
3674
3675	switch(dip->index) {
3676#if 0
3677	case GUSMAX_MIC_IN_LVL:	/* Microphone */
3678		dip->type = AUDIO_MIXER_VALUE;
3679		dip->mixer_class = GUSMAX_INPUT_CLASS;
3680		dip->prev = AUDIO_MIXER_LAST;
3681		dip->next = GUSMAX_MIC_IN_MUTE;
3682		strcpy(dip->label.name, AudioNmicrophone);
3683		dip->un.v.num_channels = 2;
3684		strcpy(dip->un.v.units.name, AudioNvolume);
3685		break;
3686#endif
3687
3688	case GUSMAX_MONO_LVL:	/* mono/microphone mixer */
3689		dip->type = AUDIO_MIXER_VALUE;
3690		dip->mixer_class = GUSMAX_INPUT_CLASS;
3691		dip->prev = AUDIO_MIXER_LAST;
3692		dip->next = GUSMAX_MONO_MUTE;
3693		strcpy(dip->label.name, AudioNmicrophone);
3694		dip->un.v.num_channels = 1;
3695		strcpy(dip->un.v.units.name, AudioNvolume);
3696		break;
3697
3698	case GUSMAX_DAC_LVL:		/*  dacout */
3699		dip->type = AUDIO_MIXER_VALUE;
3700		dip->mixer_class = GUSMAX_INPUT_CLASS;
3701		dip->prev = AUDIO_MIXER_LAST;
3702		dip->next = GUSMAX_DAC_MUTE;
3703		strcpy(dip->label.name, AudioNdac);
3704		dip->un.v.num_channels = 2;
3705		strcpy(dip->un.v.units.name, AudioNvolume);
3706		break;
3707
3708	case GUSMAX_LINE_IN_LVL:	/* line */
3709		dip->type = AUDIO_MIXER_VALUE;
3710		dip->mixer_class = GUSMAX_INPUT_CLASS;
3711		dip->prev = AUDIO_MIXER_LAST;
3712		dip->next = GUSMAX_LINE_IN_MUTE;
3713		strcpy(dip->label.name, AudioNline);
3714		dip->un.v.num_channels = 2;
3715		strcpy(dip->un.v.units.name, AudioNvolume);
3716		break;
3717
3718	case GUSMAX_CD_LVL:		/* cd */
3719		dip->type = AUDIO_MIXER_VALUE;
3720		dip->mixer_class = GUSMAX_INPUT_CLASS;
3721		dip->prev = AUDIO_MIXER_LAST;
3722		dip->next = GUSMAX_CD_MUTE;
3723		strcpy(dip->label.name, AudioNcd);
3724		dip->un.v.num_channels = 2;
3725		strcpy(dip->un.v.units.name, AudioNvolume);
3726		break;
3727
3728
3729	case GUSMAX_MONITOR_LVL:	/* monitor level */
3730		dip->type = AUDIO_MIXER_VALUE;
3731		dip->mixer_class = GUSMAX_MONITOR_CLASS;
3732		dip->next = GUSMAX_MONITOR_MUTE;
3733		dip->prev = AUDIO_MIXER_LAST;
3734		strcpy(dip->label.name, AudioNmonitor);
3735		dip->un.v.num_channels = 1;
3736		strcpy(dip->un.v.units.name, AudioNvolume);
3737		break;
3738
3739	case GUSMAX_OUT_LVL:		/* cs4231 output volume: not useful? */
3740		dip->type = AUDIO_MIXER_VALUE;
3741		dip->mixer_class = GUSMAX_MONITOR_CLASS;
3742		dip->prev = dip->next = AUDIO_MIXER_LAST;
3743		strcpy(dip->label.name, AudioNoutput);
3744		dip->un.v.num_channels = 2;
3745		strcpy(dip->un.v.units.name, AudioNvolume);
3746		break;
3747
3748	case GUSMAX_SPEAKER_LVL:		/* fake speaker volume */
3749		dip->type = AUDIO_MIXER_VALUE;
3750		dip->mixer_class = GUSMAX_MONITOR_CLASS;
3751		dip->prev = AUDIO_MIXER_LAST;
3752		dip->next = GUSMAX_SPEAKER_MUTE;
3753		strcpy(dip->label.name, AudioNmaster);
3754		dip->un.v.num_channels = 2;
3755		strcpy(dip->un.v.units.name, AudioNvolume);
3756		break;
3757
3758	case GUSMAX_LINE_IN_MUTE:
3759		dip->mixer_class = GUSMAX_INPUT_CLASS;
3760		dip->type = AUDIO_MIXER_ENUM;
3761		dip->prev = GUSMAX_LINE_IN_LVL;
3762		dip->next = AUDIO_MIXER_LAST;
3763		goto mute;
3764
3765	case GUSMAX_DAC_MUTE:
3766		dip->mixer_class = GUSMAX_INPUT_CLASS;
3767		dip->type = AUDIO_MIXER_ENUM;
3768		dip->prev = GUSMAX_DAC_LVL;
3769		dip->next = AUDIO_MIXER_LAST;
3770		goto mute;
3771
3772	case GUSMAX_CD_MUTE:
3773		dip->mixer_class = GUSMAX_INPUT_CLASS;
3774		dip->type = AUDIO_MIXER_ENUM;
3775		dip->prev = GUSMAX_CD_LVL;
3776		dip->next = AUDIO_MIXER_LAST;
3777		goto mute;
3778
3779	case GUSMAX_MONO_MUTE:
3780		dip->mixer_class = GUSMAX_INPUT_CLASS;
3781		dip->type = AUDIO_MIXER_ENUM;
3782		dip->prev = GUSMAX_MONO_LVL;
3783		dip->next = AUDIO_MIXER_LAST;
3784		goto mute;
3785
3786	case GUSMAX_MONITOR_MUTE:
3787		dip->mixer_class = GUSMAX_OUTPUT_CLASS;
3788		dip->type = AUDIO_MIXER_ENUM;
3789		dip->prev = GUSMAX_MONITOR_LVL;
3790		dip->next = AUDIO_MIXER_LAST;
3791		goto mute;
3792
3793	case GUSMAX_SPEAKER_MUTE:
3794		dip->mixer_class = GUSMAX_OUTPUT_CLASS;
3795		dip->type = AUDIO_MIXER_ENUM;
3796		dip->prev = GUSMAX_SPEAKER_LVL;
3797		dip->next = AUDIO_MIXER_LAST;
3798	mute:
3799		strcpy(dip->label.name, AudioNmute);
3800		dip->un.e.num_mem = 2;
3801		strcpy(dip->un.e.member[0].label.name, AudioNoff);
3802		dip->un.e.member[0].ord = 0;
3803		strcpy(dip->un.e.member[1].label.name, AudioNon);
3804		dip->un.e.member[1].ord = 1;
3805		break;
3806
3807	case GUSMAX_REC_LVL:	/* record level */
3808		dip->type = AUDIO_MIXER_VALUE;
3809		dip->mixer_class = GUSMAX_RECORD_CLASS;
3810		dip->prev = AUDIO_MIXER_LAST;
3811		dip->next = GUSMAX_RECORD_SOURCE;
3812		strcpy(dip->label.name, AudioNrecord);
3813		dip->un.v.num_channels = 2;
3814		strcpy(dip->un.v.units.name, AudioNvolume);
3815		break;
3816
3817	case GUSMAX_RECORD_SOURCE:
3818		dip->mixer_class = GUSMAX_RECORD_CLASS;
3819		dip->type = AUDIO_MIXER_ENUM;
3820		dip->prev = GUSMAX_REC_LVL;
3821		dip->next = AUDIO_MIXER_LAST;
3822		strcpy(dip->label.name, AudioNsource);
3823		dip->un.e.num_mem = 4;
3824		strcpy(dip->un.e.member[0].label.name, AudioNoutput);
3825		dip->un.e.member[0].ord = DAC_IN_PORT;
3826		strcpy(dip->un.e.member[1].label.name, AudioNmicrophone);
3827		dip->un.e.member[1].ord = MIC_IN_PORT;
3828		strcpy(dip->un.e.member[2].label.name, AudioNdac);
3829		dip->un.e.member[2].ord = AUX1_IN_PORT;
3830		strcpy(dip->un.e.member[3].label.name, AudioNline);
3831		dip->un.e.member[3].ord = LINE_IN_PORT;
3832		break;
3833
3834	case GUSMAX_INPUT_CLASS:		/* input class descriptor */
3835		dip->type = AUDIO_MIXER_CLASS;
3836		dip->mixer_class = GUSMAX_INPUT_CLASS;
3837		dip->next = dip->prev = AUDIO_MIXER_LAST;
3838		strcpy(dip->label.name, AudioCinputs);
3839		break;
3840
3841	case GUSMAX_OUTPUT_CLASS:		/* output class descriptor */
3842		dip->type = AUDIO_MIXER_CLASS;
3843		dip->mixer_class = GUSMAX_OUTPUT_CLASS;
3844		dip->next = dip->prev = AUDIO_MIXER_LAST;
3845		strcpy(dip->label.name, AudioCoutputs);
3846		break;
3847
3848	case GUSMAX_MONITOR_CLASS:		/* monitor class descriptor */
3849		dip->type = AUDIO_MIXER_CLASS;
3850		dip->mixer_class = GUSMAX_MONITOR_CLASS;
3851		dip->next = dip->prev = AUDIO_MIXER_LAST;
3852		strcpy(dip->label.name, AudioCmonitor);
3853		break;
3854
3855	case GUSMAX_RECORD_CLASS:		/* record source class */
3856		dip->type = AUDIO_MIXER_CLASS;
3857		dip->mixer_class = GUSMAX_RECORD_CLASS;
3858		dip->next = dip->prev = AUDIO_MIXER_LAST;
3859		strcpy(dip->label.name, AudioCrecord);
3860		break;
3861
3862	default:
3863		return ENXIO;
3864		/*NOTREACHED*/
3865	}
3866	DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name));
3867	return 0;
3868}
3869
3870STATIC int
3871gus_mixer_query_devinfo(void *addr, mixer_devinfo_t *dip)
3872{
3873	struct gus_softc *sc;
3874
3875	DPRINTF(("gusmax_query_devinfo: index=%d\n", dip->index));
3876	sc = addr;
3877	if (!HAS_MIXER(sc) && dip->index > GUSICS_MASTER_MUTE)
3878		return ENXIO;
3879
3880	switch(dip->index) {
3881
3882	case GUSICS_MIC_IN_LVL:	/* Microphone */
3883		dip->type = AUDIO_MIXER_VALUE;
3884		dip->mixer_class = GUSICS_INPUT_CLASS;
3885		dip->prev = AUDIO_MIXER_LAST;
3886		dip->next = GUSICS_MIC_IN_MUTE;
3887		strcpy(dip->label.name, AudioNmicrophone);
3888		dip->un.v.num_channels = 2;
3889		strcpy(dip->un.v.units.name, AudioNvolume);
3890		break;
3891
3892	case GUSICS_LINE_IN_LVL:	/* line */
3893		dip->type = AUDIO_MIXER_VALUE;
3894		dip->mixer_class = GUSICS_INPUT_CLASS;
3895		dip->prev = AUDIO_MIXER_LAST;
3896		dip->next = GUSICS_LINE_IN_MUTE;
3897		strcpy(dip->label.name, AudioNline);
3898		dip->un.v.num_channels = 2;
3899		strcpy(dip->un.v.units.name, AudioNvolume);
3900		break;
3901
3902	case GUSICS_CD_LVL:		/* cd */
3903		dip->type = AUDIO_MIXER_VALUE;
3904		dip->mixer_class = GUSICS_INPUT_CLASS;
3905		dip->prev = AUDIO_MIXER_LAST;
3906		dip->next = GUSICS_CD_MUTE;
3907		strcpy(dip->label.name, AudioNcd);
3908		dip->un.v.num_channels = 2;
3909		strcpy(dip->un.v.units.name, AudioNvolume);
3910		break;
3911
3912	case GUSICS_DAC_LVL:		/*  dacout */
3913		dip->type = AUDIO_MIXER_VALUE;
3914		dip->mixer_class = GUSICS_INPUT_CLASS;
3915		dip->prev = AUDIO_MIXER_LAST;
3916		dip->next = GUSICS_DAC_MUTE;
3917		strcpy(dip->label.name, AudioNdac);
3918		dip->un.v.num_channels = 2;
3919		strcpy(dip->un.v.units.name, AudioNvolume);
3920		break;
3921
3922	case GUSICS_MASTER_LVL:		/*  master output */
3923		dip->type = AUDIO_MIXER_VALUE;
3924		dip->mixer_class = GUSICS_OUTPUT_CLASS;
3925		dip->prev = AUDIO_MIXER_LAST;
3926		dip->next = GUSICS_MASTER_MUTE;
3927		strcpy(dip->label.name, AudioNmaster);
3928		dip->un.v.num_channels = 2;
3929		strcpy(dip->un.v.units.name, AudioNvolume);
3930		break;
3931
3932
3933	case GUSICS_LINE_IN_MUTE:
3934		dip->mixer_class = GUSICS_INPUT_CLASS;
3935		dip->type = AUDIO_MIXER_ENUM;
3936		dip->prev = GUSICS_LINE_IN_LVL;
3937		dip->next = AUDIO_MIXER_LAST;
3938		goto mute;
3939
3940	case GUSICS_DAC_MUTE:
3941		dip->mixer_class = GUSICS_INPUT_CLASS;
3942		dip->type = AUDIO_MIXER_ENUM;
3943		dip->prev = GUSICS_DAC_LVL;
3944		dip->next = AUDIO_MIXER_LAST;
3945		goto mute;
3946
3947	case GUSICS_CD_MUTE:
3948		dip->mixer_class = GUSICS_INPUT_CLASS;
3949		dip->type = AUDIO_MIXER_ENUM;
3950		dip->prev = GUSICS_CD_LVL;
3951		dip->next = AUDIO_MIXER_LAST;
3952		goto mute;
3953
3954	case GUSICS_MIC_IN_MUTE:
3955		dip->mixer_class = GUSICS_INPUT_CLASS;
3956		dip->type = AUDIO_MIXER_ENUM;
3957		dip->prev = GUSICS_MIC_IN_LVL;
3958		dip->next = AUDIO_MIXER_LAST;
3959		goto mute;
3960
3961	case GUSICS_MASTER_MUTE:
3962		dip->mixer_class = GUSICS_OUTPUT_CLASS;
3963		dip->type = AUDIO_MIXER_ENUM;
3964		dip->prev = GUSICS_MASTER_LVL;
3965		dip->next = AUDIO_MIXER_LAST;
3966mute:
3967		strcpy(dip->label.name, AudioNmute);
3968		dip->un.e.num_mem = 2;
3969		strcpy(dip->un.e.member[0].label.name, AudioNoff);
3970		dip->un.e.member[0].ord = 0;
3971		strcpy(dip->un.e.member[1].label.name, AudioNon);
3972		dip->un.e.member[1].ord = 1;
3973		break;
3974
3975	case GUSICS_RECORD_SOURCE:
3976		dip->mixer_class = GUSICS_RECORD_CLASS;
3977		dip->type = AUDIO_MIXER_ENUM;
3978		dip->prev = dip->next = AUDIO_MIXER_LAST;
3979		strcpy(dip->label.name, AudioNsource);
3980		dip->un.e.num_mem = 1;
3981		strcpy(dip->un.e.member[0].label.name, AudioNoutput);
3982		dip->un.e.member[0].ord = GUSICS_MASTER_LVL;
3983		break;
3984
3985	case GUSICS_INPUT_CLASS:
3986		dip->type = AUDIO_MIXER_CLASS;
3987		dip->mixer_class = GUSICS_INPUT_CLASS;
3988		dip->next = dip->prev = AUDIO_MIXER_LAST;
3989		strcpy(dip->label.name, AudioCinputs);
3990		break;
3991
3992	case GUSICS_OUTPUT_CLASS:
3993		dip->type = AUDIO_MIXER_CLASS;
3994		dip->mixer_class = GUSICS_OUTPUT_CLASS;
3995		dip->next = dip->prev = AUDIO_MIXER_LAST;
3996		strcpy(dip->label.name, AudioCoutputs);
3997		break;
3998
3999	case GUSICS_RECORD_CLASS:
4000		dip->type = AUDIO_MIXER_CLASS;
4001		dip->mixer_class = GUSICS_RECORD_CLASS;
4002		dip->next = dip->prev = AUDIO_MIXER_LAST;
4003		strcpy(dip->label.name, AudioCrecord);
4004		break;
4005
4006	default:
4007		return ENXIO;
4008		/*NOTREACHED*/
4009	}
4010	DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name));
4011	return 0;
4012}
4013
4014STATIC int
4015gus_query_encoding(void *addr, struct audio_encoding *fp)
4016{
4017
4018	switch (fp->index) {
4019	case 0:
4020		strcpy(fp->name, AudioEmulaw);
4021		fp->encoding = AUDIO_ENCODING_ULAW;
4022		fp->precision = 8;
4023		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
4024		break;
4025	case 1:
4026		strcpy(fp->name, AudioEslinear);
4027		fp->encoding = AUDIO_ENCODING_SLINEAR;
4028		fp->precision = 8;
4029		fp->flags = 0;
4030		break;
4031	case 2:
4032		strcpy(fp->name, AudioEslinear_le);
4033		fp->encoding = AUDIO_ENCODING_SLINEAR_LE;
4034		fp->precision = 16;
4035		fp->flags = 0;
4036		break;
4037	case 3:
4038		strcpy(fp->name, AudioEulinear);
4039		fp->encoding = AUDIO_ENCODING_ULINEAR;
4040		fp->precision = 8;
4041		fp->flags = 0;
4042		break;
4043	case 4:
4044		strcpy(fp->name, AudioEulinear_le);
4045		fp->encoding = AUDIO_ENCODING_ULINEAR_LE;
4046		fp->precision = 16;
4047		fp->flags = 0;
4048		break;
4049	case 5:
4050		strcpy(fp->name, AudioEslinear_be);
4051		fp->encoding = AUDIO_ENCODING_SLINEAR_BE;
4052		fp->precision = 16;
4053		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
4054		break;
4055	case 6:
4056		strcpy(fp->name, AudioEulinear_be);
4057		fp->encoding = AUDIO_ENCODING_ULINEAR_BE;
4058		fp->precision = 16;
4059		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
4060		break;
4061	case 7:
4062		strcpy(fp->name, AudioEalaw);
4063		fp->encoding = AUDIO_ENCODING_ALAW;
4064		fp->precision = 8;
4065		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
4066		break;
4067
4068	default:
4069		return EINVAL;
4070		/*NOTREACHED*/
4071	}
4072	return 0;
4073}
4074
4075/*
4076 * Setup the ICS mixer in "transparent" mode: reset everything to a sensible
4077 * level.  Levels as suggested by GUS SDK code.
4078 */
4079STATIC void
4080gus_init_ics2101(struct gus_softc *sc)
4081{
4082	struct ics2101_softc *ic;
4083
4084	ic = &sc->sc_mixer;
4085	sc->sc_mixer.sc_iot = sc->sc_iot;
4086	sc->sc_mixer.sc_selio = GUS_MIXER_SELECT;
4087	sc->sc_mixer.sc_selio_ioh = sc->sc_ioh3;
4088	sc->sc_mixer.sc_dataio = GUS_MIXER_DATA;
4089	sc->sc_mixer.sc_dataio_ioh = sc->sc_ioh2;
4090	sc->sc_mixer.sc_flags = (sc->sc_revision == 5) ? ICS_FLIP : 0;
4091
4092	ics2101_mix_attenuate(ic,
4093			      GUSMIX_CHAN_MIC,
4094			      ICSMIX_LEFT,
4095			      ICSMIX_MIN_ATTN);
4096	ics2101_mix_attenuate(ic,
4097			      GUSMIX_CHAN_MIC,
4098			      ICSMIX_RIGHT,
4099			      ICSMIX_MIN_ATTN);
4100	/*
4101	 * Start with microphone muted by the mixer...
4102	 */
4103	gusics_mic_mute(ic, 1);
4104
4105	/* ... and enabled by the GUS master mix control */
4106	gus_mic_ctl(sc, SPKR_ON);
4107
4108	ics2101_mix_attenuate(ic,
4109			      GUSMIX_CHAN_LINE,
4110			      ICSMIX_LEFT,
4111			      ICSMIX_MIN_ATTN);
4112	ics2101_mix_attenuate(ic,
4113			      GUSMIX_CHAN_LINE,
4114			      ICSMIX_RIGHT,
4115			      ICSMIX_MIN_ATTN);
4116
4117	ics2101_mix_attenuate(ic,
4118			      GUSMIX_CHAN_CD,
4119			      ICSMIX_LEFT,
4120			      ICSMIX_MIN_ATTN);
4121	ics2101_mix_attenuate(ic,
4122			      GUSMIX_CHAN_CD,
4123			      ICSMIX_RIGHT,
4124			      ICSMIX_MIN_ATTN);
4125
4126	ics2101_mix_attenuate(ic,
4127			      GUSMIX_CHAN_DAC,
4128			      ICSMIX_LEFT,
4129			      ICSMIX_MIN_ATTN);
4130	ics2101_mix_attenuate(ic,
4131			      GUSMIX_CHAN_DAC,
4132			      ICSMIX_RIGHT,
4133			      ICSMIX_MIN_ATTN);
4134
4135	ics2101_mix_attenuate(ic,
4136			      ICSMIX_CHAN_4,
4137			      ICSMIX_LEFT,
4138			      ICSMIX_MAX_ATTN);
4139	ics2101_mix_attenuate(ic,
4140			      ICSMIX_CHAN_4,
4141			      ICSMIX_RIGHT,
4142			      ICSMIX_MAX_ATTN);
4143
4144	ics2101_mix_attenuate(ic,
4145			      GUSMIX_CHAN_MASTER,
4146			      ICSMIX_LEFT,
4147			      ICSMIX_MIN_ATTN);
4148	ics2101_mix_attenuate(ic,
4149			      GUSMIX_CHAN_MASTER,
4150			      ICSMIX_RIGHT,
4151			      ICSMIX_MIN_ATTN);
4152	/* unmute other stuff: */
4153	gusics_cd_mute(ic, 0);
4154	gusics_dac_mute(ic, 0);
4155	gusics_linein_mute(ic, 0);
4156	return;
4157}
4158