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