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