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