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