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