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