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