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