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