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