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