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