1 /* $NetBSD: gus.c,v 1.104 2009/05/12 08:44:19 cegger Exp $ */
4 * Copyright (c) 1996, 1999 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Ken Hornstein and John Kohl.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
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.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
35 * . figure out why mixer activity while sound is playing causes problems
36 * (phantom interrupts?)
37 * . figure out a better deinterleave strategy that avoids sucking up
38 * CPU, memory and cache bandwidth. (Maybe a special encoding?
39 * Maybe use the double-speed sampling/hardware deinterleave trick
40 * from the GUS SDK?) A 486/33 isn't quite fast enough to keep
41 * up with 44.1kHz 16-bit stereo output without some drop-outs.
42 * . use CS4231 for 16-bit sampling, for A-law and mu-law playback.
43 * . actually test full-duplex sampling(recording) and playback.
47 * Gravis UltraSound driver
49 * For more detailed information, see the GUS developers' kit
50 * available on the net at:
52 * http://www.gravis.com/Public/sdk/GUSDK222.ZIP
54 * See ultrawrd.doc inside--it's MS Word (ick), but it's the bible
59 * The GUS Max has a slightly strange set of connections between the CS4231
60 * and the GF1 and the DMA interconnects. It's set up so that the CS4231 can
61 * be playing while the GF1 is loading patches from the system.
63 * Here's a recreation of the DMA interconnect diagram:
70 * | | play (dram) | +----+ | |
71 * | |--------------(------|-\ | | +-+ |
72 * +---------+ | | >-|----|---|C|--|------ DMA chan 1
76 * +---------+ +-+ +--(---|-\ | | | |
77 * | | play |8| | | >-|----|----+---|------ DMA chan 2
78 * | ---C----|--------|/|------(---|-/ | | |
79 * | ^ |record |1| | +----+ | |
80 * | | | /----|6|------+ +--------+
83 * CS4231 8-to-16 bit bus conversion, if needed
86 * "C" is an optional combiner.
90 #include <sys/cdefs.h>
91 __KERNEL_RCSID(0, "$NetBSD: gus.c,v 1.104 2009/05/12 08:44:19 cegger Exp $");
96 #include <sys/param.h>
97 #include <sys/systm.h>
98 #include <sys/callout.h>
99 #include <sys/errno.h>
100 #include <sys/ioctl.h>
101 #include <sys/syslog.h>
102 #include <sys/device.h>
103 #include <sys/proc.h>
105 #include <sys/fcntl.h>
106 #include <sys/malloc.h>
107 #include <sys/kernel.h>
110 #include <sys/intr.h>
113 #include <sys/audioio.h>
114 #include <dev/audio_if.h>
115 #include <dev/mulaw.h>
116 #include <dev/auconv.h>
118 #include <dev/isa/isavar.h>
119 #include <dev/isa/isadmavar.h>
121 #include <dev/ic/ics2101reg.h>
122 #include <dev/ic/cs4231reg.h>
123 #include <dev/ic/ad1848reg.h>
124 #include <dev/isa/ics2101var.h>
125 #include <dev/isa/ad1848var.h>
126 #include <dev/isa/cs4231var.h>
130 #define STATIC /* empty; for debugging symbols */
132 #define STATIC static
136 * Software state of a single "voice" on the GUS
142 * Various control bits
145 unsigned char voccntl
; /* State of voice control register */
146 unsigned char volcntl
; /* State of volume control register */
147 unsigned char pan_pos
; /* Position of volume panning (4 bits) */
148 int rate
; /* Sample rate of voice being played back */
151 * Address of the voice data into the GUS's DRAM. 20 bits each
154 u_long start_addr
; /* Starting address of voice data loop area */
155 u_long end_addr
; /* Ending address of voice data loop */
156 u_long current_addr
; /* Beginning address of voice data
157 (start playing here) */
160 * linear volume values for the GUS's volume ramp. 0-511 (9 bits).
161 * These values must be translated into the logarithmic values using
165 int start_volume
; /* Starting position of volume ramp */
166 int current_volume
; /* Current position of volume on volume ramp */
167 int end_volume
; /* Ending position of volume on volume ramp */
171 * Software state of GUS
175 struct device sc_dev
; /* base device */
176 void *sc_ih
; /* interrupt vector */
177 bus_space_tag_t sc_iot
; /* tag */
178 isa_chipset_tag_t sc_ic
; /* ISA chipset info */
179 bus_space_handle_t sc_ioh1
; /* handle */
180 bus_space_handle_t sc_ioh2
; /* handle */
181 bus_space_handle_t sc_ioh3
; /* ICS2101 handle */
182 bus_space_handle_t sc_ioh4
; /* MIDI handle */
184 callout_t sc_dmaout_ch
;
186 int sc_iobase
; /* I/O base address */
187 int sc_irq
; /* IRQ used */
188 int sc_playdrq
; /* DMA channel for play */
189 bus_size_t sc_play_maxsize
; /* DMA size for play */
190 int sc_recdrq
; /* DMA channel for recording */
191 bus_size_t sc_req_maxsize
; /* DMA size for recording */
193 int sc_flags
; /* Various flags about the GUS */
194 #define GUS_MIXER_INSTALLED 0x01 /* An ICS mixer is installed */
195 #define GUS_LOCKED 0x02 /* GUS is busy doing multi-phase DMA */
196 #define GUS_CODEC_INSTALLED 0x04 /* CS4231 installed/MAX */
197 #define GUS_PLAYING 0x08 /* GUS is playing a voice */
198 #define GUS_DMAOUT_ACTIVE 0x10 /* GUS is busy doing audio DMA */
199 #define GUS_DMAIN_ACTIVE 0x20 /* GUS is busy sampling */
200 #define GUS_OPEN 0x100 /* GUS is open */
201 int sc_dsize
; /* Size of GUS DRAM */
202 int sc_voices
; /* Number of active voices */
203 u_char sc_revision
; /* Board revision of GUS */
204 u_char sc_mixcontrol
; /* Value of GUS_MIX_CONTROL register */
206 u_long sc_orate
; /* Output sampling rate */
207 u_long sc_irate
; /* Input sampling rate */
209 int sc_encoding
; /* Current data encoding type */
210 int sc_precision
; /* # of bits of precision */
211 int sc_channels
; /* Number of active channels */
212 int sc_blocksize
; /* Current blocksize */
213 int sc_chanblocksize
; /* Current blocksize for each in-use
215 short sc_nbufs
; /* how many on-GUS bufs per-channel */
216 short sc_bufcnt
; /* how many need to be played */
217 void *sc_deintr_buf
; /* deinterleave buffer for stereo */
219 int sc_ogain
; /* Output gain control */
220 u_char sc_out_port
; /* Current out port (generic only) */
221 u_char sc_in_port
; /* keep track of it when no codec */
223 void (*sc_dmaoutintr
)(void*); /* DMA completion intr handler */
224 void *sc_outarg
; /* argument for sc_dmaoutintr() */
225 u_char
*sc_dmaoutaddr
; /* for isa_dmadone */
226 u_long sc_gusaddr
; /* where did we just put it? */
227 int sc_dmaoutcnt
; /* for isa_dmadone */
229 void (*sc_dmainintr
)(void*); /* DMA completion intr handler */
230 void *sc_inarg
; /* argument for sc_dmaoutintr() */
231 u_char
*sc_dmainaddr
; /* for isa_dmadone */
232 int sc_dmaincnt
; /* for isa_dmadone */
234 struct stereo_dma_intr
{
235 void (*intr
)(void *);
244 * State information for linear audio layer
247 int sc_dmabuf
; /* Which ring buffer we're DMA'ing to */
248 int sc_playbuf
; /* Which ring buffer we're playing */
251 * Voice information array. All voice-specific information is stored
255 struct gus_voice sc_voc
[32]; /* Voice data for each voice */
257 struct ics2101_softc sc_mixer_u
;
258 struct ad1848_isa_softc sc_codec_u
;
260 #define sc_mixer u.sc_mixer_u
261 #define sc_codec u.sc_codec_u
264 struct ics2101_volume
{
269 #define HAS_CODEC(sc) ((sc)->sc_flags & GUS_CODEC_INSTALLED)
270 #define HAS_MIXER(sc) ((sc)->sc_flags & GUS_MIXER_INSTALLED)
273 * Mixer devices for ICS2101
275 /* MIC IN mute, line in mute, line out mute are first since they can be done
276 even if no ICS mixer. */
277 #define GUSICS_MIC_IN_MUTE 0
278 #define GUSICS_LINE_IN_MUTE 1
279 #define GUSICS_MASTER_MUTE 2
280 #define GUSICS_CD_MUTE 3
281 #define GUSICS_DAC_MUTE 4
282 #define GUSICS_MIC_IN_LVL 5
283 #define GUSICS_LINE_IN_LVL 6
284 #define GUSICS_CD_LVL 7
285 #define GUSICS_DAC_LVL 8
286 #define GUSICS_MASTER_LVL 9
288 #define GUSICS_RECORD_SOURCE 10
291 #define GUSICS_INPUT_CLASS 11
292 #define GUSICS_OUTPUT_CLASS 12
293 #define GUSICS_RECORD_CLASS 13
296 * Mixer & MUX devices for CS4231
298 #define GUSMAX_MONO_LVL 0 /* mic input to MUX;
299 also mono mixer input */
300 #define GUSMAX_DAC_LVL 1 /* input to MUX; also mixer input */
301 #define GUSMAX_LINE_IN_LVL 2 /* input to MUX; also mixer input */
302 #define GUSMAX_CD_LVL 3 /* mixer input only */
303 #define GUSMAX_MONITOR_LVL 4 /* digital mix (?) */
304 #define GUSMAX_OUT_LVL 5 /* output level. (?) */
305 #define GUSMAX_SPEAKER_LVL 6 /* pseudo-device for mute */
306 #define GUSMAX_LINE_IN_MUTE 7 /* pre-mixer */
307 #define GUSMAX_DAC_MUTE 8 /* pre-mixer */
308 #define GUSMAX_CD_MUTE 9 /* pre-mixer */
309 #define GUSMAX_MONO_MUTE 10 /* pre-mixer--microphone/mono */
310 #define GUSMAX_MONITOR_MUTE 11 /* post-mixer level/mute */
311 #define GUSMAX_SPEAKER_MUTE 12 /* speaker mute */
313 #define GUSMAX_REC_LVL 13 /* post-MUX gain */
315 #define GUSMAX_RECORD_SOURCE 14
318 #define GUSMAX_INPUT_CLASS 15
319 #define GUSMAX_RECORD_CLASS 16
320 #define GUSMAX_MONITOR_CLASS 17
321 #define GUSMAX_OUTPUT_CLASS 18
324 #define GUSPLAYDEBUG /*XXX*/
325 #define DPRINTF(x) if (gusdebug) printf x
326 #define DMAPRINTF(x) if (gusdmadebug) printf x
333 int gus_dostereo
= 1;
335 #define NDMARECS 2048
345 } dmarecords
[NDMARECS
];
347 int dmarecord_index
= 0;
354 int gusopen(void *, int);
355 void gusclose(void *);
356 void gusmax_close(void *);
358 int gus_set_in_gain(void *, u_int
, u_char
);
359 int gus_get_in_gain(void *);
360 int gus_set_out_gain(void *, u_int
, u_char
);
361 int gus_get_out_gain(void *);
362 int gus_set_params(void *, int, int, audio_params_t
*,
363 audio_params_t
*, stream_filter_list_t
*, stream_filter_list_t
*);
364 int gusmax_set_params(void *, int, int, audio_params_t
*,
365 audio_params_t
*, stream_filter_list_t
*, stream_filter_list_t
*);
366 int gus_round_blocksize(void *, int, int, const audio_params_t
*);
367 int gus_commit_settings(void *);
368 int gus_dma_output(void *, void *, int, void (*)(void *), void *);
369 int gus_dma_input(void *, void *, int, void (*)(void *), void *);
370 int gus_halt_out_dma(void *);
371 int gus_halt_in_dma(void *);
372 int gus_speaker_ctl(void *, int);
373 int gusmaxopen(void *, int);
374 int gusmax_round_blocksize(void *, int, int, const audio_params_t
*);
375 int gusmax_commit_settings(void *);
376 int gusmax_dma_output(void *, void *, int, void (*)(void *), void *);
377 int gusmax_dma_input(void *, void *, int, void (*)(void *), void *);
378 int gusmax_halt_out_dma(void *);
379 int gusmax_halt_in_dma(void *);
380 int gusmax_speaker_ctl(void *, int);
381 int gus_getdev(void *, struct audio_device
*);
383 STATIC
void gus_deinterleave(struct gus_softc
*, void *, int);
385 STATIC
int gus_mic_ctl(void *, int);
386 STATIC
int gus_linein_ctl(void *, int);
387 STATIC
int gus_test_iobase(bus_space_tag_t
, int);
388 STATIC
void guspoke(bus_space_tag_t
, bus_space_handle_t
, long, u_char
);
389 STATIC
void gusdmaout(struct gus_softc
*, int, u_long
, void *, int);
390 STATIC
int gus_init_cs4231(struct gus_softc
*);
391 STATIC
void gus_init_ics2101(struct gus_softc
*);
393 STATIC
void gus_set_chan_addrs(struct gus_softc
*);
394 STATIC
void gusreset(struct gus_softc
*, int);
395 STATIC
void gus_set_voices(struct gus_softc
*, int);
396 STATIC
void gus_set_volume(struct gus_softc
*, int, int);
397 STATIC
void gus_set_samprate(struct gus_softc
*, int, int);
398 STATIC
void gus_set_recrate(struct gus_softc
*, u_long
);
399 STATIC
void gus_start_voice(struct gus_softc
*, int, int);
400 STATIC
void gus_stop_voice(struct gus_softc
*, int, int);
401 STATIC
void gus_set_endaddr(struct gus_softc
*, int, u_long
);
403 STATIC
void gus_set_curaddr(struct gus_softc
*, int, u_long
);
404 STATIC u_long
gus_get_curaddr(struct gus_softc
*, int);
406 STATIC
int gus_dmaout_intr(struct gus_softc
*);
407 STATIC
void gus_dmaout_dointr(struct gus_softc
*);
408 STATIC
void gus_dmaout_timeout(void *);
409 STATIC
int gus_dmain_intr(struct gus_softc
*);
410 STATIC
int gus_voice_intr(struct gus_softc
*);
411 STATIC
void gus_start_playing(struct gus_softc
*, int);
412 STATIC
int gus_continue_playing(struct gus_softc
*, int);
413 STATIC u_char
guspeek(bus_space_tag_t
, bus_space_handle_t
, u_long
);
414 STATIC u_long
convert_to_16bit(u_long
);
415 STATIC
int gus_mixer_set_port(void *, mixer_ctrl_t
*);
416 STATIC
int gus_mixer_get_port(void *, mixer_ctrl_t
*);
417 STATIC
int gusmax_mixer_set_port(void *, mixer_ctrl_t
*);
418 STATIC
int gusmax_mixer_get_port(void *, mixer_ctrl_t
*);
419 STATIC
int gus_mixer_query_devinfo(void *, mixer_devinfo_t
*);
420 STATIC
int gusmax_mixer_query_devinfo(void *, mixer_devinfo_t
*);
421 STATIC
int gus_query_encoding(void *, struct audio_encoding
*);
422 STATIC
int gus_get_props(void *);
423 STATIC
int gusmax_get_props(void *);
425 STATIC
void gusics_master_mute(struct ics2101_softc
*, int);
426 STATIC
void gusics_dac_mute(struct ics2101_softc
*, int);
427 STATIC
void gusics_mic_mute(struct ics2101_softc
*, int);
428 STATIC
void gusics_linein_mute(struct ics2101_softc
*, int);
429 STATIC
void gusics_cd_mute(struct ics2101_softc
*, int);
431 void stereo_dmaintr(void *);
434 * ISA bus driver routines
437 int gusprobe(device_t
, cfdata_t
, void *);
438 void gusattach(device_t
, device_t
, void *);
440 CFATTACH_DECL(gus
, sizeof(struct gus_softc
),
441 gusprobe
, gusattach
, NULL
, NULL
);
444 * A mapping from IRQ/DRQ values to the values used in the GUS's internal
445 * registers. A zero means that the referenced IRQ/DRQ is invalid
448 static const int gus_irq_map
[] = {
449 -1, -1, 1, 3, -1, 2, -1, 4,
450 -1, 1, -1, 5, 6, -1, -1, 7
452 static const int gus_drq_map
[] = {
453 -1, 1, -1, 2, -1, 3, 4, 5
457 * A list of valid base addresses for the GUS
460 static const int gus_base_addrs
[] = {
461 0x210, 0x220, 0x230, 0x240, 0x250, 0x260
463 static const int gus_addrs
= sizeof(gus_base_addrs
) / sizeof(gus_base_addrs
[0]);
466 * Maximum frequency values of the GUS based on the number of currently active
467 * voices. Since the GUS samples a voice every 1.6 us, the maximum frequency
468 * is dependent on the number of active voices. Yes, it is pretty weird.
471 static const int gus_max_frequency
[] = {
472 44100, /* 14 voices */
473 41160, /* 15 voices */
474 38587, /* 16 voices */
475 36317, /* 17 voices */
476 34300, /* 18 voices */
477 32494, /* 19 voices */
478 30870, /* 20 voices */
479 29400, /* 21 voices */
480 28063, /* 22 voices */
481 26843, /* 23 voices */
482 25725, /* 24 voices */
483 24696, /* 25 voices */
484 23746, /* 26 voices */
485 22866, /* 27 voices */
486 22050, /* 28 voices */
487 21289, /* 29 voices */
488 20580, /* 30 voices */
489 19916, /* 31 voices */
490 19293 /* 32 voices */
493 * A mapping of linear volume levels to the logarithmic volume values used
494 * by the GF1 chip on the GUS. From GUS SDK vol1.c.
497 static const unsigned short gus_log_volumes
[512] = {
499 0x0700, 0x07ff, 0x0880, 0x08ff, 0x0940, 0x0980, 0x09c0, 0x09ff, 0x0a20,
500 0x0a40, 0x0a60, 0x0a80, 0x0aa0, 0x0ac0, 0x0ae0, 0x0aff, 0x0b10, 0x0b20,
501 0x0b30, 0x0b40, 0x0b50, 0x0b60, 0x0b70, 0x0b80, 0x0b90, 0x0ba0, 0x0bb0,
502 0x0bc0, 0x0bd0, 0x0be0, 0x0bf0, 0x0bff, 0x0c08, 0x0c10, 0x0c18, 0x0c20,
503 0x0c28, 0x0c30, 0x0c38, 0x0c40, 0x0c48, 0x0c50, 0x0c58, 0x0c60, 0x0c68,
504 0x0c70, 0x0c78, 0x0c80, 0x0c88, 0x0c90, 0x0c98, 0x0ca0, 0x0ca8, 0x0cb0,
505 0x0cb8, 0x0cc0, 0x0cc8, 0x0cd0, 0x0cd8, 0x0ce0, 0x0ce8, 0x0cf0, 0x0cf8,
506 0x0cff, 0x0d04, 0x0d08, 0x0d0c, 0x0d10, 0x0d14, 0x0d18, 0x0d1c, 0x0d20,
507 0x0d24, 0x0d28, 0x0d2c, 0x0d30, 0x0d34, 0x0d38, 0x0d3c, 0x0d40, 0x0d44,
508 0x0d48, 0x0d4c, 0x0d50, 0x0d54, 0x0d58, 0x0d5c, 0x0d60, 0x0d64, 0x0d68,
509 0x0d6c, 0x0d70, 0x0d74, 0x0d78, 0x0d7c, 0x0d80, 0x0d84, 0x0d88, 0x0d8c,
510 0x0d90, 0x0d94, 0x0d98, 0x0d9c, 0x0da0, 0x0da4, 0x0da8, 0x0dac, 0x0db0,
511 0x0db4, 0x0db8, 0x0dbc, 0x0dc0, 0x0dc4, 0x0dc8, 0x0dcc, 0x0dd0, 0x0dd4,
512 0x0dd8, 0x0ddc, 0x0de0, 0x0de4, 0x0de8, 0x0dec, 0x0df0, 0x0df4, 0x0df8,
513 0x0dfc, 0x0dff, 0x0e02, 0x0e04, 0x0e06, 0x0e08, 0x0e0a, 0x0e0c, 0x0e0e,
514 0x0e10, 0x0e12, 0x0e14, 0x0e16, 0x0e18, 0x0e1a, 0x0e1c, 0x0e1e, 0x0e20,
515 0x0e22, 0x0e24, 0x0e26, 0x0e28, 0x0e2a, 0x0e2c, 0x0e2e, 0x0e30, 0x0e32,
516 0x0e34, 0x0e36, 0x0e38, 0x0e3a, 0x0e3c, 0x0e3e, 0x0e40, 0x0e42, 0x0e44,
517 0x0e46, 0x0e48, 0x0e4a, 0x0e4c, 0x0e4e, 0x0e50, 0x0e52, 0x0e54, 0x0e56,
518 0x0e58, 0x0e5a, 0x0e5c, 0x0e5e, 0x0e60, 0x0e62, 0x0e64, 0x0e66, 0x0e68,
519 0x0e6a, 0x0e6c, 0x0e6e, 0x0e70, 0x0e72, 0x0e74, 0x0e76, 0x0e78, 0x0e7a,
520 0x0e7c, 0x0e7e, 0x0e80, 0x0e82, 0x0e84, 0x0e86, 0x0e88, 0x0e8a, 0x0e8c,
521 0x0e8e, 0x0e90, 0x0e92, 0x0e94, 0x0e96, 0x0e98, 0x0e9a, 0x0e9c, 0x0e9e,
522 0x0ea0, 0x0ea2, 0x0ea4, 0x0ea6, 0x0ea8, 0x0eaa, 0x0eac, 0x0eae, 0x0eb0,
523 0x0eb2, 0x0eb4, 0x0eb6, 0x0eb8, 0x0eba, 0x0ebc, 0x0ebe, 0x0ec0, 0x0ec2,
524 0x0ec4, 0x0ec6, 0x0ec8, 0x0eca, 0x0ecc, 0x0ece, 0x0ed0, 0x0ed2, 0x0ed4,
525 0x0ed6, 0x0ed8, 0x0eda, 0x0edc, 0x0ede, 0x0ee0, 0x0ee2, 0x0ee4, 0x0ee6,
526 0x0ee8, 0x0eea, 0x0eec, 0x0eee, 0x0ef0, 0x0ef2, 0x0ef4, 0x0ef6, 0x0ef8,
527 0x0efa, 0x0efc, 0x0efe, 0x0eff, 0x0f01, 0x0f02, 0x0f03, 0x0f04, 0x0f05,
528 0x0f06, 0x0f07, 0x0f08, 0x0f09, 0x0f0a, 0x0f0b, 0x0f0c, 0x0f0d, 0x0f0e,
529 0x0f0f, 0x0f10, 0x0f11, 0x0f12, 0x0f13, 0x0f14, 0x0f15, 0x0f16, 0x0f17,
530 0x0f18, 0x0f19, 0x0f1a, 0x0f1b, 0x0f1c, 0x0f1d, 0x0f1e, 0x0f1f, 0x0f20,
531 0x0f21, 0x0f22, 0x0f23, 0x0f24, 0x0f25, 0x0f26, 0x0f27, 0x0f28, 0x0f29,
532 0x0f2a, 0x0f2b, 0x0f2c, 0x0f2d, 0x0f2e, 0x0f2f, 0x0f30, 0x0f31, 0x0f32,
533 0x0f33, 0x0f34, 0x0f35, 0x0f36, 0x0f37, 0x0f38, 0x0f39, 0x0f3a, 0x0f3b,
534 0x0f3c, 0x0f3d, 0x0f3e, 0x0f3f, 0x0f40, 0x0f41, 0x0f42, 0x0f43, 0x0f44,
535 0x0f45, 0x0f46, 0x0f47, 0x0f48, 0x0f49, 0x0f4a, 0x0f4b, 0x0f4c, 0x0f4d,
536 0x0f4e, 0x0f4f, 0x0f50, 0x0f51, 0x0f52, 0x0f53, 0x0f54, 0x0f55, 0x0f56,
537 0x0f57, 0x0f58, 0x0f59, 0x0f5a, 0x0f5b, 0x0f5c, 0x0f5d, 0x0f5e, 0x0f5f,
538 0x0f60, 0x0f61, 0x0f62, 0x0f63, 0x0f64, 0x0f65, 0x0f66, 0x0f67, 0x0f68,
539 0x0f69, 0x0f6a, 0x0f6b, 0x0f6c, 0x0f6d, 0x0f6e, 0x0f6f, 0x0f70, 0x0f71,
540 0x0f72, 0x0f73, 0x0f74, 0x0f75, 0x0f76, 0x0f77, 0x0f78, 0x0f79, 0x0f7a,
541 0x0f7b, 0x0f7c, 0x0f7d, 0x0f7e, 0x0f7f, 0x0f80, 0x0f81, 0x0f82, 0x0f83,
542 0x0f84, 0x0f85, 0x0f86, 0x0f87, 0x0f88, 0x0f89, 0x0f8a, 0x0f8b, 0x0f8c,
543 0x0f8d, 0x0f8e, 0x0f8f, 0x0f90, 0x0f91, 0x0f92, 0x0f93, 0x0f94, 0x0f95,
544 0x0f96, 0x0f97, 0x0f98, 0x0f99, 0x0f9a, 0x0f9b, 0x0f9c, 0x0f9d, 0x0f9e,
545 0x0f9f, 0x0fa0, 0x0fa1, 0x0fa2, 0x0fa3, 0x0fa4, 0x0fa5, 0x0fa6, 0x0fa7,
546 0x0fa8, 0x0fa9, 0x0faa, 0x0fab, 0x0fac, 0x0fad, 0x0fae, 0x0faf, 0x0fb0,
547 0x0fb1, 0x0fb2, 0x0fb3, 0x0fb4, 0x0fb5, 0x0fb6, 0x0fb7, 0x0fb8, 0x0fb9,
548 0x0fba, 0x0fbb, 0x0fbc, 0x0fbd, 0x0fbe, 0x0fbf, 0x0fc0, 0x0fc1, 0x0fc2,
549 0x0fc3, 0x0fc4, 0x0fc5, 0x0fc6, 0x0fc7, 0x0fc8, 0x0fc9, 0x0fca, 0x0fcb,
550 0x0fcc, 0x0fcd, 0x0fce, 0x0fcf, 0x0fd0, 0x0fd1, 0x0fd2, 0x0fd3, 0x0fd4,
551 0x0fd5, 0x0fd6, 0x0fd7, 0x0fd8, 0x0fd9, 0x0fda, 0x0fdb, 0x0fdc, 0x0fdd,
552 0x0fde, 0x0fdf, 0x0fe0, 0x0fe1, 0x0fe2, 0x0fe3, 0x0fe4, 0x0fe5, 0x0fe6,
553 0x0fe7, 0x0fe8, 0x0fe9, 0x0fea, 0x0feb, 0x0fec, 0x0fed, 0x0fee, 0x0fef,
554 0x0ff0, 0x0ff1, 0x0ff2, 0x0ff3, 0x0ff4, 0x0ff5, 0x0ff6, 0x0ff7, 0x0ff8,
555 0x0ff9, 0x0ffa, 0x0ffb, 0x0ffc, 0x0ffd, 0x0ffe, 0x0fff};
557 #define SELECT_GUS_REG(iot,ioh1,x) bus_space_write_1(iot,ioh1,GUS_REG_SELECT,x)
558 #define ADDR_HIGH(x) (unsigned int) ((x >> 7L) & 0x1fffL)
559 #define ADDR_LOW(x) (unsigned int) ((x & 0x7fL) << 9L)
561 #define GUS_MIN_VOICES 14 /* Minimum possible number of voices */
562 #define GUS_MAX_VOICES 32 /* Maximum possible number of voices */
563 #define GUS_VOICE_LEFT 0 /* Voice used for left (and mono) playback */
564 #define GUS_VOICE_RIGHT 1 /* Voice used for right playback */
565 #define GUS_MEM_OFFSET 32 /* Offset into GUS memory to begin of buffer */
566 #define GUS_BUFFER_MULTIPLE 1024 /* Audio buffers are multiples of this */
567 #define GUS_MEM_FOR_BUFFERS 131072 /* use this many bytes on-GUS */
568 #define GUS_LEFT_RIGHT_OFFSET (sc->sc_nbufs * sc->sc_chanblocksize + GUS_MEM_OFFSET)
570 #define GUS_PREC_BYTES (sc->sc_precision >> 3) /* precision to bytes */
572 /* splgus() must be splaudio() */
574 #define splgus splaudio
577 * Interface to higher level audio driver
580 const struct audio_hw_if gus_hw_if
= {
599 gus_mixer_query_devinfo
,
602 ad1848_isa_round_buffersize
,
611 static const struct audio_hw_if gusmax_hw_if
= {
615 gus_query_encoding
, /* query encoding */
617 gusmax_round_blocksize
,
618 gusmax_commit_settings
,
628 gusmax_mixer_set_port
,
629 gusmax_mixer_get_port
,
630 gusmax_mixer_query_devinfo
,
633 ad1848_isa_round_buffersize
,
643 * Some info about the current audio device
646 struct audio_device gus_device
= {
652 #define FLIP_REV 5 /* This rev has flipped mixer chans */
656 gusprobe(device_t parent
, cfdata_t match
, void *aux
)
658 struct isa_attach_args
*ia
;
669 if (ISA_DIRECT_CONFIG(ia
))
672 iobase
= ia
->ia_io
[0].ir_addr
;
674 recdrq
= ia
->ia_drq
[1].ir_drq
;
676 recdrq
= ISA_UNKNOWN_DRQ
;
679 * Before we do anything else, make sure requested IRQ and DRQ are
680 * valid for this card.
683 /* XXX range check before indexing!! */
684 if (ia
->ia_irq
[0].ir_irq
== ISA_UNKNOWN_IRQ
||
685 gus_irq_map
[ia
->ia_irq
[0].ir_irq
] == -1) {
686 printf("gus: invalid irq %d, card not probed\n",
687 ia
->ia_irq
[0].ir_irq
);
691 if (ia
->ia_drq
[0].ir_drq
== ISA_UNKNOWN_DRQ
||
692 gus_drq_map
[ia
->ia_drq
[0].ir_drq
] == -1) {
693 printf("gus: invalid drq %d, card not probed\n",
694 ia
->ia_drq
[0].ir_drq
);
698 if (recdrq
!= ISA_UNKNOWN_DRQ
) {
699 if (recdrq
> 7 || gus_drq_map
[recdrq
] == -1) {
700 printf("gus: invalid second DMA channel (%d), card not "
705 recdrq
= ia
->ia_drq
[0].ir_drq
;
707 if (iobase
== ISA_UNKNOWN_PORT
) {
709 for (i
= 0; i
< gus_addrs
; i
++)
710 if (gus_test_iobase(ia
->ia_iot
, gus_base_addrs
[i
])) {
711 iobase
= gus_base_addrs
[i
];
715 } else if (!gus_test_iobase(ia
->ia_iot
, iobase
))
719 if (!isa_drq_isfree(ia
->ia_ic
, ia
->ia_drq
[0].ir_drq
) ||
720 (recdrq
!= ia
->ia_drq
[0].ir_drq
&&
721 !isa_drq_isfree(ia
->ia_ic
, recdrq
)))
725 ia
->ia_io
[0].ir_addr
= iobase
;
726 ia
->ia_io
[0].ir_size
= GUS_NPORT1
;
729 ia
->ia_ndrq
= (recdrq
!= ia
->ia_drq
[0].ir_drq
) ? 2 : 1;
737 * Test to see if a particular I/O base is valid for the GUS. Return true
742 gus_test_iobase (bus_space_tag_t iot
, int iobase
)
744 bus_space_handle_t ioh1
, ioh2
, ioh3
, ioh4
;
750 if (bus_space_map(iot
, iobase
, GUS_NPORT1
, 0, &ioh1
))
752 if (bus_space_map(iot
, iobase
+GUS_IOH2_OFFSET
, GUS_NPORT2
, 0, &ioh2
))
755 /* XXX Maybe we shouldn't fail on mapping this, but just assume
756 * the card is of revision 0? */
757 if (bus_space_map(iot
, iobase
+GUS_IOH3_OFFSET
, GUS_NPORT3
, 0, &ioh3
))
760 if (bus_space_map(iot
, iobase
+GUS_IOH4_OFFSET
, GUS_NPORT4
, 0, &ioh4
))
764 * Reset GUS to an initial state before we do anything.
770 SELECT_GUS_REG(iot
, ioh2
, GUSREG_RESET
);
771 bus_space_write_1(iot
, ioh2
, GUS_DATA_HIGH
, 0x00);
775 SELECT_GUS_REG(iot
, ioh2
, GUSREG_RESET
);
776 bus_space_write_1(iot
, ioh2
, GUS_DATA_HIGH
, GUSMASK_MASTER_RESET
);
783 * See if we can write to the board's memory
786 s1
= guspeek(iot
, ioh2
, 0L);
787 s2
= guspeek(iot
, ioh2
, 1L);
789 guspoke(iot
, ioh2
, 0L, 0xaa);
790 guspoke(iot
, ioh2
, 1L, 0x55);
792 if (guspeek(iot
, ioh2
, 0L) != 0xaa)
795 guspoke(iot
, ioh2
, 0L, s1
);
796 guspoke(iot
, ioh2
, 1L, s2
);
801 bus_space_unmap(iot
, ioh4
, GUS_NPORT4
);
803 bus_space_unmap(iot
, ioh3
, GUS_NPORT3
);
805 bus_space_unmap(iot
, ioh2
, GUS_NPORT2
);
807 bus_space_unmap(iot
, ioh1
, GUS_NPORT1
);
812 * Setup the GUS for use; called shortly after probe
816 gusattach(device_t parent
, device_t self
, void *aux
)
818 struct gus_softc
*sc
;
819 struct isa_attach_args
*ia
;
821 bus_space_handle_t ioh1
, ioh2
, ioh3
, ioh4
;
825 const struct audio_hw_if
*hwif
;
829 callout_init(&sc
->sc_dmaout_ch
, 0);
831 sc
->sc_iot
= iot
= ia
->ia_iot
;
832 sc
->sc_ic
= ia
->ia_ic
;
833 iobase
= ia
->ia_io
[0].ir_addr
;
836 if (bus_space_map(iot
, iobase
, GUS_NPORT1
, 0, &ioh1
))
837 panic("%s: can't map io port range 1", device_xname(self
));
839 if (bus_space_map(iot
, iobase
+GUS_IOH2_OFFSET
, GUS_NPORT2
, 0, &ioh2
))
840 panic("%s: can't map io port range 2", device_xname(self
));
843 /* XXX Maybe we shouldn't fail on mapping this, but just assume
844 * the card is of revision 0? */
845 if (bus_space_map(iot
, iobase
+GUS_IOH3_OFFSET
, GUS_NPORT3
, 0, &ioh3
))
846 panic("%s: can't map io port range 3", device_xname(self
));
849 if (bus_space_map(iot
, iobase
+GUS_IOH4_OFFSET
, GUS_NPORT4
, 0, &ioh4
))
850 panic("%s: can't map io port range 4", device_xname(self
));
853 sc
->sc_iobase
= iobase
;
854 sc
->sc_irq
= ia
->ia_irq
[0].ir_irq
;
855 sc
->sc_playdrq
= ia
->ia_drq
[0].ir_drq
;
856 sc
->sc_recdrq
= (ia
->ia_ndrq
== 2) ?
857 ia
->ia_drq
[1].ir_drq
: ia
->ia_drq
[0].ir_drq
;
860 * Figure out our board rev, and see if we need to initialize the
864 sc
->sc_ic
= ia
->ia_ic
;
868 c
= bus_space_read_1(iot
, ioh3
, GUS_BOARD_REV
);
875 SELECT_GUS_REG(iot
, ioh2
, GUSREG_RESET
);
876 bus_space_write_1(iot
, ioh2
, GUS_DATA_HIGH
, 0x00);
878 gusreset(sc
, GUS_MAX_VOICES
); /* initialize all voices */
879 gusreset(sc
, GUS_MIN_VOICES
); /* then set to just the ones we use */
882 * Setup the IRQ and DRQ lines in software, using values from
886 m
= GUSMASK_LINE_IN
|GUSMASK_LINE_OUT
; /* disable all */
888 c
= ((unsigned char) gus_irq_map
[ia
->ia_irq
[0].ir_irq
]) |
891 if (sc
->sc_playdrq
!= -1) {
892 if (sc
->sc_recdrq
== sc
->sc_playdrq
)
893 d
= (unsigned char) (gus_drq_map
[sc
->sc_playdrq
] |
895 else if (sc
->sc_recdrq
!= -1)
896 d
= (unsigned char) (gus_drq_map
[sc
->sc_playdrq
] |
897 gus_drq_map
[sc
->sc_recdrq
] << 3);
900 printf("%s: WARNING: Cannot initialize drq\n",
901 device_xname(&sc
->sc_dev
));
904 * Program the IRQ and DMA channels on the GUS. Note that we hardwire
905 * the GUS to only use one IRQ channel, but we give the user the
906 * option of using two DMA channels (the other one given by the drq2
907 * option in the config file). Two DMA channels are needed for full-
910 * The order of these operations is very magical.
913 s
= splhigh(); /* XXX needed? */
915 bus_space_write_1(iot
, ioh1
, GUS_REG_CONTROL
, GUS_REG_IRQCTL
);
916 bus_space_write_1(iot
, ioh1
, GUS_MIX_CONTROL
, m
);
917 bus_space_write_1(iot
, ioh1
, GUS_IRQCTL_CONTROL
, 0x00);
918 bus_space_write_1(iot
, ioh1
, 0x0f, 0x00);
920 bus_space_write_1(iot
, ioh1
, GUS_MIX_CONTROL
, m
);
921 bus_space_write_1(iot
, ioh1
, GUS_DMA_CONTROL
, d
| 0x80); /* magic reset? */
923 bus_space_write_1(iot
, ioh1
, GUS_MIX_CONTROL
, m
| GUSMASK_CONTROL_SEL
);
924 bus_space_write_1(iot
, ioh1
, GUS_IRQ_CONTROL
, c
);
926 bus_space_write_1(iot
, ioh1
, GUS_MIX_CONTROL
, m
);
927 bus_space_write_1(iot
, ioh1
, GUS_DMA_CONTROL
, d
);
929 bus_space_write_1(iot
, ioh1
, GUS_MIX_CONTROL
, m
| GUSMASK_CONTROL_SEL
);
930 bus_space_write_1(iot
, ioh1
, GUS_IRQ_CONTROL
, c
);
932 bus_space_write_1(iot
, ioh2
, GUS_VOICE_SELECT
, 0x00);
934 /* enable line in, line out. leave mic disabled. */
935 bus_space_write_1(iot
, ioh1
, GUS_MIX_CONTROL
,
936 (m
| GUSMASK_LATCHES
) & ~(GUSMASK_LINE_OUT
|GUSMASK_LINE_IN
));
937 bus_space_write_1(iot
, ioh2
, GUS_VOICE_SELECT
, 0x00);
942 (m
| GUSMASK_LATCHES
) & ~(GUSMASK_LINE_OUT
|GUSMASK_LINE_IN
);
944 if (sc
->sc_playdrq
!= -1) {
945 sc
->sc_play_maxsize
= isa_dmamaxsize(sc
->sc_ic
,
947 if (isa_drq_alloc(sc
->sc_ic
, sc
->sc_playdrq
) != 0) {
948 aprint_error_dev(&sc
->sc_dev
, "can't reserve drq %d\n",
952 if (isa_dmamap_create(sc
->sc_ic
, sc
->sc_playdrq
,
953 sc
->sc_play_maxsize
, BUS_DMA_NOWAIT
|BUS_DMA_ALLOCNOW
)) {
954 aprint_error_dev(&sc
->sc_dev
, "can't create map for drq %d\n",
959 if (sc
->sc_recdrq
!= -1 && sc
->sc_recdrq
!= sc
->sc_playdrq
) {
960 sc
->sc_req_maxsize
= isa_dmamaxsize(sc
->sc_ic
,
962 if (isa_drq_alloc(sc
->sc_ic
, sc
->sc_recdrq
) != 0) {
963 aprint_error_dev(&sc
->sc_dev
, "can't reserve drq %d\n",
967 if (isa_dmamap_create(sc
->sc_ic
, sc
->sc_recdrq
,
968 sc
->sc_req_maxsize
, BUS_DMA_NOWAIT
|BUS_DMA_ALLOCNOW
)) {
969 aprint_error_dev(&sc
->sc_dev
, "can't create map for drq %d\n",
975 /* XXX WILL THIS ALWAYS WORK THE WAY THEY'RE OVERLAYED?! */
976 sc
->sc_codec
.sc_ic
= sc
->sc_ic
;
978 if (sc
->sc_revision
>= 5 && sc
->sc_revision
<= 9) {
979 sc
->sc_flags
|= GUS_MIXER_INSTALLED
;
980 gus_init_ics2101(sc
);
983 if (sc
->sc_revision
>= 10)
984 if (gus_init_cs4231(sc
))
985 hwif
= &gusmax_hw_if
;
987 SELECT_GUS_REG(iot
, ioh2
, GUSREG_RESET
);
989 * Check to see how much memory we have on this card; see if any
990 * "mirroring" occurs. We're assuming at least 256K already exists
991 * on the card; otherwise the initial probe would have failed
994 guspoke(iot
, ioh2
, 0L, 0x00);
995 for (i
= 1; i
< 1024; i
++) {
999 * See if we've run into mirroring yet
1002 if (guspeek(iot
, ioh2
, 0L) != 0)
1007 guspoke(iot
, ioh2
, loc
, 0xaa);
1008 if (guspeek(iot
, ioh2
, loc
) != 0xaa)
1014 /* The "official" (3.x) version number cannot easily be obtained.
1015 * The revision register does not correspond to the minor number
1016 * of the board version. Simply use the revision register as
1019 snprintf(gus_device
.version
, sizeof(gus_device
.version
), "%d",
1022 printf("\n%s: Gravis UltraSound", device_xname(&sc
->sc_dev
));
1023 if (sc
->sc_revision
>= 10)
1029 printf(" with CODEC module");
1031 printf(", %dKB memory\n", sc
->sc_dsize
);
1033 /* A GUS MAX should always have a CODEC installed */
1034 if ((sc
->sc_revision
>= 10) & !(HAS_CODEC(sc
)))
1035 printf("%s: WARNING: did not attach CODEC on MAX\n",
1036 device_xname(&sc
->sc_dev
));
1039 * Setup a default interrupt handler
1042 /* XXX we shouldn't have to use splgus == splclock, nor should
1045 sc
->sc_ih
= isa_intr_establish(ia
->ia_ic
, ia
->ia_irq
[0].ir_irq
,
1046 IST_EDGE
, IPL_AUDIO
, gusintr
, sc
/* sc->sc_gusdsp */);
1049 * Set some default values
1050 * XXX others start with 8kHz mono mu-law
1053 sc
->sc_irate
= sc
->sc_orate
= 44100;
1054 sc
->sc_encoding
= AUDIO_ENCODING_SLINEAR_LE
;
1055 sc
->sc_precision
= 16;
1056 sc
->sc_voc
[GUS_VOICE_LEFT
].voccntl
|= GUSMASK_DATA_SIZE16
;
1057 sc
->sc_voc
[GUS_VOICE_RIGHT
].voccntl
|= GUSMASK_DATA_SIZE16
;
1058 sc
->sc_channels
= 1;
1060 gus_commit_settings(sc
);
1063 * We always put the left channel full left & right channel
1065 * For mono playback, we set up both voices playing the same buffer.
1067 bus_space_write_1(iot
, ioh2
, GUS_VOICE_SELECT
, (unsigned char) GUS_VOICE_LEFT
);
1068 SELECT_GUS_REG(iot
, ioh2
, GUSREG_PAN_POS
);
1069 bus_space_write_1(iot
, ioh2
, GUS_DATA_HIGH
, GUS_PAN_FULL_LEFT
);
1071 bus_space_write_1(iot
, ioh2
, GUS_VOICE_SELECT
, (unsigned char) GUS_VOICE_RIGHT
);
1072 SELECT_GUS_REG(iot
, ioh2
, GUSREG_PAN_POS
);
1073 bus_space_write_1(iot
, ioh2
, GUS_DATA_HIGH
, GUS_PAN_FULL_RIGHT
);
1076 * Attach to the generic audio layer
1079 audio_attach_mi(hwif
,
1080 HAS_CODEC(sc
) ? (void *)&sc
->sc_codec
: (void *)sc
, &sc
->sc_dev
);
1084 gusopen(void *addr
, int flags
)
1086 struct gus_softc
*sc
;
1089 DPRINTF(("gusopen() called\n"));
1091 if (sc
->sc_flags
& GUS_OPEN
)
1095 * Some initialization
1098 sc
->sc_flags
|= GUS_OPEN
;
1100 sc
->sc_playbuf
= -1;
1102 sc
->sc_voc
[GUS_VOICE_LEFT
].start_addr
= GUS_MEM_OFFSET
- 1;
1103 sc
->sc_voc
[GUS_VOICE_LEFT
].current_addr
= GUS_MEM_OFFSET
;
1105 if (HAS_CODEC(sc
)) {
1106 ad1848_open(&sc
->sc_codec
.sc_ad1848
, flags
);
1107 sc
->sc_codec
.sc_ad1848
.mute
[AD1848_AUX1_CHANNEL
] = 0;
1109 /* turn on DAC output */
1110 ad1848_mute_channel(&sc
->sc_codec
.sc_ad1848
,
1111 AD1848_AUX1_CHANNEL
, 0);
1112 if (flags
& FREAD
) {
1113 sc
->sc_codec
.sc_ad1848
.mute
[AD1848_MONO_CHANNEL
] = 0;
1114 ad1848_mute_channel(&sc
->sc_codec
.sc_ad1848
,
1115 AD1848_MONO_CHANNEL
, 0);
1117 } else if (flags
& FREAD
) {
1118 /* enable/unmute the microphone */
1119 if (HAS_MIXER(sc
)) {
1120 gusics_mic_mute(&sc
->sc_mixer
, 0);
1122 gus_mic_ctl(sc
, SPKR_ON
);
1124 if (sc
->sc_nbufs
== 0)
1125 gus_round_blocksize(sc
, GUS_BUFFER_MULTIPLE
, /* default blksiz */
1131 gusmaxopen(void *addr
, int flags
)
1133 struct ad1848_isa_softc
*ac
;
1136 return gusopen(ac
->sc_ad1848
.parent
, flags
);
1140 gus_deinterleave(struct gus_softc
*sc
, void *tbuf
, int size
)
1142 /* deinterleave the stereo data. We can use sc->sc_deintr_buf
1143 for scratch space. */
1146 if (size
> sc
->sc_blocksize
) {
1147 printf("gus: deinterleave %d > %d\n", size
, sc
->sc_blocksize
);
1149 } else if (size
< sc
->sc_blocksize
) {
1150 DPRINTF(("gus: deinterleave %d < %d\n", size
, sc
->sc_blocksize
));
1156 if (sc
->sc_precision
== 16) {
1157 u_short
*dei
= sc
->sc_deintr_buf
;
1158 u_short
*sbuf
= tbuf
;
1159 size
>>= 1; /* bytecnt to shortcnt */
1160 /* copy 2nd of each pair of samples to the staging area, while
1161 compacting the 1st of each pair into the original area. */
1162 for (i
= 0; i
< size
/2-1; i
++) {
1163 dei
[i
] = sbuf
[i
*2+1];
1164 sbuf
[i
+1] = sbuf
[i
*2+2];
1167 * this has copied one less sample than half of the
1168 * buffer. The first sample of the 1st stream was
1169 * already in place and didn't need copying.
1170 * Therefore, we've moved all of the 1st stream's
1171 * samples into place. We have one sample from 2nd
1172 * stream in the last slot of original area, not
1173 * copied to the staging area (But we don't need to!).
1174 * Copy the remainder of the original stream into place.
1176 memcpy(&sbuf
[size
/2], dei
, i
* sizeof(short));
1178 u_char
*dei
= sc
->sc_deintr_buf
;
1179 u_char
*sbuf
= tbuf
;
1180 for (i
= 0; i
< size
/2-1; i
++) {
1181 dei
[i
] = sbuf
[i
*2+1];
1182 sbuf
[i
+1] = sbuf
[i
*2+2];
1184 memcpy(&sbuf
[size
/2], dei
, i
);
1189 * Actually output a buffer to the DSP chip
1193 gusmax_dma_output(void *addr
, void *tbuf
, int size
,
1194 void (*intr
)(void *), void *arg
)
1196 struct ad1848_isa_softc
*ac
;
1199 return gus_dma_output(ac
->sc_ad1848
.parent
, tbuf
, size
, intr
, arg
);
1203 * called at splgus() from interrupt handler.
1206 stereo_dmaintr(void *arg
)
1208 struct gus_softc
*sc
;
1209 struct stereo_dma_intr
*sa
;
1211 DMAPRINTF(("stereo_dmaintr"));
1213 sa
= &sc
->sc_stereo
;
1216 * Put other half in its place, then call the real interrupt routine :)
1219 sc
->sc_dmaoutintr
= sa
->intr
;
1220 sc
->sc_outarg
= sa
->arg
;
1224 microtime(&dmarecords
[dmarecord_index
].tv
);
1225 dmarecords
[dmarecord_index
].gusaddr
= sa
->dmabuf
;
1226 dmarecords
[dmarecord_index
].bsdaddr
= sa
->buffer
;
1227 dmarecords
[dmarecord_index
].count
= sa
->size
;
1228 dmarecords
[dmarecord_index
].channel
= 1;
1229 dmarecords
[dmarecord_index
].direction
= 1;
1230 dmarecord_index
= (dmarecord_index
+ 1) % NDMARECS
;
1234 gusdmaout(sc
, sa
->flags
, sa
->dmabuf
, (void *) sa
->buffer
, sa
->size
);
1245 * Start up DMA output to the card.
1246 * Called at splgus/splaudio already, either from intr handler or from
1247 * generic audio code.
1250 gus_dma_output(void *addr
, void *tbuf
, int size
,
1251 void (*intr
)(void *), void *arg
)
1253 struct gus_softc
*sc
;
1258 DMAPRINTF(("gus_dma_output %d @ %p\n", size
, tbuf
));
1262 if (size
!= sc
->sc_blocksize
) {
1263 DPRINTF(("gus_dma_output reqsize %d not sc_blocksize %d\n",
1264 size
, sc
->sc_blocksize
));
1268 flags
= GUSMASK_DMA_WRITE
;
1269 if (sc
->sc_precision
== 16)
1270 flags
|= GUSMASK_DMA_DATA_SIZE
;
1271 if (sc
->sc_encoding
== AUDIO_ENCODING_ULAW
||
1272 sc
->sc_encoding
== AUDIO_ENCODING_ALAW
||
1273 sc
->sc_encoding
== AUDIO_ENCODING_ULINEAR_BE
||
1274 sc
->sc_encoding
== AUDIO_ENCODING_ULINEAR_LE
)
1275 flags
|= GUSMASK_DMA_INVBIT
;
1277 if (sc
->sc_channels
== 2) {
1278 if (sc
->sc_precision
== 16) {
1280 DPRINTF(("gus_dma_output: unpaired 16bit samples"));
1283 } else if (size
& 1) {
1284 DPRINTF(("gus_dma_output: unpaired samples"));
1290 gus_deinterleave(sc
, (void *)buffer
, size
);
1294 boarddma
= size
* sc
->sc_dmabuf
+ GUS_MEM_OFFSET
;
1296 sc
->sc_stereo
.intr
= intr
;
1297 sc
->sc_stereo
.arg
= arg
;
1298 sc
->sc_stereo
.size
= size
;
1299 sc
->sc_stereo
.dmabuf
= boarddma
+ GUS_LEFT_RIGHT_OFFSET
;
1300 sc
->sc_stereo
.buffer
= buffer
+ size
;
1301 sc
->sc_stereo
.flags
= flags
;
1303 intr
= stereo_dmaintr
;
1307 boarddma
= size
* sc
->sc_dmabuf
+ GUS_MEM_OFFSET
;
1310 sc
->sc_flags
|= GUS_LOCKED
;
1311 sc
->sc_dmaoutintr
= intr
;
1312 sc
->sc_outarg
= arg
;
1316 microtime(&dmarecords
[dmarecord_index
].tv
);
1317 dmarecords
[dmarecord_index
].gusaddr
= boarddma
;
1318 dmarecords
[dmarecord_index
].bsdaddr
= buffer
;
1319 dmarecords
[dmarecord_index
].count
= size
;
1320 dmarecords
[dmarecord_index
].channel
= 0;
1321 dmarecords
[dmarecord_index
].direction
= 1;
1322 dmarecord_index
= (dmarecord_index
+ 1) % NDMARECS
;
1326 gusdmaout(sc
, flags
, boarddma
, (void *) buffer
, size
);
1332 gusmax_close(void *addr
)
1334 struct ad1848_isa_softc
*ac
;
1335 struct gus_softc
*sc
;
1338 sc
= ac
->sc_ad1848
.parent
;
1340 ac
->mute
[AD1848_AUX1_CHANNEL
] = MUTE_ALL
;
1341 ad1848_mute_channel(ac
, MUTE_ALL
); /* turn off DAC output */
1343 ad1848_close(&ac
->sc_ad1848
);
1348 * Close out device stuff. Called at splgus() from generic audio layer.
1351 gusclose(void *addr
)
1353 struct gus_softc
*sc
;
1356 DPRINTF(("gus_close: sc=%p\n", sc
));
1359 /* if (sc->sc_flags & GUS_DMAOUT_ACTIVE) */ {
1360 gus_halt_out_dma(sc
);
1362 /* if (sc->sc_flags & GUS_DMAIN_ACTIVE) */ {
1363 gus_halt_in_dma(sc
);
1365 sc
->sc_flags
&= ~(GUS_OPEN
|GUS_LOCKED
|GUS_DMAOUT_ACTIVE
|GUS_DMAIN_ACTIVE
);
1367 if (sc
->sc_deintr_buf
) {
1368 free(sc
->sc_deintr_buf
, M_DEVBUF
);
1369 sc
->sc_deintr_buf
= NULL
;
1371 /* turn off speaker, etc. */
1373 /* make sure the voices shut up: */
1374 gus_stop_voice(sc
, GUS_VOICE_LEFT
, 1);
1375 gus_stop_voice(sc
, GUS_VOICE_RIGHT
, 0);
1379 * Service interrupts. Farm them off to helper routines if we are using the
1380 * GUS for simple playback/record
1392 struct gus_softc
*sc
;
1393 bus_space_tag_t iot
;
1394 bus_space_handle_t ioh1
;
1395 bus_space_handle_t ioh2
;
1399 DPRINTF(("gusintr\n"));
1409 retval
= ad1848_isa_intr(&sc
->sc_codec
);
1410 if ((intr
= bus_space_read_1(iot
, ioh1
, GUS_IRQ_STATUS
)) & GUSMASK_IRQ_DMATC
) {
1411 DMAPRINTF(("gusintr DMA flags=%x\n", sc
->sc_flags
));
1415 retval
+= gus_dmaout_intr(sc
);
1416 if (sc
->sc_flags
& GUS_DMAIN_ACTIVE
) {
1417 SELECT_GUS_REG(iot
, ioh2
, GUSREG_SAMPLE_CONTROL
);
1418 intr
= bus_space_read_1(iot
, ioh2
, GUS_DATA_HIGH
);
1419 if (intr
& GUSMASK_SAMPLE_DMATC
) {
1420 retval
+= gus_dmain_intr(sc
);
1424 if (intr
& (GUSMASK_IRQ_VOICE
| GUSMASK_IRQ_VOLUME
)) {
1425 DMAPRINTF(("gusintr voice flags=%x\n", sc
->sc_flags
));
1429 retval
+= gus_voice_intr(sc
);
1436 int gus_bufcnt
[GUS_MEM_FOR_BUFFERS
/ GUS_BUFFER_MULTIPLE
];
1437 int gus_restart
; /* how many restarts? */
1438 int gus_stops
; /* how many times did voice stop? */
1439 int gus_falsestops
; /* stopped but not done? */
1452 } playstats
[NDMARECS
];
1457 gus_dmaout_timeout(void *arg
)
1459 struct gus_softc
*sc
;
1460 bus_space_tag_t iot
;
1461 bus_space_handle_t ioh2
;
1467 printf("%s: dmaout timeout\n", device_xname(&sc
->sc_dev
));
1472 SELECT_GUS_REG(iot
, ioh2
, GUSREG_DMA_CONTROL
);
1473 bus_space_write_1(iot
, ioh2
, GUS_DATA_HIGH
, 0);
1475 /* XXX we will dmadone below? */
1476 isa_dmaabort(device_parent(&sc
->sc_dev
), sc
->sc_playdrq
);
1479 gus_dmaout_dointr(sc
);
1485 * Service DMA interrupts. This routine will only get called if we're doing
1486 * a DMA transfer for playback/record requests from the audio layer.
1490 gus_dmaout_intr(struct gus_softc
*sc
)
1492 bus_space_tag_t iot
;
1493 bus_space_handle_t ioh2
;
1498 * If we got a DMA transfer complete from the GUS DRAM, then deal
1502 SELECT_GUS_REG(iot
, ioh2
, GUSREG_DMA_CONTROL
);
1503 if (bus_space_read_1(iot
, ioh2
, GUS_DATA_HIGH
) & GUSMASK_DMA_IRQPEND
) {
1504 callout_stop(&sc
->sc_dmaout_ch
);
1505 gus_dmaout_dointr(sc
);
1512 gus_dmaout_dointr(struct gus_softc
*sc
)
1514 bus_space_tag_t iot
;
1515 bus_space_handle_t ioh2
;
1519 /* sc->sc_dmaoutcnt - 1 because DMA controller counts from zero?. */
1520 isa_dmadone(sc
->sc_ic
, sc
->sc_playdrq
);
1521 sc
->sc_flags
&= ~GUS_DMAOUT_ACTIVE
; /* pending DMA is done */
1522 DMAPRINTF(("gus_dmaout_dointr %d @ %p\n", sc
->sc_dmaoutcnt
,
1523 sc
->sc_dmaoutaddr
));
1526 * to prevent clicking, we need to copy last sample
1527 * from last buffer to scratch area just before beginning of
1528 * buffer. However, if we're doing formats that are converted by
1529 * the card during the DMA process, we need to pick up the converted
1530 * byte rather than the one we have in memory.
1532 if (sc
->sc_dmabuf
== sc
->sc_nbufs
- 1) {
1534 switch (sc
->sc_encoding
) {
1535 case AUDIO_ENCODING_SLINEAR_LE
:
1536 case AUDIO_ENCODING_SLINEAR_BE
:
1537 if (sc
->sc_precision
== 8)
1539 /* we have the native format */
1540 for (i
= 1; i
<= 2; i
++)
1541 guspoke(iot
, ioh2
, sc
->sc_gusaddr
-
1542 (sc
->sc_nbufs
- 1) * sc
->sc_chanblocksize
- i
,
1543 sc
->sc_dmaoutaddr
[sc
->sc_dmaoutcnt
-i
]);
1545 case AUDIO_ENCODING_ULINEAR_LE
:
1546 case AUDIO_ENCODING_ULINEAR_BE
:
1547 guspoke(iot
, ioh2
, sc
->sc_gusaddr
-
1548 (sc
->sc_nbufs
- 1) * sc
->sc_chanblocksize
- 2,
1550 sc
->sc_gusaddr
+ sc
->sc_chanblocksize
- 2));
1551 case AUDIO_ENCODING_ALAW
:
1552 case AUDIO_ENCODING_ULAW
:
1554 /* we need to fetch the translated byte, then stuff it. */
1555 guspoke(iot
, ioh2
, sc
->sc_gusaddr
-
1556 (sc
->sc_nbufs
- 1) * sc
->sc_chanblocksize
- 1,
1558 sc
->sc_gusaddr
+ sc
->sc_chanblocksize
- 1));
1563 * If this is the first half of stereo, "ignore" this one
1564 * and copy out the second half.
1566 if (sc
->sc_dmaoutintr
== stereo_dmaintr
) {
1567 (*sc
->sc_dmaoutintr
)(sc
->sc_outarg
);
1571 * If the voice is stopped, then start it. Reset the loop
1572 * and roll bits. Call the audio layer routine, since if
1573 * we're starting a stopped voice, that means that the next
1574 * buffer can be filled
1577 sc
->sc_flags
&= ~GUS_LOCKED
;
1578 if (sc
->sc_voc
[GUS_VOICE_LEFT
].voccntl
&
1579 GUSMASK_VOICE_STOPPED
) {
1580 if (sc
->sc_flags
& GUS_PLAYING
) {
1581 printf("%s: playing yet stopped?\n", device_xname(&sc
->sc_dev
));
1583 sc
->sc_bufcnt
++; /* another yet to be played */
1584 gus_start_playing(sc
, sc
->sc_dmabuf
);
1588 * set the sound action based on which buffer we
1589 * just transferred. If we just transferred buffer 0
1590 * we want the sound to loop when it gets to the nth
1591 * buffer; if we just transferred
1592 * any other buffer, we want the sound to roll over
1593 * at least one more time. The voice interrupt
1594 * handlers will take care of accounting &
1595 * setting control bits if it's not caught up to us
1598 if (++sc
->sc_bufcnt
== 2) {
1601 * If we're too slow in reaction here,
1602 * the voice could be just approaching the
1603 * end of its run. It should be set to stop,
1604 * so these adjustments might not DTRT.
1606 if (sc
->sc_dmabuf
== 0 &&
1607 sc
->sc_playbuf
== sc
->sc_nbufs
- 1) {
1608 /* player is just at the last tbuf, we're at the
1609 first. Turn on looping, turn off rolling. */
1610 sc
->sc_voc
[GUS_VOICE_LEFT
].voccntl
|= GUSMASK_LOOP_ENABLE
;
1611 sc
->sc_voc
[GUS_VOICE_LEFT
].volcntl
&= ~GUSMASK_VOICE_ROLL
;
1612 playstats
[playcntr
].vaction
= 3;
1614 /* player is at previous tbuf:
1615 turn on rolling, turn off looping */
1616 sc
->sc_voc
[GUS_VOICE_LEFT
].voccntl
&= ~GUSMASK_LOOP_ENABLE
;
1617 sc
->sc_voc
[GUS_VOICE_LEFT
].volcntl
|= GUSMASK_VOICE_ROLL
;
1618 playstats
[playcntr
].vaction
= 4;
1622 microtime(&playstats
[playcntr
].tv
);
1623 playstats
[playcntr
].endaddr
1624 = sc
->sc_voc
[GUS_VOICE_LEFT
].end_addr
;
1625 playstats
[playcntr
].voccntl
1626 = sc
->sc_voc
[GUS_VOICE_LEFT
].voccntl
;
1627 playstats
[playcntr
].volcntl
1628 = sc
->sc_voc
[GUS_VOICE_LEFT
].volcntl
;
1629 playstats
[playcntr
].playbuf
= sc
->sc_playbuf
;
1630 playstats
[playcntr
].dmabuf
= sc
->sc_dmabuf
;
1631 playstats
[playcntr
].bufcnt
= sc
->sc_bufcnt
;
1632 playstats
[playcntr
].curaddr
1633 = gus_get_curaddr(sc
, GUS_VOICE_LEFT
);
1634 playcntr
= (playcntr
+ 1) % NDMARECS
;
1637 bus_space_write_1(iot
, ioh2
, GUS_VOICE_SELECT
, GUS_VOICE_LEFT
);
1638 SELECT_GUS_REG(iot
, ioh2
, GUSREG_VOICE_CNTL
);
1639 bus_space_write_1(iot
, ioh2
, GUS_DATA_HIGH
,
1640 sc
->sc_voc
[GUS_VOICE_LEFT
].voccntl
);
1641 SELECT_GUS_REG(iot
, ioh2
, GUSREG_VOLUME_CONTROL
);
1642 bus_space_write_1(iot
, ioh2
, GUS_DATA_HIGH
,
1643 sc
->sc_voc
[GUS_VOICE_LEFT
].volcntl
);
1646 gus_bufcnt
[sc
->sc_bufcnt
-1]++;
1648 * flip to the next DMA buffer
1651 sc
->sc_dmabuf
= ++sc
->sc_dmabuf
% sc
->sc_nbufs
;
1653 * See comments below about DMA admission control strategy.
1654 * We can call the upper level here if we have an
1655 * idle buffer (not currently playing) to DMA into.
1657 if (sc
->sc_dmaoutintr
&& sc
->sc_bufcnt
< sc
->sc_nbufs
) {
1658 /* clean out to prevent double calls */
1659 void (*pfunc
)(void *);
1662 pfunc
= sc
->sc_dmaoutintr
;
1663 arg
= sc
->sc_outarg
;
1665 sc
->sc_dmaoutintr
= 0;
1671 * Service voice interrupts
1675 gus_voice_intr(struct gus_softc
*sc
)
1677 bus_space_tag_t iot
;
1678 bus_space_handle_t ioh2
;
1679 int ignore
, voice
, rval
;
1680 unsigned char intr
, status
;
1687 * The point of this may not be obvious at first. A voice can
1688 * interrupt more than once; according to the GUS SDK we are supposed
1689 * to ignore multiple interrupts for the same voice.
1693 SELECT_GUS_REG(iot
, ioh2
, GUSREG_IRQ_STATUS
);
1694 intr
= bus_space_read_1(iot
, ioh2
, GUS_DATA_HIGH
);
1696 if ((intr
& (GUSMASK_WIRQ_VOLUME
| GUSMASK_WIRQ_VOICE
))
1697 == (GUSMASK_WIRQ_VOLUME
| GUSMASK_WIRQ_VOICE
))
1699 * No more interrupts, time to return
1703 if ((intr
& GUSMASK_WIRQ_VOICE
) == 0) {
1706 * We've got a voice interrupt. Ignore previous
1707 * interrupts by the same voice.
1711 voice
= intr
& GUSMASK_WIRQ_VOICEMASK
;
1713 if ((1 << voice
) & ignore
)
1716 ignore
|= 1 << voice
;
1719 * If the voice is stopped, then force it to stop
1720 * (this stops it from continuously generating IRQs)
1723 SELECT_GUS_REG(iot
, ioh2
, GUSREG_VOICE_CNTL
+0x80);
1724 status
= bus_space_read_1(iot
, ioh2
, GUS_DATA_HIGH
);
1725 if (status
& GUSMASK_VOICE_STOPPED
) {
1726 if (voice
!= GUS_VOICE_LEFT
) {
1727 DMAPRINTF(("%s: spurious voice %d stop?\n",
1728 device_xname(&sc
->sc_dev
), voice
));
1729 gus_stop_voice(sc
, voice
, 0);
1732 gus_stop_voice(sc
, voice
, 1);
1733 /* also kill right voice */
1734 gus_stop_voice(sc
, GUS_VOICE_RIGHT
, 0);
1735 sc
->sc_bufcnt
--; /* it finished a buffer */
1736 if (sc
->sc_bufcnt
> 0) {
1738 * probably a race to get here: the
1739 * voice stopped while the DMA code was
1740 * just trying to get the next buffer
1741 * in place. Start the voice again.
1743 printf("%s: stopped voice not drained? (%x)\n",
1744 device_xname(&sc
->sc_dev
), sc
->sc_bufcnt
);
1747 sc
->sc_playbuf
= ++sc
->sc_playbuf
% sc
->sc_nbufs
;
1748 gus_start_playing(sc
, sc
->sc_playbuf
);
1749 } else if (sc
->sc_bufcnt
< 0) {
1750 panic("%s: negative bufcnt in stopped voice",
1751 device_xname(&sc
->sc_dev
));
1753 sc
->sc_playbuf
= -1; /* none are active */
1756 /* fall through to callback and admit another
1758 } else if (sc
->sc_bufcnt
!= 0) {
1760 * This should always be taken if the voice
1764 if (gus_continue_playing(sc
, voice
)) {
1766 * we shouldn't have continued--active
1767 * DMA is in the way in the ring, for
1768 * some as-yet undebugged reason.
1770 gus_stop_voice(sc
, GUS_VOICE_LEFT
, 1);
1771 /* also kill right voice */
1772 gus_stop_voice(sc
, GUS_VOICE_RIGHT
, 0);
1773 sc
->sc_playbuf
= -1;
1778 * call the upper level to send on down another
1779 * block. We do admission rate control as follows:
1781 * When starting up output (in the first N
1782 * blocks), call the upper layer after the DMA is
1783 * complete (see above in gus_dmaout_intr()).
1785 * When output is already in progress and we have
1786 * no more GUS buffers to use for DMA, the DMA
1787 * output routines do not call the upper layer.
1788 * Instead, we call the DMA completion routine
1789 * here, after the voice interrupts indicating
1790 * that it's finished with a buffer.
1792 * However, don't call anything here if the DMA
1793 * output flag is set, (which shouldn't happen)
1794 * because we'll squish somebody else's DMA if
1795 * that's the case. When DMA is done, it will
1796 * call back if there is a spare buffer.
1798 if (sc
->sc_dmaoutintr
&& !(sc
->sc_flags
& GUS_LOCKED
)) {
1799 if (sc
->sc_dmaoutintr
== stereo_dmaintr
)
1800 printf("gusdmaout botch?\n");
1802 /* clean out to avoid double calls */
1803 void (*pfunc
)(void *);
1806 pfunc
= sc
->sc_dmaoutintr
;
1807 arg
= sc
->sc_outarg
;
1809 sc
->sc_dmaoutintr
= 0;
1816 * Ignore other interrupts for now
1823 * Start the voices playing, with buffer BUFNO.
1826 gus_start_playing(struct gus_softc
*sc
, int bufno
)
1828 bus_space_tag_t iot
;
1829 bus_space_handle_t ioh2
;
1834 * Loop or roll if we have buffers ready.
1837 if (sc
->sc_bufcnt
== 1) {
1838 sc
->sc_voc
[GUS_VOICE_LEFT
].voccntl
&= ~(GUSMASK_LOOP_ENABLE
);
1839 sc
->sc_voc
[GUS_VOICE_LEFT
].volcntl
&= ~(GUSMASK_VOICE_ROLL
);
1841 if (bufno
== sc
->sc_nbufs
- 1) {
1842 sc
->sc_voc
[GUS_VOICE_LEFT
].voccntl
|= GUSMASK_LOOP_ENABLE
;
1843 sc
->sc_voc
[GUS_VOICE_LEFT
].volcntl
&= ~(GUSMASK_VOICE_ROLL
);
1845 sc
->sc_voc
[GUS_VOICE_LEFT
].voccntl
&= ~GUSMASK_LOOP_ENABLE
;
1846 sc
->sc_voc
[GUS_VOICE_LEFT
].volcntl
|= GUSMASK_VOICE_ROLL
;
1850 bus_space_write_1(iot
, ioh2
, GUS_VOICE_SELECT
, GUS_VOICE_LEFT
);
1852 SELECT_GUS_REG(iot
, ioh2
, GUSREG_VOICE_CNTL
);
1853 bus_space_write_1(iot
, ioh2
, GUS_DATA_HIGH
, sc
->sc_voc
[GUS_VOICE_LEFT
].voccntl
);
1855 SELECT_GUS_REG(iot
, ioh2
, GUSREG_VOLUME_CONTROL
);
1856 bus_space_write_1(iot
, ioh2
, GUS_DATA_HIGH
, sc
->sc_voc
[GUS_VOICE_LEFT
].volcntl
);
1858 sc
->sc_voc
[GUS_VOICE_LEFT
].current_addr
=
1859 GUS_MEM_OFFSET
+ sc
->sc_chanblocksize
* bufno
;
1860 sc
->sc_voc
[GUS_VOICE_LEFT
].end_addr
=
1861 sc
->sc_voc
[GUS_VOICE_LEFT
].current_addr
+ sc
->sc_chanblocksize
- 1;
1862 sc
->sc_voc
[GUS_VOICE_RIGHT
].current_addr
=
1863 sc
->sc_voc
[GUS_VOICE_LEFT
].current_addr
+
1864 (gus_dostereo
&& sc
->sc_channels
== 2 ? GUS_LEFT_RIGHT_OFFSET
: 0);
1866 * set up right channel to just loop forever, no interrupts,
1867 * starting at the buffer we just filled. We'll feed it data
1868 * at the same time as left channel.
1870 sc
->sc_voc
[GUS_VOICE_RIGHT
].voccntl
|= GUSMASK_LOOP_ENABLE
;
1871 sc
->sc_voc
[GUS_VOICE_RIGHT
].volcntl
&= ~(GUSMASK_VOICE_ROLL
);
1875 microtime(&playstats
[playcntr
].tv
);
1876 playstats
[playcntr
].curaddr
= sc
->sc_voc
[GUS_VOICE_LEFT
].current_addr
;
1878 playstats
[playcntr
].voccntl
= sc
->sc_voc
[GUS_VOICE_LEFT
].voccntl
;
1879 playstats
[playcntr
].volcntl
= sc
->sc_voc
[GUS_VOICE_LEFT
].volcntl
;
1880 playstats
[playcntr
].endaddr
= sc
->sc_voc
[GUS_VOICE_LEFT
].end_addr
;
1881 playstats
[playcntr
].playbuf
= bufno
;
1882 playstats
[playcntr
].dmabuf
= sc
->sc_dmabuf
;
1883 playstats
[playcntr
].bufcnt
= sc
->sc_bufcnt
;
1884 playstats
[playcntr
].vaction
= 5;
1885 playcntr
= (playcntr
+ 1) % NDMARECS
;
1889 bus_space_write_1(iot
, ioh2
, GUS_VOICE_SELECT
, GUS_VOICE_RIGHT
);
1890 SELECT_GUS_REG(iot
, ioh2
, GUSREG_VOICE_CNTL
);
1891 bus_space_write_1(iot
, ioh2
, GUS_DATA_HIGH
, sc
->sc_voc
[GUS_VOICE_RIGHT
].voccntl
);
1892 SELECT_GUS_REG(iot
, ioh2
, GUSREG_VOLUME_CONTROL
);
1893 bus_space_write_1(iot
, ioh2
, GUS_DATA_HIGH
, sc
->sc_voc
[GUS_VOICE_RIGHT
].volcntl
);
1895 gus_start_voice(sc
, GUS_VOICE_RIGHT
, 0);
1896 gus_start_voice(sc
, GUS_VOICE_LEFT
, 1);
1897 if (sc
->sc_playbuf
== -1)
1898 /* mark start of playing */
1899 sc
->sc_playbuf
= bufno
;
1903 gus_continue_playing(struct gus_softc
*sc
, int voice
)
1905 bus_space_tag_t iot
;
1906 bus_space_handle_t ioh2
;
1909 * stop this voice from interrupting while we work.
1914 SELECT_GUS_REG(iot
, ioh2
, GUSREG_VOICE_CNTL
);
1915 bus_space_write_1(iot
, ioh2
, GUS_DATA_HIGH
,
1916 sc
->sc_voc
[voice
].voccntl
& ~(GUSMASK_VOICE_IRQ
));
1919 * update playbuf to point to the buffer the hardware just started
1922 sc
->sc_playbuf
= ++sc
->sc_playbuf
% sc
->sc_nbufs
;
1925 * account for buffer just finished
1927 if (--sc
->sc_bufcnt
== 0) {
1928 DPRINTF(("gus: bufcnt 0 on continuing voice?\n"));
1930 if (sc
->sc_playbuf
== sc
->sc_dmabuf
&& (sc
->sc_flags
& GUS_LOCKED
)) {
1931 aprint_error_dev(&sc
->sc_dev
, "continue into active dmabuf?\n");
1936 * Select the end of the buffer based on the currently active
1937 * buffer, [plus extra contiguous buffers (if ready)].
1941 * set endpoint at end of buffer we just started playing.
1943 * The total gets -1 because end addrs are one less than you might
1944 * think (the end_addr is the address of the last sample to play)
1946 gus_set_endaddr(sc
, voice
, GUS_MEM_OFFSET
+
1947 sc
->sc_chanblocksize
* (sc
->sc_playbuf
+ 1) - 1);
1949 if (sc
->sc_bufcnt
< 2) {
1951 * Clear out the loop and roll flags, and rotate the currently
1952 * playing buffer. That way, if we don't manage to get more
1953 * data before this buffer finishes, we'll just stop.
1955 sc
->sc_voc
[voice
].voccntl
&= ~GUSMASK_LOOP_ENABLE
;
1956 sc
->sc_voc
[voice
].volcntl
&= ~GUSMASK_VOICE_ROLL
;
1957 playstats
[playcntr
].vaction
= 0;
1960 * We have some buffers to play. set LOOP if we're on the
1961 * last buffer in the ring, otherwise set ROLL.
1963 if (sc
->sc_playbuf
== sc
->sc_nbufs
- 1) {
1964 sc
->sc_voc
[voice
].voccntl
|= GUSMASK_LOOP_ENABLE
;
1965 sc
->sc_voc
[voice
].volcntl
&= ~GUSMASK_VOICE_ROLL
;
1966 playstats
[playcntr
].vaction
= 1;
1968 sc
->sc_voc
[voice
].voccntl
&= ~GUSMASK_LOOP_ENABLE
;
1969 sc
->sc_voc
[voice
].volcntl
|= GUSMASK_VOICE_ROLL
;
1970 playstats
[playcntr
].vaction
= 2;
1975 microtime(&playstats
[playcntr
].tv
);
1976 playstats
[playcntr
].curaddr
= gus_get_curaddr(sc
, voice
);
1978 playstats
[playcntr
].voccntl
= sc
->sc_voc
[voice
].voccntl
;
1979 playstats
[playcntr
].volcntl
= sc
->sc_voc
[voice
].volcntl
;
1980 playstats
[playcntr
].endaddr
= sc
->sc_voc
[voice
].end_addr
;
1981 playstats
[playcntr
].playbuf
= sc
->sc_playbuf
;
1982 playstats
[playcntr
].dmabuf
= sc
->sc_dmabuf
;
1983 playstats
[playcntr
].bufcnt
= sc
->sc_bufcnt
;
1984 playcntr
= (playcntr
+ 1) % NDMARECS
;
1989 * (re-)set voice parameters. This will reenable interrupts from this
1993 SELECT_GUS_REG(iot
, ioh2
, GUSREG_VOICE_CNTL
);
1994 bus_space_write_1(iot
, ioh2
, GUS_DATA_HIGH
, sc
->sc_voc
[voice
].voccntl
);
1995 SELECT_GUS_REG(iot
, ioh2
, GUSREG_VOLUME_CONTROL
);
1996 bus_space_write_1(iot
, ioh2
, GUS_DATA_HIGH
, sc
->sc_voc
[voice
].volcntl
);
2001 * Send/receive data into GUS's DRAM using DMA. Called at splgus()
2004 gusdmaout(struct gus_softc
*sc
, int flags
,
2005 u_long gusaddr
, void *buffaddr
, int length
)
2008 bus_space_tag_t iot
;
2009 bus_space_handle_t ioh2
;
2011 DMAPRINTF(("gusdmaout flags=%x scflags=%x\n", flags
, sc
->sc_flags
));
2012 c
= (unsigned char) flags
;
2016 sc
->sc_gusaddr
= gusaddr
;
2019 * If we're using a 16 bit DMA channel, we have to jump through some
2020 * extra hoops; this includes translating the DRAM address a bit
2023 if (sc
->sc_playdrq
>= 4) {
2024 c
|= GUSMASK_DMA_WIDTH
;
2025 gusaddr
= convert_to_16bit(gusaddr
);
2029 * Add flag bits that we always set - fast DMA, enable IRQ
2032 c
|= GUSMASK_DMA_ENABLE
| GUSMASK_DMA_R0
| GUSMASK_DMA_IRQ
;
2035 * Make sure the GUS _isn't_ setup for DMA
2038 SELECT_GUS_REG(iot
, ioh2
, GUSREG_DMA_CONTROL
);
2039 bus_space_write_1(iot
, ioh2
, GUS_DATA_HIGH
, 0);
2042 * Tell the PC DMA controller to start doing DMA
2045 sc
->sc_dmaoutaddr
= (u_char
*) buffaddr
;
2046 sc
->sc_dmaoutcnt
= length
;
2047 isa_dmastart(sc
->sc_ic
, sc
->sc_playdrq
, buffaddr
, length
,
2048 NULL
, DMAMODE_WRITE
, BUS_DMA_NOWAIT
);
2051 * Set up DMA address - use the upper 16 bits ONLY
2054 sc
->sc_flags
|= GUS_DMAOUT_ACTIVE
;
2056 SELECT_GUS_REG(iot
, ioh2
, GUSREG_DMA_START
);
2057 bus_space_write_2(iot
, ioh2
, GUS_DATA_LOW
, (int) (gusaddr
>> 4));
2060 * Tell the GUS to start doing DMA
2063 SELECT_GUS_REG(iot
, ioh2
, GUSREG_DMA_CONTROL
);
2064 bus_space_write_1(iot
, ioh2
, GUS_DATA_HIGH
, c
);
2067 * XXX If we don't finish in one second, give up...
2069 callout_reset(&sc
->sc_dmaout_ch
, hz
, gus_dmaout_timeout
, sc
);
2073 * Start a voice playing on the GUS. Called from interrupt handler at
2078 gus_start_voice(struct gus_softc
*sc
, int voice
, int intrs
)
2080 bus_space_tag_t iot
;
2081 bus_space_handle_t ioh2
;
2089 * Pick all the values for the voice out of the gus_voice struct
2090 * and use those to program the voice
2093 start
= sc
->sc_voc
[voice
].start_addr
;
2094 current
= sc
->sc_voc
[voice
].current_addr
;
2095 end
= sc
->sc_voc
[voice
].end_addr
;
2098 * If we're using 16 bit data, mangle the addresses a bit
2101 if (sc
->sc_voc
[voice
].voccntl
& GUSMASK_DATA_SIZE16
) {
2102 /* -1 on start so that we get onto sample boundary--other
2103 * code always sets it for 1-byte rollover protection */
2104 start
= convert_to_16bit(start
-1);
2105 current
= convert_to_16bit(current
);
2106 end
= convert_to_16bit(end
);
2110 * Select the voice we want to use, and program the data addresses
2113 bus_space_write_1(iot
, ioh2
, GUS_VOICE_SELECT
, (unsigned char) voice
);
2115 SELECT_GUS_REG(iot
, ioh2
, GUSREG_START_ADDR_HIGH
);
2116 bus_space_write_2(iot
, ioh2
, GUS_DATA_LOW
, ADDR_HIGH(start
));
2117 SELECT_GUS_REG(iot
, ioh2
, GUSREG_START_ADDR_LOW
);
2118 bus_space_write_2(iot
, ioh2
, GUS_DATA_LOW
, ADDR_LOW(start
));
2120 SELECT_GUS_REG(iot
, ioh2
, GUSREG_CUR_ADDR_HIGH
);
2121 bus_space_write_2(iot
, ioh2
, GUS_DATA_LOW
, ADDR_HIGH(current
));
2122 SELECT_GUS_REG(iot
, ioh2
, GUSREG_CUR_ADDR_LOW
);
2123 bus_space_write_2(iot
, ioh2
, GUS_DATA_LOW
, ADDR_LOW(current
));
2125 SELECT_GUS_REG(iot
, ioh2
, GUSREG_END_ADDR_HIGH
);
2126 bus_space_write_2(iot
, ioh2
, GUS_DATA_LOW
, ADDR_HIGH(end
));
2127 SELECT_GUS_REG(iot
, ioh2
, GUSREG_END_ADDR_LOW
);
2128 bus_space_write_2(iot
, ioh2
, GUS_DATA_LOW
, ADDR_LOW(end
));
2131 * (maybe) enable interrupts, disable voice stopping
2135 sc
->sc_flags
|= GUS_PLAYING
; /* playing is about to start */
2136 sc
->sc_voc
[voice
].voccntl
|= GUSMASK_VOICE_IRQ
;
2137 DMAPRINTF(("gus voice playing=%x\n", sc
->sc_flags
));
2139 sc
->sc_voc
[voice
].voccntl
&= ~GUSMASK_VOICE_IRQ
;
2140 sc
->sc_voc
[voice
].voccntl
&= ~(GUSMASK_VOICE_STOPPED
|
2141 GUSMASK_STOP_VOICE
);
2144 * Tell the GUS about it. Note that we're doing volume ramping here
2145 * from 0 up to the set volume to help reduce clicks.
2148 SELECT_GUS_REG(iot
, ioh2
, GUSREG_START_VOLUME
);
2149 bus_space_write_1(iot
, ioh2
, GUS_DATA_HIGH
, 0x00);
2150 SELECT_GUS_REG(iot
, ioh2
, GUSREG_END_VOLUME
);
2151 bus_space_write_1(iot
, ioh2
, GUS_DATA_HIGH
,
2152 sc
->sc_voc
[voice
].current_volume
>> 4);
2153 SELECT_GUS_REG(iot
, ioh2
, GUSREG_CUR_VOLUME
);
2154 bus_space_write_2(iot
, ioh2
, GUS_DATA_LOW
, 0x00);
2155 SELECT_GUS_REG(iot
, ioh2
, GUSREG_VOLUME_RATE
);
2156 bus_space_write_1(iot
, ioh2
, GUS_DATA_HIGH
, 63);
2158 SELECT_GUS_REG(iot
, ioh2
, GUSREG_VOICE_CNTL
);
2159 bus_space_write_1(iot
, ioh2
, GUS_DATA_HIGH
, sc
->sc_voc
[voice
].voccntl
);
2160 SELECT_GUS_REG(iot
, ioh2
, GUSREG_VOLUME_CONTROL
);
2161 bus_space_write_1(iot
, ioh2
, GUS_DATA_HIGH
, 0x00);
2163 SELECT_GUS_REG(iot
, ioh2
, GUSREG_VOICE_CNTL
);
2164 bus_space_write_1(iot
, ioh2
, GUS_DATA_HIGH
, sc
->sc_voc
[voice
].voccntl
);
2165 SELECT_GUS_REG(iot
, ioh2
, GUSREG_VOLUME_CONTROL
);
2166 bus_space_write_1(iot
, ioh2
, GUS_DATA_HIGH
, 0x00);
2171 * Stop a given voice. called at splgus()
2174 gus_stop_voice(struct gus_softc
*sc
, int voice
, int intrs_too
)
2176 bus_space_tag_t iot
;
2177 bus_space_handle_t ioh2
;
2181 sc
->sc_voc
[voice
].voccntl
|= GUSMASK_VOICE_STOPPED
|
2184 sc
->sc_voc
[voice
].voccntl
&= ~(GUSMASK_VOICE_IRQ
);
2185 /* no more DMA to do */
2186 sc
->sc_flags
&= ~GUS_PLAYING
;
2188 DMAPRINTF(("gusintr voice notplaying=%x\n", sc
->sc_flags
));
2190 guspoke(iot
, ioh2
, 0L, 0);
2192 bus_space_write_1(iot
, ioh2
, GUS_VOICE_SELECT
, (unsigned char) voice
);
2194 SELECT_GUS_REG(iot
, ioh2
, GUSREG_CUR_VOLUME
);
2195 bus_space_write_2(iot
, ioh2
, GUS_DATA_LOW
, 0x0000);
2196 SELECT_GUS_REG(iot
, ioh2
, GUSREG_VOICE_CNTL
);
2197 bus_space_write_1(iot
, ioh2
, GUS_DATA_HIGH
, sc
->sc_voc
[voice
].voccntl
);
2199 SELECT_GUS_REG(iot
, ioh2
, GUSREG_CUR_VOLUME
);
2200 bus_space_write_2(iot
, ioh2
, GUS_DATA_LOW
, 0x0000);
2201 SELECT_GUS_REG(iot
, ioh2
, GUSREG_VOICE_CNTL
);
2202 bus_space_write_1(iot
, ioh2
, GUS_DATA_HIGH
, sc
->sc_voc
[voice
].voccntl
);
2204 SELECT_GUS_REG(iot
, ioh2
, GUSREG_CUR_ADDR_HIGH
);
2205 bus_space_write_2(iot
, ioh2
, GUS_DATA_LOW
, 0x0000);
2206 SELECT_GUS_REG(iot
, ioh2
, GUSREG_CUR_ADDR_LOW
);
2207 bus_space_write_2(iot
, ioh2
, GUS_DATA_LOW
, 0x0000);
2213 * Set the volume of a given voice. Called at splgus().
2216 gus_set_volume(struct gus_softc
*sc
, int voice
, int volume
)
2218 bus_space_tag_t iot
;
2219 bus_space_handle_t ioh2
;
2220 unsigned int gusvol
;
2224 gusvol
= gus_log_volumes
[volume
< 512 ? volume
: 511];
2226 sc
->sc_voc
[voice
].current_volume
= gusvol
;
2228 bus_space_write_1(iot
, ioh2
, GUS_VOICE_SELECT
, (unsigned char) voice
);
2230 SELECT_GUS_REG(iot
, ioh2
, GUSREG_START_VOLUME
);
2231 bus_space_write_1(iot
, ioh2
, GUS_DATA_HIGH
, (unsigned char) (gusvol
>> 4));
2233 SELECT_GUS_REG(iot
, ioh2
, GUSREG_END_VOLUME
);
2234 bus_space_write_1(iot
, ioh2
, GUS_DATA_HIGH
, (unsigned char) (gusvol
>> 4));
2236 SELECT_GUS_REG(iot
, ioh2
, GUSREG_CUR_VOLUME
);
2237 bus_space_write_2(iot
, ioh2
, GUS_DATA_LOW
, gusvol
<< 4);
2239 bus_space_write_2(iot
, ioh2
, GUS_DATA_LOW
, gusvol
<< 4);
2244 * Interface to the audio layer.
2248 gusmax_set_params(void *addr
, int setmode
, int usemode
, audio_params_t
*p
,
2249 audio_params_t
*r
, stream_filter_list_t
*pfil
,
2250 stream_filter_list_t
*rfil
)
2252 struct ad1848_isa_softc
*ac
;
2253 struct gus_softc
*sc
;
2257 sc
= ac
->sc_ad1848
.parent
;
2258 error
= ad1848_set_params(ac
, setmode
, usemode
, p
, r
, pfil
, rfil
);
2262 * ad1848_set_params() sets a filter for
2263 * SLINEAR_LE 8, SLINEAR_BE 16, ULINEAR_LE 16, ULINEAR_BE 16.
2264 * gus_set_params() sets a filter for
2265 * ULAW, ALAW, ULINEAR_BE (16), SLINEAR_BE (16)
2267 error
= gus_set_params(sc
, setmode
, usemode
, p
, r
, pfil
, rfil
);
2274 int setmode
, int usemode
,
2275 audio_params_t
*p
, audio_params_t
*r
,
2276 stream_filter_list_t
*pfil
, stream_filter_list_t
*rfil
)
2279 struct gus_softc
*sc
;
2283 switch (p
->encoding
) {
2284 case AUDIO_ENCODING_ULAW
:
2285 case AUDIO_ENCODING_ALAW
:
2286 case AUDIO_ENCODING_SLINEAR_LE
:
2287 case AUDIO_ENCODING_ULINEAR_LE
:
2288 case AUDIO_ENCODING_SLINEAR_BE
:
2289 case AUDIO_ENCODING_ULINEAR_BE
:
2297 if (p
->precision
== 8) {
2298 sc
->sc_voc
[GUS_VOICE_LEFT
].voccntl
&= ~GUSMASK_DATA_SIZE16
;
2299 sc
->sc_voc
[GUS_VOICE_RIGHT
].voccntl
&= ~GUSMASK_DATA_SIZE16
;
2301 sc
->sc_voc
[GUS_VOICE_LEFT
].voccntl
|= GUSMASK_DATA_SIZE16
;
2302 sc
->sc_voc
[GUS_VOICE_RIGHT
].voccntl
|= GUSMASK_DATA_SIZE16
;
2305 sc
->sc_encoding
= p
->encoding
;
2306 sc
->sc_precision
= p
->precision
;
2307 sc
->sc_channels
= p
->channels
;
2311 if (p
->sample_rate
> gus_max_frequency
[sc
->sc_voices
- GUS_MIN_VOICES
])
2312 p
->sample_rate
= gus_max_frequency
[sc
->sc_voices
- GUS_MIN_VOICES
];
2313 if (setmode
& AUMODE_RECORD
)
2314 sc
->sc_irate
= p
->sample_rate
;
2315 if (setmode
& AUMODE_PLAY
)
2316 sc
->sc_orate
= p
->sample_rate
;
2319 /* clear req_size before setting a filter to avoid confliction
2320 * in gusmax_set_params() */
2321 switch (p
->encoding
) {
2322 case AUDIO_ENCODING_ULAW
:
2323 hw
.encoding
= AUDIO_ENCODING_ULINEAR_LE
;
2324 pfil
->req_size
= rfil
->req_size
= 0;
2325 pfil
->append(pfil
, mulaw_to_linear8
, &hw
);
2326 rfil
->append(rfil
, linear8_to_mulaw
, &hw
);
2328 case AUDIO_ENCODING_ALAW
:
2329 hw
.encoding
= AUDIO_ENCODING_ULINEAR_LE
;
2330 pfil
->req_size
= rfil
->req_size
= 0;
2331 pfil
->append(pfil
, alaw_to_linear8
, &hw
);
2332 rfil
->append(rfil
, linear8_to_alaw
, &hw
);
2334 case AUDIO_ENCODING_ULINEAR_BE
:
2335 hw
.encoding
= AUDIO_ENCODING_ULINEAR_LE
;
2336 pfil
->req_size
= rfil
->req_size
= 0;
2337 pfil
->append(pfil
, swap_bytes
, &hw
);
2338 rfil
->append(rfil
, swap_bytes
, &hw
);
2340 case AUDIO_ENCODING_SLINEAR_BE
:
2341 hw
.encoding
= AUDIO_ENCODING_SLINEAR_LE
;
2342 pfil
->req_size
= rfil
->req_size
= 0;
2343 pfil
->append(pfil
, swap_bytes
, &hw
);
2344 rfil
->append(rfil
, swap_bytes
, &hw
);
2352 * Interface to the audio layer - set the blocksize to the correct number
2357 gusmax_round_blocksize(void *addr
, int blocksize
,
2358 int mode
, const audio_params_t
*param
)
2360 struct ad1848_isa_softc
*ac
;
2361 struct gus_softc
*sc
;
2364 sc
= ac
->sc_ad1848
.parent
;
2365 /* blocksize = ad1848_round_blocksize(ac, blocksize, mode, param);*/
2366 return gus_round_blocksize(sc
, blocksize
, mode
, param
);
2370 gus_round_blocksize(void *addr
, int blocksize
,
2371 int mode
, const audio_params_t
*param
)
2373 struct gus_softc
*sc
;
2375 DPRINTF(("gus_round_blocksize called\n"));
2378 if ((sc
->sc_encoding
== AUDIO_ENCODING_ULAW
||
2379 sc
->sc_encoding
== AUDIO_ENCODING_ALAW
) && blocksize
> 32768)
2381 else if (blocksize
> 65536)
2384 if ((blocksize
% GUS_BUFFER_MULTIPLE
) != 0)
2385 blocksize
= (blocksize
/ GUS_BUFFER_MULTIPLE
+ 1) *
2386 GUS_BUFFER_MULTIPLE
;
2388 /* set up temporary buffer to hold the deinterleave, if necessary
2389 for stereo output */
2390 if (sc
->sc_deintr_buf
) {
2391 free(sc
->sc_deintr_buf
, M_DEVBUF
);
2392 sc
->sc_deintr_buf
= NULL
;
2394 sc
->sc_deintr_buf
= malloc(blocksize
>>1, M_DEVBUF
, M_WAITOK
);
2396 sc
->sc_blocksize
= blocksize
;
2397 /* multi-buffering not quite working yet. */
2398 sc
->sc_nbufs
= /*GUS_MEM_FOR_BUFFERS / blocksize*/ 2;
2400 gus_set_chan_addrs(sc
);
2406 gus_get_out_gain(void *addr
)
2408 struct gus_softc
*sc
;
2410 DPRINTF(("gus_get_out_gain called\n"));
2411 sc
= (struct gus_softc
*) addr
;
2412 return sc
->sc_ogain
/ 2;
2416 gus_set_voices(struct gus_softc
*sc
, int voices
)
2418 bus_space_tag_t iot
;
2419 bus_space_handle_t ioh2
;
2424 * Select the active number of voices
2426 SELECT_GUS_REG(iot
, ioh2
, GUSREG_ACTIVE_VOICES
);
2427 bus_space_write_1(iot
, ioh2
, GUS_DATA_HIGH
, (voices
-1) | 0xc0);
2429 sc
->sc_voices
= voices
;
2433 * Actually set the settings of various values on the card
2436 gusmax_commit_settings(void *addr
)
2438 struct ad1848_isa_softc
*ac
;
2439 struct gus_softc
*sc
;
2443 sc
= ac
->sc_ad1848
.parent
;
2444 error
= ad1848_commit_settings(ac
);
2447 return gus_commit_settings(sc
);
2451 * Commit the settings. Called at normal IPL.
2454 gus_commit_settings(void *addr
)
2456 struct gus_softc
*sc
;
2460 DPRINTF(("gus_commit_settings called (gain = %d)\n",sc
->sc_ogain
));
2465 gus_set_recrate(sc
, sc
->sc_irate
);
2466 gus_set_volume(sc
, GUS_VOICE_LEFT
, sc
->sc_ogain
);
2467 gus_set_volume(sc
, GUS_VOICE_RIGHT
, sc
->sc_ogain
);
2468 gus_set_samprate(sc
, GUS_VOICE_LEFT
, sc
->sc_orate
);
2469 gus_set_samprate(sc
, GUS_VOICE_RIGHT
, sc
->sc_orate
);
2471 gus_set_chan_addrs(sc
);
2477 gus_set_chan_addrs(struct gus_softc
*sc
)
2481 * We use sc_nbufs * blocksize bytes of storage in the on-board GUS
2483 * For mono, each of the sc_nbufs buffers is DMA'd to in one chunk,
2484 * and both left & right channels play the same buffer.
2486 * For stereo, each channel gets a contiguous half of the memory,
2487 * and each has sc_nbufs buffers of size blocksize/2.
2488 * Stereo data are deinterleaved in main memory before the DMA out
2489 * routines are called to queue the output.
2491 * The blocksize per channel is kept in sc_chanblocksize.
2493 if (sc
->sc_channels
== 2)
2494 sc
->sc_chanblocksize
= sc
->sc_blocksize
/2;
2496 sc
->sc_chanblocksize
= sc
->sc_blocksize
;
2498 sc
->sc_voc
[GUS_VOICE_LEFT
].start_addr
= GUS_MEM_OFFSET
- 1;
2499 sc
->sc_voc
[GUS_VOICE_RIGHT
].start_addr
=
2500 (gus_dostereo
&& sc
->sc_channels
== 2 ? GUS_LEFT_RIGHT_OFFSET
: 0)
2501 + GUS_MEM_OFFSET
- 1;
2502 sc
->sc_voc
[GUS_VOICE_RIGHT
].current_addr
=
2503 sc
->sc_voc
[GUS_VOICE_RIGHT
].start_addr
+ 1;
2504 sc
->sc_voc
[GUS_VOICE_RIGHT
].end_addr
=
2505 sc
->sc_voc
[GUS_VOICE_RIGHT
].start_addr
+
2506 sc
->sc_nbufs
* sc
->sc_chanblocksize
;
2511 * Set the sample rate of the given voice. Called at splgus().
2514 gus_set_samprate(struct gus_softc
*sc
, int voice
, int freq
)
2516 bus_space_tag_t iot
;
2517 bus_space_handle_t ioh2
;
2525 * calculate fc based on the number of active voices;
2526 * we need to use longs to preserve enough bits
2529 temp
= (u_long
) gus_max_frequency
[sc
->sc_voices
-GUS_MIN_VOICES
];
2531 fc
= (unsigned int)(((f
<< 9L) + (temp
>> 1L)) / temp
);
2535 * Program the voice frequency, and set it in the voice data record
2538 bus_space_write_1(iot
, ioh2
, GUS_VOICE_SELECT
, (unsigned char) voice
);
2539 SELECT_GUS_REG(iot
, ioh2
, GUSREG_FREQ_CONTROL
);
2540 bus_space_write_2(iot
, ioh2
, GUS_DATA_LOW
, fc
);
2542 sc
->sc_voc
[voice
].rate
= freq
;
2547 * Set the sample rate of the recording frequency. Formula is from the GUS
2548 * SDK. Called at splgus().
2551 gus_set_recrate(struct gus_softc
*sc
, u_long rate
)
2553 bus_space_tag_t iot
;
2554 bus_space_handle_t ioh2
;
2557 DPRINTF(("gus_set_recrate %lu\n", rate
));
2562 realrate
= 9878400/(16*(rate
+2)); /* formula from GUS docs */
2564 realrate
= (9878400 >> 4)/rate
- 2; /* formula from code, sigh. */
2566 SELECT_GUS_REG(iot
, ioh2
, GUSREG_SAMPLE_FREQ
);
2567 bus_space_write_1(iot
, ioh2
, GUS_DATA_HIGH
, realrate
);
2571 * Interface to the audio layer - turn the output on or off. Note that some
2572 * of these bits are flipped in the register
2576 gusmax_speaker_ctl(void *addr
, int newstate
)
2578 struct ad1848_isa_softc
*sc
;
2581 return gus_speaker_ctl(sc
->sc_ad1848
.parent
, newstate
);
2585 gus_speaker_ctl(void *addr
, int newstate
)
2587 struct gus_softc
*sc
;
2588 bus_space_tag_t iot
;
2589 bus_space_handle_t ioh1
;
2591 sc
= (struct gus_softc
*) addr
;
2594 /* Line out bit is flipped: 0 enables, 1 disables */
2595 if ((newstate
== SPKR_ON
) &&
2596 (sc
->sc_mixcontrol
& GUSMASK_LINE_OUT
)) {
2597 sc
->sc_mixcontrol
&= ~GUSMASK_LINE_OUT
;
2598 bus_space_write_1(iot
, ioh1
, GUS_MIX_CONTROL
, sc
->sc_mixcontrol
);
2600 if ((newstate
== SPKR_OFF
) &&
2601 (sc
->sc_mixcontrol
& GUSMASK_LINE_OUT
) == 0) {
2602 sc
->sc_mixcontrol
|= GUSMASK_LINE_OUT
;
2603 bus_space_write_1(iot
, ioh1
, GUS_MIX_CONTROL
, sc
->sc_mixcontrol
);
2610 gus_linein_ctl(void *addr
, int newstate
)
2612 struct gus_softc
*sc
;
2613 bus_space_tag_t iot
;
2614 bus_space_handle_t ioh1
;
2616 sc
= (struct gus_softc
*) addr
;
2619 /* Line in bit is flipped: 0 enables, 1 disables */
2620 if ((newstate
== SPKR_ON
) &&
2621 (sc
->sc_mixcontrol
& GUSMASK_LINE_IN
)) {
2622 sc
->sc_mixcontrol
&= ~GUSMASK_LINE_IN
;
2623 bus_space_write_1(iot
, ioh1
, GUS_MIX_CONTROL
, sc
->sc_mixcontrol
);
2625 if ((newstate
== SPKR_OFF
) &&
2626 (sc
->sc_mixcontrol
& GUSMASK_LINE_IN
) == 0) {
2627 sc
->sc_mixcontrol
|= GUSMASK_LINE_IN
;
2628 bus_space_write_1(iot
, ioh1
, GUS_MIX_CONTROL
, sc
->sc_mixcontrol
);
2635 gus_mic_ctl(void *addr
, int newstate
)
2637 struct gus_softc
*sc
;
2638 bus_space_tag_t iot
;
2639 bus_space_handle_t ioh1
;
2641 sc
= (struct gus_softc
*) addr
;
2644 /* Mic bit is normal: 1 enables, 0 disables */
2645 if ((newstate
== SPKR_ON
) &&
2646 (sc
->sc_mixcontrol
& GUSMASK_MIC_IN
) == 0) {
2647 sc
->sc_mixcontrol
|= GUSMASK_MIC_IN
;
2648 bus_space_write_1(iot
, ioh1
, GUS_MIX_CONTROL
, sc
->sc_mixcontrol
);
2650 if ((newstate
== SPKR_OFF
) &&
2651 (sc
->sc_mixcontrol
& GUSMASK_MIC_IN
)) {
2652 sc
->sc_mixcontrol
&= ~GUSMASK_MIC_IN
;
2653 bus_space_write_1(iot
, ioh1
, GUS_MIX_CONTROL
, sc
->sc_mixcontrol
);
2660 * Set the end address of a give voice. Called at splgus()
2663 gus_set_endaddr(struct gus_softc
*sc
, int voice
, u_long addr
)
2665 bus_space_tag_t iot
;
2666 bus_space_handle_t ioh2
;
2670 sc
->sc_voc
[voice
].end_addr
= addr
;
2672 if (sc
->sc_voc
[voice
].voccntl
& GUSMASK_DATA_SIZE16
)
2673 addr
= convert_to_16bit(addr
);
2675 SELECT_GUS_REG(iot
, ioh2
, GUSREG_END_ADDR_HIGH
);
2676 bus_space_write_2(iot
, ioh2
, GUS_DATA_LOW
, ADDR_HIGH(addr
));
2677 SELECT_GUS_REG(iot
, ioh2
, GUSREG_END_ADDR_LOW
);
2678 bus_space_write_2(iot
, ioh2
, GUS_DATA_LOW
, ADDR_LOW(addr
));
2684 * Set current address. called at splgus()
2687 gus_set_curaddr(struct gus_softc
*sc
, int voice
, u_long addr
)
2689 bus_space_tag_t iot
;
2690 bus_space_handle_t ioh2
;
2694 sc
->sc_voc
[voice
].current_addr
= addr
;
2696 if (sc
->sc_voc
[voice
].voccntl
& GUSMASK_DATA_SIZE16
)
2697 addr
= convert_to_16bit(addr
);
2699 bus_space_write_1(iot
, ioh2
, GUS_VOICE_SELECT
, (unsigned char) voice
);
2701 SELECT_GUS_REG(iot
, ioh2
, GUSREG_CUR_ADDR_HIGH
);
2702 bus_space_write_2(iot
, ioh2
, GUS_DATA_LOW
, ADDR_HIGH(addr
));
2703 SELECT_GUS_REG(iot
, ioh2
, GUSREG_CUR_ADDR_LOW
);
2704 bus_space_write_2(iot
, ioh2
, GUS_DATA_LOW
, ADDR_LOW(addr
));
2709 * Get current GUS playback address. Called at splgus().
2712 gus_get_curaddr(struct gus_softc
*sc
, int voice
)
2714 bus_space_tag_t iot
;
2715 bus_space_handle_t ioh2
;
2720 bus_space_write_1(iot
, ioh2
, GUS_VOICE_SELECT
, (unsigned char) voice
);
2721 SELECT_GUS_REG(iot
, ioh2
, GUSREG_CUR_ADDR_HIGH
|GUSREG_READ
);
2722 addr
= (bus_space_read_2(iot
, ioh2
, GUS_DATA_LOW
) & 0x1fff) << 7;
2723 SELECT_GUS_REG(iot
, ioh2
, GUSREG_CUR_ADDR_LOW
|GUSREG_READ
);
2724 addr
|= (bus_space_read_2(iot
, ioh2
, GUS_DATA_LOW
) >> 9L) & 0x7f;
2726 if (sc
->sc_voc
[voice
].voccntl
& GUSMASK_DATA_SIZE16
)
2727 addr
= (addr
& 0xc0000) | ((addr
& 0x1ffff) << 1); /* undo 16-bit change */
2728 DPRINTF(("gus voice %d curaddr %ld end_addr %ld\n",
2729 voice
, addr
, sc
->sc_voc
[voice
].end_addr
));
2730 /* XXX sanity check the address? */
2737 * Convert an address value to a "16 bit" value - why this is necessary I
2742 convert_to_16bit(u_long address
)
2746 old_address
= address
;
2748 address
&= 0x0001ffffL
;
2749 address
|= (old_address
& 0x000c0000L
);
2755 * Write a value into the GUS's DRAM
2758 guspoke(bus_space_tag_t iot
, bus_space_handle_t ioh2
,
2759 long address
, unsigned char value
)
2763 * Select the DRAM address
2766 SELECT_GUS_REG(iot
, ioh2
, GUSREG_DRAM_ADDR_LOW
);
2767 bus_space_write_2(iot
, ioh2
, GUS_DATA_LOW
, (unsigned int) (address
& 0xffff));
2768 SELECT_GUS_REG(iot
, ioh2
, GUSREG_DRAM_ADDR_HIGH
);
2769 bus_space_write_1(iot
, ioh2
, GUS_DATA_HIGH
, (unsigned char) ((address
>> 16) & 0xff));
2772 * Actually write the data
2775 bus_space_write_1(iot
, ioh2
, GUS_DRAM_DATA
, value
);
2779 * Read a value from the GUS's DRAM
2781 STATIC
unsigned char
2782 guspeek(bus_space_tag_t iot
, bus_space_handle_t ioh2
, u_long address
)
2786 * Select the DRAM address
2789 SELECT_GUS_REG(iot
, ioh2
, GUSREG_DRAM_ADDR_LOW
);
2790 bus_space_write_2(iot
, ioh2
, GUS_DATA_LOW
, (unsigned int) (address
& 0xffff));
2791 SELECT_GUS_REG(iot
, ioh2
, GUSREG_DRAM_ADDR_HIGH
);
2792 bus_space_write_1(iot
, ioh2
, GUS_DATA_HIGH
, (unsigned char) ((address
>> 16) & 0xff));
2795 * Read in the data from the board
2798 return (unsigned char) bus_space_read_1(iot
, ioh2
, GUS_DRAM_DATA
);
2802 * Reset the Gravis UltraSound card, completely
2805 gusreset(struct gus_softc
*sc
, int voices
)
2807 bus_space_tag_t iot
;
2808 bus_space_handle_t ioh1
;
2809 bus_space_handle_t ioh2
;
2810 bus_space_handle_t ioh4
;
2820 * Reset the GF1 chip
2823 SELECT_GUS_REG(iot
, ioh2
, GUSREG_RESET
);
2824 bus_space_write_1(iot
, ioh2
, GUS_DATA_HIGH
, 0x00);
2832 SELECT_GUS_REG(iot
, ioh2
, GUSREG_RESET
);
2833 bus_space_write_1(iot
, ioh2
, GUS_DATA_HIGH
, GUSMASK_MASTER_RESET
);
2838 * Reset MIDI port as well
2841 bus_space_write_1(iot
, ioh4
, GUS_MIDI_CONTROL
, MIDI_RESET
);
2845 bus_space_write_1(iot
, ioh4
, GUS_MIDI_CONTROL
, 0x00);
2851 SELECT_GUS_REG(iot
, ioh2
, GUSREG_DMA_CONTROL
);
2852 bus_space_write_1(iot
, ioh2
, GUS_DATA_HIGH
, 0x00);
2853 SELECT_GUS_REG(iot
, ioh2
, GUSREG_TIMER_CONTROL
);
2854 bus_space_write_1(iot
, ioh2
, GUS_DATA_HIGH
, 0x00);
2855 SELECT_GUS_REG(iot
, ioh2
, GUSREG_SAMPLE_CONTROL
);
2856 bus_space_write_1(iot
, ioh2
, GUS_DATA_HIGH
, 0x00);
2858 gus_set_voices(sc
, voices
);
2860 bus_space_read_1(iot
, ioh1
, GUS_IRQ_STATUS
);
2861 SELECT_GUS_REG(iot
, ioh2
, GUSREG_DMA_CONTROL
);
2862 bus_space_read_1(iot
, ioh2
, GUS_DATA_HIGH
);
2863 SELECT_GUS_REG(iot
, ioh2
, GUSREG_SAMPLE_CONTROL
);
2864 bus_space_read_1(iot
, ioh2
, GUS_DATA_HIGH
);
2865 SELECT_GUS_REG(iot
, ioh2
, GUSREG_IRQ_STATUS
);
2866 bus_space_read_1(iot
, ioh2
, GUS_DATA_HIGH
);
2869 * Reset voice specific information
2872 for(i
= 0; i
< voices
; i
++) {
2873 bus_space_write_1(iot
, ioh2
, GUS_VOICE_SELECT
, (unsigned char) i
);
2875 SELECT_GUS_REG(iot
, ioh2
, GUSREG_VOICE_CNTL
);
2877 sc
->sc_voc
[i
].voccntl
= GUSMASK_VOICE_STOPPED
|
2880 bus_space_write_1(iot
, ioh2
, GUS_DATA_HIGH
, sc
->sc_voc
[i
].voccntl
);
2882 sc
->sc_voc
[i
].volcntl
= GUSMASK_VOLUME_STOPPED
|
2883 GUSMASK_STOP_VOLUME
;
2885 SELECT_GUS_REG(iot
, ioh2
, GUSREG_VOLUME_CONTROL
);
2886 bus_space_write_1(iot
, ioh2
, GUS_DATA_HIGH
, sc
->sc_voc
[i
].volcntl
);
2890 gus_set_samprate(sc
, i
, 8000);
2891 SELECT_GUS_REG(iot
, ioh2
, GUSREG_START_ADDR_HIGH
);
2892 bus_space_write_2(iot
, ioh2
, GUS_DATA_LOW
, 0x0000);
2893 SELECT_GUS_REG(iot
, ioh2
, GUSREG_START_ADDR_LOW
);
2894 bus_space_write_2(iot
, ioh2
, GUS_DATA_LOW
, 0x0000);
2895 SELECT_GUS_REG(iot
, ioh2
, GUSREG_END_ADDR_HIGH
);
2896 bus_space_write_2(iot
, ioh2
, GUS_DATA_LOW
, 0x0000);
2897 SELECT_GUS_REG(iot
, ioh2
, GUSREG_END_ADDR_LOW
);
2898 bus_space_write_2(iot
, ioh2
, GUS_DATA_LOW
, 0x0000);
2899 SELECT_GUS_REG(iot
, ioh2
, GUSREG_VOLUME_RATE
);
2900 bus_space_write_1(iot
, ioh2
, GUS_DATA_HIGH
, 0x01);
2901 SELECT_GUS_REG(iot
, ioh2
, GUSREG_START_VOLUME
);
2902 bus_space_write_1(iot
, ioh2
, GUS_DATA_HIGH
, 0x10);
2903 SELECT_GUS_REG(iot
, ioh2
, GUSREG_END_VOLUME
);
2904 bus_space_write_1(iot
, ioh2
, GUS_DATA_HIGH
, 0xe0);
2905 SELECT_GUS_REG(iot
, ioh2
, GUSREG_CUR_VOLUME
);
2906 bus_space_write_2(iot
, ioh2
, GUS_DATA_LOW
, 0x0000);
2908 SELECT_GUS_REG(iot
, ioh2
, GUSREG_CUR_ADDR_HIGH
);
2909 bus_space_write_2(iot
, ioh2
, GUS_DATA_LOW
, 0x0000);
2910 SELECT_GUS_REG(iot
, ioh2
, GUSREG_CUR_ADDR_LOW
);
2911 bus_space_write_2(iot
, ioh2
, GUS_DATA_LOW
, 0x0000);
2912 SELECT_GUS_REG(iot
, ioh2
, GUSREG_PAN_POS
);
2913 bus_space_write_1(iot
, ioh2
, GUS_DATA_HIGH
, 0x07);
2917 * Clear out any pending IRQs
2920 bus_space_read_1(iot
, ioh1
, GUS_IRQ_STATUS
);
2921 SELECT_GUS_REG(iot
, ioh2
, GUSREG_DMA_CONTROL
);
2922 bus_space_read_1(iot
, ioh2
, GUS_DATA_HIGH
);
2923 SELECT_GUS_REG(iot
, ioh2
, GUSREG_SAMPLE_CONTROL
);
2924 bus_space_read_1(iot
, ioh2
, GUS_DATA_HIGH
);
2925 SELECT_GUS_REG(iot
, ioh2
, GUSREG_IRQ_STATUS
);
2926 bus_space_read_1(iot
, ioh2
, GUS_DATA_HIGH
);
2928 SELECT_GUS_REG(iot
, ioh2
, GUSREG_RESET
);
2929 bus_space_write_1(iot
, ioh2
, GUS_DATA_HIGH
, GUSMASK_MASTER_RESET
| GUSMASK_DAC_ENABLE
|
2930 GUSMASK_IRQ_ENABLE
);
2937 gus_init_cs4231(struct gus_softc
*sc
)
2939 bus_space_tag_t iot
;
2940 bus_space_handle_t ioh1
;
2946 port
= sc
->sc_iobase
;
2947 ctrl
= (port
& 0xf0) >> 4; /* set port address middle nibble */
2949 * The codec is a bit weird--swapped DMA channels.
2951 ctrl
|= GUS_MAX_CODEC_ENABLE
;
2952 if (sc
->sc_playdrq
>= 4)
2953 ctrl
|= GUS_MAX_RECCHAN16
;
2954 if (sc
->sc_recdrq
>= 4)
2955 ctrl
|= GUS_MAX_PLAYCHAN16
;
2957 bus_space_write_1(iot
, ioh1
, GUS_MAX_CTRL
, ctrl
);
2959 sc
->sc_codec
.sc_ad1848
.sc_iot
= sc
->sc_iot
;
2960 sc
->sc_codec
.sc_iobase
= port
+GUS_MAX_CODEC_BASE
;
2962 if (ad1848_isa_mapprobe(&sc
->sc_codec
, sc
->sc_codec
.sc_iobase
) == 0) {
2963 sc
->sc_flags
&= ~GUS_CODEC_INSTALLED
;
2966 struct ad1848_volume vol
= {AUDIO_MAX_GAIN
, AUDIO_MAX_GAIN
};
2967 sc
->sc_flags
|= GUS_CODEC_INSTALLED
;
2968 sc
->sc_codec
.sc_ad1848
.parent
= sc
;
2969 sc
->sc_codec
.sc_playdrq
= sc
->sc_recdrq
;
2970 sc
->sc_codec
.sc_play_maxsize
= sc
->sc_req_maxsize
;
2971 sc
->sc_codec
.sc_recdrq
= sc
->sc_playdrq
;
2972 sc
->sc_codec
.sc_rec_maxsize
= sc
->sc_play_maxsize
;
2973 /* enable line in and mic in the GUS mixer; the codec chip
2974 will do the real mixing for them. */
2975 sc
->sc_mixcontrol
&= ~GUSMASK_LINE_IN
; /* 0 enables. */
2976 sc
->sc_mixcontrol
|= GUSMASK_MIC_IN
; /* 1 enables. */
2977 bus_space_write_1(iot
, ioh1
, GUS_MIX_CONTROL
, sc
->sc_mixcontrol
);
2979 ad1848_isa_attach(&sc
->sc_codec
);
2980 /* turn on pre-MUX microphone gain. */
2981 ad1848_set_mic_gain(&sc
->sc_codec
.sc_ad1848
, &vol
);
2989 * Return info about the audio device, for the AUDIO_GETINFO ioctl
2992 gus_getdev(void *addr
, struct audio_device
*dev
)
3004 gus_set_in_gain(void *addr
, u_int gain
,
3008 DPRINTF(("gus_set_in_gain called\n"));
3013 gus_get_in_gain(void *addr
)
3016 DPRINTF(("gus_get_in_gain called\n"));
3021 gusmax_dma_input(void *addr
, void *tbuf
, int size
,
3022 void (*callback
)(void *), void *arg
)
3024 struct ad1848_isa_softc
*sc
;
3027 return gus_dma_input(sc
->sc_ad1848
.parent
, tbuf
, size
, callback
, arg
);
3031 * Start sampling the input source into the requested DMA buffer.
3032 * Called at splgus(), either from top-half or from interrupt handler.
3035 gus_dma_input(void *addr
, void *tbuf
, int size
,
3036 void (*callback
)(void *), void *arg
)
3038 struct gus_softc
*sc
;
3039 bus_space_tag_t iot
;
3040 bus_space_handle_t ioh2
;
3043 DMAPRINTF(("gus_dma_input called\n"));
3049 * Sample SIZE bytes of data from the card, into buffer at BUF.
3052 if (sc
->sc_precision
== 16)
3053 return EINVAL
; /* XXX */
3056 dmac
= GUSMASK_SAMPLE_IRQ
|GUSMASK_SAMPLE_START
;
3057 if (sc
->sc_recdrq
>= 4)
3058 dmac
|= GUSMASK_SAMPLE_DATA16
;
3059 if (sc
->sc_encoding
== AUDIO_ENCODING_ULAW
||
3060 sc
->sc_encoding
== AUDIO_ENCODING_ALAW
||
3061 sc
->sc_encoding
== AUDIO_ENCODING_ULINEAR_LE
||
3062 sc
->sc_encoding
== AUDIO_ENCODING_ULINEAR_BE
)
3063 dmac
|= GUSMASK_SAMPLE_INVBIT
;
3064 if (sc
->sc_channels
== 2)
3065 dmac
|= GUSMASK_SAMPLE_STEREO
;
3066 isa_dmastart(sc
->sc_ic
, sc
->sc_recdrq
, tbuf
, size
,
3067 NULL
, DMAMODE_READ
, BUS_DMA_NOWAIT
);
3069 DMAPRINTF(("gus_dma_input isa_dmastarted\n"));
3070 sc
->sc_flags
|= GUS_DMAIN_ACTIVE
;
3071 sc
->sc_dmainintr
= callback
;
3073 sc
->sc_dmaincnt
= size
;
3074 sc
->sc_dmainaddr
= tbuf
;
3076 SELECT_GUS_REG(iot
, ioh2
, GUSREG_SAMPLE_CONTROL
);
3077 bus_space_write_1(iot
, ioh2
, GUS_DATA_HIGH
, dmac
); /* Go! */
3080 DMAPRINTF(("gus_dma_input returning\n"));
3086 gus_dmain_intr(struct gus_softc
*sc
)
3088 void (*callback
)(void *);
3091 DMAPRINTF(("gus_dmain_intr called\n"));
3092 if (sc
->sc_dmainintr
) {
3093 isa_dmadone(sc
->sc_ic
, sc
->sc_recdrq
);
3094 callback
= sc
->sc_dmainintr
;
3097 sc
->sc_dmainaddr
= 0;
3098 sc
->sc_dmaincnt
= 0;
3099 sc
->sc_dmainintr
= 0;
3102 sc
->sc_flags
&= ~GUS_DMAIN_ACTIVE
;
3103 DMAPRINTF(("calling dmain_intr callback %p(%p)\n", callback
, arg
));
3107 DMAPRINTF(("gus_dmain_intr false?\n"));
3108 return 0; /* XXX ??? */
3113 gusmax_halt_out_dma(void *addr
)
3115 struct ad1848_isa_softc
*sc
;
3118 return gus_halt_out_dma(sc
->sc_ad1848
.parent
);
3123 gusmax_halt_in_dma(void *addr
)
3125 struct ad1848_isa_softc
*sc
;
3128 return gus_halt_in_dma(sc
->sc_ad1848
.parent
);
3132 * Stop any DMA output. Called at splgus().
3135 gus_halt_out_dma(void *addr
)
3137 struct gus_softc
*sc
;
3138 bus_space_tag_t iot
;
3139 bus_space_handle_t ioh2
;
3141 DMAPRINTF(("gus_halt_out_dma called\n"));
3146 * Make sure the GUS _isn't_ setup for DMA
3149 SELECT_GUS_REG(iot
, ioh2
, GUSREG_DMA_CONTROL
);
3150 bus_space_write_1(iot
, ioh2
, GUS_DATA_HIGH
, 0);
3152 callout_stop(&sc
->sc_dmaout_ch
);
3153 isa_dmaabort(sc
->sc_ic
, sc
->sc_playdrq
);
3154 sc
->sc_flags
&= ~(GUS_DMAOUT_ACTIVE
|GUS_LOCKED
);
3155 sc
->sc_dmaoutintr
= 0;
3157 sc
->sc_dmaoutaddr
= 0;
3158 sc
->sc_dmaoutcnt
= 0;
3161 sc
->sc_playbuf
= -1;
3162 /* also stop playing */
3163 gus_stop_voice(sc
, GUS_VOICE_LEFT
, 1);
3164 gus_stop_voice(sc
, GUS_VOICE_RIGHT
, 0);
3170 * Stop any DMA output. Called at splgus().
3173 gus_halt_in_dma(void *addr
)
3175 struct gus_softc
*sc
;
3176 bus_space_tag_t iot
;
3177 bus_space_handle_t ioh2
;
3179 DMAPRINTF(("gus_halt_in_dma called\n"));
3185 * Make sure the GUS _isn't_ setup for DMA
3188 SELECT_GUS_REG(iot
, ioh2
, GUSREG_SAMPLE_CONTROL
);
3189 bus_space_write_1(iot
, ioh2
, GUS_DATA_HIGH
,
3190 bus_space_read_1(iot
, ioh2
, GUS_DATA_HIGH
)
3191 & ~(GUSMASK_SAMPLE_START
|GUSMASK_SAMPLE_IRQ
));
3193 isa_dmaabort(sc
->sc_ic
, sc
->sc_recdrq
);
3194 sc
->sc_flags
&= ~GUS_DMAIN_ACTIVE
;
3195 sc
->sc_dmainintr
= 0;
3197 sc
->sc_dmainaddr
= 0;
3198 sc
->sc_dmaincnt
= 0;
3204 static ad1848_devmap_t gusmapping
[] = {
3205 { GUSMAX_DAC_LVL
, AD1848_KIND_LVL
, AD1848_AUX1_CHANNEL
},
3206 { GUSMAX_LINE_IN_LVL
, AD1848_KIND_LVL
, AD1848_LINE_CHANNEL
},
3207 { GUSMAX_MONO_LVL
, AD1848_KIND_LVL
, AD1848_MONO_CHANNEL
},
3208 { GUSMAX_CD_LVL
, AD1848_KIND_LVL
, AD1848_AUX2_CHANNEL
},
3209 { GUSMAX_MONITOR_LVL
, AD1848_KIND_LVL
, AD1848_MONITOR_CHANNEL
},
3210 { GUSMAX_OUT_LVL
, AD1848_KIND_LVL
, AD1848_DAC_CHANNEL
},
3211 { GUSMAX_DAC_MUTE
, AD1848_KIND_MUTE
, AD1848_AUX1_CHANNEL
},
3212 { GUSMAX_LINE_IN_MUTE
, AD1848_KIND_MUTE
, AD1848_LINE_CHANNEL
},
3213 { GUSMAX_MONO_MUTE
, AD1848_KIND_MUTE
, AD1848_MONO_CHANNEL
},
3214 { GUSMAX_CD_MUTE
, AD1848_KIND_MUTE
, AD1848_AUX2_CHANNEL
},
3215 { GUSMAX_MONITOR_MUTE
, AD1848_KIND_MUTE
, AD1848_MONITOR_CHANNEL
},
3216 { GUSMAX_REC_LVL
, AD1848_KIND_RECORDGAIN
, -1 },
3217 { GUSMAX_RECORD_SOURCE
, AD1848_KIND_RECORDSOURCE
, -1 }
3220 static int nummap
= sizeof(gusmapping
) / sizeof(gusmapping
[0]);
3223 gusmax_mixer_get_port(void *addr
, mixer_ctrl_t
*cp
)
3225 struct ad1848_isa_softc
*ac
;
3226 struct gus_softc
*sc
;
3227 struct ad1848_volume vol
;
3231 sc
= ac
->sc_ad1848
.parent
;
3232 error
= ad1848_mixer_get_port(&ac
->sc_ad1848
, gusmapping
, nummap
, cp
);
3239 case GUSMAX_SPEAKER_LVL
: /* fake speaker for mute naming */
3240 if (cp
->type
== AUDIO_MIXER_VALUE
) {
3241 if (sc
->sc_mixcontrol
& GUSMASK_LINE_OUT
)
3242 vol
.left
= vol
.right
= AUDIO_MAX_GAIN
;
3244 vol
.left
= vol
.right
= AUDIO_MIN_GAIN
;
3246 ad1848_from_vol(cp
, &vol
);
3250 case GUSMAX_SPEAKER_MUTE
:
3251 if (cp
->type
== AUDIO_MIXER_ENUM
) {
3252 cp
->un
.ord
= sc
->sc_mixcontrol
& GUSMASK_LINE_OUT
? 1 : 0;
3265 gus_mixer_get_port(void *addr
, mixer_ctrl_t
*cp
)
3267 struct gus_softc
*sc
;
3268 struct ics2101_softc
*ic
;
3269 struct ad1848_volume vol
;
3272 DPRINTF(("gus_mixer_get_port: dev=%d type=%d\n", cp
->dev
, cp
->type
));
3277 if (!HAS_MIXER(sc
) && cp
->dev
> GUSICS_MASTER_MUTE
)
3282 case GUSICS_MIC_IN_MUTE
: /* Microphone */
3283 if (cp
->type
== AUDIO_MIXER_ENUM
) {
3285 cp
->un
.ord
= ic
->sc_mute
[GUSMIX_CHAN_MIC
][ICSMIX_LEFT
];
3288 sc
->sc_mixcontrol
& GUSMASK_MIC_IN
? 0 : 1;
3293 case GUSICS_LINE_IN_MUTE
:
3294 if (cp
->type
== AUDIO_MIXER_ENUM
) {
3296 cp
->un
.ord
= ic
->sc_mute
[GUSMIX_CHAN_LINE
][ICSMIX_LEFT
];
3299 sc
->sc_mixcontrol
& GUSMASK_LINE_IN
? 1 : 0;
3304 case GUSICS_MASTER_MUTE
:
3305 if (cp
->type
== AUDIO_MIXER_ENUM
) {
3307 cp
->un
.ord
= ic
->sc_mute
[GUSMIX_CHAN_MASTER
][ICSMIX_LEFT
];
3310 sc
->sc_mixcontrol
& GUSMASK_LINE_OUT
? 1 : 0;
3315 case GUSICS_DAC_MUTE
:
3316 if (cp
->type
== AUDIO_MIXER_ENUM
) {
3317 cp
->un
.ord
= ic
->sc_mute
[GUSMIX_CHAN_DAC
][ICSMIX_LEFT
];
3322 case GUSICS_CD_MUTE
:
3323 if (cp
->type
== AUDIO_MIXER_ENUM
) {
3324 cp
->un
.ord
= ic
->sc_mute
[GUSMIX_CHAN_CD
][ICSMIX_LEFT
];
3329 case GUSICS_MASTER_LVL
:
3330 if (cp
->type
== AUDIO_MIXER_VALUE
) {
3331 vol
.left
= ic
->sc_setting
[GUSMIX_CHAN_MASTER
][ICSMIX_LEFT
];
3332 vol
.right
= ic
->sc_setting
[GUSMIX_CHAN_MASTER
][ICSMIX_RIGHT
];
3333 if (ad1848_from_vol(cp
, &vol
))
3338 case GUSICS_MIC_IN_LVL
: /* Microphone */
3339 if (cp
->type
== AUDIO_MIXER_VALUE
) {
3340 vol
.left
= ic
->sc_setting
[GUSMIX_CHAN_MIC
][ICSMIX_LEFT
];
3341 vol
.right
= ic
->sc_setting
[GUSMIX_CHAN_MIC
][ICSMIX_RIGHT
];
3342 if (ad1848_from_vol(cp
, &vol
))
3347 case GUSICS_LINE_IN_LVL
: /* line in */
3348 if (cp
->type
== AUDIO_MIXER_VALUE
) {
3349 vol
.left
= ic
->sc_setting
[GUSMIX_CHAN_LINE
][ICSMIX_LEFT
];
3350 vol
.right
= ic
->sc_setting
[GUSMIX_CHAN_LINE
][ICSMIX_RIGHT
];
3351 if (ad1848_from_vol(cp
, &vol
))
3358 if (cp
->type
== AUDIO_MIXER_VALUE
) {
3359 vol
.left
= ic
->sc_setting
[GUSMIX_CHAN_CD
][ICSMIX_LEFT
];
3360 vol
.right
= ic
->sc_setting
[GUSMIX_CHAN_CD
][ICSMIX_RIGHT
];
3361 if (ad1848_from_vol(cp
, &vol
))
3366 case GUSICS_DAC_LVL
: /* dac out */
3367 if (cp
->type
== AUDIO_MIXER_VALUE
) {
3368 vol
.left
= ic
->sc_setting
[GUSMIX_CHAN_DAC
][ICSMIX_LEFT
];
3369 vol
.right
= ic
->sc_setting
[GUSMIX_CHAN_DAC
][ICSMIX_RIGHT
];
3370 if (ad1848_from_vol(cp
, &vol
))
3376 case GUSICS_RECORD_SOURCE
:
3377 if (cp
->type
== AUDIO_MIXER_ENUM
) {
3378 /* Can't set anything else useful, sigh. */
3391 gusics_master_mute(struct ics2101_softc
*ic
, int mute
)
3394 ics2101_mix_mute(ic
, GUSMIX_CHAN_MASTER
, ICSMIX_LEFT
, mute
);
3395 ics2101_mix_mute(ic
, GUSMIX_CHAN_MASTER
, ICSMIX_RIGHT
, mute
);
3399 gusics_mic_mute(struct ics2101_softc
*ic
, int mute
)
3402 ics2101_mix_mute(ic
, GUSMIX_CHAN_MIC
, ICSMIX_LEFT
, mute
);
3403 ics2101_mix_mute(ic
, GUSMIX_CHAN_MIC
, ICSMIX_RIGHT
, mute
);
3407 gusics_linein_mute(struct ics2101_softc
*ic
, int mute
)
3410 ics2101_mix_mute(ic
, GUSMIX_CHAN_LINE
, ICSMIX_LEFT
, mute
);
3411 ics2101_mix_mute(ic
, GUSMIX_CHAN_LINE
, ICSMIX_RIGHT
, mute
);
3415 gusics_cd_mute(struct ics2101_softc
*ic
, int mute
)
3418 ics2101_mix_mute(ic
, GUSMIX_CHAN_CD
, ICSMIX_LEFT
, mute
);
3419 ics2101_mix_mute(ic
, GUSMIX_CHAN_CD
, ICSMIX_RIGHT
, mute
);
3423 gusics_dac_mute(struct ics2101_softc
*ic
, int mute
)
3426 ics2101_mix_mute(ic
, GUSMIX_CHAN_DAC
, ICSMIX_LEFT
, mute
);
3427 ics2101_mix_mute(ic
, GUSMIX_CHAN_DAC
, ICSMIX_RIGHT
, mute
);
3431 gusmax_mixer_set_port(void *addr
, mixer_ctrl_t
*cp
)
3433 struct ad1848_isa_softc
*ac
;
3434 struct gus_softc
*sc
;
3435 struct ad1848_volume vol
;
3439 sc
= ac
->sc_ad1848
.parent
;
3440 error
= ad1848_mixer_set_port(&ac
->sc_ad1848
, gusmapping
, nummap
, cp
);
3444 DPRINTF(("gusmax_mixer_set_port: dev=%d type=%d\n", cp
->dev
, cp
->type
));
3447 case GUSMAX_SPEAKER_LVL
:
3448 if (cp
->type
== AUDIO_MIXER_VALUE
&&
3449 cp
->un
.value
.num_channels
== 1) {
3450 if (ad1848_to_vol(cp
, &vol
)) {
3451 gus_speaker_ctl(sc
, vol
.left
> AUDIO_MIN_GAIN
?
3452 SPKR_ON
: SPKR_OFF
);
3458 case GUSMAX_SPEAKER_MUTE
:
3459 if (cp
->type
== AUDIO_MIXER_ENUM
) {
3460 gus_speaker_ctl(sc
, cp
->un
.ord
? SPKR_OFF
: SPKR_ON
);
3473 gus_mixer_set_port(void *addr
, mixer_ctrl_t
*cp
)
3475 struct gus_softc
*sc
;
3476 struct ics2101_softc
*ic
;
3477 struct ad1848_volume vol
;
3480 DPRINTF(("gus_mixer_set_port: dev=%d type=%d\n", cp
->dev
, cp
->type
));
3485 if (!HAS_MIXER(sc
) && cp
->dev
> GUSICS_MASTER_MUTE
)
3490 case GUSICS_MIC_IN_MUTE
: /* Microphone */
3491 if (cp
->type
== AUDIO_MIXER_ENUM
) {
3492 DPRINTF(("mic mute %d\n", cp
->un
.ord
));
3493 if (HAS_MIXER(sc
)) {
3494 gusics_mic_mute(ic
, cp
->un
.ord
);
3496 gus_mic_ctl(sc
, cp
->un
.ord
? SPKR_OFF
: SPKR_ON
);
3501 case GUSICS_LINE_IN_MUTE
:
3502 if (cp
->type
== AUDIO_MIXER_ENUM
) {
3503 DPRINTF(("linein mute %d\n", cp
->un
.ord
));
3504 if (HAS_MIXER(sc
)) {
3505 gusics_linein_mute(ic
, cp
->un
.ord
);
3507 gus_linein_ctl(sc
, cp
->un
.ord
? SPKR_OFF
: SPKR_ON
);
3512 case GUSICS_MASTER_MUTE
:
3513 if (cp
->type
== AUDIO_MIXER_ENUM
) {
3514 DPRINTF(("master mute %d\n", cp
->un
.ord
));
3515 if (HAS_MIXER(sc
)) {
3516 gusics_master_mute(ic
, cp
->un
.ord
);
3518 gus_speaker_ctl(sc
, cp
->un
.ord
? SPKR_OFF
: SPKR_ON
);
3523 case GUSICS_DAC_MUTE
:
3524 if (cp
->type
== AUDIO_MIXER_ENUM
) {
3525 gusics_dac_mute(ic
, cp
->un
.ord
);
3530 case GUSICS_CD_MUTE
:
3531 if (cp
->type
== AUDIO_MIXER_ENUM
) {
3532 gusics_cd_mute(ic
, cp
->un
.ord
);
3537 case GUSICS_MASTER_LVL
:
3538 if (cp
->type
== AUDIO_MIXER_VALUE
) {
3539 if (ad1848_to_vol(cp
, &vol
)) {
3540 ics2101_mix_attenuate(ic
,
3544 ics2101_mix_attenuate(ic
,
3553 case GUSICS_MIC_IN_LVL
: /* Microphone */
3554 if (cp
->type
== AUDIO_MIXER_VALUE
) {
3555 if (ad1848_to_vol(cp
, &vol
)) {
3556 ics2101_mix_attenuate(ic
,
3560 ics2101_mix_attenuate(ic
,
3569 case GUSICS_LINE_IN_LVL
: /* line in */
3570 if (cp
->type
== AUDIO_MIXER_VALUE
) {
3571 if (ad1848_to_vol(cp
, &vol
)) {
3572 ics2101_mix_attenuate(ic
,
3576 ics2101_mix_attenuate(ic
,
3587 if (cp
->type
== AUDIO_MIXER_VALUE
) {
3588 if (ad1848_to_vol(cp
, &vol
)) {
3589 ics2101_mix_attenuate(ic
,
3593 ics2101_mix_attenuate(ic
,
3602 case GUSICS_DAC_LVL
: /* dac out */
3603 if (cp
->type
== AUDIO_MIXER_VALUE
) {
3604 if (ad1848_to_vol(cp
, &vol
)) {
3605 ics2101_mix_attenuate(ic
,
3609 ics2101_mix_attenuate(ic
,
3619 case GUSICS_RECORD_SOURCE
:
3620 if (cp
->type
== AUDIO_MIXER_ENUM
&& cp
->un
.ord
== 0) {
3621 /* Can't set anything else useful, sigh. */
3634 gus_get_props(void *addr
)
3636 struct gus_softc
*sc
;
3639 return AUDIO_PROP_MMAP
|
3640 (sc
->sc_recdrq
== sc
->sc_playdrq
? 0 : AUDIO_PROP_FULLDUPLEX
);
3644 gusmax_get_props(void *addr
)
3646 struct ad1848_isa_softc
*ac
;
3649 return gus_get_props(ac
->sc_ad1848
.parent
);
3653 gusmax_mixer_query_devinfo(void *addr
, mixer_devinfo_t
*dip
)
3656 DPRINTF(("gusmax_query_devinfo: index=%d\n", dip
->index
));
3658 switch(dip
->index
) {
3660 case GUSMAX_MIC_IN_LVL
: /* Microphone */
3661 dip
->type
= AUDIO_MIXER_VALUE
;
3662 dip
->mixer_class
= GUSMAX_INPUT_CLASS
;
3663 dip
->prev
= AUDIO_MIXER_LAST
;
3664 dip
->next
= GUSMAX_MIC_IN_MUTE
;
3665 strcpy(dip
->label
.name
, AudioNmicrophone
);
3666 dip
->un
.v
.num_channels
= 2;
3667 strcpy(dip
->un
.v
.units
.name
, AudioNvolume
);
3671 case GUSMAX_MONO_LVL
: /* mono/microphone mixer */
3672 dip
->type
= AUDIO_MIXER_VALUE
;
3673 dip
->mixer_class
= GUSMAX_INPUT_CLASS
;
3674 dip
->prev
= AUDIO_MIXER_LAST
;
3675 dip
->next
= GUSMAX_MONO_MUTE
;
3676 strcpy(dip
->label
.name
, AudioNmicrophone
);
3677 dip
->un
.v
.num_channels
= 1;
3678 strcpy(dip
->un
.v
.units
.name
, AudioNvolume
);
3681 case GUSMAX_DAC_LVL
: /* dacout */
3682 dip
->type
= AUDIO_MIXER_VALUE
;
3683 dip
->mixer_class
= GUSMAX_INPUT_CLASS
;
3684 dip
->prev
= AUDIO_MIXER_LAST
;
3685 dip
->next
= GUSMAX_DAC_MUTE
;
3686 strcpy(dip
->label
.name
, AudioNdac
);
3687 dip
->un
.v
.num_channels
= 2;
3688 strcpy(dip
->un
.v
.units
.name
, AudioNvolume
);
3691 case GUSMAX_LINE_IN_LVL
: /* line */
3692 dip
->type
= AUDIO_MIXER_VALUE
;
3693 dip
->mixer_class
= GUSMAX_INPUT_CLASS
;
3694 dip
->prev
= AUDIO_MIXER_LAST
;
3695 dip
->next
= GUSMAX_LINE_IN_MUTE
;
3696 strcpy(dip
->label
.name
, AudioNline
);
3697 dip
->un
.v
.num_channels
= 2;
3698 strcpy(dip
->un
.v
.units
.name
, AudioNvolume
);
3701 case GUSMAX_CD_LVL
: /* cd */
3702 dip
->type
= AUDIO_MIXER_VALUE
;
3703 dip
->mixer_class
= GUSMAX_INPUT_CLASS
;
3704 dip
->prev
= AUDIO_MIXER_LAST
;
3705 dip
->next
= GUSMAX_CD_MUTE
;
3706 strcpy(dip
->label
.name
, AudioNcd
);
3707 dip
->un
.v
.num_channels
= 2;
3708 strcpy(dip
->un
.v
.units
.name
, AudioNvolume
);
3712 case GUSMAX_MONITOR_LVL
: /* monitor level */
3713 dip
->type
= AUDIO_MIXER_VALUE
;
3714 dip
->mixer_class
= GUSMAX_MONITOR_CLASS
;
3715 dip
->next
= GUSMAX_MONITOR_MUTE
;
3716 dip
->prev
= AUDIO_MIXER_LAST
;
3717 strcpy(dip
->label
.name
, AudioNmonitor
);
3718 dip
->un
.v
.num_channels
= 1;
3719 strcpy(dip
->un
.v
.units
.name
, AudioNvolume
);
3722 case GUSMAX_OUT_LVL
: /* cs4231 output volume: not useful? */
3723 dip
->type
= AUDIO_MIXER_VALUE
;
3724 dip
->mixer_class
= GUSMAX_MONITOR_CLASS
;
3725 dip
->prev
= dip
->next
= AUDIO_MIXER_LAST
;
3726 strcpy(dip
->label
.name
, AudioNoutput
);
3727 dip
->un
.v
.num_channels
= 2;
3728 strcpy(dip
->un
.v
.units
.name
, AudioNvolume
);
3731 case GUSMAX_SPEAKER_LVL
: /* fake speaker volume */
3732 dip
->type
= AUDIO_MIXER_VALUE
;
3733 dip
->mixer_class
= GUSMAX_MONITOR_CLASS
;
3734 dip
->prev
= AUDIO_MIXER_LAST
;
3735 dip
->next
= GUSMAX_SPEAKER_MUTE
;
3736 strcpy(dip
->label
.name
, AudioNmaster
);
3737 dip
->un
.v
.num_channels
= 2;
3738 strcpy(dip
->un
.v
.units
.name
, AudioNvolume
);
3741 case GUSMAX_LINE_IN_MUTE
:
3742 dip
->mixer_class
= GUSMAX_INPUT_CLASS
;
3743 dip
->type
= AUDIO_MIXER_ENUM
;
3744 dip
->prev
= GUSMAX_LINE_IN_LVL
;
3745 dip
->next
= AUDIO_MIXER_LAST
;
3748 case GUSMAX_DAC_MUTE
:
3749 dip
->mixer_class
= GUSMAX_INPUT_CLASS
;
3750 dip
->type
= AUDIO_MIXER_ENUM
;
3751 dip
->prev
= GUSMAX_DAC_LVL
;
3752 dip
->next
= AUDIO_MIXER_LAST
;
3755 case GUSMAX_CD_MUTE
:
3756 dip
->mixer_class
= GUSMAX_INPUT_CLASS
;
3757 dip
->type
= AUDIO_MIXER_ENUM
;
3758 dip
->prev
= GUSMAX_CD_LVL
;
3759 dip
->next
= AUDIO_MIXER_LAST
;
3762 case GUSMAX_MONO_MUTE
:
3763 dip
->mixer_class
= GUSMAX_INPUT_CLASS
;
3764 dip
->type
= AUDIO_MIXER_ENUM
;
3765 dip
->prev
= GUSMAX_MONO_LVL
;
3766 dip
->next
= AUDIO_MIXER_LAST
;
3769 case GUSMAX_MONITOR_MUTE
:
3770 dip
->mixer_class
= GUSMAX_OUTPUT_CLASS
;
3771 dip
->type
= AUDIO_MIXER_ENUM
;
3772 dip
->prev
= GUSMAX_MONITOR_LVL
;
3773 dip
->next
= AUDIO_MIXER_LAST
;
3776 case GUSMAX_SPEAKER_MUTE
:
3777 dip
->mixer_class
= GUSMAX_OUTPUT_CLASS
;
3778 dip
->type
= AUDIO_MIXER_ENUM
;
3779 dip
->prev
= GUSMAX_SPEAKER_LVL
;
3780 dip
->next
= AUDIO_MIXER_LAST
;
3782 strcpy(dip
->label
.name
, AudioNmute
);
3783 dip
->un
.e
.num_mem
= 2;
3784 strcpy(dip
->un
.e
.member
[0].label
.name
, AudioNoff
);
3785 dip
->un
.e
.member
[0].ord
= 0;
3786 strcpy(dip
->un
.e
.member
[1].label
.name
, AudioNon
);
3787 dip
->un
.e
.member
[1].ord
= 1;
3790 case GUSMAX_REC_LVL
: /* record level */
3791 dip
->type
= AUDIO_MIXER_VALUE
;
3792 dip
->mixer_class
= GUSMAX_RECORD_CLASS
;
3793 dip
->prev
= AUDIO_MIXER_LAST
;
3794 dip
->next
= GUSMAX_RECORD_SOURCE
;
3795 strcpy(dip
->label
.name
, AudioNrecord
);
3796 dip
->un
.v
.num_channels
= 2;
3797 strcpy(dip
->un
.v
.units
.name
, AudioNvolume
);
3800 case GUSMAX_RECORD_SOURCE
:
3801 dip
->mixer_class
= GUSMAX_RECORD_CLASS
;
3802 dip
->type
= AUDIO_MIXER_ENUM
;
3803 dip
->prev
= GUSMAX_REC_LVL
;
3804 dip
->next
= AUDIO_MIXER_LAST
;
3805 strcpy(dip
->label
.name
, AudioNsource
);
3806 dip
->un
.e
.num_mem
= 4;
3807 strcpy(dip
->un
.e
.member
[0].label
.name
, AudioNoutput
);
3808 dip
->un
.e
.member
[0].ord
= DAC_IN_PORT
;
3809 strcpy(dip
->un
.e
.member
[1].label
.name
, AudioNmicrophone
);
3810 dip
->un
.e
.member
[1].ord
= MIC_IN_PORT
;
3811 strcpy(dip
->un
.e
.member
[2].label
.name
, AudioNdac
);
3812 dip
->un
.e
.member
[2].ord
= AUX1_IN_PORT
;
3813 strcpy(dip
->un
.e
.member
[3].label
.name
, AudioNline
);
3814 dip
->un
.e
.member
[3].ord
= LINE_IN_PORT
;
3817 case GUSMAX_INPUT_CLASS
: /* input class descriptor */
3818 dip
->type
= AUDIO_MIXER_CLASS
;
3819 dip
->mixer_class
= GUSMAX_INPUT_CLASS
;
3820 dip
->next
= dip
->prev
= AUDIO_MIXER_LAST
;
3821 strcpy(dip
->label
.name
, AudioCinputs
);
3824 case GUSMAX_OUTPUT_CLASS
: /* output class descriptor */
3825 dip
->type
= AUDIO_MIXER_CLASS
;
3826 dip
->mixer_class
= GUSMAX_OUTPUT_CLASS
;
3827 dip
->next
= dip
->prev
= AUDIO_MIXER_LAST
;
3828 strcpy(dip
->label
.name
, AudioCoutputs
);
3831 case GUSMAX_MONITOR_CLASS
: /* monitor class descriptor */
3832 dip
->type
= AUDIO_MIXER_CLASS
;
3833 dip
->mixer_class
= GUSMAX_MONITOR_CLASS
;
3834 dip
->next
= dip
->prev
= AUDIO_MIXER_LAST
;
3835 strcpy(dip
->label
.name
, AudioCmonitor
);
3838 case GUSMAX_RECORD_CLASS
: /* record source class */
3839 dip
->type
= AUDIO_MIXER_CLASS
;
3840 dip
->mixer_class
= GUSMAX_RECORD_CLASS
;
3841 dip
->next
= dip
->prev
= AUDIO_MIXER_LAST
;
3842 strcpy(dip
->label
.name
, AudioCrecord
);
3849 DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip
->label
.name
));
3854 gus_mixer_query_devinfo(void *addr
, mixer_devinfo_t
*dip
)
3856 struct gus_softc
*sc
;
3858 DPRINTF(("gusmax_query_devinfo: index=%d\n", dip
->index
));
3860 if (!HAS_MIXER(sc
) && dip
->index
> GUSICS_MASTER_MUTE
)
3863 switch(dip
->index
) {
3865 case GUSICS_MIC_IN_LVL
: /* Microphone */
3866 dip
->type
= AUDIO_MIXER_VALUE
;
3867 dip
->mixer_class
= GUSICS_INPUT_CLASS
;
3868 dip
->prev
= AUDIO_MIXER_LAST
;
3869 dip
->next
= GUSICS_MIC_IN_MUTE
;
3870 strcpy(dip
->label
.name
, AudioNmicrophone
);
3871 dip
->un
.v
.num_channels
= 2;
3872 strcpy(dip
->un
.v
.units
.name
, AudioNvolume
);
3875 case GUSICS_LINE_IN_LVL
: /* line */
3876 dip
->type
= AUDIO_MIXER_VALUE
;
3877 dip
->mixer_class
= GUSICS_INPUT_CLASS
;
3878 dip
->prev
= AUDIO_MIXER_LAST
;
3879 dip
->next
= GUSICS_LINE_IN_MUTE
;
3880 strcpy(dip
->label
.name
, AudioNline
);
3881 dip
->un
.v
.num_channels
= 2;
3882 strcpy(dip
->un
.v
.units
.name
, AudioNvolume
);
3885 case GUSICS_CD_LVL
: /* cd */
3886 dip
->type
= AUDIO_MIXER_VALUE
;
3887 dip
->mixer_class
= GUSICS_INPUT_CLASS
;
3888 dip
->prev
= AUDIO_MIXER_LAST
;
3889 dip
->next
= GUSICS_CD_MUTE
;
3890 strcpy(dip
->label
.name
, AudioNcd
);
3891 dip
->un
.v
.num_channels
= 2;
3892 strcpy(dip
->un
.v
.units
.name
, AudioNvolume
);
3895 case GUSICS_DAC_LVL
: /* dacout */
3896 dip
->type
= AUDIO_MIXER_VALUE
;
3897 dip
->mixer_class
= GUSICS_INPUT_CLASS
;
3898 dip
->prev
= AUDIO_MIXER_LAST
;
3899 dip
->next
= GUSICS_DAC_MUTE
;
3900 strcpy(dip
->label
.name
, AudioNdac
);
3901 dip
->un
.v
.num_channels
= 2;
3902 strcpy(dip
->un
.v
.units
.name
, AudioNvolume
);
3905 case GUSICS_MASTER_LVL
: /* master output */
3906 dip
->type
= AUDIO_MIXER_VALUE
;
3907 dip
->mixer_class
= GUSICS_OUTPUT_CLASS
;
3908 dip
->prev
= AUDIO_MIXER_LAST
;
3909 dip
->next
= GUSICS_MASTER_MUTE
;
3910 strcpy(dip
->label
.name
, AudioNmaster
);
3911 dip
->un
.v
.num_channels
= 2;
3912 strcpy(dip
->un
.v
.units
.name
, AudioNvolume
);
3916 case GUSICS_LINE_IN_MUTE
:
3917 dip
->mixer_class
= GUSICS_INPUT_CLASS
;
3918 dip
->type
= AUDIO_MIXER_ENUM
;
3919 dip
->prev
= GUSICS_LINE_IN_LVL
;
3920 dip
->next
= AUDIO_MIXER_LAST
;
3923 case GUSICS_DAC_MUTE
:
3924 dip
->mixer_class
= GUSICS_INPUT_CLASS
;
3925 dip
->type
= AUDIO_MIXER_ENUM
;
3926 dip
->prev
= GUSICS_DAC_LVL
;
3927 dip
->next
= AUDIO_MIXER_LAST
;
3930 case GUSICS_CD_MUTE
:
3931 dip
->mixer_class
= GUSICS_INPUT_CLASS
;
3932 dip
->type
= AUDIO_MIXER_ENUM
;
3933 dip
->prev
= GUSICS_CD_LVL
;
3934 dip
->next
= AUDIO_MIXER_LAST
;
3937 case GUSICS_MIC_IN_MUTE
:
3938 dip
->mixer_class
= GUSICS_INPUT_CLASS
;
3939 dip
->type
= AUDIO_MIXER_ENUM
;
3940 dip
->prev
= GUSICS_MIC_IN_LVL
;
3941 dip
->next
= AUDIO_MIXER_LAST
;
3944 case GUSICS_MASTER_MUTE
:
3945 dip
->mixer_class
= GUSICS_OUTPUT_CLASS
;
3946 dip
->type
= AUDIO_MIXER_ENUM
;
3947 dip
->prev
= GUSICS_MASTER_LVL
;
3948 dip
->next
= AUDIO_MIXER_LAST
;
3950 strcpy(dip
->label
.name
, AudioNmute
);
3951 dip
->un
.e
.num_mem
= 2;
3952 strcpy(dip
->un
.e
.member
[0].label
.name
, AudioNoff
);
3953 dip
->un
.e
.member
[0].ord
= 0;
3954 strcpy(dip
->un
.e
.member
[1].label
.name
, AudioNon
);
3955 dip
->un
.e
.member
[1].ord
= 1;
3958 case GUSICS_RECORD_SOURCE
:
3959 dip
->mixer_class
= GUSICS_RECORD_CLASS
;
3960 dip
->type
= AUDIO_MIXER_ENUM
;
3961 dip
->prev
= dip
->next
= AUDIO_MIXER_LAST
;
3962 strcpy(dip
->label
.name
, AudioNsource
);
3963 dip
->un
.e
.num_mem
= 1;
3964 strcpy(dip
->un
.e
.member
[0].label
.name
, AudioNoutput
);
3965 dip
->un
.e
.member
[0].ord
= GUSICS_MASTER_LVL
;
3968 case GUSICS_INPUT_CLASS
:
3969 dip
->type
= AUDIO_MIXER_CLASS
;
3970 dip
->mixer_class
= GUSICS_INPUT_CLASS
;
3971 dip
->next
= dip
->prev
= AUDIO_MIXER_LAST
;
3972 strcpy(dip
->label
.name
, AudioCinputs
);
3975 case GUSICS_OUTPUT_CLASS
:
3976 dip
->type
= AUDIO_MIXER_CLASS
;
3977 dip
->mixer_class
= GUSICS_OUTPUT_CLASS
;
3978 dip
->next
= dip
->prev
= AUDIO_MIXER_LAST
;
3979 strcpy(dip
->label
.name
, AudioCoutputs
);
3982 case GUSICS_RECORD_CLASS
:
3983 dip
->type
= AUDIO_MIXER_CLASS
;
3984 dip
->mixer_class
= GUSICS_RECORD_CLASS
;
3985 dip
->next
= dip
->prev
= AUDIO_MIXER_LAST
;
3986 strcpy(dip
->label
.name
, AudioCrecord
);
3993 DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip
->label
.name
));
3998 gus_query_encoding(void *addr
, struct audio_encoding
*fp
)
4001 switch (fp
->index
) {
4003 strcpy(fp
->name
, AudioEmulaw
);
4004 fp
->encoding
= AUDIO_ENCODING_ULAW
;
4006 fp
->flags
= AUDIO_ENCODINGFLAG_EMULATED
;
4009 strcpy(fp
->name
, AudioEslinear
);
4010 fp
->encoding
= AUDIO_ENCODING_SLINEAR
;
4015 strcpy(fp
->name
, AudioEslinear_le
);
4016 fp
->encoding
= AUDIO_ENCODING_SLINEAR_LE
;
4021 strcpy(fp
->name
, AudioEulinear
);
4022 fp
->encoding
= AUDIO_ENCODING_ULINEAR
;
4027 strcpy(fp
->name
, AudioEulinear_le
);
4028 fp
->encoding
= AUDIO_ENCODING_ULINEAR_LE
;
4033 strcpy(fp
->name
, AudioEslinear_be
);
4034 fp
->encoding
= AUDIO_ENCODING_SLINEAR_BE
;
4036 fp
->flags
= AUDIO_ENCODINGFLAG_EMULATED
;
4039 strcpy(fp
->name
, AudioEulinear_be
);
4040 fp
->encoding
= AUDIO_ENCODING_ULINEAR_BE
;
4042 fp
->flags
= AUDIO_ENCODINGFLAG_EMULATED
;
4045 strcpy(fp
->name
, AudioEalaw
);
4046 fp
->encoding
= AUDIO_ENCODING_ALAW
;
4048 fp
->flags
= AUDIO_ENCODINGFLAG_EMULATED
;
4059 * Setup the ICS mixer in "transparent" mode: reset everything to a sensible
4060 * level. Levels as suggested by GUS SDK code.
4063 gus_init_ics2101(struct gus_softc
*sc
)
4065 struct ics2101_softc
*ic
;
4068 sc
->sc_mixer
.sc_iot
= sc
->sc_iot
;
4069 sc
->sc_mixer
.sc_selio
= GUS_MIXER_SELECT
;
4070 sc
->sc_mixer
.sc_selio_ioh
= sc
->sc_ioh3
;
4071 sc
->sc_mixer
.sc_dataio
= GUS_MIXER_DATA
;
4072 sc
->sc_mixer
.sc_dataio_ioh
= sc
->sc_ioh2
;
4073 sc
->sc_mixer
.sc_flags
= (sc
->sc_revision
== 5) ? ICS_FLIP
: 0;
4075 ics2101_mix_attenuate(ic
,
4079 ics2101_mix_attenuate(ic
,
4084 * Start with microphone muted by the mixer...
4086 gusics_mic_mute(ic
, 1);
4088 /* ... and enabled by the GUS master mix control */
4089 gus_mic_ctl(sc
, SPKR_ON
);
4091 ics2101_mix_attenuate(ic
,
4095 ics2101_mix_attenuate(ic
,
4100 ics2101_mix_attenuate(ic
,
4104 ics2101_mix_attenuate(ic
,
4109 ics2101_mix_attenuate(ic
,
4113 ics2101_mix_attenuate(ic
,
4118 ics2101_mix_attenuate(ic
,
4122 ics2101_mix_attenuate(ic
,
4127 ics2101_mix_attenuate(ic
,
4131 ics2101_mix_attenuate(ic
,
4135 /* unmute other stuff: */
4136 gusics_cd_mute(ic
, 0);
4137 gusics_dac_mute(ic
, 0);
4138 gusics_linein_mute(ic
, 0);