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