Home | History | Annotate | Line # | Download | only in isa
gus.c revision 1.39
      1 /*	$NetBSD: gus.c,v 1.39 1997/08/07 22:48:10 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 	if (audio_hardware_attach(&gus_hw_if, HAS_CODEC(sc) ? (void *)&sc->sc_codec : (void *)sc, &sc->sc_dev) != 0)
    946 		printf("gus: could not attach to audio pseudo-device driver\n");
    947 }
    948 
    949 int
    950 gusopen(addr, flags)
    951 	void *addr;
    952 	int flags;
    953 {
    954 	struct gus_softc *sc = addr;
    955 
    956 	DPRINTF(("gusopen() called\n"));
    957 
    958 	if (sc->sc_flags & GUS_OPEN)
    959 		return EBUSY;
    960 
    961 	/*
    962 	 * Some initialization
    963 	 */
    964 
    965 	sc->sc_flags |= GUS_OPEN;
    966 	sc->sc_dmabuf = 0;
    967 	sc->sc_playbuf = -1;
    968 	sc->sc_bufcnt = 0;
    969 	sc->sc_voc[GUS_VOICE_LEFT].start_addr = GUS_MEM_OFFSET - 1;
    970 	sc->sc_voc[GUS_VOICE_LEFT].current_addr = GUS_MEM_OFFSET;
    971 
    972 	if (HAS_CODEC(sc)) {
    973 		ad1848_open(&sc->sc_codec, flags);
    974 		sc->sc_codec.aux1_mute = 0;
    975 		ad1848_mute_aux1(&sc->sc_codec, 0); /* turn on DAC output */
    976 		if (flags & FREAD) {
    977 			sc->sc_codec.mono_mute = 0;
    978 			cs4231_mute_mono(&sc->sc_codec, 0);
    979 		}
    980 	} else if (flags & FREAD) {
    981 		/* enable/unmute the microphone */
    982 		if (HAS_MIXER(sc)) {
    983 			gusics_mic_mute(&sc->sc_mixer, 0);
    984 		} else
    985 			gus_mic_ctl(sc, SPKR_ON);
    986 	}
    987 	if (sc->sc_nbufs == 0)
    988 	    gus_round_blocksize(sc, GUS_BUFFER_MULTIPLE); /* default blksiz */
    989 	return 0;
    990 }
    991 
    992 int
    993 gusmaxopen(addr, flags)
    994 	void *addr;
    995 	int flags;
    996 {
    997 	struct ad1848_softc *ac = addr;
    998 	return gusopen(ac->parent, flags);
    999 }
   1000 
   1001 STATIC void
   1002 gus_deinterleave(sc, buf, size)
   1003 	struct gus_softc *sc;
   1004 	void *buf;
   1005 	int size;
   1006 {
   1007 	/* deinterleave the stereo data.  We can use sc->sc_deintr_buf
   1008 	   for scratch space. */
   1009 	int i;
   1010 
   1011 	if (size > sc->sc_blocksize) {
   1012 		printf("gus: deinterleave %d > %d\n", size, sc->sc_blocksize);
   1013 		return;
   1014 	} else if (size < sc->sc_blocksize) {
   1015 		DPRINTF(("gus: deinterleave %d < %d\n", size, sc->sc_blocksize));
   1016 	}
   1017 
   1018 	/*
   1019 	 * size is in bytes.
   1020 	 */
   1021 	if (sc->sc_precision == 16) {
   1022 		u_short *dei = sc->sc_deintr_buf;
   1023 		u_short *sbuf = buf;
   1024 		size >>= 1;		/* bytecnt to shortcnt */
   1025 		/* copy 2nd of each pair of samples to the staging area, while
   1026 		   compacting the 1st of each pair into the original area. */
   1027 		for (i = 0; i < size/2-1; i++)  {
   1028 			dei[i] = sbuf[i*2+1];
   1029 			sbuf[i+1] = sbuf[i*2+2];
   1030 		}
   1031 		/*
   1032 		 * this has copied one less sample than half of the
   1033 		 * buffer.  The first sample of the 1st stream was
   1034 		 * already in place and didn't need copying.
   1035 		 * Therefore, we've moved all of the 1st stream's
   1036 		 * samples into place.  We have one sample from 2nd
   1037 		 * stream in the last slot of original area, not
   1038 		 * copied to the staging area (But we don't need to!).
   1039 		 * Copy the remainder of the original stream into place.
   1040 		 */
   1041 		bcopy(dei, &sbuf[size/2], i * sizeof(short));
   1042 	} else {
   1043 		u_char *dei = sc->sc_deintr_buf;
   1044 		u_char *sbuf = buf;
   1045 		for (i = 0; i < size/2-1; i++)  {
   1046 			dei[i] = sbuf[i*2+1];
   1047 			sbuf[i+1] = sbuf[i*2+2];
   1048 		}
   1049 		bcopy(dei, &sbuf[size/2], i);
   1050 	}
   1051 }
   1052 
   1053 /*
   1054  * Actually output a buffer to the DSP chip
   1055  */
   1056 
   1057 int
   1058 gusmax_dma_output(addr, buf, size, intr, arg)
   1059 	void * addr;
   1060 	void *buf;
   1061 	int size;
   1062 	void (*intr) __P((void *));
   1063 	void *arg;
   1064 {
   1065 	struct ad1848_softc *ac = addr;
   1066 	return gus_dma_output(ac->parent, buf, size, intr, arg);
   1067 }
   1068 
   1069 /*
   1070  * called at splgus() from interrupt handler.
   1071  */
   1072 void
   1073 stereo_dmaintr(arg)
   1074 	void *arg;
   1075 {
   1076     struct gus_softc *sc = arg;
   1077     struct stereo_dma_intr *sa = &sc->sc_stereo;
   1078 
   1079     DMAPRINTF(("stereo_dmaintr"));
   1080 
   1081     /*
   1082      * Put other half in its place, then call the real interrupt routine :)
   1083      */
   1084 
   1085     sc->sc_dmaoutintr = sa->intr;
   1086     sc->sc_outarg = sa->arg;
   1087 
   1088 #ifdef GUSPLAYDEBUG
   1089     if (gusstats) {
   1090       microtime(&dmarecords[dmarecord_index].tv);
   1091       dmarecords[dmarecord_index].gusaddr = sa->dmabuf;
   1092       dmarecords[dmarecord_index].bsdaddr = sa->buffer;
   1093       dmarecords[dmarecord_index].count = sa->size;
   1094       dmarecords[dmarecord_index].channel = 1;
   1095       dmarecords[dmarecord_index].direction = 1;
   1096       dmarecord_index = ++dmarecord_index % NDMARECS;
   1097     }
   1098 #endif
   1099 
   1100     gusdmaout(sc, sa->flags, sa->dmabuf, (caddr_t) sa->buffer, sa->size);
   1101 
   1102     sa->flags = 0;
   1103     sa->dmabuf = 0;
   1104     sa->buffer = 0;
   1105     sa->size = 0;
   1106     sa->intr = 0;
   1107     sa->arg = 0;
   1108 }
   1109 
   1110 /*
   1111  * Start up DMA output to the card.
   1112  * Called at splgus/splaudio already, either from intr handler or from
   1113  * generic audio code.
   1114  */
   1115 int
   1116 gus_dma_output(addr, buf, size, intr, arg)
   1117 	void * addr;
   1118 	void *buf;
   1119 	int size;
   1120 	void (*intr) __P((void *));
   1121 	void *arg;
   1122 {
   1123 	struct gus_softc *sc = addr;
   1124 	u_char *buffer = buf;
   1125 	u_long boarddma;
   1126 	int flags;
   1127 
   1128 	DMAPRINTF(("gus_dma_output %d @ %p\n", size, buf));
   1129 
   1130 	if (size != sc->sc_blocksize) {
   1131 	    DPRINTF(("gus_dma_output reqsize %d not sc_blocksize %d\n",
   1132 		     size, sc->sc_blocksize));
   1133 	    return EINVAL;
   1134 	}
   1135 
   1136 	flags = GUSMASK_DMA_WRITE;
   1137 	if (sc->sc_precision == 16)
   1138 	    flags |= GUSMASK_DMA_DATA_SIZE;
   1139 	if (sc->sc_encoding == AUDIO_ENCODING_ULAW ||
   1140 	    sc->sc_encoding == AUDIO_ENCODING_ALAW ||
   1141 	    sc->sc_encoding == AUDIO_ENCODING_ULINEAR_BE ||
   1142 	    sc->sc_encoding == AUDIO_ENCODING_ULINEAR_LE)
   1143 	    flags |= GUSMASK_DMA_INVBIT;
   1144 
   1145 	if (sc->sc_channels == 2) {
   1146 		if (sc->sc_precision == 16) {
   1147 			if (size & 3) {
   1148 				DPRINTF(("gus_dma_output: unpaired 16bit samples"));
   1149 				size &= 3;
   1150 			}
   1151 		} else if (size & 1) {
   1152 			DPRINTF(("gus_dma_output: unpaired samples"));
   1153 			size &= 1;
   1154 		}
   1155 		if (size == 0)
   1156 			return 0;
   1157 
   1158 		gus_deinterleave(sc, (void *)buffer, size);
   1159 
   1160 		size >>= 1;
   1161 
   1162  		boarddma = size * sc->sc_dmabuf + GUS_MEM_OFFSET;
   1163 
   1164 		sc->sc_stereo.intr = intr;
   1165 		sc->sc_stereo.arg = arg;
   1166 		sc->sc_stereo.size = size;
   1167 		sc->sc_stereo.dmabuf = boarddma + GUS_LEFT_RIGHT_OFFSET;
   1168 		sc->sc_stereo.buffer = buffer + size;
   1169 		sc->sc_stereo.flags = flags;
   1170 		if (gus_dostereo) {
   1171 		  intr = stereo_dmaintr;
   1172 		  arg = sc;
   1173 		}
   1174 	} else
   1175 		boarddma = size * sc->sc_dmabuf + GUS_MEM_OFFSET;
   1176 
   1177 
   1178 	sc->sc_flags |= GUS_LOCKED;
   1179 	sc->sc_dmaoutintr = intr;
   1180 	sc->sc_outarg = arg;
   1181 
   1182 #ifdef GUSPLAYDEBUG
   1183 	if (gusstats) {
   1184 	  microtime(&dmarecords[dmarecord_index].tv);
   1185 	  dmarecords[dmarecord_index].gusaddr = boarddma;
   1186 	  dmarecords[dmarecord_index].bsdaddr = buffer;
   1187 	  dmarecords[dmarecord_index].count = size;
   1188 	  dmarecords[dmarecord_index].channel = 0;
   1189 	  dmarecords[dmarecord_index].direction = 1;
   1190 	  dmarecord_index = ++dmarecord_index % NDMARECS;
   1191 	}
   1192 #endif
   1193 
   1194 	gusdmaout(sc, flags, boarddma, (caddr_t) buffer, size);
   1195 
   1196 	return 0;
   1197 }
   1198 
   1199 void
   1200 gusmax_close(addr)
   1201 	void *addr;
   1202 {
   1203 	struct ad1848_softc *ac = addr;
   1204 	struct gus_softc *sc = ac->parent;
   1205 #if 0
   1206 	ac->aux1_mute = 1;
   1207 	ad1848_mute_aux1(ac, 1);	/* turn off DAC output */
   1208 #endif
   1209 	ad1848_close(ac);
   1210 	gusclose(sc);
   1211 }
   1212 
   1213 /*
   1214  * Close out device stuff.  Called at splgus() from generic audio layer.
   1215  */
   1216 void
   1217 gusclose(addr)
   1218 	void *addr;
   1219 {
   1220 	struct gus_softc *sc = addr;
   1221 
   1222         DPRINTF(("gus_close: sc=%p\n", sc));
   1223 
   1224 
   1225 /*	if (sc->sc_flags & GUS_DMAOUT_ACTIVE) */ {
   1226 		gus_halt_out_dma(sc);
   1227 	}
   1228 /*	if (sc->sc_flags & GUS_DMAIN_ACTIVE) */ {
   1229 		gus_halt_in_dma(sc);
   1230 	}
   1231 	sc->sc_flags &= ~(GUS_OPEN|GUS_LOCKED|GUS_DMAOUT_ACTIVE|GUS_DMAIN_ACTIVE);
   1232 
   1233 	if (sc->sc_deintr_buf) {
   1234 		FREE(sc->sc_deintr_buf, M_DEVBUF);
   1235 		sc->sc_deintr_buf = NULL;
   1236 	}
   1237 	/* turn off speaker, etc. */
   1238 
   1239 	/* make sure the voices shut up: */
   1240 	gus_stop_voice(sc, GUS_VOICE_LEFT, 1);
   1241 	gus_stop_voice(sc, GUS_VOICE_RIGHT, 0);
   1242 }
   1243 
   1244 /*
   1245  * Service interrupts.  Farm them off to helper routines if we are using the
   1246  * GUS for simple playback/record
   1247  */
   1248 
   1249 #ifdef DIAGNOSTIC
   1250 int gusintrcnt;
   1251 int gusdmaintrcnt;
   1252 int gusvocintrcnt;
   1253 #endif
   1254 
   1255 int
   1256 gusintr(arg)
   1257 	void *arg;
   1258 {
   1259 	struct gus_softc *sc = arg;
   1260 	unsigned char intr;
   1261 	int port = sc->sc_iobase;
   1262 	int retval = 0;
   1263 
   1264 	DPRINTF(("gusintr\n"));
   1265 #ifdef DIAGNOSTIC
   1266 	gusintrcnt++;
   1267 #endif
   1268 	if (HAS_CODEC(sc))
   1269 		retval = ad1848_intr(&sc->sc_codec);
   1270 	if ((intr = inb(port+GUS_IRQ_STATUS)) & GUSMASK_IRQ_DMATC) {
   1271 		DMAPRINTF(("gusintr dma flags=%x\n", sc->sc_flags));
   1272 #ifdef DIAGNOSTIC
   1273 		gusdmaintrcnt++;
   1274 #endif
   1275 		retval += gus_dmaout_intr(sc);
   1276 		if (sc->sc_flags & GUS_DMAIN_ACTIVE) {
   1277 		    SELECT_GUS_REG(port, GUSREG_SAMPLE_CONTROL);
   1278 		    intr = inb(port+GUS_DATA_HIGH);
   1279 		    if (intr & GUSMASK_SAMPLE_DMATC) {
   1280 			retval += gus_dmain_intr(sc);
   1281 		    }
   1282 		}
   1283 	}
   1284 	if (intr & (GUSMASK_IRQ_VOICE | GUSMASK_IRQ_VOLUME)) {
   1285 		DMAPRINTF(("gusintr voice flags=%x\n", sc->sc_flags));
   1286 #ifdef DIAGNOSTIC
   1287 		gusvocintrcnt++;
   1288 #endif
   1289 		retval += gus_voice_intr(sc);
   1290 	}
   1291 	if (retval)
   1292 		return 1;
   1293 	return retval;
   1294 }
   1295 
   1296 int gus_bufcnt[GUS_MEM_FOR_BUFFERS / GUS_BUFFER_MULTIPLE];
   1297 int gus_restart;				/* how many restarts? */
   1298 int gus_stops;				/* how many times did voice stop? */
   1299 int gus_falsestops;			/* stopped but not done? */
   1300 int gus_continues;
   1301 
   1302 struct playcont {
   1303 	struct timeval tv;
   1304 	u_int playbuf;
   1305 	u_int dmabuf;
   1306 	u_char bufcnt;
   1307 	u_char vaction;
   1308 	u_char voccntl;
   1309 	u_char volcntl;
   1310 	u_long curaddr;
   1311 	u_long endaddr;
   1312 } playstats[NDMARECS];
   1313 
   1314 int playcntr;
   1315 
   1316 STATIC void
   1317 gus_dmaout_timeout(arg)
   1318      void *arg;
   1319 {
   1320     struct gus_softc *sc = arg;
   1321     int port = sc->sc_iobase;
   1322     int s;
   1323 
   1324     printf("%s: dmaout timeout\n", sc->sc_dev.dv_xname);
   1325     /*
   1326      * Stop any DMA.
   1327      */
   1328 
   1329     s = splgus();
   1330     SELECT_GUS_REG(port, GUSREG_DMA_CONTROL);
   1331     outb(sc->sc_iobase+GUS_DATA_HIGH, 0);
   1332 
   1333 #if 0
   1334     /* XXX we will dmadone below? */
   1335     isa_dmaabort(sc->sc_dev.dv_parent, sc->sc_drq);
   1336 #endif
   1337 
   1338     gus_dmaout_dointr(sc);
   1339     splx(s);
   1340 }
   1341 
   1342 
   1343 /*
   1344  * Service DMA interrupts.  This routine will only get called if we're doing
   1345  * a DMA transfer for playback/record requests from the audio layer.
   1346  */
   1347 
   1348 STATIC int
   1349 gus_dmaout_intr(sc)
   1350 	struct gus_softc *sc;
   1351 {
   1352 	int port = sc->sc_iobase;
   1353 
   1354 	/*
   1355 	 * If we got a DMA transfer complete from the GUS DRAM, then deal
   1356 	 * with it.
   1357 	 */
   1358 
   1359 	SELECT_GUS_REG(port, GUSREG_DMA_CONTROL);
   1360  	if (inb(port+GUS_DATA_HIGH) & GUSMASK_DMA_IRQPEND) {
   1361 	    untimeout(gus_dmaout_timeout, sc);
   1362 	    gus_dmaout_dointr(sc);
   1363 	    return 1;
   1364 	}
   1365 	return 0;
   1366 }
   1367 
   1368 STATIC void
   1369 gus_dmaout_dointr(sc)
   1370 	struct gus_softc *sc;
   1371 {
   1372 	int port = sc->sc_iobase;
   1373 
   1374 	/* sc->sc_dmaoutcnt - 1 because DMA controller counts from zero?. */
   1375 	isa_dmadone(sc->sc_dev.dv_parent, sc->sc_drq);
   1376 	sc->sc_flags &= ~GUS_DMAOUT_ACTIVE;  /* pending DMA is done */
   1377 	DMAPRINTF(("gus_dmaout_dointr %d @ %p\n", sc->sc_dmaoutcnt,
   1378 		   sc->sc_dmaoutaddr));
   1379 
   1380 	/*
   1381 	 * to prevent clicking, we need to copy last sample
   1382 	 * from last buffer to scratch area just before beginning of
   1383 	 * buffer.  However, if we're doing formats that are converted by
   1384 	 * the card during the DMA process, we need to pick up the converted
   1385 	 * byte rather than the one we have in memory.
   1386 	 */
   1387 	if (sc->sc_dmabuf == sc->sc_nbufs - 1) {
   1388 	  int i;
   1389 	  switch (sc->sc_encoding) {
   1390 	  case AUDIO_ENCODING_SLINEAR_LE:
   1391 	  case AUDIO_ENCODING_SLINEAR_BE:
   1392 	    if (sc->sc_precision == 8)
   1393 	      goto byte;
   1394 	    /* we have the native format */
   1395 	    for (i = 1; i <= 2; i++)
   1396 	      guspoke(port, sc->sc_gusaddr -
   1397 		      (sc->sc_nbufs - 1) * sc->sc_chanblocksize - i,
   1398 		      sc->sc_dmaoutaddr[sc->sc_dmaoutcnt-i]);
   1399 	    break;
   1400 	  case AUDIO_ENCODING_ULINEAR_LE:
   1401 	  case AUDIO_ENCODING_ULINEAR_BE:
   1402 	    guspoke(port, sc->sc_gusaddr -
   1403 		    (sc->sc_nbufs - 1) * sc->sc_chanblocksize - 2,
   1404 		    guspeek(port,
   1405 			    sc->sc_gusaddr + sc->sc_chanblocksize - 2));
   1406 	  case AUDIO_ENCODING_ALAW:
   1407 	  case AUDIO_ENCODING_ULAW:
   1408 	  byte:
   1409 	    /* we need to fetch the translated byte, then stuff it. */
   1410 	    guspoke(port, sc->sc_gusaddr -
   1411 		    (sc->sc_nbufs - 1) * sc->sc_chanblocksize - 1,
   1412 		    guspeek(port,
   1413 			    sc->sc_gusaddr + sc->sc_chanblocksize - 1));
   1414 	    break;
   1415 	  }
   1416 	}
   1417 	/*
   1418 	 * If this is the first half of stereo, "ignore" this one
   1419 	 * and copy out the second half.
   1420 	 */
   1421 	if (sc->sc_dmaoutintr == stereo_dmaintr) {
   1422 	    (*sc->sc_dmaoutintr)(sc->sc_outarg);
   1423 	    return;
   1424 	}
   1425 	/*
   1426 	 * If the voice is stopped, then start it.  Reset the loop
   1427 	 * and roll bits.  Call the audio layer routine, since if
   1428 	 * we're starting a stopped voice, that means that the next
   1429 	 * buffer can be filled
   1430 	 */
   1431 
   1432 	sc->sc_flags &= ~GUS_LOCKED;
   1433 	if (sc->sc_voc[GUS_VOICE_LEFT].voccntl &
   1434 	    GUSMASK_VOICE_STOPPED) {
   1435 	    if (sc->sc_flags & GUS_PLAYING) {
   1436 		printf("%s: playing yet stopped?\n", sc->sc_dev.dv_xname);
   1437 	    }
   1438 	    sc->sc_bufcnt++; /* another yet to be played */
   1439 	    gus_start_playing(sc, sc->sc_dmabuf);
   1440 	    gus_restart++;
   1441 	} else {
   1442 	    /*
   1443 	     * set the sound action based on which buffer we
   1444 	     * just transferred.  If we just transferred buffer 0
   1445 	     * we want the sound to loop when it gets to the nth
   1446 	     * buffer; if we just transferred
   1447 	     * any other buffer, we want the sound to roll over
   1448 	     * at least one more time.  The voice interrupt
   1449 	     * handlers will take care of accounting &
   1450 	     * setting control bits if it's not caught up to us
   1451 	     * yet.
   1452 	     */
   1453 	    if (++sc->sc_bufcnt == 2) {
   1454 		/*
   1455 		 * XXX
   1456 		 * If we're too slow in reaction here,
   1457 		 * the voice could be just approaching the
   1458 		 * end of its run.  It should be set to stop,
   1459 		 * so these adjustments might not DTRT.
   1460 		 */
   1461 		if (sc->sc_dmabuf == 0 &&
   1462 		    sc->sc_playbuf == sc->sc_nbufs - 1) {
   1463 		    /* player is just at the last buf, we're at the
   1464 		       first.  Turn on looping, turn off rolling. */
   1465 		    sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_LOOP_ENABLE;
   1466 		    sc->sc_voc[GUS_VOICE_LEFT].volcntl &= ~GUSMASK_VOICE_ROLL;
   1467 		    playstats[playcntr].vaction = 3;
   1468 		} else {
   1469 		    /* player is at previous buf:
   1470 		       turn on rolling, turn off looping */
   1471 		    sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~GUSMASK_LOOP_ENABLE;
   1472 		    sc->sc_voc[GUS_VOICE_LEFT].volcntl |= GUSMASK_VOICE_ROLL;
   1473 		    playstats[playcntr].vaction = 4;
   1474 		}
   1475 #ifdef GUSPLAYDEBUG
   1476 		if (gusstats) {
   1477 		  microtime(&playstats[playcntr].tv);
   1478 		  playstats[playcntr].endaddr = sc->sc_voc[GUS_VOICE_LEFT].end_addr;
   1479 		  playstats[playcntr].voccntl = sc->sc_voc[GUS_VOICE_LEFT].voccntl;
   1480 		  playstats[playcntr].volcntl = sc->sc_voc[GUS_VOICE_LEFT].volcntl;
   1481 		  playstats[playcntr].playbuf = sc->sc_playbuf;
   1482 		  playstats[playcntr].dmabuf = sc->sc_dmabuf;
   1483 		  playstats[playcntr].bufcnt = sc->sc_bufcnt;
   1484 		  playstats[playcntr].curaddr = gus_get_curaddr(sc, GUS_VOICE_LEFT);
   1485 		  playcntr = ++playcntr % NDMARECS;
   1486 		}
   1487 #endif
   1488 		outb(port+GUS_VOICE_SELECT, GUS_VOICE_LEFT);
   1489 		SELECT_GUS_REG(port, GUSREG_VOICE_CNTL);
   1490 		outb(port+GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_LEFT].voccntl);
   1491 		SELECT_GUS_REG(port, GUSREG_VOLUME_CONTROL);
   1492 		outb(port+GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_LEFT].volcntl);
   1493 	    }
   1494 	}
   1495 	gus_bufcnt[sc->sc_bufcnt-1]++;
   1496 	/*
   1497 	 * flip to the next DMA buffer
   1498 	 */
   1499 
   1500 	sc->sc_dmabuf = ++sc->sc_dmabuf % sc->sc_nbufs;
   1501 	/*
   1502 	 * See comments below about DMA admission control strategy.
   1503 	 * We can call the upper level here if we have an
   1504 	 * idle buffer (not currently playing) to DMA into.
   1505 	 */
   1506 	if (sc->sc_dmaoutintr && sc->sc_bufcnt < sc->sc_nbufs) {
   1507 	    /* clean out to prevent double calls */
   1508 	    void (*pfunc) __P((void *)) = sc->sc_dmaoutintr;
   1509 	    void *arg = sc->sc_outarg;
   1510 
   1511 	    sc->sc_outarg = 0;
   1512 	    sc->sc_dmaoutintr = 0;
   1513 	    (*pfunc)(arg);
   1514 	}
   1515 }
   1516 
   1517 /*
   1518  * Service voice interrupts
   1519  */
   1520 
   1521 STATIC int
   1522 gus_voice_intr(sc)
   1523 	struct gus_softc *sc;
   1524 {
   1525 	int port = sc->sc_iobase;
   1526 	int ignore = 0, voice, rval = 0;
   1527 	unsigned char intr, status;
   1528 
   1529 	/*
   1530 	 * The point of this may not be obvious at first.  A voice can
   1531 	 * interrupt more than once; according to the GUS SDK we are supposed
   1532 	 * to ignore multiple interrupts for the same voice.
   1533 	 */
   1534 
   1535 	while(1) {
   1536 		SELECT_GUS_REG(port, GUSREG_IRQ_STATUS);
   1537 		intr = inb(port+GUS_DATA_HIGH);
   1538 
   1539 		if ((intr & (GUSMASK_WIRQ_VOLUME | GUSMASK_WIRQ_VOICE))
   1540 			== (GUSMASK_WIRQ_VOLUME | GUSMASK_WIRQ_VOICE))
   1541 			/*
   1542 			 * No more interrupts, time to return
   1543 			 */
   1544 		 	return rval;
   1545 
   1546 		if ((intr & GUSMASK_WIRQ_VOICE) == 0) {
   1547 
   1548 		    /*
   1549 		     * We've got a voice interrupt.  Ignore previous
   1550 		     * interrupts by the same voice.
   1551 		     */
   1552 
   1553 		    rval = 1;
   1554 		    voice = intr & GUSMASK_WIRQ_VOICEMASK;
   1555 
   1556 		    if ((1 << voice) & ignore)
   1557 			break;
   1558 
   1559 		    ignore |= 1 << voice;
   1560 
   1561 		    /*
   1562 		     * If the voice is stopped, then force it to stop
   1563 		     * (this stops it from continuously generating IRQs)
   1564 		     */
   1565 
   1566 		    SELECT_GUS_REG(port, GUSREG_VOICE_CNTL+0x80);
   1567 		    status = inb(port+GUS_DATA_HIGH);
   1568 		    if (status & GUSMASK_VOICE_STOPPED) {
   1569 			if (voice != GUS_VOICE_LEFT) {
   1570 			    DMAPRINTF(("%s: spurious voice %d stop?\n",
   1571 				       sc->sc_dev.dv_xname, voice));
   1572 			    gus_stop_voice(sc, voice, 0);
   1573 			    continue;
   1574 			}
   1575 			gus_stop_voice(sc, voice, 1);
   1576 			/* also kill right voice */
   1577 			gus_stop_voice(sc, GUS_VOICE_RIGHT, 0);
   1578 			sc->sc_bufcnt--; /* it finished a buffer */
   1579 			if (sc->sc_bufcnt > 0) {
   1580 			    /*
   1581 			     * probably a race to get here: the voice
   1582 			     * stopped while the DMA code was just trying to
   1583 			     * get the next buffer in place.
   1584 			     * Start the voice again.
   1585 			     */
   1586 			    printf("%s: stopped voice not drained? (%x)\n",
   1587 				   sc->sc_dev.dv_xname, sc->sc_bufcnt);
   1588 			    gus_falsestops++;
   1589 
   1590 			    sc->sc_playbuf = ++sc->sc_playbuf % sc->sc_nbufs;
   1591 			    gus_start_playing(sc, sc->sc_playbuf);
   1592 			} else if (sc->sc_bufcnt < 0) {
   1593 #ifdef DDB
   1594 			    printf("%s: negative bufcnt in stopped voice\n",
   1595 				   sc->sc_dev.dv_xname);
   1596 			    Debugger();
   1597 #else
   1598 			    panic("%s: negative bufcnt in stopped voice",
   1599 				  sc->sc_dev.dv_xname);
   1600 #endif
   1601 			} else {
   1602 			    sc->sc_playbuf = -1; /* none are active */
   1603 			    gus_stops++;
   1604 			}
   1605 			/* fall through to callback and admit another
   1606 			   buffer.... */
   1607 		    } else if (sc->sc_bufcnt != 0) {
   1608 			/*
   1609 			 * This should always be taken if the voice
   1610 			 * is not stopped.
   1611 			 */
   1612 			gus_continues++;
   1613 			if (gus_continue_playing(sc, voice)) {
   1614 				/*
   1615 				 * we shouldn't have continued--active DMA
   1616 				 * is in the way in the ring, for
   1617 				 * some as-yet undebugged reason.
   1618 				 */
   1619 				gus_stop_voice(sc, GUS_VOICE_LEFT, 1);
   1620 				/* also kill right voice */
   1621 				gus_stop_voice(sc, GUS_VOICE_RIGHT, 0);
   1622 				sc->sc_playbuf = -1;
   1623 				gus_stops++;
   1624 			}
   1625 		    }
   1626 		    /*
   1627 		     * call the upper level to send on down another
   1628 		     * block. We do admission rate control as follows:
   1629 		     *
   1630 		     * When starting up output (in the first N
   1631 		     * blocks), call the upper layer after the DMA is
   1632 		     * complete (see above in gus_dmaout_intr()).
   1633 		     *
   1634 		     * When output is already in progress and we have
   1635 		     * no more GUS buffers to use for DMA, the DMA
   1636 		     * output routines do not call the upper layer.
   1637 		     * Instead, we call the DMA completion routine
   1638 		     * here, after the voice interrupts indicating
   1639 		     * that it's finished with a buffer.
   1640 		     *
   1641 		     * However, don't call anything here if the DMA
   1642 		     * output flag is set, (which shouldn't happen)
   1643 		     * because we'll squish somebody else's DMA if
   1644 		     * that's the case.  When DMA is done, it will
   1645 		     * call back if there is a spare buffer.
   1646 		     */
   1647 		    if (sc->sc_dmaoutintr && !(sc->sc_flags & GUS_LOCKED)) {
   1648 			if (sc->sc_dmaoutintr == stereo_dmaintr)
   1649 			    printf("gusdmaout botch?\n");
   1650 			else {
   1651 			    /* clean out to avoid double calls */
   1652 			    void (*pfunc) __P((void *)) = sc->sc_dmaoutintr;
   1653 			    void *arg = sc->sc_outarg;
   1654 
   1655 			    sc->sc_outarg = 0;
   1656 			    sc->sc_dmaoutintr = 0;
   1657 			    (*pfunc)(arg);
   1658 			}
   1659 		    }
   1660 		}
   1661 
   1662 		/*
   1663 		 * Ignore other interrupts for now
   1664 		 */
   1665 	}
   1666 	return 0;
   1667 }
   1668 
   1669 STATIC void
   1670 gus_start_playing(sc, bufno)
   1671 struct gus_softc *sc;
   1672 int bufno;
   1673 {
   1674     int port = sc->sc_iobase;
   1675     /*
   1676      * Start the voices playing, with buffer BUFNO.
   1677      */
   1678 
   1679     /*
   1680      * Loop or roll if we have buffers ready.
   1681      */
   1682 
   1683     if (sc->sc_bufcnt == 1) {
   1684 	sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~(GUSMASK_LOOP_ENABLE);
   1685 	sc->sc_voc[GUS_VOICE_LEFT].volcntl &= ~(GUSMASK_VOICE_ROLL);
   1686     } else {
   1687 	if (bufno == sc->sc_nbufs - 1) {
   1688 	    sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_LOOP_ENABLE;
   1689 	    sc->sc_voc[GUS_VOICE_LEFT].volcntl &= ~(GUSMASK_VOICE_ROLL);
   1690 	} else {
   1691 	    sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~GUSMASK_LOOP_ENABLE;
   1692 	    sc->sc_voc[GUS_VOICE_LEFT].volcntl |= GUSMASK_VOICE_ROLL;
   1693 	}
   1694     }
   1695 
   1696     outb(port+GUS_VOICE_SELECT, GUS_VOICE_LEFT);
   1697 
   1698     SELECT_GUS_REG(port, GUSREG_VOICE_CNTL);
   1699     outb(port+GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_LEFT].voccntl);
   1700 
   1701     SELECT_GUS_REG(port, GUSREG_VOLUME_CONTROL);
   1702     outb(port+GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_LEFT].volcntl);
   1703 
   1704     sc->sc_voc[GUS_VOICE_LEFT].current_addr =
   1705 	GUS_MEM_OFFSET + sc->sc_chanblocksize * bufno;
   1706     sc->sc_voc[GUS_VOICE_LEFT].end_addr =
   1707 	sc->sc_voc[GUS_VOICE_LEFT].current_addr + sc->sc_chanblocksize - 1;
   1708     sc->sc_voc[GUS_VOICE_RIGHT].current_addr =
   1709 	sc->sc_voc[GUS_VOICE_LEFT].current_addr +
   1710 	(gus_dostereo && sc->sc_channels == 2 ? GUS_LEFT_RIGHT_OFFSET : 0);
   1711     /*
   1712      * set up right channel to just loop forever, no interrupts,
   1713      * starting at the buffer we just filled.  We'll feed it data
   1714      * at the same time as left channel.
   1715      */
   1716     sc->sc_voc[GUS_VOICE_RIGHT].voccntl |= GUSMASK_LOOP_ENABLE;
   1717     sc->sc_voc[GUS_VOICE_RIGHT].volcntl &= ~(GUSMASK_VOICE_ROLL);
   1718 
   1719 #ifdef GUSPLAYDEBUG
   1720     if (gusstats) {
   1721       microtime(&playstats[playcntr].tv);
   1722       playstats[playcntr].curaddr = sc->sc_voc[GUS_VOICE_LEFT].current_addr;
   1723 
   1724       playstats[playcntr].voccntl = sc->sc_voc[GUS_VOICE_LEFT].voccntl;
   1725       playstats[playcntr].volcntl = sc->sc_voc[GUS_VOICE_LEFT].volcntl;
   1726       playstats[playcntr].endaddr = sc->sc_voc[GUS_VOICE_LEFT].end_addr;
   1727       playstats[playcntr].playbuf = bufno;
   1728       playstats[playcntr].dmabuf = sc->sc_dmabuf;
   1729       playstats[playcntr].bufcnt = sc->sc_bufcnt;
   1730       playstats[playcntr].vaction = 5;
   1731       playcntr = ++playcntr % NDMARECS;
   1732     }
   1733 #endif
   1734 
   1735     outb(port+GUS_VOICE_SELECT, GUS_VOICE_RIGHT);
   1736     SELECT_GUS_REG(port, GUSREG_VOICE_CNTL);
   1737     outb(port+GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_RIGHT].voccntl);
   1738     SELECT_GUS_REG(port, GUSREG_VOLUME_CONTROL);
   1739     outb(port+GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_RIGHT].volcntl);
   1740 
   1741     gus_start_voice(sc, GUS_VOICE_RIGHT, 0);
   1742     gus_start_voice(sc, GUS_VOICE_LEFT, 1);
   1743     if (sc->sc_playbuf == -1)
   1744 	/* mark start of playing */
   1745 	sc->sc_playbuf = bufno;
   1746 }
   1747 
   1748 STATIC int
   1749 gus_continue_playing(sc, voice)
   1750 struct gus_softc *sc;
   1751 int voice;
   1752 {
   1753     int port = sc->sc_iobase;
   1754 
   1755     /*
   1756      * stop this voice from interrupting while we work.
   1757      */
   1758 
   1759     SELECT_GUS_REG(port, GUSREG_VOICE_CNTL);
   1760     outb(port+GUS_DATA_HIGH, sc->sc_voc[voice].voccntl & ~(GUSMASK_VOICE_IRQ));
   1761 
   1762     /*
   1763      * update playbuf to point to the buffer the hardware just started
   1764      * playing
   1765      */
   1766     sc->sc_playbuf = ++sc->sc_playbuf % sc->sc_nbufs;
   1767 
   1768     /*
   1769      * account for buffer just finished
   1770      */
   1771     if (--sc->sc_bufcnt == 0) {
   1772 	DPRINTF(("gus: bufcnt 0 on continuing voice?\n"));
   1773     }
   1774     if (sc->sc_playbuf == sc->sc_dmabuf && (sc->sc_flags & GUS_LOCKED)) {
   1775 	printf("%s: continue into active dmabuf?\n", sc->sc_dev.dv_xname);
   1776 	return 1;
   1777     }
   1778 
   1779     /*
   1780      * Select the end of the buffer based on the currently active
   1781      * buffer, [plus extra contiguous buffers (if ready)].
   1782      */
   1783 
   1784     /*
   1785      * set endpoint at end of buffer we just started playing.
   1786      *
   1787      * The total gets -1 because end addrs are one less than you might
   1788      * think (the end_addr is the address of the last sample to play)
   1789      */
   1790     gus_set_endaddr(sc, voice, GUS_MEM_OFFSET +
   1791 		    sc->sc_chanblocksize * (sc->sc_playbuf + 1) - 1);
   1792 
   1793     if (sc->sc_bufcnt < 2) {
   1794 	/*
   1795 	 * Clear out the loop and roll flags, and rotate the currently
   1796 	 * playing buffer.  That way, if we don't manage to get more
   1797 	 * data before this buffer finishes, we'll just stop.
   1798 	 */
   1799 	sc->sc_voc[voice].voccntl &= ~GUSMASK_LOOP_ENABLE;
   1800 	sc->sc_voc[voice].volcntl &= ~GUSMASK_VOICE_ROLL;
   1801 	playstats[playcntr].vaction = 0;
   1802     } else {
   1803 	/*
   1804 	 * We have some buffers to play.  set LOOP if we're on the
   1805 	 * last buffer in the ring, otherwise set ROLL.
   1806 	 */
   1807 	if (sc->sc_playbuf == sc->sc_nbufs - 1) {
   1808 	    sc->sc_voc[voice].voccntl |= GUSMASK_LOOP_ENABLE;
   1809 	    sc->sc_voc[voice].volcntl &= ~GUSMASK_VOICE_ROLL;
   1810 	    playstats[playcntr].vaction = 1;
   1811 	} else {
   1812 	    sc->sc_voc[voice].voccntl &= ~GUSMASK_LOOP_ENABLE;
   1813 	    sc->sc_voc[voice].volcntl |= GUSMASK_VOICE_ROLL;
   1814 	    playstats[playcntr].vaction = 2;
   1815 	}
   1816     }
   1817 #ifdef GUSPLAYDEBUG
   1818     if (gusstats) {
   1819       microtime(&playstats[playcntr].tv);
   1820       playstats[playcntr].curaddr = gus_get_curaddr(sc, voice);
   1821 
   1822       playstats[playcntr].voccntl = sc->sc_voc[voice].voccntl;
   1823       playstats[playcntr].volcntl = sc->sc_voc[voice].volcntl;
   1824       playstats[playcntr].endaddr = sc->sc_voc[voice].end_addr;
   1825       playstats[playcntr].playbuf = sc->sc_playbuf;
   1826       playstats[playcntr].dmabuf = sc->sc_dmabuf;
   1827       playstats[playcntr].bufcnt = sc->sc_bufcnt;
   1828       playcntr = ++playcntr % NDMARECS;
   1829     }
   1830 #endif
   1831 
   1832     /*
   1833      * (re-)set voice parameters.  This will reenable interrupts from this
   1834      * voice.
   1835      */
   1836 
   1837     SELECT_GUS_REG(port, GUSREG_VOICE_CNTL);
   1838     outb(port+GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
   1839     SELECT_GUS_REG(port, GUSREG_VOLUME_CONTROL);
   1840     outb(port+GUS_DATA_HIGH, sc->sc_voc[voice].volcntl);
   1841     return 0;
   1842 }
   1843 
   1844 /*
   1845  * Send/receive data into GUS's DRAM using DMA.  Called at splgus()
   1846  */
   1847 
   1848 STATIC void
   1849 gusdmaout(sc, flags, gusaddr, buffaddr, length)
   1850 	struct gus_softc *sc;
   1851 	int flags, length;
   1852 	u_long gusaddr;
   1853 	caddr_t buffaddr;
   1854 {
   1855 	unsigned char c = (unsigned char) flags;
   1856 	int port = sc->sc_iobase;
   1857 
   1858 	DMAPRINTF(("gusdmaout flags=%x scflags=%x\n", flags, sc->sc_flags));
   1859 
   1860 	sc->sc_gusaddr = gusaddr;
   1861 
   1862 	/*
   1863 	 * If we're using a 16 bit DMA channel, we have to jump through some
   1864 	 * extra hoops; this includes translating the DRAM address a bit
   1865 	 */
   1866 
   1867 	if (sc->sc_drq >= 4) {
   1868 		c |= GUSMASK_DMA_WIDTH;
   1869 		gusaddr = convert_to_16bit(gusaddr);
   1870 	}
   1871 
   1872 	/*
   1873 	 * Add flag bits that we always set - fast DMA, enable IRQ
   1874 	 */
   1875 
   1876 	c |= GUSMASK_DMA_ENABLE | GUSMASK_DMA_R0 | GUSMASK_DMA_IRQ;
   1877 
   1878 	/*
   1879 	 * Make sure the GUS _isn't_ setup for DMA
   1880 	 */
   1881 
   1882  	SELECT_GUS_REG(port, GUSREG_DMA_CONTROL);
   1883 	outb(port+GUS_DATA_HIGH, 0);
   1884 
   1885 	/*
   1886 	 * Tell the PC DMA controller to start doing DMA
   1887 	 */
   1888 
   1889 	sc->sc_dmaoutaddr = (u_char *) buffaddr;
   1890 	sc->sc_dmaoutcnt = length;
   1891 	isa_dmastart(sc->sc_dev.dv_parent, sc->sc_drq, buffaddr, length,
   1892 	    NULL, DMAMODE_WRITE, BUS_DMA_NOWAIT);
   1893 
   1894 	/*
   1895 	 * Set up DMA address - use the upper 16 bits ONLY
   1896 	 */
   1897 
   1898 	sc->sc_flags |= GUS_DMAOUT_ACTIVE;
   1899 
   1900  	SELECT_GUS_REG(port, GUSREG_DMA_START);
   1901  	outw(port+GUS_DATA_LOW, (int) (gusaddr >> 4));
   1902 
   1903  	/*
   1904  	 * Tell the GUS to start doing DMA
   1905  	 */
   1906 
   1907  	SELECT_GUS_REG(port, GUSREG_DMA_CONTROL);
   1908 	outb(port+GUS_DATA_HIGH, c);
   1909 
   1910 	/*
   1911 	 * XXX If we don't finish in one second, give up...
   1912 	 */
   1913 	untimeout(gus_dmaout_timeout, sc); /* flush old one, if there is one */
   1914 	timeout(gus_dmaout_timeout, sc, hz);
   1915 }
   1916 
   1917 /*
   1918  * Start a voice playing on the GUS.  Called from interrupt handler at
   1919  * splgus().
   1920  */
   1921 
   1922 STATIC void
   1923 gus_start_voice(sc, voice, intrs)
   1924 	struct gus_softc *sc;
   1925 	int voice;
   1926 	int intrs;
   1927 {
   1928 	int port = sc->sc_iobase;
   1929 	u_long start;
   1930 	u_long current;
   1931 	u_long end;
   1932 
   1933 	/*
   1934 	 * Pick all the values for the voice out of the gus_voice struct
   1935 	 * and use those to program the voice
   1936 	 */
   1937 
   1938  	start = sc->sc_voc[voice].start_addr;
   1939  	current = sc->sc_voc[voice].current_addr;
   1940  	end = sc->sc_voc[voice].end_addr;
   1941 
   1942  	/*
   1943 	 * If we're using 16 bit data, mangle the addresses a bit
   1944 	 */
   1945 
   1946 	if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16) {
   1947 	        /* -1 on start so that we get onto sample boundary--other
   1948 		   code always sets it for 1-byte rollover protection */
   1949 		start = convert_to_16bit(start-1);
   1950 		current = convert_to_16bit(current);
   1951 		end = convert_to_16bit(end);
   1952 	}
   1953 
   1954 	/*
   1955 	 * Select the voice we want to use, and program the data addresses
   1956 	 */
   1957 
   1958 	outb(port+GUS_VOICE_SELECT, (unsigned char) voice);
   1959 
   1960 	SELECT_GUS_REG(port, GUSREG_START_ADDR_HIGH);
   1961 	outw(port+GUS_DATA_LOW, ADDR_HIGH(start));
   1962 	SELECT_GUS_REG(port, GUSREG_START_ADDR_LOW);
   1963 	outw(port+GUS_DATA_LOW, ADDR_LOW(start));
   1964 
   1965 	SELECT_GUS_REG(port, GUSREG_CUR_ADDR_HIGH);
   1966 	outw(port+GUS_DATA_LOW, ADDR_HIGH(current));
   1967 	SELECT_GUS_REG(port, GUSREG_CUR_ADDR_LOW);
   1968 	outw(port+GUS_DATA_LOW, ADDR_LOW(current));
   1969 
   1970 	SELECT_GUS_REG(port, GUSREG_END_ADDR_HIGH);
   1971 	outw(port+GUS_DATA_LOW, ADDR_HIGH(end));
   1972 	SELECT_GUS_REG(port, GUSREG_END_ADDR_LOW);
   1973 	outw(port+GUS_DATA_LOW, ADDR_LOW(end));
   1974 
   1975 	/*
   1976 	 * (maybe) enable interrupts, disable voice stopping
   1977 	 */
   1978 
   1979 	if (intrs) {
   1980 		sc->sc_flags |= GUS_PLAYING; /* playing is about to start */
   1981 		sc->sc_voc[voice].voccntl |= GUSMASK_VOICE_IRQ;
   1982 		DMAPRINTF(("gus voice playing=%x\n", sc->sc_flags));
   1983 	} else
   1984 		sc->sc_voc[voice].voccntl &= ~GUSMASK_VOICE_IRQ;
   1985 	sc->sc_voc[voice].voccntl &= ~(GUSMASK_VOICE_STOPPED |
   1986 		GUSMASK_STOP_VOICE);
   1987 
   1988 	/*
   1989 	 * Tell the GUS about it.  Note that we're doing volume ramping here
   1990 	 * from 0 up to the set volume to help reduce clicks.
   1991 	 */
   1992 
   1993 	SELECT_GUS_REG(port, GUSREG_START_VOLUME);
   1994 	outb(port+GUS_DATA_HIGH, 0x00);
   1995 	SELECT_GUS_REG(port, GUSREG_END_VOLUME);
   1996 	outb(port+GUS_DATA_HIGH, sc->sc_voc[voice].current_volume >> 4);
   1997 	SELECT_GUS_REG(port, GUSREG_CUR_VOLUME);
   1998 	outw(port+GUS_DATA_LOW, 0x00);
   1999 	SELECT_GUS_REG(port, GUSREG_VOLUME_RATE);
   2000 	outb(port+GUS_DATA_HIGH, 63);
   2001 
   2002 	SELECT_GUS_REG(port, GUSREG_VOICE_CNTL);
   2003 	outb(port+GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
   2004 	SELECT_GUS_REG(port, GUSREG_VOLUME_CONTROL);
   2005 	outb(port+GUS_DATA_HIGH, 0x00);
   2006 	delay(50);
   2007 	SELECT_GUS_REG(port, GUSREG_VOICE_CNTL);
   2008 	outb(port+GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
   2009 	SELECT_GUS_REG(port, GUSREG_VOLUME_CONTROL);
   2010 	outb(port+GUS_DATA_HIGH, 0x00);
   2011 
   2012 }
   2013 
   2014 /*
   2015  * Stop a given voice.  called at splgus()
   2016  */
   2017 
   2018 STATIC void
   2019 gus_stop_voice(sc, voice, intrs_too)
   2020 	struct gus_softc *sc;
   2021 	int voice;
   2022 	int intrs_too;
   2023 {
   2024 	int port = sc->sc_iobase;
   2025 
   2026 	sc->sc_voc[voice].voccntl |= GUSMASK_VOICE_STOPPED |
   2027 		GUSMASK_STOP_VOICE;
   2028 	if (intrs_too) {
   2029 	  sc->sc_voc[voice].voccntl &= ~(GUSMASK_VOICE_IRQ);
   2030 	  /* no more DMA to do */
   2031 	  sc->sc_flags &= ~GUS_PLAYING;
   2032 	}
   2033 	DMAPRINTF(("gusintr voice notplaying=%x\n", sc->sc_flags));
   2034 
   2035 	guspoke(port, 0L, 0);
   2036 
   2037 	outb(port+GUS_VOICE_SELECT, (unsigned char) voice);
   2038 
   2039 	SELECT_GUS_REG(port, GUSREG_CUR_VOLUME);
   2040 	outw(port+GUS_DATA_LOW, 0x0000);
   2041 	SELECT_GUS_REG(port, GUSREG_VOICE_CNTL);
   2042 	outb(port+GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
   2043 	delay(100);
   2044 	SELECT_GUS_REG(port, GUSREG_CUR_VOLUME);
   2045 	outw(port+GUS_DATA_LOW, 0x0000);
   2046 	SELECT_GUS_REG(port, GUSREG_VOICE_CNTL);
   2047 	outb(port+GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
   2048 
   2049 	SELECT_GUS_REG(port, GUSREG_CUR_ADDR_HIGH);
   2050 	outw(port+GUS_DATA_LOW, 0x0000);
   2051 	SELECT_GUS_REG(port, GUSREG_CUR_ADDR_LOW);
   2052 	outw(port+GUS_DATA_LOW, 0x0000);
   2053 
   2054 }
   2055 
   2056 
   2057 /*
   2058  * Set the volume of a given voice.  Called at splgus().
   2059  */
   2060 STATIC void
   2061 gus_set_volume(sc, voice, volume)
   2062 	struct gus_softc *sc;
   2063 	int voice, volume;
   2064 {
   2065 	int port = sc->sc_iobase;
   2066 	unsigned int gusvol;
   2067 
   2068 	gusvol = gus_log_volumes[volume < 512 ? volume : 511];
   2069 
   2070 	sc->sc_voc[voice].current_volume = gusvol;
   2071 
   2072 	outb(port+GUS_VOICE_SELECT, (unsigned char) voice);
   2073 
   2074 	SELECT_GUS_REG(port, GUSREG_START_VOLUME);
   2075 	outb(port+GUS_DATA_HIGH, (unsigned char) (gusvol >> 4));
   2076 
   2077 	SELECT_GUS_REG(port, GUSREG_END_VOLUME);
   2078 	outb(port+GUS_DATA_HIGH, (unsigned char) (gusvol >> 4));
   2079 
   2080 	SELECT_GUS_REG(port, GUSREG_CUR_VOLUME);
   2081 	outw(port+GUS_DATA_LOW, gusvol << 4);
   2082 	delay(500);
   2083 	outw(port+GUS_DATA_LOW, gusvol << 4);
   2084 
   2085 }
   2086 
   2087 /*
   2088  * Interface to the audio layer.
   2089  */
   2090 
   2091 int
   2092 gusmax_set_params(addr, mode, p, q)
   2093 	void *addr;
   2094 	int mode;
   2095 	struct audio_params *p, *q;
   2096 {
   2097 	struct ad1848_softc *ac = addr;
   2098 	struct gus_softc *sc = ac->parent;
   2099 	int error;
   2100 
   2101 	error = ad1848_set_params(ac, mode, p, q);
   2102 	if (error)
   2103 		return error;
   2104 	error = gus_set_params(sc, mode, p, q);
   2105 	return error;
   2106 }
   2107 
   2108 int
   2109 gus_set_params(addr, mode, p, q)
   2110 	void *addr;
   2111 	int mode;
   2112 	struct audio_params *p, *q;
   2113 {
   2114 	struct gus_softc *sc = addr;
   2115 	int s;
   2116 
   2117 	switch (p->encoding) {
   2118 	case AUDIO_ENCODING_ULAW:
   2119 	case AUDIO_ENCODING_ALAW:
   2120 	case AUDIO_ENCODING_SLINEAR_LE:
   2121 	case AUDIO_ENCODING_ULINEAR_LE:
   2122 	case AUDIO_ENCODING_SLINEAR_BE:
   2123 	case AUDIO_ENCODING_ULINEAR_BE:
   2124 		break;
   2125 	default:
   2126 		return (EINVAL);
   2127 	}
   2128 
   2129 	s = splaudio();
   2130 
   2131 	if (p->precision == 8) {
   2132 		sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~GUSMASK_DATA_SIZE16;
   2133 		sc->sc_voc[GUS_VOICE_RIGHT].voccntl &= ~GUSMASK_DATA_SIZE16;
   2134 	} else {
   2135 		sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_DATA_SIZE16;
   2136 		sc->sc_voc[GUS_VOICE_RIGHT].voccntl |= GUSMASK_DATA_SIZE16;
   2137 	}
   2138 
   2139 	sc->sc_encoding = p->encoding;
   2140 	sc->sc_precision = p->precision;
   2141 	sc->sc_channels = p->channels;
   2142 
   2143 	splx(s);
   2144 
   2145 	if (p->sample_rate > gus_max_frequency[sc->sc_voices - GUS_MIN_VOICES])
   2146 		p->sample_rate = gus_max_frequency[sc->sc_voices - GUS_MIN_VOICES];
   2147 	if (mode == AUMODE_RECORD)
   2148 		sc->sc_irate = p->sample_rate;
   2149 	else
   2150 		sc->sc_orate = p->sample_rate;
   2151 
   2152 	switch (p->encoding) {
   2153 	case AUDIO_ENCODING_ULAW:
   2154 		p->sw_code = mode == AUMODE_PLAY ?
   2155 			mulaw_to_ulinear8 : ulinear8_to_mulaw;
   2156 		break;
   2157 	case AUDIO_ENCODING_ALAW:
   2158 		p->sw_code = mode == AUMODE_PLAY ?
   2159 			alaw_to_ulinear8 : ulinear8_to_alaw;
   2160 		break;
   2161 	case AUDIO_ENCODING_ULINEAR_BE:
   2162 	case AUDIO_ENCODING_SLINEAR_BE:
   2163 		p->sw_code = swap_bytes;
   2164 		break;
   2165 	default:
   2166 		p->sw_code = 0;
   2167 	}
   2168 
   2169 	/* Update setting for the other mode. */
   2170 	q->encoding = p->encoding;
   2171 	q->channels = p->channels;
   2172 	q->precision = p->precision;
   2173 	return 0;
   2174 }
   2175 
   2176 /*
   2177  * Interface to the audio layer - set the blocksize to the correct number
   2178  * of units
   2179  */
   2180 
   2181 int
   2182 gusmax_round_blocksize(addr, blocksize)
   2183 	void * addr;
   2184 	int blocksize;
   2185 {
   2186 	struct ad1848_softc *ac = addr;
   2187 	struct gus_softc *sc = ac->parent;
   2188 
   2189 /*	blocksize = ad1848_round_blocksize(ac, blocksize);*/
   2190 	return gus_round_blocksize(sc, blocksize);
   2191 }
   2192 
   2193 int
   2194 gus_round_blocksize(addr, blocksize)
   2195 	void * addr;
   2196 	int blocksize;
   2197 {
   2198 	struct gus_softc *sc = addr;
   2199 
   2200 	DPRINTF(("gus_round_blocksize called\n"));
   2201 
   2202 	if ((sc->sc_encoding == AUDIO_ENCODING_ULAW ||
   2203 	     sc->sc_encoding == AUDIO_ENCODING_ALAW) && blocksize > 32768)
   2204 		blocksize = 32768;
   2205 	else if (blocksize > 65536)
   2206 		blocksize = 65536;
   2207 
   2208 	if ((blocksize % GUS_BUFFER_MULTIPLE) != 0)
   2209 		blocksize = (blocksize / GUS_BUFFER_MULTIPLE + 1) *
   2210 			GUS_BUFFER_MULTIPLE;
   2211 
   2212 	/* set up temporary buffer to hold the deinterleave, if necessary
   2213 	   for stereo output */
   2214 	if (sc->sc_deintr_buf) {
   2215 		FREE(sc->sc_deintr_buf, M_DEVBUF);
   2216 		sc->sc_deintr_buf = NULL;
   2217 	}
   2218 	MALLOC(sc->sc_deintr_buf, void *, blocksize>>1, M_DEVBUF, M_WAITOK);
   2219 
   2220 	sc->sc_blocksize = blocksize;
   2221 	/* multi-buffering not quite working yet. */
   2222 	sc->sc_nbufs = /*GUS_MEM_FOR_BUFFERS / blocksize*/ 2;
   2223 
   2224 	gus_set_chan_addrs(sc);
   2225 
   2226 	return blocksize;
   2227 }
   2228 
   2229 int
   2230 gus_get_out_gain(addr)
   2231 	caddr_t addr;
   2232 {
   2233 	struct gus_softc *sc = (struct gus_softc *) addr;
   2234 
   2235 	DPRINTF(("gus_get_out_gain called\n"));
   2236 	return sc->sc_ogain / 2;
   2237 }
   2238 
   2239 STATIC inline void gus_set_voices(sc, voices)
   2240 struct gus_softc *sc;
   2241 int voices;
   2242 {
   2243 	int port = sc->sc_iobase;
   2244 	/*
   2245 	 * Select the active number of voices
   2246 	 */
   2247 
   2248 	SELECT_GUS_REG(port, GUSREG_ACTIVE_VOICES);
   2249 	outb(port+GUS_DATA_HIGH, (voices-1) | 0xc0);
   2250 
   2251 	sc->sc_voices = voices;
   2252 }
   2253 
   2254 /*
   2255  * Actually set the settings of various values on the card
   2256  */
   2257 
   2258 int
   2259 gusmax_commit_settings(addr)
   2260 	void * addr;
   2261 {
   2262 	struct ad1848_softc *ac = addr;
   2263 	struct gus_softc *sc = ac->parent;
   2264 
   2265 	(void) ad1848_commit_settings(ac);
   2266 	return gus_commit_settings(sc);
   2267 }
   2268 
   2269 /*
   2270  * Commit the settings.  Called at normal IPL.
   2271  */
   2272 int
   2273 gus_commit_settings(addr)
   2274 	void * addr;
   2275 {
   2276 	struct gus_softc *sc = addr;
   2277 	int s;
   2278 
   2279 	DPRINTF(("gus_commit_settings called (gain = %d)\n",sc->sc_ogain));
   2280 
   2281 
   2282 	s = splgus();
   2283 
   2284 	gus_set_recrate(sc, sc->sc_irate);
   2285 	gus_set_volume(sc, GUS_VOICE_LEFT, sc->sc_ogain);
   2286 	gus_set_volume(sc, GUS_VOICE_RIGHT, sc->sc_ogain);
   2287 	gus_set_samprate(sc, GUS_VOICE_LEFT, sc->sc_orate);
   2288 	gus_set_samprate(sc, GUS_VOICE_RIGHT, sc->sc_orate);
   2289 	splx(s);
   2290 	gus_set_chan_addrs(sc);
   2291 
   2292 	return 0;
   2293 }
   2294 
   2295 STATIC void
   2296 gus_set_chan_addrs(sc)
   2297 struct gus_softc *sc;
   2298 {
   2299 	/*
   2300 	 * We use sc_nbufs * blocksize bytes of storage in the on-board GUS
   2301 	 * ram.
   2302 	 * For mono, each of the sc_nbufs buffers is DMA'd to in one chunk,
   2303 	 * and both left & right channels play the same buffer.
   2304 	 *
   2305 	 * For stereo, each channel gets a contiguous half of the memory,
   2306 	 * and each has sc_nbufs buffers of size blocksize/2.
   2307 	 * Stereo data are deinterleaved in main memory before the DMA out
   2308 	 * routines are called to queue the output.
   2309 	 *
   2310 	 * The blocksize per channel is kept in sc_chanblocksize.
   2311 	 */
   2312 	if (sc->sc_channels == 2)
   2313 	    sc->sc_chanblocksize = sc->sc_blocksize/2;
   2314 	else
   2315 	    sc->sc_chanblocksize = sc->sc_blocksize;
   2316 
   2317 	sc->sc_voc[GUS_VOICE_LEFT].start_addr = GUS_MEM_OFFSET - 1;
   2318 	sc->sc_voc[GUS_VOICE_RIGHT].start_addr =
   2319 	    (gus_dostereo && sc->sc_channels == 2 ? GUS_LEFT_RIGHT_OFFSET : 0)
   2320 	      + GUS_MEM_OFFSET - 1;
   2321 	sc->sc_voc[GUS_VOICE_RIGHT].current_addr =
   2322 	    sc->sc_voc[GUS_VOICE_RIGHT].start_addr + 1;
   2323 	sc->sc_voc[GUS_VOICE_RIGHT].end_addr =
   2324 	    sc->sc_voc[GUS_VOICE_RIGHT].start_addr +
   2325 	    sc->sc_nbufs * sc->sc_chanblocksize;
   2326 
   2327 }
   2328 
   2329 /*
   2330  * Set the sample rate of the given voice.  Called at splgus().
   2331  */
   2332 
   2333 STATIC void
   2334 gus_set_samprate(sc, voice, freq)
   2335 	struct gus_softc *sc;
   2336 	int voice, freq;
   2337 {
   2338 	int port = sc->sc_iobase;
   2339 	unsigned int fc;
   2340 	u_long temp, f = (u_long) freq;
   2341 
   2342 	/*
   2343 	 * calculate fc based on the number of active voices;
   2344 	 * we need to use longs to preserve enough bits
   2345 	 */
   2346 
   2347 	temp = (u_long) gus_max_frequency[sc->sc_voices-GUS_MIN_VOICES];
   2348 
   2349  	fc = (unsigned int)(((f << 9L) + (temp >> 1L)) / temp);
   2350 
   2351  	fc <<= 1;
   2352 
   2353 
   2354 	/*
   2355 	 * Program the voice frequency, and set it in the voice data record
   2356 	 */
   2357 
   2358 	outb(port+GUS_VOICE_SELECT, (unsigned char) voice);
   2359 	SELECT_GUS_REG(port, GUSREG_FREQ_CONTROL);
   2360 	outw(port+GUS_DATA_LOW, fc);
   2361 
   2362 	sc->sc_voc[voice].rate = freq;
   2363 
   2364 }
   2365 
   2366 /*
   2367  * Set the sample rate of the recording frequency.  Formula is from the GUS
   2368  * SDK.  Called at splgus().
   2369  */
   2370 
   2371 STATIC void
   2372 gus_set_recrate(sc, rate)
   2373 	struct gus_softc *sc;
   2374 	u_long rate;
   2375 {
   2376 	int port = sc->sc_iobase;
   2377 	u_char realrate;
   2378 	DPRINTF(("gus_set_recrate %lu\n", rate));
   2379 
   2380 #if 0
   2381 	realrate = 9878400/(16*(rate+2)); /* formula from GUS docs */
   2382 #endif
   2383 	realrate = (9878400 >> 4)/rate - 2; /* formula from code, sigh. */
   2384 
   2385 	SELECT_GUS_REG(port, GUSREG_SAMPLE_FREQ);
   2386  	outb(port+GUS_DATA_HIGH, realrate);
   2387 }
   2388 
   2389 /*
   2390  * Interface to the audio layer - turn the output on or off.  Note that some
   2391  * of these bits are flipped in the register
   2392  */
   2393 
   2394 int
   2395 gusmax_speaker_ctl(addr, newstate)
   2396 	void * addr;
   2397 	int newstate;
   2398 {
   2399 	struct ad1848_softc *sc = addr;
   2400 	return gus_speaker_ctl(sc->parent, newstate);
   2401 }
   2402 
   2403 int
   2404 gus_speaker_ctl(addr, newstate)
   2405 	void * addr;
   2406 	int newstate;
   2407 {
   2408 	struct gus_softc *sc = (struct gus_softc *) addr;
   2409 
   2410 	/* Line out bit is flipped: 0 enables, 1 disables */
   2411 	if ((newstate == SPKR_ON) &&
   2412 	    (sc->sc_mixcontrol & GUSMASK_LINE_OUT)) {
   2413 		sc->sc_mixcontrol &= ~GUSMASK_LINE_OUT;
   2414 		outb(sc->sc_iobase+GUS_MIX_CONTROL, sc->sc_mixcontrol);
   2415 	}
   2416 	if ((newstate == SPKR_OFF) &&
   2417 	    (sc->sc_mixcontrol & GUSMASK_LINE_OUT) == 0) {
   2418 		sc->sc_mixcontrol |= GUSMASK_LINE_OUT;
   2419 		outb(sc->sc_iobase+GUS_MIX_CONTROL, sc->sc_mixcontrol);
   2420 	}
   2421 
   2422 	return 0;
   2423 }
   2424 
   2425 STATIC int
   2426 gus_linein_ctl(addr, newstate)
   2427 	void * addr;
   2428 	int newstate;
   2429 {
   2430 	struct gus_softc *sc = (struct gus_softc *) addr;
   2431 
   2432 	/* Line in bit is flipped: 0 enables, 1 disables */
   2433 	if ((newstate == SPKR_ON) &&
   2434 	    (sc->sc_mixcontrol & GUSMASK_LINE_IN)) {
   2435 		sc->sc_mixcontrol &= ~GUSMASK_LINE_IN;
   2436 		outb(sc->sc_iobase+GUS_MIX_CONTROL, sc->sc_mixcontrol);
   2437 	}
   2438 	if ((newstate == SPKR_OFF) &&
   2439 	    (sc->sc_mixcontrol & GUSMASK_LINE_IN) == 0) {
   2440 		sc->sc_mixcontrol |= GUSMASK_LINE_IN;
   2441 		outb(sc->sc_iobase+GUS_MIX_CONTROL, sc->sc_mixcontrol);
   2442 	}
   2443 
   2444 	return 0;
   2445 }
   2446 
   2447 STATIC int
   2448 gus_mic_ctl(addr, newstate)
   2449 	void * addr;
   2450 	int newstate;
   2451 {
   2452 	struct gus_softc *sc = (struct gus_softc *) addr;
   2453 
   2454 	/* Mic bit is normal: 1 enables, 0 disables */
   2455 	if ((newstate == SPKR_ON) &&
   2456 	    (sc->sc_mixcontrol & GUSMASK_MIC_IN) == 0) {
   2457 		sc->sc_mixcontrol |= GUSMASK_MIC_IN;
   2458 		outb(sc->sc_iobase+GUS_MIX_CONTROL, sc->sc_mixcontrol);
   2459 	}
   2460 	if ((newstate == SPKR_OFF) &&
   2461 	    (sc->sc_mixcontrol & GUSMASK_MIC_IN)) {
   2462 		sc->sc_mixcontrol &= ~GUSMASK_MIC_IN;
   2463 		outb(sc->sc_iobase+GUS_MIX_CONTROL, sc->sc_mixcontrol);
   2464 	}
   2465 
   2466 	return 0;
   2467 }
   2468 
   2469 /*
   2470  * Set the end address of a give voice.  Called at splgus()
   2471  */
   2472 
   2473 STATIC void
   2474 gus_set_endaddr(sc, voice, addr)
   2475 	struct gus_softc *sc;
   2476 	int voice;
   2477 	u_long addr;
   2478 {
   2479 	int port = sc->sc_iobase;
   2480 
   2481 	sc->sc_voc[voice].end_addr = addr;
   2482 
   2483 	if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16)
   2484 		addr = convert_to_16bit(addr);
   2485 
   2486 	SELECT_GUS_REG(port, GUSREG_END_ADDR_HIGH);
   2487 	outw(port+GUS_DATA_LOW, ADDR_HIGH(addr));
   2488 	SELECT_GUS_REG(port, GUSREG_END_ADDR_LOW);
   2489 	outw(port+GUS_DATA_LOW, ADDR_LOW(addr));
   2490 
   2491 }
   2492 
   2493 #ifdef GUSPLAYDEBUG
   2494 /*
   2495  * Set current address.  called at splgus()
   2496  */
   2497 STATIC void
   2498 gus_set_curaddr(sc, voice, addr)
   2499 	struct gus_softc *sc;
   2500 	int voice;
   2501 	u_long addr;
   2502 {
   2503 	int port = sc->sc_iobase;
   2504 
   2505 	sc->sc_voc[voice].current_addr = addr;
   2506 
   2507 	if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16)
   2508 		addr = convert_to_16bit(addr);
   2509 
   2510 	outb(port+GUS_VOICE_SELECT, (unsigned char) voice);
   2511 
   2512 	SELECT_GUS_REG(port, GUSREG_CUR_ADDR_HIGH);
   2513 	outw(port+GUS_DATA_LOW, ADDR_HIGH(addr));
   2514 	SELECT_GUS_REG(port, GUSREG_CUR_ADDR_LOW);
   2515 	outw(port+GUS_DATA_LOW, ADDR_LOW(addr));
   2516 
   2517 }
   2518 
   2519 /*
   2520  * Get current GUS playback address.  Called at splgus().
   2521  */
   2522 STATIC u_long
   2523 gus_get_curaddr(sc, voice)
   2524 	struct gus_softc *sc;
   2525 	int voice;
   2526 {
   2527 	int port = sc->sc_iobase;
   2528 	u_long addr;
   2529 
   2530 	outb(port+GUS_VOICE_SELECT, (unsigned char) voice);
   2531 	SELECT_GUS_REG(port, GUSREG_CUR_ADDR_HIGH|GUSREG_READ);
   2532 	addr = (inw(port+GUS_DATA_LOW) & 0x1fff) << 7;
   2533 	SELECT_GUS_REG(port, GUSREG_CUR_ADDR_LOW|GUSREG_READ);
   2534 	addr |= (inw(port+GUS_DATA_LOW) >> 9L) & 0x7f;
   2535 
   2536 	if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16)
   2537 	    addr = (addr & 0xc0000) | ((addr & 0x1ffff) << 1); /* undo 16-bit change */
   2538 	DPRINTF(("gus voice %d curaddr %ld end_addr %ld\n",
   2539 		 voice, addr, sc->sc_voc[voice].end_addr));
   2540 	/* XXX sanity check the address? */
   2541 
   2542 	return(addr);
   2543 }
   2544 #endif
   2545 
   2546 /*
   2547  * Convert an address value to a "16 bit" value - why this is necessary I
   2548  * have NO idea
   2549  */
   2550 
   2551 STATIC u_long
   2552 convert_to_16bit(address)
   2553 	u_long address;
   2554 {
   2555 	u_long old_address;
   2556 
   2557 	old_address = address;
   2558 	address >>= 1;
   2559 	address &= 0x0001ffffL;
   2560 	address |= (old_address & 0x000c0000L);
   2561 
   2562 	return (address);
   2563 }
   2564 
   2565 /*
   2566  * Write a value into the GUS's DRAM
   2567  */
   2568 
   2569 STATIC void
   2570 guspoke(port, address, value)
   2571 	int port;
   2572 	long address;
   2573 	unsigned char value;
   2574 {
   2575 
   2576 	/*
   2577 	 * Select the DRAM address
   2578 	 */
   2579 
   2580  	SELECT_GUS_REG(port, GUSREG_DRAM_ADDR_LOW);
   2581  	outw(port+GUS_DATA_LOW, (unsigned int) (address & 0xffff));
   2582  	SELECT_GUS_REG(port, GUSREG_DRAM_ADDR_HIGH);
   2583  	outb(port+GUS_DATA_HIGH, (unsigned char) ((address >> 16) & 0xff));
   2584 
   2585 	/*
   2586 	 * Actually write the data
   2587 	 */
   2588 
   2589 	outb(port+GUS_DRAM_DATA, value);
   2590 }
   2591 
   2592 /*
   2593  * Read a value from the GUS's DRAM
   2594  */
   2595 
   2596 STATIC unsigned char
   2597 guspeek(port, address)
   2598 	int port;
   2599 	u_long address;
   2600 {
   2601 
   2602 	/*
   2603 	 * Select the DRAM address
   2604 	 */
   2605 
   2606  	SELECT_GUS_REG(port, GUSREG_DRAM_ADDR_LOW);
   2607  	outw(port+GUS_DATA_LOW, (unsigned int) (address & 0xffff));
   2608  	SELECT_GUS_REG(port, GUSREG_DRAM_ADDR_HIGH);
   2609  	outb(port+GUS_DATA_HIGH, (unsigned char) ((address >> 16) & 0xff));
   2610 
   2611 	/*
   2612 	 * Read in the data from the board
   2613 	 */
   2614 
   2615 	return (unsigned char) inb(port+GUS_DRAM_DATA);
   2616 }
   2617 
   2618 /*
   2619  * Reset the Gravis UltraSound card, completely
   2620  */
   2621 
   2622 STATIC void
   2623 gusreset(sc, voices)
   2624 	struct gus_softc *sc;
   2625 	int voices;
   2626 {
   2627 	int port = sc->sc_iobase;
   2628 	int i,s;
   2629 
   2630 	s = splgus();
   2631 
   2632 	/*
   2633 	 * Reset the GF1 chip
   2634 	 */
   2635 
   2636 	SELECT_GUS_REG(port, GUSREG_RESET);
   2637 	outb(port+GUS_DATA_HIGH, 0x00);
   2638 
   2639 	delay(500);
   2640 
   2641 	/*
   2642 	 * Release reset
   2643 	 */
   2644 
   2645 	SELECT_GUS_REG(port, GUSREG_RESET);
   2646 	outb(port+GUS_DATA_HIGH, GUSMASK_MASTER_RESET);
   2647 
   2648 	delay(500);
   2649 
   2650 	/*
   2651 	 * Reset MIDI port as well
   2652 	 */
   2653 
   2654 	outb(GUS_MIDI_CONTROL,MIDI_RESET);
   2655 
   2656 	delay(500);
   2657 
   2658 	outb(GUS_MIDI_CONTROL,0x00);
   2659 
   2660 	/*
   2661 	 * Clear interrupts
   2662 	 */
   2663 
   2664 	SELECT_GUS_REG(port, GUSREG_DMA_CONTROL);
   2665 	outb(port+GUS_DATA_HIGH, 0x00);
   2666 	SELECT_GUS_REG(port, GUSREG_TIMER_CONTROL);
   2667 	outb(port+GUS_DATA_HIGH, 0x00);
   2668 	SELECT_GUS_REG(port, GUSREG_SAMPLE_CONTROL);
   2669 	outb(port+GUS_DATA_HIGH, 0x00);
   2670 
   2671 	gus_set_voices(sc, voices);
   2672 
   2673 	inb(port+GUS_IRQ_STATUS);
   2674 	SELECT_GUS_REG(port, GUSREG_DMA_CONTROL);
   2675 	inb(port+GUS_DATA_HIGH);
   2676 	SELECT_GUS_REG(port, GUSREG_SAMPLE_CONTROL);
   2677 	inb(port+GUS_DATA_HIGH);
   2678 	SELECT_GUS_REG(port, GUSREG_IRQ_STATUS);
   2679 	inb(port+GUS_DATA_HIGH);
   2680 
   2681 	/*
   2682 	 * Reset voice specific information
   2683 	 */
   2684 
   2685 	for(i = 0; i < voices; i++) {
   2686 		outb(port+GUS_VOICE_SELECT, (unsigned char) i);
   2687 
   2688 		SELECT_GUS_REG(port, GUSREG_VOICE_CNTL);
   2689 
   2690 		sc->sc_voc[i].voccntl = GUSMASK_VOICE_STOPPED |
   2691 			GUSMASK_STOP_VOICE;
   2692 
   2693 		outb(port+GUS_DATA_HIGH, sc->sc_voc[i].voccntl);
   2694 
   2695 		sc->sc_voc[i].volcntl = GUSMASK_VOLUME_STOPPED |
   2696 				GUSMASK_STOP_VOLUME;
   2697 
   2698 		SELECT_GUS_REG(port, GUSREG_VOLUME_CONTROL);
   2699 		outb(port+GUS_DATA_HIGH, sc->sc_voc[i].volcntl);
   2700 
   2701 		delay(100);
   2702 
   2703 		gus_set_samprate(sc, i, 8000);
   2704 		SELECT_GUS_REG(port, GUSREG_START_ADDR_HIGH);
   2705 		outw(port+GUS_DATA_LOW, 0x0000);
   2706 		SELECT_GUS_REG(port, GUSREG_START_ADDR_LOW);
   2707 		outw(port+GUS_DATA_LOW, 0x0000);
   2708 		SELECT_GUS_REG(port, GUSREG_END_ADDR_HIGH);
   2709 		outw(port+GUS_DATA_LOW, 0x0000);
   2710 		SELECT_GUS_REG(port, GUSREG_END_ADDR_LOW);
   2711 		outw(port+GUS_DATA_LOW, 0x0000);
   2712 		SELECT_GUS_REG(port, GUSREG_VOLUME_RATE);
   2713 		outb(port+GUS_DATA_HIGH, 0x01);
   2714 		SELECT_GUS_REG(port, GUSREG_START_VOLUME);
   2715 		outb(port+GUS_DATA_HIGH, 0x10);
   2716 		SELECT_GUS_REG(port, GUSREG_END_VOLUME);
   2717 		outb(port+GUS_DATA_HIGH, 0xe0);
   2718 		SELECT_GUS_REG(port, GUSREG_CUR_VOLUME);
   2719 		outw(port+GUS_DATA_LOW, 0x0000);
   2720 
   2721 		SELECT_GUS_REG(port, GUSREG_CUR_ADDR_HIGH);
   2722 		outw(port+GUS_DATA_LOW, 0x0000);
   2723 		SELECT_GUS_REG(port, GUSREG_CUR_ADDR_LOW);
   2724 		outw(port+GUS_DATA_LOW, 0x0000);
   2725 		SELECT_GUS_REG(port, GUSREG_PAN_POS);
   2726 		outb(port+GUS_DATA_HIGH, 0x07);
   2727 	}
   2728 
   2729 	/*
   2730 	 * Clear out any pending IRQs
   2731 	 */
   2732 
   2733 	inb(port+GUS_IRQ_STATUS);
   2734 	SELECT_GUS_REG(port, GUSREG_DMA_CONTROL);
   2735 	inb(port+GUS_DATA_HIGH);
   2736 	SELECT_GUS_REG(port, GUSREG_SAMPLE_CONTROL);
   2737 	inb(port+GUS_DATA_HIGH);
   2738 	SELECT_GUS_REG(port, GUSREG_IRQ_STATUS);
   2739 	inb(port+GUS_DATA_HIGH);
   2740 
   2741 	SELECT_GUS_REG(port, GUSREG_RESET);
   2742 	outb(port+GUS_DATA_HIGH, GUSMASK_MASTER_RESET | GUSMASK_DAC_ENABLE |
   2743 		GUSMASK_IRQ_ENABLE);
   2744 
   2745 	splx(s);
   2746 }
   2747 
   2748 
   2749 STATIC void
   2750 gus_init_cs4231(sc)
   2751 	struct gus_softc *sc;
   2752 {
   2753 	int port = sc->sc_iobase;
   2754 	u_char ctrl;
   2755 
   2756 	ctrl = (port & 0xf0) >> 4;	/* set port address middle nibble */
   2757 	/*
   2758 	 * The codec is a bit weird--swapped dma channels.
   2759 	 */
   2760 	ctrl |= GUS_MAX_CODEC_ENABLE;
   2761 	if (sc->sc_drq >= 4)
   2762 		ctrl |= GUS_MAX_RECCHAN16;
   2763 	if (sc->sc_recdrq >= 4)
   2764 		ctrl |= GUS_MAX_PLAYCHAN16;
   2765 
   2766 	outb(port+GUS_MAX_CTRL, ctrl);
   2767 
   2768 	sc->sc_codec.sc_iot = sc->sc_iot;
   2769 	sc->sc_codec.sc_iobase = port+GUS_MAX_CODEC_BASE;
   2770 
   2771 	if (ad1848_probe(&sc->sc_codec) == 0) {
   2772 		sc->sc_flags &= ~GUS_CODEC_INSTALLED;
   2773 	} else {
   2774 		struct ad1848_volume vol = {AUDIO_MAX_GAIN, AUDIO_MAX_GAIN};
   2775 		static struct audio_hw_if gusmax_hw_if = {
   2776 			gusmaxopen,
   2777 			gusmax_close,
   2778 			NULL,				/* drain */
   2779 
   2780 			gus_query_encoding, /* query encoding */
   2781 
   2782 			gusmax_set_params,
   2783 
   2784 			gusmax_round_blocksize,
   2785 
   2786 			gusmax_set_out_port,
   2787 			gusmax_get_out_port,
   2788 			gusmax_set_in_port,
   2789 			gusmax_get_in_port,
   2790 
   2791 			gusmax_commit_settings,
   2792 
   2793 			NULL,
   2794 			NULL,
   2795 
   2796 			gusmax_dma_output,
   2797 			gusmax_dma_input,
   2798 			gusmax_halt_out_dma,
   2799 			gusmax_halt_in_dma,
   2800 			gusmax_cont_out_dma,
   2801 			gusmax_cont_in_dma,
   2802 
   2803 			gusmax_speaker_ctl,
   2804 
   2805 			gus_getdev,
   2806 			NULL,
   2807 			gusmax_mixer_set_port,
   2808 			gusmax_mixer_get_port,
   2809 			gusmax_mixer_query_devinfo,
   2810 			NULL,
   2811 			NULL,
   2812 			NULL,
   2813                         NULL,
   2814 			gusmax_get_props,
   2815 		};
   2816 		sc->sc_flags |= GUS_CODEC_INSTALLED;
   2817 		sc->sc_codec.parent = sc;
   2818 		sc->sc_codec.sc_drq = sc->sc_recdrq;
   2819 		sc->sc_codec.sc_recdrq = sc->sc_drq;
   2820 		gus_hw_if = gusmax_hw_if;
   2821 		/* enable line in and mic in the GUS mixer; the codec chip
   2822 		   will do the real mixing for them. */
   2823 		sc->sc_mixcontrol &= ~GUSMASK_LINE_IN; /* 0 enables. */
   2824 		sc->sc_mixcontrol |= GUSMASK_MIC_IN; /* 1 enables. */
   2825 		outb(sc->sc_iobase+GUS_MIX_CONTROL, sc->sc_mixcontrol);
   2826 
   2827 		ad1848_attach(&sc->sc_codec);
   2828 		/* turn on pre-MUX microphone gain. */
   2829 		ad1848_set_mic_gain(&sc->sc_codec, &vol);
   2830 	}
   2831 }
   2832 
   2833 
   2834 /*
   2835  * Return info about the audio device, for the AUDIO_GETINFO ioctl
   2836  */
   2837 
   2838 int
   2839 gus_getdev(addr, dev)
   2840 	void * addr;
   2841 	struct audio_device *dev;
   2842 {
   2843 	*dev = gus_device;
   2844 	return 0;
   2845 }
   2846 
   2847 /*
   2848  * stubs (XXX)
   2849  */
   2850 
   2851 int
   2852 gus_set_in_gain(addr, gain, balance)
   2853 	caddr_t addr;
   2854 	u_int gain;
   2855 	u_char balance;
   2856 {
   2857 	DPRINTF(("gus_set_in_gain called\n"));
   2858 	return 0;
   2859 }
   2860 
   2861 int
   2862 gus_get_in_gain(addr)
   2863 	caddr_t addr;
   2864 {
   2865 	DPRINTF(("gus_get_in_gain called\n"));
   2866 	return 0;
   2867 }
   2868 
   2869 int
   2870 gusmax_set_out_port(addr, port)
   2871 	void * addr;
   2872 	int port;
   2873 {
   2874 	struct ad1848_softc *sc = addr;
   2875 	return gus_set_out_port(sc->parent, port);
   2876 }
   2877 
   2878 int
   2879 gus_set_out_port(addr, port)
   2880 	void * addr;
   2881 	int port;
   2882 {
   2883 	struct gus_softc *sc = addr;
   2884 	DPRINTF(("gus_set_out_port called\n"));
   2885 	sc->sc_out_port = port;
   2886 
   2887 	return 0;
   2888 }
   2889 
   2890 int
   2891 gusmax_get_out_port(addr)
   2892 	void * addr;
   2893 {
   2894 	struct ad1848_softc *sc = addr;
   2895 	return gus_get_out_port(sc->parent);
   2896 }
   2897 
   2898 int
   2899 gus_get_out_port(addr)
   2900 	void * addr;
   2901 {
   2902 	struct gus_softc *sc = addr;
   2903 	DPRINTF(("gus_get_out_port() called\n"));
   2904 	return sc->sc_out_port;
   2905 }
   2906 
   2907 int
   2908 gusmax_set_in_port(addr, port)
   2909 	void * addr;
   2910 	int port;
   2911 {
   2912 	struct ad1848_softc *sc = addr;
   2913 	DPRINTF(("gusmax_set_in_port: %d\n", port));
   2914 
   2915 	switch(port) {
   2916 	case MIC_IN_PORT:
   2917 	case LINE_IN_PORT:
   2918 	case AUX1_IN_PORT:
   2919 	case DAC_IN_PORT:
   2920 		break;
   2921 	default:
   2922 		return(EINVAL);
   2923 		/*NOTREACHED*/
   2924 	}
   2925 	return(ad1848_set_rec_port(sc, port));
   2926 }
   2927 
   2928 int
   2929 gusmax_get_in_port(addr)
   2930 	void * addr;
   2931 {
   2932 	struct ad1848_softc *sc = addr;
   2933 	int port;
   2934 
   2935 	port = ad1848_get_rec_port(sc);
   2936 	DPRINTF(("gusmax_get_in_port: %d\n", port));
   2937 
   2938 	return(port);
   2939 }
   2940 
   2941 int
   2942 gus_set_in_port(addr, port)
   2943 	void * addr;
   2944 	int port;
   2945 {
   2946 	struct gus_softc *sc = addr;
   2947 	DPRINTF(("gus_set_in_port called\n"));
   2948 	/*
   2949 	 * On the GUS with ICS mixer, the ADC input is after the mixer stage,
   2950 	 * so we can't set the input port.
   2951 	 *
   2952 	 * On the GUS with CS4231 codec/mixer, see gusmax_set_in_port().
   2953 	 */
   2954 	sc->sc_in_port = port;
   2955 
   2956 	return 0;
   2957 }
   2958 
   2959 
   2960 int
   2961 gus_get_in_port(addr)
   2962 	void * addr;
   2963 {
   2964 	struct gus_softc *sc = addr;
   2965 	DPRINTF(("gus_get_in_port called\n"));
   2966 	return sc->sc_in_port;
   2967 }
   2968 
   2969 
   2970 int
   2971 gusmax_dma_input(addr, buf, size, callback, arg)
   2972 	void * addr;
   2973 	void *buf;
   2974 	int size;
   2975 	void (*callback) __P((void *));
   2976 	void *arg;
   2977 {
   2978 	struct ad1848_softc *sc = addr;
   2979 	return gus_dma_input(sc->parent, buf, size, callback, arg);
   2980 }
   2981 
   2982 /*
   2983  * Start sampling the input source into the requested DMA buffer.
   2984  * Called at splgus(), either from top-half or from interrupt handler.
   2985  */
   2986 int
   2987 gus_dma_input(addr, buf, size, callback, arg)
   2988 	void * addr;
   2989 	void *buf;
   2990 	int size;
   2991 	void (*callback) __P((void *));
   2992 	void *arg;
   2993 {
   2994 	struct gus_softc *sc = addr;
   2995 	int port = sc->sc_iobase;
   2996 	u_char dmac;
   2997 	DMAPRINTF(("gus_dma_input called\n"));
   2998 
   2999 	/*
   3000 	 * Sample SIZE bytes of data from the card, into buffer at BUF.
   3001 	 */
   3002 
   3003 	if (sc->sc_precision == 16)
   3004 	    return EINVAL;		/* XXX */
   3005 
   3006 	/* set DMA modes */
   3007 	dmac = GUSMASK_SAMPLE_IRQ|GUSMASK_SAMPLE_START;
   3008 	if (sc->sc_recdrq >= 4)
   3009 		dmac |= GUSMASK_SAMPLE_DATA16;
   3010 	if (sc->sc_encoding == AUDIO_ENCODING_ULAW ||
   3011 	    sc->sc_encoding == AUDIO_ENCODING_ALAW ||
   3012 	    sc->sc_encoding == AUDIO_ENCODING_ULINEAR_LE ||
   3013 	    sc->sc_encoding == AUDIO_ENCODING_ULINEAR_BE)
   3014 	    dmac |= GUSMASK_SAMPLE_INVBIT;
   3015 	if (sc->sc_channels == 2)
   3016 	    dmac |= GUSMASK_SAMPLE_STEREO;
   3017 	isa_dmastart(sc->sc_dev.dv_parent, sc->sc_recdrq, buf, size,
   3018 	    NULL, DMAMODE_READ, BUS_DMA_NOWAIT);
   3019 
   3020 	DMAPRINTF(("gus_dma_input isa_dmastarted\n"));
   3021 	sc->sc_flags |= GUS_DMAIN_ACTIVE;
   3022 	sc->sc_dmainintr = callback;
   3023 	sc->sc_inarg = arg;
   3024 	sc->sc_dmaincnt = size;
   3025 	sc->sc_dmainaddr = buf;
   3026 
   3027 	SELECT_GUS_REG(port, GUSREG_SAMPLE_CONTROL);
   3028 	outb(port+GUS_DATA_HIGH, dmac);	/* Go! */
   3029 
   3030 
   3031 	DMAPRINTF(("gus_dma_input returning\n"));
   3032 
   3033 	return 0;
   3034 }
   3035 
   3036 STATIC int
   3037 gus_dmain_intr(sc)
   3038 	struct gus_softc *sc;
   3039 {
   3040         void (*callback) __P((void *));
   3041 	void *arg;
   3042 
   3043 	DMAPRINTF(("gus_dmain_intr called\n"));
   3044 	if (sc->sc_dmainintr) {
   3045 	    isa_dmadone(sc->sc_dev.dv_parent, sc->sc_recdrq);
   3046 	    callback = sc->sc_dmainintr;
   3047 	    arg = sc->sc_inarg;
   3048 
   3049 	    sc->sc_dmainaddr = 0;
   3050 	    sc->sc_dmaincnt = 0;
   3051 	    sc->sc_dmainintr = 0;
   3052 	    sc->sc_inarg = 0;
   3053 
   3054 	    sc->sc_flags &= ~GUS_DMAIN_ACTIVE;
   3055 	    DMAPRINTF(("calling dmain_intr callback %p(%p)\n", callback, arg));
   3056 	    (*callback)(arg);
   3057 	    return 1;
   3058 	} else {
   3059 	    DMAPRINTF(("gus_dmain_intr false?\n"));
   3060 	    return 0;			/* XXX ??? */
   3061 	}
   3062 }
   3063 
   3064 int
   3065 gusmax_halt_out_dma(addr)
   3066 	void * addr;
   3067 {
   3068 	struct ad1848_softc *sc = addr;
   3069 	return gus_halt_out_dma(sc->parent);
   3070 }
   3071 
   3072 
   3073 int
   3074 gusmax_halt_in_dma(addr)
   3075 	void * addr;
   3076 {
   3077 	struct ad1848_softc *sc = addr;
   3078 	return gus_halt_in_dma(sc->parent);
   3079 }
   3080 
   3081 int
   3082 gusmax_cont_out_dma(addr)
   3083 	void * addr;
   3084 {
   3085 	struct ad1848_softc *sc = addr;
   3086 	return gus_cont_out_dma(sc->parent);
   3087 }
   3088 
   3089 int
   3090 gusmax_cont_in_dma(addr)
   3091 	void * addr;
   3092 {
   3093 	struct ad1848_softc *sc = addr;
   3094 	return gus_cont_in_dma(sc->parent);
   3095 }
   3096 
   3097 /*
   3098  * Stop any DMA output.  Called at splgus().
   3099  */
   3100 int
   3101 gus_halt_out_dma(addr)
   3102 	void * addr;
   3103 {
   3104 	struct gus_softc *sc = addr;
   3105 	int port = sc->sc_iobase;
   3106 
   3107 	DMAPRINTF(("gus_halt_out_dma called\n"));
   3108 	/*
   3109 	 * Make sure the GUS _isn't_ setup for DMA
   3110 	 */
   3111 
   3112  	SELECT_GUS_REG(port, GUSREG_DMA_CONTROL);
   3113 	outb(sc->sc_iobase+GUS_DATA_HIGH, 0);
   3114 
   3115 	untimeout(gus_dmaout_timeout, sc);
   3116 	isa_dmaabort(sc->sc_dev.dv_parent, sc->sc_drq);
   3117 	sc->sc_flags &= ~(GUS_DMAOUT_ACTIVE|GUS_LOCKED);
   3118 	sc->sc_dmaoutintr = 0;
   3119 	sc->sc_outarg = 0;
   3120 	sc->sc_dmaoutaddr = 0;
   3121 	sc->sc_dmaoutcnt = 0;
   3122 	sc->sc_dmabuf = 0;
   3123 	sc->sc_bufcnt = 0;
   3124 	sc->sc_playbuf = -1;
   3125 	/* also stop playing */
   3126 	gus_stop_voice(sc, GUS_VOICE_LEFT, 1);
   3127 	gus_stop_voice(sc, GUS_VOICE_RIGHT, 0);
   3128 
   3129 	return 0;
   3130 }
   3131 
   3132 /*
   3133  * Stop any DMA output.  Called at splgus().
   3134  */
   3135 int
   3136 gus_halt_in_dma(addr)
   3137 	void * addr;
   3138 {
   3139 	struct gus_softc *sc = addr;
   3140 	int port = sc->sc_iobase;
   3141 	DMAPRINTF(("gus_halt_in_dma called\n"));
   3142 
   3143 	/*
   3144 	 * Make sure the GUS _isn't_ setup for DMA
   3145 	 */
   3146 
   3147  	SELECT_GUS_REG(port, GUSREG_SAMPLE_CONTROL);
   3148 	outb(port+GUS_DATA_HIGH,
   3149 	     inb(port+GUS_DATA_HIGH) & ~(GUSMASK_SAMPLE_START|GUSMASK_SAMPLE_IRQ));
   3150 
   3151 	isa_dmaabort(sc->sc_dev.dv_parent, sc->sc_recdrq);
   3152 	sc->sc_flags &= ~GUS_DMAIN_ACTIVE;
   3153 	sc->sc_dmainintr = 0;
   3154 	sc->sc_inarg = 0;
   3155 	sc->sc_dmainaddr = 0;
   3156 	sc->sc_dmaincnt = 0;
   3157 
   3158 	return 0;
   3159 }
   3160 
   3161 int
   3162 gus_cont_out_dma(addr)
   3163 	void * addr;
   3164 {
   3165 	DPRINTF(("gus_cont_out_dma called\n"));
   3166 	return EOPNOTSUPP;
   3167 }
   3168 
   3169 int
   3170 gus_cont_in_dma(addr)
   3171 	void * addr;
   3172 {
   3173 	DPRINTF(("gus_cont_in_dma called\n"));
   3174 	return EOPNOTSUPP;
   3175 }
   3176 
   3177 
   3178 STATIC __inline int
   3179 gus_to_vol(cp, vol)
   3180 	mixer_ctrl_t *cp;
   3181 	struct ad1848_volume *vol;
   3182 {
   3183 	if (cp->un.value.num_channels == 1) {
   3184 		vol->left = vol->right = cp->un.value.level[AUDIO_MIXER_LEVEL_MONO];
   3185 		return(1);
   3186 	}
   3187 	else if (cp->un.value.num_channels == 2) {
   3188 		vol->left  = cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT];
   3189 		vol->right = cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT];
   3190 		return(1);
   3191 	}
   3192 	return(0);
   3193 }
   3194 
   3195 STATIC __inline int
   3196 gus_from_vol(cp, vol)
   3197 	mixer_ctrl_t *cp;
   3198 	struct ad1848_volume *vol;
   3199 {
   3200 	if (cp->un.value.num_channels == 1) {
   3201 		cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = vol->left;
   3202 		return(1);
   3203 	}
   3204 	else if (cp->un.value.num_channels == 2) {
   3205 		cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = vol->left;
   3206 		cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = vol->right;
   3207 		return(1);
   3208 	}
   3209 	return(0);
   3210 }
   3211 
   3212 STATIC int
   3213 gusmax_mixer_get_port(addr, cp)
   3214 	void *addr;
   3215 	mixer_ctrl_t *cp;
   3216 {
   3217 	struct ad1848_softc *ac = addr;
   3218 	struct gus_softc *sc = ac->parent;
   3219 	struct ad1848_volume vol;
   3220 	int error = EINVAL;
   3221 
   3222 	DPRINTF(("gusmax_mixer_get_port: port=%d\n", cp->dev));
   3223 
   3224 	switch (cp->dev) {
   3225 #if 0 /* use mono level instead */
   3226 	case GUSMAX_MIC_IN_LVL:	/* Microphone */
   3227 		if (cp->type == AUDIO_MIXER_VALUE) {
   3228 			error = ad1848_get_mic_gain(ac, &vol);
   3229 			if (!error)
   3230 				gus_from_vol(cp, &vol);
   3231 		}
   3232 		break;
   3233 #endif
   3234 
   3235 	case GUSMAX_DAC_LVL:		/* dac out */
   3236 		if (cp->type == AUDIO_MIXER_VALUE) {
   3237 			error = ad1848_get_aux1_gain(ac, &vol);
   3238 			if (!error)
   3239 				gus_from_vol(cp, &vol);
   3240 		}
   3241 		break;
   3242 
   3243 	case GUSMAX_LINE_IN_LVL:	/* line in */
   3244 		if (cp->type == AUDIO_MIXER_VALUE) {
   3245 			error = cs4231_get_linein_gain(ac, &vol);
   3246 			if (!error)
   3247 				gus_from_vol(cp, &vol);
   3248 		}
   3249 		break;
   3250 
   3251 	case GUSMAX_MONO_LVL:	/* mono */
   3252 		if (cp->type == AUDIO_MIXER_VALUE &&
   3253 		    cp->un.value.num_channels == 1) {
   3254 			error = cs4231_get_mono_gain(ac, &vol);
   3255 			if (!error)
   3256 				gus_from_vol(cp, &vol);
   3257 		}
   3258 		break;
   3259 
   3260 	case GUSMAX_CD_LVL:	/* CD */
   3261 		if (cp->type == AUDIO_MIXER_VALUE) {
   3262 			error = ad1848_get_aux2_gain(ac, &vol);
   3263 			if (!error)
   3264 				gus_from_vol(cp, &vol);
   3265 		}
   3266 		break;
   3267 
   3268 	case GUSMAX_MONITOR_LVL:	/* monitor level */
   3269 		if (cp->type == AUDIO_MIXER_VALUE &&
   3270 		    cp->un.value.num_channels == 1) {
   3271 			error = ad1848_get_mon_gain(ac, &vol);
   3272 			if (!error)
   3273 				cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
   3274 					vol.left;
   3275 		}
   3276 		break;
   3277 
   3278 	case GUSMAX_OUT_LVL:	/* output level */
   3279 		if (cp->type == AUDIO_MIXER_VALUE) {
   3280 			error = ad1848_get_out_gain(ac, &vol);
   3281 			if (!error)
   3282 				gus_from_vol(cp, &vol);
   3283 		}
   3284 		break;
   3285 
   3286 	case GUSMAX_SPEAKER_LVL:	/* fake speaker for mute naming */
   3287 		if (cp->type == AUDIO_MIXER_VALUE) {
   3288 			if (sc->sc_mixcontrol & GUSMASK_LINE_OUT)
   3289 				vol.left = vol.right = AUDIO_MAX_GAIN;
   3290 			else
   3291 				vol.left = vol.right = AUDIO_MIN_GAIN;
   3292 			error = 0;
   3293 			gus_from_vol(cp, &vol);
   3294 		}
   3295 		break;
   3296 
   3297 	case GUSMAX_LINE_IN_MUTE:
   3298 		if (cp->type == AUDIO_MIXER_ENUM) {
   3299 			cp->un.ord = ac->line_mute;
   3300 			error = 0;
   3301 		}
   3302 		break;
   3303 
   3304 
   3305 	case GUSMAX_DAC_MUTE:
   3306 		if (cp->type == AUDIO_MIXER_ENUM) {
   3307 			cp->un.ord = ac->aux1_mute;
   3308 			error = 0;
   3309 		}
   3310 		break;
   3311 
   3312 	case GUSMAX_CD_MUTE:
   3313 		if (cp->type == AUDIO_MIXER_ENUM) {
   3314 			cp->un.ord = ac->aux2_mute;
   3315 			error = 0;
   3316 		}
   3317 		break;
   3318 
   3319 	case GUSMAX_MONO_MUTE:
   3320 		if (cp->type == AUDIO_MIXER_ENUM) {
   3321 			cp->un.ord = ac->mono_mute;
   3322 			error = 0;
   3323 		}
   3324 		break;
   3325 
   3326 	case GUSMAX_MONITOR_MUTE:
   3327 		if (cp->type == AUDIO_MIXER_ENUM) {
   3328 			cp->un.ord = ac->mon_mute;
   3329 			error = 0;
   3330 		}
   3331 		break;
   3332 
   3333 	case GUSMAX_SPEAKER_MUTE:
   3334 		if (cp->type == AUDIO_MIXER_ENUM) {
   3335 			cp->un.ord = sc->sc_mixcontrol & GUSMASK_LINE_OUT ? 1 : 0;
   3336 			error = 0;
   3337 		}
   3338 		break;
   3339 
   3340 	case GUSMAX_REC_LVL:		/* record level */
   3341 		if (cp->type == AUDIO_MIXER_VALUE) {
   3342 			error = ad1848_get_rec_gain(ac, &vol);
   3343 			if (!error)
   3344 				gus_from_vol(cp, &vol);
   3345 		}
   3346 		break;
   3347 
   3348 	case GUSMAX_RECORD_SOURCE:
   3349 		if (cp->type == AUDIO_MIXER_ENUM) {
   3350 			cp->un.ord = ad1848_get_rec_port(ac);
   3351 			error = 0;
   3352 		}
   3353 		break;
   3354 
   3355 	default:
   3356 		error = ENXIO;
   3357 		break;
   3358 	}
   3359 
   3360 	return(error);
   3361 }
   3362 
   3363 STATIC int
   3364 gus_mixer_get_port(addr, cp)
   3365 	void *addr;
   3366 	mixer_ctrl_t *cp;
   3367 {
   3368 	struct gus_softc *sc = addr;
   3369 	struct ics2101_softc *ic = &sc->sc_mixer;
   3370 	struct ad1848_volume vol;
   3371 	int error = EINVAL;
   3372 
   3373 	DPRINTF(("gus_mixer_get_port: dev=%d type=%d\n", cp->dev, cp->type));
   3374 
   3375 	if (!HAS_MIXER(sc) && cp->dev > GUSICS_MASTER_MUTE)
   3376 		return ENXIO;
   3377 
   3378 	switch (cp->dev) {
   3379 
   3380 	case GUSICS_MIC_IN_MUTE:	/* Microphone */
   3381 		if (cp->type == AUDIO_MIXER_ENUM) {
   3382 			if (HAS_MIXER(sc))
   3383 				cp->un.ord = ic->sc_mute[GUSMIX_CHAN_MIC][ICSMIX_LEFT];
   3384 			else
   3385 				cp->un.ord =
   3386 				    sc->sc_mixcontrol & GUSMASK_MIC_IN ? 0 : 1;
   3387 			error = 0;
   3388 		}
   3389 		break;
   3390 
   3391 	case GUSICS_LINE_IN_MUTE:
   3392 		if (cp->type == AUDIO_MIXER_ENUM) {
   3393 			if (HAS_MIXER(sc))
   3394 				cp->un.ord = ic->sc_mute[GUSMIX_CHAN_LINE][ICSMIX_LEFT];
   3395 			else
   3396 				cp->un.ord =
   3397 				    sc->sc_mixcontrol & GUSMASK_LINE_IN ? 1 : 0;
   3398 			error = 0;
   3399 		}
   3400 		break;
   3401 
   3402 	case GUSICS_MASTER_MUTE:
   3403 		if (cp->type == AUDIO_MIXER_ENUM) {
   3404 			if (HAS_MIXER(sc))
   3405 				cp->un.ord = ic->sc_mute[GUSMIX_CHAN_MASTER][ICSMIX_LEFT];
   3406 			else
   3407 				cp->un.ord =
   3408 				    sc->sc_mixcontrol & GUSMASK_LINE_OUT ? 1 : 0;
   3409 			error = 0;
   3410 		}
   3411 		break;
   3412 
   3413 	case GUSICS_DAC_MUTE:
   3414 		if (cp->type == AUDIO_MIXER_ENUM) {
   3415 			cp->un.ord = ic->sc_mute[GUSMIX_CHAN_DAC][ICSMIX_LEFT];
   3416 			error = 0;
   3417 		}
   3418 		break;
   3419 
   3420 	case GUSICS_CD_MUTE:
   3421 		if (cp->type == AUDIO_MIXER_ENUM) {
   3422 			cp->un.ord = ic->sc_mute[GUSMIX_CHAN_CD][ICSMIX_LEFT];
   3423 			error = 0;
   3424 		}
   3425 		break;
   3426 
   3427 	case GUSICS_MASTER_LVL:
   3428 		if (cp->type == AUDIO_MIXER_VALUE) {
   3429 			vol.left = ic->sc_setting[GUSMIX_CHAN_MASTER][ICSMIX_LEFT];
   3430 			vol.right = ic->sc_setting[GUSMIX_CHAN_MASTER][ICSMIX_RIGHT];
   3431 			if (gus_from_vol(cp, &vol))
   3432 				error = 0;
   3433 		}
   3434 		break;
   3435 
   3436 	case GUSICS_MIC_IN_LVL:	/* Microphone */
   3437 		if (cp->type == AUDIO_MIXER_VALUE) {
   3438 			vol.left = ic->sc_setting[GUSMIX_CHAN_MIC][ICSMIX_LEFT];
   3439 			vol.right = ic->sc_setting[GUSMIX_CHAN_MIC][ICSMIX_RIGHT];
   3440 			if (gus_from_vol(cp, &vol))
   3441 				error = 0;
   3442 		}
   3443 		break;
   3444 
   3445 	case GUSICS_LINE_IN_LVL:	/* line in */
   3446 		if (cp->type == AUDIO_MIXER_VALUE) {
   3447 			vol.left = ic->sc_setting[GUSMIX_CHAN_LINE][ICSMIX_LEFT];
   3448 			vol.right = ic->sc_setting[GUSMIX_CHAN_LINE][ICSMIX_RIGHT];
   3449 			if (gus_from_vol(cp, &vol))
   3450 				error = 0;
   3451 		}
   3452 		break;
   3453 
   3454 
   3455 	case GUSICS_CD_LVL:
   3456 		if (cp->type == AUDIO_MIXER_VALUE) {
   3457 			vol.left = ic->sc_setting[GUSMIX_CHAN_CD][ICSMIX_LEFT];
   3458 			vol.right = ic->sc_setting[GUSMIX_CHAN_CD][ICSMIX_RIGHT];
   3459 			if (gus_from_vol(cp, &vol))
   3460 				error = 0;
   3461 		}
   3462 		break;
   3463 
   3464 	case GUSICS_DAC_LVL:		/* dac out */
   3465 		if (cp->type == AUDIO_MIXER_VALUE) {
   3466 			vol.left = ic->sc_setting[GUSMIX_CHAN_DAC][ICSMIX_LEFT];
   3467 			vol.right = ic->sc_setting[GUSMIX_CHAN_DAC][ICSMIX_RIGHT];
   3468 			if (gus_from_vol(cp, &vol))
   3469 				error = 0;
   3470 		}
   3471 		break;
   3472 
   3473 
   3474 	case GUSICS_RECORD_SOURCE:
   3475 		if (cp->type == AUDIO_MIXER_ENUM) {
   3476 			/* Can't set anything else useful, sigh. */
   3477 			 cp->un.ord = 0;
   3478 		}
   3479 		break;
   3480 
   3481 	default:
   3482 		return ENXIO;
   3483 	    /*NOTREACHED*/
   3484 	}
   3485 	return error;
   3486 }
   3487 
   3488 STATIC void
   3489 gusics_master_mute(ic, mute)
   3490 	struct ics2101_softc *ic;
   3491 	int mute;
   3492 {
   3493 	ics2101_mix_mute(ic, GUSMIX_CHAN_MASTER, ICSMIX_LEFT, mute);
   3494 	ics2101_mix_mute(ic, GUSMIX_CHAN_MASTER, ICSMIX_RIGHT, mute);
   3495 }
   3496 
   3497 STATIC void
   3498 gusics_mic_mute(ic, mute)
   3499 	struct ics2101_softc *ic;
   3500 	int mute;
   3501 {
   3502 	ics2101_mix_mute(ic, GUSMIX_CHAN_MIC, ICSMIX_LEFT, mute);
   3503 	ics2101_mix_mute(ic, GUSMIX_CHAN_MIC, ICSMIX_RIGHT, mute);
   3504 }
   3505 
   3506 STATIC void
   3507 gusics_linein_mute(ic, mute)
   3508 	struct ics2101_softc *ic;
   3509 	int mute;
   3510 {
   3511 	ics2101_mix_mute(ic, GUSMIX_CHAN_LINE, ICSMIX_LEFT, mute);
   3512 	ics2101_mix_mute(ic, GUSMIX_CHAN_LINE, ICSMIX_RIGHT, mute);
   3513 }
   3514 
   3515 STATIC void
   3516 gusics_cd_mute(ic, mute)
   3517 	struct ics2101_softc *ic;
   3518 	int mute;
   3519 {
   3520 	ics2101_mix_mute(ic, GUSMIX_CHAN_CD, ICSMIX_LEFT, mute);
   3521 	ics2101_mix_mute(ic, GUSMIX_CHAN_CD, ICSMIX_RIGHT, mute);
   3522 }
   3523 
   3524 STATIC void
   3525 gusics_dac_mute(ic, mute)
   3526 	struct ics2101_softc *ic;
   3527 	int mute;
   3528 {
   3529 	ics2101_mix_mute(ic, GUSMIX_CHAN_DAC, ICSMIX_LEFT, mute);
   3530 	ics2101_mix_mute(ic, GUSMIX_CHAN_DAC, ICSMIX_RIGHT, mute);
   3531 }
   3532 
   3533 STATIC int
   3534 gusmax_mixer_set_port(addr, cp)
   3535 	void *addr;
   3536 	mixer_ctrl_t *cp;
   3537 {
   3538 	struct ad1848_softc *ac = addr;
   3539 	struct gus_softc *sc = ac->parent;
   3540 	struct ad1848_volume vol;
   3541 	int error = EINVAL;
   3542 
   3543 	DPRINTF(("gusmax_mixer_set_port: dev=%d type=%d\n", cp->dev, cp->type));
   3544 
   3545 	switch (cp->dev) {
   3546 #if 0
   3547 	case GUSMAX_MIC_IN_LVL:	/* Microphone */
   3548 		if (cp->type == AUDIO_MIXER_VALUE &&
   3549 		    cp->un.value.num_channels == 1) {
   3550 			/* XXX enable/disable pre-MUX fixed gain */
   3551 			if (gus_to_vol(cp, &vol))
   3552 				error = ad1848_set_mic_gain(ac, &vol);
   3553 		}
   3554 		break;
   3555 #endif
   3556 
   3557 	case GUSMAX_DAC_LVL:		/* dac out */
   3558 		if (cp->type == AUDIO_MIXER_VALUE) {
   3559 			if (gus_to_vol(cp, &vol))
   3560 				error = ad1848_set_aux1_gain(ac, &vol);
   3561 		}
   3562 		break;
   3563 
   3564 	case GUSMAX_LINE_IN_LVL:	/* line in */
   3565 		if (cp->type == AUDIO_MIXER_VALUE) {
   3566 			if (gus_to_vol(cp, &vol))
   3567 				error = cs4231_set_linein_gain(ac, &vol);
   3568 		}
   3569 		break;
   3570 
   3571 	case GUSMAX_MONO_LVL:	/* mic/mono in */
   3572 		if (cp->type == AUDIO_MIXER_VALUE &&
   3573 		    cp->un.value.num_channels == 1) {
   3574 			if (gus_to_vol(cp, &vol))
   3575 				error = cs4231_set_mono_gain(ac, &vol);
   3576 		}
   3577 		break;
   3578 
   3579 	case GUSMAX_CD_LVL:	/* CD: AUX2 */
   3580 		if (cp->type == AUDIO_MIXER_VALUE) {
   3581 			if (gus_to_vol(cp, &vol))
   3582 				error = ad1848_set_aux2_gain(ac, &vol);
   3583 		}
   3584 		break;
   3585 
   3586 	case GUSMAX_MONITOR_LVL:
   3587 		if (cp->type == AUDIO_MIXER_VALUE &&
   3588 		    cp->un.value.num_channels == 1) {
   3589 			vol.left  = cp->un.value.level[AUDIO_MIXER_LEVEL_MONO];
   3590 			error = ad1848_set_mon_gain(ac, &vol);
   3591 		}
   3592 		break;
   3593 
   3594 	case GUSMAX_OUT_LVL:	/* output volume */
   3595 		if (cp->type == AUDIO_MIXER_VALUE) {
   3596 			if (gus_to_vol(cp, &vol))
   3597 				error = ad1848_set_out_gain(ac, &vol);
   3598 		}
   3599 		break;
   3600 
   3601 	case GUSMAX_SPEAKER_LVL:
   3602 		if (cp->type == AUDIO_MIXER_VALUE &&
   3603 		    cp->un.value.num_channels == 1) {
   3604 			if (gus_to_vol(cp, &vol)) {
   3605 				gus_speaker_ctl(sc, vol.left > AUDIO_MIN_GAIN ?
   3606 						SPKR_ON : SPKR_OFF);
   3607 				error = 0;
   3608 			}
   3609 		}
   3610 		break;
   3611 
   3612 	case GUSMAX_LINE_IN_MUTE:
   3613 		if (cp->type == AUDIO_MIXER_ENUM) {
   3614 			ac->line_mute = cp->un.ord ? 1 : 0;
   3615 			DPRINTF(("line mute %d\n", cp->un.ord));
   3616 			cs4231_mute_line(ac, ac->line_mute);
   3617 			gus_linein_ctl(sc, ac->line_mute ? SPKR_OFF : SPKR_ON);
   3618 			error = 0;
   3619 		}
   3620 		break;
   3621 
   3622 	case GUSMAX_DAC_MUTE:
   3623 		if (cp->type == AUDIO_MIXER_ENUM) {
   3624 			ac->aux1_mute = cp->un.ord ? 1 : 0;
   3625 			DPRINTF(("dac mute %d\n", cp->un.ord));
   3626 			ad1848_mute_aux1(ac, ac->aux1_mute);
   3627 			error = 0;
   3628 		}
   3629 		break;
   3630 
   3631 	case GUSMAX_CD_MUTE:
   3632 		if (cp->type == AUDIO_MIXER_ENUM) {
   3633 			ac->aux2_mute = cp->un.ord ? 1 : 0;
   3634 			DPRINTF(("cd mute %d\n", cp->un.ord));
   3635 			ad1848_mute_aux2(ac, ac->aux2_mute);
   3636 			error = 0;
   3637 		}
   3638 		break;
   3639 
   3640 	case GUSMAX_MONO_MUTE:	/* Microphone */
   3641 		if (cp->type == AUDIO_MIXER_ENUM) {
   3642 			ac->mono_mute = cp->un.ord ? 1 : 0;
   3643 			DPRINTF(("mono mute %d\n", cp->un.ord));
   3644 			cs4231_mute_mono(ac, ac->mono_mute);
   3645 			gus_mic_ctl(sc, ac->mono_mute ? SPKR_OFF : SPKR_ON);
   3646 			error = 0;
   3647 		}
   3648 		break;
   3649 
   3650 	case GUSMAX_MONITOR_MUTE:
   3651 		if (cp->type == AUDIO_MIXER_ENUM) {
   3652 			ac->mon_mute = cp->un.ord ? 1 : 0;
   3653 			DPRINTF(("mono mute %d\n", cp->un.ord));
   3654 			cs4231_mute_monitor(ac, ac->mon_mute);
   3655 			error = 0;
   3656 		}
   3657 		break;
   3658 
   3659 	case GUSMAX_SPEAKER_MUTE:
   3660 		if (cp->type == AUDIO_MIXER_ENUM) {
   3661 			gus_speaker_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON);
   3662 			error = 0;
   3663 		}
   3664 		break;
   3665 
   3666 	case GUSMAX_REC_LVL:		/* record level */
   3667 		if (cp->type == AUDIO_MIXER_VALUE) {
   3668 			if (gus_to_vol(cp, &vol))
   3669 				error = ad1848_set_rec_gain(ac, &vol);
   3670 		}
   3671 		break;
   3672 
   3673 	case GUSMAX_RECORD_SOURCE:
   3674 		if (cp->type == AUDIO_MIXER_ENUM) {
   3675 			error = ad1848_set_rec_port(ac, cp->un.ord);
   3676 		}
   3677 		break;
   3678 
   3679 	default:
   3680 		return ENXIO;
   3681 	    /*NOTREACHED*/
   3682     }
   3683     return error;
   3684 }
   3685 
   3686 STATIC int
   3687 gus_mixer_set_port(addr, cp)
   3688 	void *addr;
   3689 	mixer_ctrl_t *cp;
   3690 {
   3691 	struct gus_softc *sc = addr;
   3692 	struct ics2101_softc *ic = &sc->sc_mixer;
   3693 	struct ad1848_volume vol;
   3694 	int error = EINVAL;
   3695 
   3696 	DPRINTF(("gus_mixer_set_port: dev=%d type=%d\n", cp->dev, cp->type));
   3697 
   3698 	if (!HAS_MIXER(sc) && cp->dev > GUSICS_MASTER_MUTE)
   3699 		return ENXIO;
   3700 
   3701 	switch (cp->dev) {
   3702 
   3703 	case GUSICS_MIC_IN_MUTE:	/* Microphone */
   3704 		if (cp->type == AUDIO_MIXER_ENUM) {
   3705 			DPRINTF(("mic mute %d\n", cp->un.ord));
   3706 			if (HAS_MIXER(sc)) {
   3707 				gusics_mic_mute(ic, cp->un.ord);
   3708 			}
   3709 			gus_mic_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON);
   3710 			error = 0;
   3711 		}
   3712 		break;
   3713 
   3714 	case GUSICS_LINE_IN_MUTE:
   3715 		if (cp->type == AUDIO_MIXER_ENUM) {
   3716 			DPRINTF(("linein mute %d\n", cp->un.ord));
   3717 			if (HAS_MIXER(sc)) {
   3718 				gusics_linein_mute(ic, cp->un.ord);
   3719 			}
   3720 			gus_linein_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON);
   3721 			error = 0;
   3722 		}
   3723 		break;
   3724 
   3725 	case GUSICS_MASTER_MUTE:
   3726 		if (cp->type == AUDIO_MIXER_ENUM) {
   3727 			DPRINTF(("master mute %d\n", cp->un.ord));
   3728 			if (HAS_MIXER(sc)) {
   3729 				gusics_master_mute(ic, cp->un.ord);
   3730 			}
   3731 			gus_speaker_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON);
   3732 			error = 0;
   3733 		}
   3734 		break;
   3735 
   3736 	case GUSICS_DAC_MUTE:
   3737 		if (cp->type == AUDIO_MIXER_ENUM) {
   3738 			gusics_dac_mute(ic, cp->un.ord);
   3739 			error = 0;
   3740 		}
   3741 		break;
   3742 
   3743 	case GUSICS_CD_MUTE:
   3744 		if (cp->type == AUDIO_MIXER_ENUM) {
   3745 			gusics_cd_mute(ic, cp->un.ord);
   3746 			error = 0;
   3747 		}
   3748 		break;
   3749 
   3750 	case GUSICS_MASTER_LVL:
   3751 		if (cp->type == AUDIO_MIXER_VALUE) {
   3752 			if (gus_to_vol(cp, &vol)) {
   3753 				ics2101_mix_attenuate(ic,
   3754 						      GUSMIX_CHAN_MASTER,
   3755 						      ICSMIX_LEFT,
   3756 						      vol.left);
   3757 				ics2101_mix_attenuate(ic,
   3758 						      GUSMIX_CHAN_MASTER,
   3759 						      ICSMIX_RIGHT,
   3760 						      vol.right);
   3761 				error = 0;
   3762 			}
   3763 		}
   3764 		break;
   3765 
   3766 	case GUSICS_MIC_IN_LVL:	/* Microphone */
   3767 		if (cp->type == AUDIO_MIXER_VALUE) {
   3768 			if (gus_to_vol(cp, &vol)) {
   3769 				ics2101_mix_attenuate(ic,
   3770 						      GUSMIX_CHAN_MIC,
   3771 						      ICSMIX_LEFT,
   3772 						      vol.left);
   3773 				ics2101_mix_attenuate(ic,
   3774 						      GUSMIX_CHAN_MIC,
   3775 						      ICSMIX_RIGHT,
   3776 						      vol.right);
   3777 				error = 0;
   3778 			}
   3779 		}
   3780 		break;
   3781 
   3782 	case GUSICS_LINE_IN_LVL:	/* line in */
   3783 		if (cp->type == AUDIO_MIXER_VALUE) {
   3784 			if (gus_to_vol(cp, &vol)) {
   3785 				ics2101_mix_attenuate(ic,
   3786 						      GUSMIX_CHAN_LINE,
   3787 						      ICSMIX_LEFT,
   3788 						      vol.left);
   3789 				ics2101_mix_attenuate(ic,
   3790 						      GUSMIX_CHAN_LINE,
   3791 						      ICSMIX_RIGHT,
   3792 						      vol.right);
   3793 				error = 0;
   3794 			}
   3795 		}
   3796 		break;
   3797 
   3798 
   3799 	case GUSICS_CD_LVL:
   3800 		if (cp->type == AUDIO_MIXER_VALUE) {
   3801 			if (gus_to_vol(cp, &vol)) {
   3802 				ics2101_mix_attenuate(ic,
   3803 						      GUSMIX_CHAN_CD,
   3804 						      ICSMIX_LEFT,
   3805 						      vol.left);
   3806 				ics2101_mix_attenuate(ic,
   3807 						      GUSMIX_CHAN_CD,
   3808 						      ICSMIX_RIGHT,
   3809 						      vol.right);
   3810 				error = 0;
   3811 			}
   3812 		}
   3813 		break;
   3814 
   3815 	case GUSICS_DAC_LVL:		/* dac out */
   3816 		if (cp->type == AUDIO_MIXER_VALUE) {
   3817 			if (gus_to_vol(cp, &vol)) {
   3818 				ics2101_mix_attenuate(ic,
   3819 						      GUSMIX_CHAN_DAC,
   3820 						      ICSMIX_LEFT,
   3821 						      vol.left);
   3822 				ics2101_mix_attenuate(ic,
   3823 						      GUSMIX_CHAN_DAC,
   3824 						      ICSMIX_RIGHT,
   3825 						      vol.right);
   3826 				error = 0;
   3827 			}
   3828 		}
   3829 		break;
   3830 
   3831 
   3832 	case GUSICS_RECORD_SOURCE:
   3833 		if (cp->type == AUDIO_MIXER_ENUM && cp->un.ord == 0) {
   3834 			/* Can't set anything else useful, sigh. */
   3835 			error = 0;
   3836 		}
   3837 		break;
   3838 
   3839 	default:
   3840 		return ENXIO;
   3841 	    /*NOTREACHED*/
   3842 	}
   3843 	return error;
   3844 }
   3845 
   3846 STATIC int
   3847 gus_get_props(addr)
   3848 	void *addr;
   3849 {
   3850 	struct gus_softc *sc = addr;
   3851 	return sc->sc_recdrq == sc->sc_drq ? 0 : AUDIO_PROP_FULLDUPLEX;
   3852 }
   3853 
   3854 STATIC int
   3855 gusmax_get_props(addr)
   3856 	void *addr;
   3857 {
   3858 	struct ad1848_softc *ac = addr;
   3859 	return gus_get_props(ac->parent);
   3860 }
   3861 
   3862 STATIC int
   3863 gusmax_mixer_query_devinfo(addr, dip)
   3864 	void *addr;
   3865 	mixer_devinfo_t *dip;
   3866 {
   3867 	DPRINTF(("gusmax_query_devinfo: index=%d\n", dip->index));
   3868 
   3869 	switch(dip->index) {
   3870 #if 0
   3871     case GUSMAX_MIC_IN_LVL:	/* Microphone */
   3872 	dip->type = AUDIO_MIXER_VALUE;
   3873 	dip->mixer_class = GUSMAX_INPUT_CLASS;
   3874 	dip->prev = AUDIO_MIXER_LAST;
   3875 	dip->next = GUSMAX_MIC_IN_MUTE;
   3876 	strcpy(dip->label.name, AudioNmicrophone);
   3877 	dip->un.v.num_channels = 2;
   3878 	strcpy(dip->un.v.units.name, AudioNvolume);
   3879 	break;
   3880 #endif
   3881 
   3882     case GUSMAX_MONO_LVL:	/* mono/microphone mixer */
   3883 	dip->type = AUDIO_MIXER_VALUE;
   3884 	dip->mixer_class = GUSMAX_INPUT_CLASS;
   3885 	dip->prev = AUDIO_MIXER_LAST;
   3886 	dip->next = GUSMAX_MONO_MUTE;
   3887 	strcpy(dip->label.name, AudioNmicrophone);
   3888 	dip->un.v.num_channels = 1;
   3889 	strcpy(dip->un.v.units.name, AudioNvolume);
   3890 	break;
   3891 
   3892     case GUSMAX_DAC_LVL:		/*  dacout */
   3893 	dip->type = AUDIO_MIXER_VALUE;
   3894 	dip->mixer_class = GUSMAX_INPUT_CLASS;
   3895 	dip->prev = AUDIO_MIXER_LAST;
   3896 	dip->next = GUSMAX_DAC_MUTE;
   3897 	strcpy(dip->label.name, AudioNdac);
   3898 	dip->un.v.num_channels = 2;
   3899 	strcpy(dip->un.v.units.name, AudioNvolume);
   3900 	break;
   3901 
   3902     case GUSMAX_LINE_IN_LVL:	/* line */
   3903 	dip->type = AUDIO_MIXER_VALUE;
   3904 	dip->mixer_class = GUSMAX_INPUT_CLASS;
   3905 	dip->prev = AUDIO_MIXER_LAST;
   3906 	dip->next = GUSMAX_LINE_IN_MUTE;
   3907 	strcpy(dip->label.name, AudioNline);
   3908 	dip->un.v.num_channels = 2;
   3909 	strcpy(dip->un.v.units.name, AudioNvolume);
   3910 	break;
   3911 
   3912     case GUSMAX_CD_LVL:		/* cd */
   3913 	dip->type = AUDIO_MIXER_VALUE;
   3914 	dip->mixer_class = GUSMAX_INPUT_CLASS;
   3915 	dip->prev = AUDIO_MIXER_LAST;
   3916 	dip->next = GUSMAX_CD_MUTE;
   3917 	strcpy(dip->label.name, AudioNcd);
   3918 	dip->un.v.num_channels = 2;
   3919 	strcpy(dip->un.v.units.name, AudioNvolume);
   3920 	break;
   3921 
   3922 
   3923     case GUSMAX_MONITOR_LVL:	/* monitor level */
   3924 	dip->type = AUDIO_MIXER_VALUE;
   3925 	dip->mixer_class = GUSMAX_MONITOR_CLASS;
   3926 	dip->next = GUSMAX_MONITOR_MUTE;
   3927 	dip->prev = AUDIO_MIXER_LAST;
   3928 	strcpy(dip->label.name, AudioNmonitor);
   3929 	dip->un.v.num_channels = 1;
   3930 	strcpy(dip->un.v.units.name, AudioNvolume);
   3931 	break;
   3932 
   3933     case GUSMAX_OUT_LVL:		/* cs4231 output volume: not useful? */
   3934 	dip->type = AUDIO_MIXER_VALUE;
   3935 	dip->mixer_class = GUSMAX_MONITOR_CLASS;
   3936 	dip->prev = dip->next = AUDIO_MIXER_LAST;
   3937 	strcpy(dip->label.name, AudioNoutput);
   3938 	dip->un.v.num_channels = 2;
   3939 	strcpy(dip->un.v.units.name, AudioNvolume);
   3940 	break;
   3941 
   3942     case GUSMAX_SPEAKER_LVL:		/* fake speaker volume */
   3943 	dip->type = AUDIO_MIXER_VALUE;
   3944 	dip->mixer_class = GUSMAX_MONITOR_CLASS;
   3945 	dip->prev = AUDIO_MIXER_LAST;
   3946 	dip->next = GUSMAX_SPEAKER_MUTE;
   3947 	strcpy(dip->label.name, AudioNspeaker);
   3948 	dip->un.v.num_channels = 2;
   3949 	strcpy(dip->un.v.units.name, AudioNvolume);
   3950 	break;
   3951 
   3952     case GUSMAX_LINE_IN_MUTE:
   3953 	dip->mixer_class = GUSMAX_INPUT_CLASS;
   3954 	dip->type = AUDIO_MIXER_ENUM;
   3955 	dip->prev = GUSMAX_LINE_IN_LVL;
   3956 	dip->next = AUDIO_MIXER_LAST;
   3957 	goto mute;
   3958 
   3959     case GUSMAX_DAC_MUTE:
   3960 	dip->mixer_class = GUSMAX_INPUT_CLASS;
   3961 	dip->type = AUDIO_MIXER_ENUM;
   3962 	dip->prev = GUSMAX_DAC_LVL;
   3963 	dip->next = AUDIO_MIXER_LAST;
   3964 	goto mute;
   3965 
   3966     case GUSMAX_CD_MUTE:
   3967 	dip->mixer_class = GUSMAX_INPUT_CLASS;
   3968 	dip->type = AUDIO_MIXER_ENUM;
   3969 	dip->prev = GUSMAX_CD_LVL;
   3970 	dip->next = AUDIO_MIXER_LAST;
   3971 	goto mute;
   3972 
   3973     case GUSMAX_MONO_MUTE:
   3974 	dip->mixer_class = GUSMAX_INPUT_CLASS;
   3975 	dip->type = AUDIO_MIXER_ENUM;
   3976 	dip->prev = GUSMAX_MONO_LVL;
   3977 	dip->next = AUDIO_MIXER_LAST;
   3978 	goto mute;
   3979 
   3980     case GUSMAX_MONITOR_MUTE:
   3981 	dip->mixer_class = GUSMAX_OUTPUT_CLASS;
   3982 	dip->type = AUDIO_MIXER_ENUM;
   3983 	dip->prev = GUSMAX_MONITOR_LVL;
   3984 	dip->next = AUDIO_MIXER_LAST;
   3985 	goto mute;
   3986 
   3987     case GUSMAX_SPEAKER_MUTE:
   3988 	dip->mixer_class = GUSMAX_OUTPUT_CLASS;
   3989 	dip->type = AUDIO_MIXER_ENUM;
   3990 	dip->prev = GUSMAX_SPEAKER_LVL;
   3991 	dip->next = AUDIO_MIXER_LAST;
   3992     mute:
   3993 	strcpy(dip->label.name, AudioNmute);
   3994 	dip->un.e.num_mem = 2;
   3995 	strcpy(dip->un.e.member[0].label.name, AudioNoff);
   3996 	dip->un.e.member[0].ord = 0;
   3997 	strcpy(dip->un.e.member[1].label.name, AudioNon);
   3998 	dip->un.e.member[1].ord = 1;
   3999 	break;
   4000 
   4001     case GUSMAX_REC_LVL:	/* record level */
   4002 	dip->type = AUDIO_MIXER_VALUE;
   4003 	dip->mixer_class = GUSMAX_RECORD_CLASS;
   4004 	dip->prev = AUDIO_MIXER_LAST;
   4005 	dip->next = GUSMAX_RECORD_SOURCE;
   4006 	strcpy(dip->label.name, AudioNrecord);
   4007 	dip->un.v.num_channels = 2;
   4008 	strcpy(dip->un.v.units.name, AudioNvolume);
   4009 	break;
   4010 
   4011     case GUSMAX_RECORD_SOURCE:
   4012 	dip->mixer_class = GUSMAX_RECORD_CLASS;
   4013 	dip->type = AUDIO_MIXER_ENUM;
   4014 	dip->prev = GUSMAX_REC_LVL;
   4015 	dip->next = AUDIO_MIXER_LAST;
   4016 	strcpy(dip->label.name, AudioNsource);
   4017 	dip->un.e.num_mem = 4;
   4018 	strcpy(dip->un.e.member[0].label.name, AudioNoutput);
   4019 	dip->un.e.member[0].ord = DAC_IN_PORT;
   4020 	strcpy(dip->un.e.member[1].label.name, AudioNmicrophone);
   4021 	dip->un.e.member[1].ord = MIC_IN_PORT;
   4022 	strcpy(dip->un.e.member[2].label.name, AudioNdac);
   4023 	dip->un.e.member[2].ord = AUX1_IN_PORT;
   4024 	strcpy(dip->un.e.member[3].label.name, AudioNline);
   4025 	dip->un.e.member[3].ord = LINE_IN_PORT;
   4026 	break;
   4027 
   4028     case GUSMAX_INPUT_CLASS:			/* input class descriptor */
   4029 	dip->type = AUDIO_MIXER_CLASS;
   4030 	dip->mixer_class = GUSMAX_INPUT_CLASS;
   4031 	dip->next = dip->prev = AUDIO_MIXER_LAST;
   4032 	strcpy(dip->label.name, AudioCInputs);
   4033 	break;
   4034 
   4035     case GUSMAX_OUTPUT_CLASS:			/* output class descriptor */
   4036 	dip->type = AUDIO_MIXER_CLASS;
   4037 	dip->mixer_class = GUSMAX_OUTPUT_CLASS;
   4038 	dip->next = dip->prev = AUDIO_MIXER_LAST;
   4039 	strcpy(dip->label.name, AudioCOutputs);
   4040 	break;
   4041 
   4042     case GUSMAX_MONITOR_CLASS:			/* monitor class descriptor */
   4043 	dip->type = AUDIO_MIXER_CLASS;
   4044 	dip->mixer_class = GUSMAX_MONITOR_CLASS;
   4045 	dip->next = dip->prev = AUDIO_MIXER_LAST;
   4046 	strcpy(dip->label.name, AudioCMonitor);
   4047 	break;
   4048 
   4049     case GUSMAX_RECORD_CLASS:			/* record source class */
   4050 	dip->type = AUDIO_MIXER_CLASS;
   4051 	dip->mixer_class = GUSMAX_RECORD_CLASS;
   4052 	dip->next = dip->prev = AUDIO_MIXER_LAST;
   4053 	strcpy(dip->label.name, AudioCRecord);
   4054 	break;
   4055 
   4056     default:
   4057 	return ENXIO;
   4058 	/*NOTREACHED*/
   4059     }
   4060     DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name));
   4061 	return 0;
   4062 }
   4063 
   4064 STATIC int
   4065 gus_mixer_query_devinfo(addr, dip)
   4066 	void *addr;
   4067 	mixer_devinfo_t *dip;
   4068 {
   4069 	struct gus_softc *sc = addr;
   4070 
   4071 	DPRINTF(("gusmax_query_devinfo: index=%d\n", dip->index));
   4072 
   4073 	if (!HAS_MIXER(sc) && dip->index > GUSICS_MASTER_MUTE)
   4074 		return ENXIO;
   4075 
   4076 	switch(dip->index) {
   4077 
   4078 	case GUSICS_MIC_IN_LVL:	/* Microphone */
   4079 		dip->type = AUDIO_MIXER_VALUE;
   4080 		dip->mixer_class = GUSICS_INPUT_CLASS;
   4081 		dip->prev = AUDIO_MIXER_LAST;
   4082 		dip->next = GUSICS_MIC_IN_MUTE;
   4083 		strcpy(dip->label.name, AudioNmicrophone);
   4084 		dip->un.v.num_channels = 2;
   4085 		strcpy(dip->un.v.units.name, AudioNvolume);
   4086 		break;
   4087 
   4088 	case GUSICS_LINE_IN_LVL:	/* line */
   4089 		dip->type = AUDIO_MIXER_VALUE;
   4090 		dip->mixer_class = GUSICS_INPUT_CLASS;
   4091 		dip->prev = AUDIO_MIXER_LAST;
   4092 		dip->next = GUSICS_LINE_IN_MUTE;
   4093 		strcpy(dip->label.name, AudioNline);
   4094 		dip->un.v.num_channels = 2;
   4095 		strcpy(dip->un.v.units.name, AudioNvolume);
   4096 		break;
   4097 
   4098 	case GUSICS_CD_LVL:		/* cd */
   4099 		dip->type = AUDIO_MIXER_VALUE;
   4100 		dip->mixer_class = GUSICS_INPUT_CLASS;
   4101 		dip->prev = AUDIO_MIXER_LAST;
   4102 		dip->next = GUSICS_CD_MUTE;
   4103 		strcpy(dip->label.name, AudioNcd);
   4104 		dip->un.v.num_channels = 2;
   4105 		strcpy(dip->un.v.units.name, AudioNvolume);
   4106 		break;
   4107 
   4108 	case GUSICS_DAC_LVL:		/*  dacout */
   4109 		dip->type = AUDIO_MIXER_VALUE;
   4110 		dip->mixer_class = GUSICS_INPUT_CLASS;
   4111 		dip->prev = AUDIO_MIXER_LAST;
   4112 		dip->next = GUSICS_DAC_MUTE;
   4113 		strcpy(dip->label.name, AudioNdac);
   4114 		dip->un.v.num_channels = 2;
   4115 		strcpy(dip->un.v.units.name, AudioNvolume);
   4116 		break;
   4117 
   4118 	case GUSICS_MASTER_LVL:		/*  master output */
   4119 		dip->type = AUDIO_MIXER_VALUE;
   4120 		dip->mixer_class = GUSICS_OUTPUT_CLASS;
   4121 		dip->prev = AUDIO_MIXER_LAST;
   4122 		dip->next = GUSICS_MASTER_MUTE;
   4123 		strcpy(dip->label.name, AudioNvolume);
   4124 		dip->un.v.num_channels = 2;
   4125 		strcpy(dip->un.v.units.name, AudioNvolume);
   4126 		break;
   4127 
   4128 
   4129 	case GUSICS_LINE_IN_MUTE:
   4130 		dip->mixer_class = GUSICS_INPUT_CLASS;
   4131 		dip->type = AUDIO_MIXER_ENUM;
   4132 		dip->prev = GUSICS_LINE_IN_LVL;
   4133 		dip->next = AUDIO_MIXER_LAST;
   4134 		goto mute;
   4135 
   4136 	case GUSICS_DAC_MUTE:
   4137 		dip->mixer_class = GUSICS_INPUT_CLASS;
   4138 		dip->type = AUDIO_MIXER_ENUM;
   4139 		dip->prev = GUSICS_DAC_LVL;
   4140 		dip->next = AUDIO_MIXER_LAST;
   4141 		goto mute;
   4142 
   4143 	case GUSICS_CD_MUTE:
   4144 		dip->mixer_class = GUSICS_INPUT_CLASS;
   4145 		dip->type = AUDIO_MIXER_ENUM;
   4146 		dip->prev = GUSICS_CD_LVL;
   4147 		dip->next = AUDIO_MIXER_LAST;
   4148 		goto mute;
   4149 
   4150 	case GUSICS_MIC_IN_MUTE:
   4151 		dip->mixer_class = GUSICS_INPUT_CLASS;
   4152 		dip->type = AUDIO_MIXER_ENUM;
   4153 		dip->prev = GUSICS_MIC_IN_LVL;
   4154 		dip->next = AUDIO_MIXER_LAST;
   4155 		goto mute;
   4156 
   4157 	case GUSICS_MASTER_MUTE:
   4158 		dip->mixer_class = GUSICS_OUTPUT_CLASS;
   4159 		dip->type = AUDIO_MIXER_ENUM;
   4160 		dip->prev = GUSICS_MASTER_LVL;
   4161 		dip->next = AUDIO_MIXER_LAST;
   4162 mute:
   4163 		strcpy(dip->label.name, AudioNmute);
   4164 		dip->un.e.num_mem = 2;
   4165 		strcpy(dip->un.e.member[0].label.name, AudioNoff);
   4166 		dip->un.e.member[0].ord = 0;
   4167 		strcpy(dip->un.e.member[1].label.name, AudioNon);
   4168 		dip->un.e.member[1].ord = 1;
   4169 		break;
   4170 
   4171 	case GUSICS_RECORD_SOURCE:
   4172 		dip->mixer_class = GUSICS_RECORD_CLASS;
   4173 		dip->type = AUDIO_MIXER_ENUM;
   4174 		dip->prev = dip->next = AUDIO_MIXER_LAST;
   4175 		strcpy(dip->label.name, AudioNsource);
   4176 		dip->un.e.num_mem = 1;
   4177 		strcpy(dip->un.e.member[0].label.name, AudioNoutput);
   4178 		dip->un.e.member[0].ord = GUSICS_MASTER_LVL;
   4179 		break;
   4180 
   4181 	case GUSICS_INPUT_CLASS:
   4182 		dip->type = AUDIO_MIXER_CLASS;
   4183 		dip->mixer_class = GUSICS_INPUT_CLASS;
   4184 		dip->next = dip->prev = AUDIO_MIXER_LAST;
   4185 		strcpy(dip->label.name, AudioCInputs);
   4186 		break;
   4187 
   4188 	case GUSICS_OUTPUT_CLASS:
   4189 		dip->type = AUDIO_MIXER_CLASS;
   4190 		dip->mixer_class = GUSICS_OUTPUT_CLASS;
   4191 		dip->next = dip->prev = AUDIO_MIXER_LAST;
   4192 		strcpy(dip->label.name, AudioCOutputs);
   4193 		break;
   4194 
   4195 	case GUSICS_RECORD_CLASS:
   4196 		dip->type = AUDIO_MIXER_CLASS;
   4197 		dip->mixer_class = GUSICS_RECORD_CLASS;
   4198 		dip->next = dip->prev = AUDIO_MIXER_LAST;
   4199 		strcpy(dip->label.name, AudioCRecord);
   4200 		break;
   4201 
   4202 	default:
   4203 		return ENXIO;
   4204 	/*NOTREACHED*/
   4205 	}
   4206 	DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name));
   4207 	return 0;
   4208 }
   4209 
   4210 STATIC int
   4211 gus_query_encoding(addr, fp)
   4212 	void *addr;
   4213 	struct audio_encoding *fp;
   4214 {
   4215 	switch (fp->index) {
   4216 	case 0:
   4217 		strcpy(fp->name, AudioEmulaw);
   4218 		fp->encoding = AUDIO_ENCODING_ULAW;
   4219 		fp->precision = 8;
   4220 		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
   4221 		break;
   4222 	case 1:
   4223 		strcpy(fp->name, AudioElinear);
   4224 		fp->encoding = AUDIO_ENCODING_SLINEAR;
   4225 		fp->precision = 8;
   4226 		fp->flags = 0;
   4227 		break;
   4228 	case 2:
   4229 		strcpy(fp->name, AudioElinear_le);
   4230 		fp->encoding = AUDIO_ENCODING_SLINEAR_LE;
   4231 		fp->precision = 16;
   4232 		fp->flags = 0;
   4233 		break;
   4234 	case 3:
   4235 		strcpy(fp->name, AudioEulinear);
   4236 		fp->encoding = AUDIO_ENCODING_ULINEAR;
   4237 		fp->precision = 8;
   4238 		fp->flags = 0;
   4239 		break;
   4240 	case 4:
   4241 		strcpy(fp->name, AudioEulinear_le);
   4242 		fp->encoding = AUDIO_ENCODING_ULINEAR_LE;
   4243 		fp->precision = 16;
   4244 		fp->flags = 0;
   4245 		break;
   4246 	case 5:
   4247 		strcpy(fp->name, AudioElinear_be);
   4248 		fp->encoding = AUDIO_ENCODING_SLINEAR_BE;
   4249 		fp->precision = 16;
   4250 		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
   4251 		break;
   4252 	case 6:
   4253 		strcpy(fp->name, AudioEulinear_be);
   4254 		fp->encoding = AUDIO_ENCODING_ULINEAR_BE;
   4255 		fp->precision = 16;
   4256 		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
   4257 		break;
   4258 	case 7:
   4259 		strcpy(fp->name, AudioEalaw);
   4260 		fp->encoding = AUDIO_ENCODING_ALAW;
   4261 		fp->precision = 8;
   4262 		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
   4263 		break;
   4264 
   4265 	default:
   4266 		return(EINVAL);
   4267 		/*NOTREACHED*/
   4268 	}
   4269 	return (0);
   4270 }
   4271 
   4272 /*
   4273  * Setup the ICS mixer in "transparent" mode: reset everything to a sensible
   4274  * level.  Levels as suggested by GUS SDK code.
   4275  */
   4276 
   4277 STATIC void
   4278 gus_init_ics2101(sc)
   4279 	struct gus_softc *sc;
   4280 {
   4281 	int port = sc->sc_iobase;
   4282 	struct ics2101_softc *ic = &sc->sc_mixer;
   4283 	sc->sc_mixer.sc_selio = port+GUS_MIXER_SELECT;
   4284 	sc->sc_mixer.sc_dataio = port+GUS_MIXER_DATA;
   4285 	sc->sc_mixer.sc_flags = (sc->sc_revision == 5) ? ICS_FLIP : 0;
   4286 
   4287 	ics2101_mix_attenuate(ic,
   4288 			      GUSMIX_CHAN_MIC,
   4289 			      ICSMIX_LEFT,
   4290 			      ICSMIX_MIN_ATTN);
   4291 	ics2101_mix_attenuate(ic,
   4292 			      GUSMIX_CHAN_MIC,
   4293 			      ICSMIX_RIGHT,
   4294 			      ICSMIX_MIN_ATTN);
   4295 	/*
   4296 	 * Start with microphone muted by the mixer...
   4297 	 */
   4298 	gusics_mic_mute(ic, 1);
   4299 
   4300 	/* ... and enabled by the GUS master mix control */
   4301 	gus_mic_ctl(sc, SPKR_ON);
   4302 
   4303 	ics2101_mix_attenuate(ic,
   4304 			      GUSMIX_CHAN_LINE,
   4305 			      ICSMIX_LEFT,
   4306 			      ICSMIX_MIN_ATTN);
   4307 	ics2101_mix_attenuate(ic,
   4308 			      GUSMIX_CHAN_LINE,
   4309 			      ICSMIX_RIGHT,
   4310 			      ICSMIX_MIN_ATTN);
   4311 
   4312 	ics2101_mix_attenuate(ic,
   4313 			      GUSMIX_CHAN_CD,
   4314 			      ICSMIX_LEFT,
   4315 			      ICSMIX_MIN_ATTN);
   4316 	ics2101_mix_attenuate(ic,
   4317 			      GUSMIX_CHAN_CD,
   4318 			      ICSMIX_RIGHT,
   4319 			      ICSMIX_MIN_ATTN);
   4320 
   4321 	ics2101_mix_attenuate(ic,
   4322 			      GUSMIX_CHAN_DAC,
   4323 			      ICSMIX_LEFT,
   4324 			      ICSMIX_MIN_ATTN);
   4325 	ics2101_mix_attenuate(ic,
   4326 			      GUSMIX_CHAN_DAC,
   4327 			      ICSMIX_RIGHT,
   4328 			      ICSMIX_MIN_ATTN);
   4329 
   4330 	ics2101_mix_attenuate(ic,
   4331 			      ICSMIX_CHAN_4,
   4332 			      ICSMIX_LEFT,
   4333 			      ICSMIX_MAX_ATTN);
   4334 	ics2101_mix_attenuate(ic,
   4335 			      ICSMIX_CHAN_4,
   4336 			      ICSMIX_RIGHT,
   4337 			      ICSMIX_MAX_ATTN);
   4338 
   4339 	ics2101_mix_attenuate(ic,
   4340 			      GUSMIX_CHAN_MASTER,
   4341 			      ICSMIX_LEFT,
   4342 			      ICSMIX_MIN_ATTN);
   4343 	ics2101_mix_attenuate(ic,
   4344 			      GUSMIX_CHAN_MASTER,
   4345 			      ICSMIX_RIGHT,
   4346 			      ICSMIX_MIN_ATTN);
   4347 	/* unmute other stuff: */
   4348 	gusics_cd_mute(ic, 0);
   4349 	gusics_dac_mute(ic, 0);
   4350 	gusics_linein_mute(ic, 0);
   4351 	return;
   4352 }
   4353 
   4354 
   4355 #endif /* NGUS */
   4356