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