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