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