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