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