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