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