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