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