gus.c revision 1.70 1 /* $NetBSD: gus.c,v 1.70 2001/01/18 20:28:19 jdolecek 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 };
617
618 static struct audio_hw_if gusmax_hw_if = {
619 gusmaxopen,
620 gusmax_close,
621 NULL, /* drain */
622
623 gus_query_encoding, /* query encoding */
624
625 gusmax_set_params,
626
627 gusmax_round_blocksize,
628
629 gusmax_commit_settings,
630
631 NULL,
632 NULL,
633
634 gusmax_dma_output,
635 gusmax_dma_input,
636 gusmax_halt_out_dma,
637 gusmax_halt_in_dma,
638
639 gusmax_speaker_ctl,
640
641 gus_getdev,
642 NULL,
643 gusmax_mixer_set_port,
644 gusmax_mixer_get_port,
645 gusmax_mixer_query_devinfo,
646 ad1848_isa_malloc,
647 ad1848_isa_free,
648 ad1848_isa_round_buffersize,
649 ad1848_isa_mappage,
650 gusmax_get_props,
651 };
652
653 /*
654 * Some info about the current audio device
655 */
656
657 struct audio_device gus_device = {
658 "UltraSound",
659 "",
660 "gus",
661 };
662
663 #define FLIP_REV 5 /* This rev has flipped mixer chans */
664
665
666 int
667 gusprobe(parent, match, aux)
668 struct device *parent;
669 struct cfdata *match;
670 void *aux;
671 {
672 struct isa_attach_args *ia = aux;
673 int iobase = ia->ia_iobase;
674 int recdrq = ia->ia_drq2;
675
676 /*
677 * Before we do anything else, make sure requested IRQ and DRQ are
678 * valid for this card.
679 */
680
681 /* XXX range check before indexing!! */
682 if (ia->ia_irq == IRQUNK || gus_irq_map[ia->ia_irq] == IRQUNK) {
683 printf("gus: invalid irq %d, card not probed\n", ia->ia_irq);
684 return 0;
685 }
686
687 if (ia->ia_drq == DRQUNK || gus_drq_map[ia->ia_drq] == DRQUNK) {
688 printf("gus: invalid drq %d, card not probed\n", ia->ia_drq);
689 return 0;
690 }
691
692 if (recdrq != DRQUNK) {
693 if (recdrq > 7 || gus_drq_map[recdrq] == DRQUNK) {
694 printf("gus: invalid second DMA channel (%d), card not probed\n", recdrq);
695 return 0;
696 }
697 } else
698 recdrq = ia->ia_drq;
699
700 if (iobase == IOBASEUNK) {
701 int i;
702 for(i = 0; i < gus_addrs; i++)
703 if (gus_test_iobase(ia->ia_iot, gus_base_addrs[i])) {
704 iobase = gus_base_addrs[i];
705 goto done;
706 }
707 return 0;
708 } else if (!gus_test_iobase(ia->ia_iot, iobase))
709 return 0;
710
711 done:
712 if ((ia->ia_drq != -1 && !isa_drq_isfree(ia->ia_ic, ia->ia_drq)) ||
713 (recdrq != -1 && !isa_drq_isfree(ia->ia_ic, recdrq)))
714 return 0;
715
716 ia->ia_iobase = iobase;
717 ia->ia_iosize = GUS_NPORT1;
718 return 1;
719 }
720
721 /*
722 * Test to see if a particular I/O base is valid for the GUS. Return true
723 * if it is.
724 */
725
726 STATIC int
727 gus_test_iobase (iot, iobase)
728 bus_space_tag_t iot;
729 int iobase;
730 {
731 bus_space_handle_t ioh1, ioh2, ioh3, ioh4;
732 u_char s1, s2;
733 int s, rv = 0;
734
735 /* Map i/o space */
736 if (bus_space_map(iot, iobase, GUS_NPORT1, 0, &ioh1))
737 return 0;
738 if (bus_space_map(iot, iobase+GUS_IOH2_OFFSET, GUS_NPORT2, 0, &ioh2))
739 goto bad1;
740
741 /* XXX Maybe we shouldn't fail on mapping this, but just assume
742 * the card is of revision 0? */
743 if (bus_space_map(iot, iobase+GUS_IOH3_OFFSET, GUS_NPORT3, 0, &ioh3))
744 goto bad2;
745
746 if (bus_space_map(iot, iobase+GUS_IOH4_OFFSET, GUS_NPORT4, 0, &ioh4))
747 goto bad3;
748
749 /*
750 * Reset GUS to an initial state before we do anything.
751 */
752
753 s = splgus();
754 delay(500);
755
756 SELECT_GUS_REG(iot, ioh2, GUSREG_RESET);
757 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
758
759 delay(500);
760
761 SELECT_GUS_REG(iot, ioh2, GUSREG_RESET);
762 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, GUSMASK_MASTER_RESET);
763
764 delay(500);
765
766 splx(s);
767
768 /*
769 * See if we can write to the board's memory
770 */
771
772 s1 = guspeek(iot, ioh2, 0L);
773 s2 = guspeek(iot, ioh2, 1L);
774
775 guspoke(iot, ioh2, 0L, 0xaa);
776 guspoke(iot, ioh2, 1L, 0x55);
777
778 if (guspeek(iot, ioh2, 0L) != 0xaa)
779 goto bad;
780
781 guspoke(iot, ioh2, 0L, s1);
782 guspoke(iot, ioh2, 1L, s2);
783
784 rv = 1;
785
786 bad:
787 bus_space_unmap(iot, ioh4, GUS_NPORT4);
788 bad3:
789 bus_space_unmap(iot, ioh3, GUS_NPORT3);
790 bad2:
791 bus_space_unmap(iot, ioh2, GUS_NPORT2);
792 bad1:
793 bus_space_unmap(iot, ioh1, GUS_NPORT1);
794 return rv;
795 }
796
797 /*
798 * Setup the GUS for use; called shortly after probe
799 */
800
801 void
802 gusattach(parent, self, aux)
803 struct device *parent, *self;
804 void *aux;
805 {
806 struct gus_softc *sc = (void *) self;
807 struct isa_attach_args *ia = aux;
808 bus_space_tag_t iot;
809 bus_space_handle_t ioh1, ioh2, ioh3, ioh4;
810 int iobase, i;
811 unsigned char c,d,m;
812
813 callout_init(&sc->sc_dmaout_ch);
814
815 sc->sc_iot = iot = ia->ia_iot;
816 sc->sc_ic = ia->ia_ic;
817 iobase = ia->ia_iobase;
818
819 /* Map i/o space */
820 if (bus_space_map(iot, iobase, GUS_NPORT1, 0, &ioh1))
821 panic("%s: can't map io port range 1", self->dv_xname);
822 sc->sc_ioh1 = ioh1;
823 if (bus_space_map(iot, iobase+GUS_IOH2_OFFSET, GUS_NPORT2, 0, &ioh2))
824 panic("%s: can't map io port range 2", self->dv_xname);
825 sc->sc_ioh2 = ioh2;
826
827 /* XXX Maybe we shouldn't fail on mapping this, but just assume
828 * the card is of revision 0? */
829 if (bus_space_map(iot, iobase+GUS_IOH3_OFFSET, GUS_NPORT3, 0, &ioh3))
830 panic("%s: can't map io port range 3", self->dv_xname);
831 sc->sc_ioh3 = ioh3;
832
833 if (bus_space_map(iot, iobase+GUS_IOH4_OFFSET, GUS_NPORT4, 0, &ioh4))
834 panic("%s: can't map io port range 4", self->dv_xname);
835 sc->sc_ioh4 = ioh4;
836
837 sc->sc_iobase = iobase;
838 sc->sc_irq = ia->ia_irq;
839 sc->sc_playdrq = ia->ia_drq;
840 sc->sc_recdrq = ia->ia_drq2;
841
842 /*
843 * Figure out our board rev, and see if we need to initialize the
844 * mixer
845 */
846
847 sc->sc_ic = ia->ia_ic;
848
849 delay(500);
850
851 c = bus_space_read_1(iot, ioh3, GUS_BOARD_REV);
852 if (c != 0xff)
853 sc->sc_revision = c;
854 else
855 sc->sc_revision = 0;
856
857
858 SELECT_GUS_REG(iot, ioh2, GUSREG_RESET);
859 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
860
861 gusreset(sc, GUS_MAX_VOICES); /* initialize all voices */
862 gusreset(sc, GUS_MIN_VOICES); /* then set to just the ones we use */
863
864 /*
865 * Setup the IRQ and DRQ lines in software, using values from
866 * config file
867 */
868
869 m = GUSMASK_LINE_IN|GUSMASK_LINE_OUT; /* disable all */
870
871 c = ((unsigned char) gus_irq_map[ia->ia_irq]) | GUSMASK_BOTH_RQ;
872
873 if (sc->sc_recdrq == sc->sc_playdrq)
874 d = (unsigned char) (gus_drq_map[sc->sc_playdrq] |
875 GUSMASK_BOTH_RQ);
876 else
877 d = (unsigned char) (gus_drq_map[sc->sc_playdrq] |
878 gus_drq_map[sc->sc_recdrq] << 3);
879
880 /*
881 * Program the IRQ and DMA channels on the GUS. Note that we hardwire
882 * the GUS to only use one IRQ channel, but we give the user the
883 * option of using two DMA channels (the other one given by the drq2
884 * option in the config file). Two DMA channels are needed for full-
885 * duplex operation.
886 *
887 * The order of these operations is very magical.
888 */
889
890 disable_intr(); /* XXX needed? */
891
892 bus_space_write_1(iot, ioh1, GUS_REG_CONTROL, GUS_REG_IRQCTL);
893 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, m);
894 bus_space_write_1(iot, ioh1, GUS_IRQCTL_CONTROL, 0x00);
895 bus_space_write_1(iot, ioh1, 0x0f, 0x00);
896
897 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, m);
898 bus_space_write_1(iot, ioh1, GUS_DMA_CONTROL, d | 0x80); /* magic reset? */
899
900 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, m | GUSMASK_CONTROL_SEL);
901 bus_space_write_1(iot, ioh1, GUS_IRQ_CONTROL, c);
902
903 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, m);
904 bus_space_write_1(iot, ioh1, GUS_DMA_CONTROL, d);
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, ioh2, GUS_VOICE_SELECT, 0x00);
910
911 /* enable line in, line out. leave mic disabled. */
912 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL,
913 (m | GUSMASK_LATCHES) & ~(GUSMASK_LINE_OUT|GUSMASK_LINE_IN));
914 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, 0x00);
915
916 enable_intr();
917
918 sc->sc_mixcontrol =
919 (m | GUSMASK_LATCHES) & ~(GUSMASK_LINE_OUT|GUSMASK_LINE_IN);
920
921 if (sc->sc_playdrq != -1) {
922 sc->sc_play_maxsize = isa_dmamaxsize(sc->sc_ic,
923 sc->sc_playdrq);
924 if (isa_dmamap_create(sc->sc_ic, sc->sc_playdrq,
925 sc->sc_play_maxsize, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) {
926 printf("%s: can't create map for drq %d\n",
927 sc->sc_dev.dv_xname, sc->sc_playdrq);
928 return;
929 }
930 }
931 if (sc->sc_recdrq != -1 && sc->sc_recdrq != sc->sc_playdrq) {
932 sc->sc_req_maxsize = isa_dmamaxsize(sc->sc_ic,
933 sc->sc_recdrq);
934 if (isa_dmamap_create(sc->sc_ic, sc->sc_recdrq,
935 sc->sc_req_maxsize, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) {
936 printf("%s: can't create map for drq %d\n",
937 sc->sc_dev.dv_xname, sc->sc_recdrq);
938 return;
939 }
940 }
941
942 /* XXX WILL THIS ALWAYS WORK THE WAY THEY'RE OVERLAYED?! */
943 sc->sc_codec.sc_ic = sc->sc_ic;
944
945 if (sc->sc_revision >= 5 && sc->sc_revision <= 9) {
946 sc->sc_flags |= GUS_MIXER_INSTALLED;
947 gus_init_ics2101(sc);
948 }
949 if (sc->sc_revision >= 10)
950 gus_init_cs4231(sc);
951
952 SELECT_GUS_REG(iot, ioh2, GUSREG_RESET);
953 /*
954 * Check to see how much memory we have on this card; see if any
955 * "mirroring" occurs. We're assuming at least 256K already exists
956 * on the card; otherwise the initial probe would have failed
957 */
958
959 guspoke(iot, ioh2, 0L, 0x00);
960 for(i = 1; i < 1024; i++) {
961 u_long loc;
962
963 /*
964 * See if we've run into mirroring yet
965 */
966
967 if (guspeek(iot, ioh2, 0L) != 0)
968 break;
969
970 loc = i << 10;
971
972 guspoke(iot, ioh2, loc, 0xaa);
973 if (guspeek(iot, ioh2, loc) != 0xaa)
974 break;
975 }
976
977 sc->sc_dsize = i;
978
979 /* The "official" (3.x) version number cannot easily be obtained.
980 * The revision register does not correspond to the minor number
981 * of the board version. Simply use the revision register as
982 * identification.
983 */
984 sprintf(gus_device.version, "%d", sc->sc_revision);
985
986 printf("\n%s: Gravis UltraSound", sc->sc_dev.dv_xname);
987 if (sc->sc_revision >= 10)
988 printf(" MAX");
989 else {
990 if (HAS_MIXER(sc))
991 printf(", mixer");
992 if (HAS_CODEC(sc))
993 printf(" with CODEC module");
994 }
995 printf(", %dKB memory\n", sc->sc_dsize);
996
997 /* A GUS MAX should always have a CODEC installed */
998 if ((sc->sc_revision >= 10) & !(HAS_CODEC(sc)))
999 printf("%s: WARNING: did not attach CODEC on MAX\n",
1000 sc->sc_dev.dv_xname);
1001
1002 /*
1003 * Setup a default interrupt handler
1004 */
1005
1006 /* XXX we shouldn't have to use splgus == splclock, nor should
1007 * we use IPL_CLOCK.
1008 */
1009 sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq, IST_EDGE,
1010 IPL_AUDIO, gusintr, sc /* sc->sc_gusdsp */);
1011
1012 /*
1013 * Set some default values
1014 * XXX others start with 8kHz mono mulaw
1015 */
1016
1017 sc->sc_irate = sc->sc_orate = 44100;
1018 sc->sc_encoding = AUDIO_ENCODING_SLINEAR_LE;
1019 sc->sc_precision = 16;
1020 sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_DATA_SIZE16;
1021 sc->sc_voc[GUS_VOICE_RIGHT].voccntl |= GUSMASK_DATA_SIZE16;
1022 sc->sc_channels = 1;
1023 sc->sc_ogain = 340;
1024 gus_commit_settings(sc);
1025
1026 /*
1027 * We always put the left channel full left & right channel
1028 * full right.
1029 * For mono playback, we set up both voices playing the same buffer.
1030 */
1031 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) GUS_VOICE_LEFT);
1032 SELECT_GUS_REG(iot, ioh2, GUSREG_PAN_POS);
1033 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, GUS_PAN_FULL_LEFT);
1034
1035 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) GUS_VOICE_RIGHT);
1036 SELECT_GUS_REG(iot, ioh2, GUSREG_PAN_POS);
1037 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, GUS_PAN_FULL_RIGHT);
1038
1039 /*
1040 * Attach to the generic audio layer
1041 */
1042
1043 audio_attach_mi(&gus_hw_if, HAS_CODEC(sc) ? (void *)&sc->sc_codec : (void *)sc, &sc->sc_dev);
1044 }
1045
1046 int
1047 gusopen(addr, flags)
1048 void *addr;
1049 int flags;
1050 {
1051 struct gus_softc *sc = addr;
1052
1053 DPRINTF(("gusopen() called\n"));
1054
1055 if (sc->sc_flags & GUS_OPEN)
1056 return EBUSY;
1057
1058 /*
1059 * Some initialization
1060 */
1061
1062 sc->sc_flags |= GUS_OPEN;
1063 sc->sc_dmabuf = 0;
1064 sc->sc_playbuf = -1;
1065 sc->sc_bufcnt = 0;
1066 sc->sc_voc[GUS_VOICE_LEFT].start_addr = GUS_MEM_OFFSET - 1;
1067 sc->sc_voc[GUS_VOICE_LEFT].current_addr = GUS_MEM_OFFSET;
1068
1069 if (HAS_CODEC(sc)) {
1070 ad1848_open(&sc->sc_codec.sc_ad1848, flags);
1071 sc->sc_codec.sc_ad1848.mute[AD1848_AUX1_CHANNEL] = 0;
1072
1073 /* turn on DAC output */
1074 ad1848_mute_channel(&sc->sc_codec.sc_ad1848,
1075 AD1848_AUX1_CHANNEL, 0);
1076 if (flags & FREAD) {
1077 sc->sc_codec.sc_ad1848.mute[AD1848_MONO_CHANNEL] = 0;
1078 ad1848_mute_channel(&sc->sc_codec.sc_ad1848,
1079 AD1848_MONO_CHANNEL, 0);
1080 }
1081 } else if (flags & FREAD) {
1082 /* enable/unmute the microphone */
1083 if (HAS_MIXER(sc)) {
1084 gusics_mic_mute(&sc->sc_mixer, 0);
1085 } else
1086 gus_mic_ctl(sc, SPKR_ON);
1087 }
1088 if (sc->sc_nbufs == 0)
1089 gus_round_blocksize(sc, GUS_BUFFER_MULTIPLE); /* default blksiz */
1090 return 0;
1091 }
1092
1093 int
1094 gusmaxopen(addr, flags)
1095 void *addr;
1096 int flags;
1097 {
1098 struct ad1848_isa_softc *ac = addr;
1099 return gusopen(ac->sc_ad1848.parent, flags);
1100 }
1101
1102 STATIC void
1103 gus_deinterleave(sc, buf, size)
1104 struct gus_softc *sc;
1105 void *buf;
1106 int size;
1107 {
1108 /* deinterleave the stereo data. We can use sc->sc_deintr_buf
1109 for scratch space. */
1110 int i;
1111
1112 if (size > sc->sc_blocksize) {
1113 printf("gus: deinterleave %d > %d\n", size, sc->sc_blocksize);
1114 return;
1115 } else if (size < sc->sc_blocksize) {
1116 DPRINTF(("gus: deinterleave %d < %d\n", size, sc->sc_blocksize));
1117 }
1118
1119 /*
1120 * size is in bytes.
1121 */
1122 if (sc->sc_precision == 16) {
1123 u_short *dei = sc->sc_deintr_buf;
1124 u_short *sbuf = buf;
1125 size >>= 1; /* bytecnt to shortcnt */
1126 /* copy 2nd of each pair of samples to the staging area, while
1127 compacting the 1st of each pair into the original area. */
1128 for (i = 0; i < size/2-1; i++) {
1129 dei[i] = sbuf[i*2+1];
1130 sbuf[i+1] = sbuf[i*2+2];
1131 }
1132 /*
1133 * this has copied one less sample than half of the
1134 * buffer. The first sample of the 1st stream was
1135 * already in place and didn't need copying.
1136 * Therefore, we've moved all of the 1st stream's
1137 * samples into place. We have one sample from 2nd
1138 * stream in the last slot of original area, not
1139 * copied to the staging area (But we don't need to!).
1140 * Copy the remainder of the original stream into place.
1141 */
1142 bcopy(dei, &sbuf[size/2], i * sizeof(short));
1143 } else {
1144 u_char *dei = sc->sc_deintr_buf;
1145 u_char *sbuf = buf;
1146 for (i = 0; i < size/2-1; i++) {
1147 dei[i] = sbuf[i*2+1];
1148 sbuf[i+1] = sbuf[i*2+2];
1149 }
1150 bcopy(dei, &sbuf[size/2], i);
1151 }
1152 }
1153
1154 /*
1155 * Actually output a buffer to the DSP chip
1156 */
1157
1158 int
1159 gusmax_dma_output(addr, buf, size, intr, arg)
1160 void * addr;
1161 void *buf;
1162 int size;
1163 void (*intr) __P((void *));
1164 void *arg;
1165 {
1166 struct ad1848_isa_softc *ac = addr;
1167 return gus_dma_output(ac->sc_ad1848.parent, buf, size, intr, arg);
1168 }
1169
1170 /*
1171 * called at splgus() from interrupt handler.
1172 */
1173 void
1174 stereo_dmaintr(arg)
1175 void *arg;
1176 {
1177 struct gus_softc *sc = arg;
1178 struct stereo_dma_intr *sa = &sc->sc_stereo;
1179
1180 DMAPRINTF(("stereo_dmaintr"));
1181
1182 /*
1183 * Put other half in its place, then call the real interrupt routine :)
1184 */
1185
1186 sc->sc_dmaoutintr = sa->intr;
1187 sc->sc_outarg = sa->arg;
1188
1189 #ifdef GUSPLAYDEBUG
1190 if (gusstats) {
1191 microtime(&dmarecords[dmarecord_index].tv);
1192 dmarecords[dmarecord_index].gusaddr = sa->dmabuf;
1193 dmarecords[dmarecord_index].bsdaddr = sa->buffer;
1194 dmarecords[dmarecord_index].count = sa->size;
1195 dmarecords[dmarecord_index].channel = 1;
1196 dmarecords[dmarecord_index].direction = 1;
1197 dmarecord_index = ++dmarecord_index % NDMARECS;
1198 }
1199 #endif
1200
1201 gusdmaout(sc, sa->flags, sa->dmabuf, (caddr_t) sa->buffer, sa->size);
1202
1203 sa->flags = 0;
1204 sa->dmabuf = 0;
1205 sa->buffer = 0;
1206 sa->size = 0;
1207 sa->intr = 0;
1208 sa->arg = 0;
1209 }
1210
1211 /*
1212 * Start up DMA output to the card.
1213 * Called at splgus/splaudio already, either from intr handler or from
1214 * generic audio code.
1215 */
1216 int
1217 gus_dma_output(addr, buf, size, intr, arg)
1218 void * addr;
1219 void *buf;
1220 int size;
1221 void (*intr) __P((void *));
1222 void *arg;
1223 {
1224 struct gus_softc *sc = addr;
1225 u_char *buffer = buf;
1226 u_long boarddma;
1227 int flags;
1228
1229 DMAPRINTF(("gus_dma_output %d @ %p\n", size, buf));
1230
1231 if (size != sc->sc_blocksize) {
1232 DPRINTF(("gus_dma_output reqsize %d not sc_blocksize %d\n",
1233 size, sc->sc_blocksize));
1234 return EINVAL;
1235 }
1236
1237 flags = GUSMASK_DMA_WRITE;
1238 if (sc->sc_precision == 16)
1239 flags |= GUSMASK_DMA_DATA_SIZE;
1240 if (sc->sc_encoding == AUDIO_ENCODING_ULAW ||
1241 sc->sc_encoding == AUDIO_ENCODING_ALAW ||
1242 sc->sc_encoding == AUDIO_ENCODING_ULINEAR_BE ||
1243 sc->sc_encoding == AUDIO_ENCODING_ULINEAR_LE)
1244 flags |= GUSMASK_DMA_INVBIT;
1245
1246 if (sc->sc_channels == 2) {
1247 if (sc->sc_precision == 16) {
1248 if (size & 3) {
1249 DPRINTF(("gus_dma_output: unpaired 16bit samples"));
1250 size &= 3;
1251 }
1252 } else if (size & 1) {
1253 DPRINTF(("gus_dma_output: unpaired samples"));
1254 size &= 1;
1255 }
1256 if (size == 0)
1257 return 0;
1258
1259 gus_deinterleave(sc, (void *)buffer, size);
1260
1261 size >>= 1;
1262
1263 boarddma = size * sc->sc_dmabuf + GUS_MEM_OFFSET;
1264
1265 sc->sc_stereo.intr = intr;
1266 sc->sc_stereo.arg = arg;
1267 sc->sc_stereo.size = size;
1268 sc->sc_stereo.dmabuf = boarddma + GUS_LEFT_RIGHT_OFFSET;
1269 sc->sc_stereo.buffer = buffer + size;
1270 sc->sc_stereo.flags = flags;
1271 if (gus_dostereo) {
1272 intr = stereo_dmaintr;
1273 arg = sc;
1274 }
1275 } else
1276 boarddma = size * sc->sc_dmabuf + GUS_MEM_OFFSET;
1277
1278
1279 sc->sc_flags |= GUS_LOCKED;
1280 sc->sc_dmaoutintr = intr;
1281 sc->sc_outarg = arg;
1282
1283 #ifdef GUSPLAYDEBUG
1284 if (gusstats) {
1285 microtime(&dmarecords[dmarecord_index].tv);
1286 dmarecords[dmarecord_index].gusaddr = boarddma;
1287 dmarecords[dmarecord_index].bsdaddr = buffer;
1288 dmarecords[dmarecord_index].count = size;
1289 dmarecords[dmarecord_index].channel = 0;
1290 dmarecords[dmarecord_index].direction = 1;
1291 dmarecord_index = ++dmarecord_index % NDMARECS;
1292 }
1293 #endif
1294
1295 gusdmaout(sc, flags, boarddma, (caddr_t) buffer, size);
1296
1297 return 0;
1298 }
1299
1300 void
1301 gusmax_close(addr)
1302 void *addr;
1303 {
1304 struct ad1848_isa_softc *ac = addr;
1305 struct gus_softc *sc = ac->sc_ad1848.parent;
1306 #if 0
1307 ac->mute[AD1848_AUX1_CHANNEL] = MUTE_ALL;
1308 ad1848_mute_channel(ac, MUTE_ALL); /* turn off DAC output */
1309 #endif
1310 ad1848_close(&ac->sc_ad1848);
1311 gusclose(sc);
1312 }
1313
1314 /*
1315 * Close out device stuff. Called at splgus() from generic audio layer.
1316 */
1317 void
1318 gusclose(addr)
1319 void *addr;
1320 {
1321 struct gus_softc *sc = addr;
1322
1323 DPRINTF(("gus_close: sc=%p\n", sc));
1324
1325
1326 /* if (sc->sc_flags & GUS_DMAOUT_ACTIVE) */ {
1327 gus_halt_out_dma(sc);
1328 }
1329 /* if (sc->sc_flags & GUS_DMAIN_ACTIVE) */ {
1330 gus_halt_in_dma(sc);
1331 }
1332 sc->sc_flags &= ~(GUS_OPEN|GUS_LOCKED|GUS_DMAOUT_ACTIVE|GUS_DMAIN_ACTIVE);
1333
1334 if (sc->sc_deintr_buf) {
1335 FREE(sc->sc_deintr_buf, M_DEVBUF);
1336 sc->sc_deintr_buf = NULL;
1337 }
1338 /* turn off speaker, etc. */
1339
1340 /* make sure the voices shut up: */
1341 gus_stop_voice(sc, GUS_VOICE_LEFT, 1);
1342 gus_stop_voice(sc, GUS_VOICE_RIGHT, 0);
1343 }
1344
1345 /*
1346 * Service interrupts. Farm them off to helper routines if we are using the
1347 * GUS for simple playback/record
1348 */
1349
1350 #ifdef DIAGNOSTIC
1351 int gusintrcnt;
1352 int gusdmaintrcnt;
1353 int gusvocintrcnt;
1354 #endif
1355
1356 int
1357 gusintr(arg)
1358 void *arg;
1359 {
1360 struct gus_softc *sc = arg;
1361 bus_space_tag_t iot = sc->sc_iot;
1362 bus_space_handle_t ioh1 = sc->sc_ioh1;
1363 bus_space_handle_t ioh2 = sc->sc_ioh2;
1364 unsigned char intr;
1365
1366 int retval = 0;
1367
1368 DPRINTF(("gusintr\n"));
1369 #ifdef DIAGNOSTIC
1370 gusintrcnt++;
1371 #endif
1372 if (HAS_CODEC(sc))
1373 retval = ad1848_isa_intr(&sc->sc_codec);
1374 if ((intr = bus_space_read_1(iot, ioh1, GUS_IRQ_STATUS)) & GUSMASK_IRQ_DMATC) {
1375 DMAPRINTF(("gusintr dma flags=%x\n", sc->sc_flags));
1376 #ifdef DIAGNOSTIC
1377 gusdmaintrcnt++;
1378 #endif
1379 retval += gus_dmaout_intr(sc);
1380 if (sc->sc_flags & GUS_DMAIN_ACTIVE) {
1381 SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
1382 intr = bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
1383 if (intr & GUSMASK_SAMPLE_DMATC) {
1384 retval += gus_dmain_intr(sc);
1385 }
1386 }
1387 }
1388 if (intr & (GUSMASK_IRQ_VOICE | GUSMASK_IRQ_VOLUME)) {
1389 DMAPRINTF(("gusintr voice flags=%x\n", sc->sc_flags));
1390 #ifdef DIAGNOSTIC
1391 gusvocintrcnt++;
1392 #endif
1393 retval += gus_voice_intr(sc);
1394 }
1395 if (retval)
1396 return 1;
1397 return retval;
1398 }
1399
1400 int gus_bufcnt[GUS_MEM_FOR_BUFFERS / GUS_BUFFER_MULTIPLE];
1401 int gus_restart; /* how many restarts? */
1402 int gus_stops; /* how many times did voice stop? */
1403 int gus_falsestops; /* stopped but not done? */
1404 int gus_continues;
1405
1406 struct playcont {
1407 struct timeval tv;
1408 u_int playbuf;
1409 u_int dmabuf;
1410 u_char bufcnt;
1411 u_char vaction;
1412 u_char voccntl;
1413 u_char volcntl;
1414 u_long curaddr;
1415 u_long endaddr;
1416 } playstats[NDMARECS];
1417
1418 int playcntr;
1419
1420 STATIC void
1421 gus_dmaout_timeout(arg)
1422 void *arg;
1423 {
1424 struct gus_softc *sc = arg;
1425 bus_space_tag_t iot = sc->sc_iot;
1426 bus_space_handle_t ioh2 = sc->sc_ioh2;
1427 int s;
1428
1429 printf("%s: dmaout timeout\n", sc->sc_dev.dv_xname);
1430 /*
1431 * Stop any DMA.
1432 */
1433
1434 s = splgus();
1435 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
1436 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0);
1437
1438 #if 0
1439 /* XXX we will dmadone below? */
1440 isa_dmaabort(sc->sc_dev.dv_parent, sc->sc_playdrq);
1441 #endif
1442
1443 gus_dmaout_dointr(sc);
1444 splx(s);
1445 }
1446
1447
1448 /*
1449 * Service DMA interrupts. This routine will only get called if we're doing
1450 * a DMA transfer for playback/record requests from the audio layer.
1451 */
1452
1453 STATIC int
1454 gus_dmaout_intr(sc)
1455 struct gus_softc *sc;
1456 {
1457 bus_space_tag_t iot = sc->sc_iot;
1458 bus_space_handle_t ioh2 = sc->sc_ioh2;
1459
1460 /*
1461 * If we got a DMA transfer complete from the GUS DRAM, then deal
1462 * with it.
1463 */
1464
1465 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
1466 if (bus_space_read_1(iot, ioh2, GUS_DATA_HIGH) & GUSMASK_DMA_IRQPEND) {
1467 callout_stop(&sc->sc_dmaout_ch);
1468 gus_dmaout_dointr(sc);
1469 return 1;
1470 }
1471 return 0;
1472 }
1473
1474 STATIC void
1475 gus_dmaout_dointr(sc)
1476 struct gus_softc *sc;
1477 {
1478 bus_space_tag_t iot = sc->sc_iot;
1479 bus_space_handle_t ioh2 = sc->sc_ioh2;
1480
1481 /* sc->sc_dmaoutcnt - 1 because DMA controller counts from zero?. */
1482 isa_dmadone(sc->sc_ic, sc->sc_playdrq);
1483 sc->sc_flags &= ~GUS_DMAOUT_ACTIVE; /* pending DMA is done */
1484 DMAPRINTF(("gus_dmaout_dointr %d @ %p\n", sc->sc_dmaoutcnt,
1485 sc->sc_dmaoutaddr));
1486
1487 /*
1488 * to prevent clicking, we need to copy last sample
1489 * from last buffer to scratch area just before beginning of
1490 * buffer. However, if we're doing formats that are converted by
1491 * the card during the DMA process, we need to pick up the converted
1492 * byte rather than the one we have in memory.
1493 */
1494 if (sc->sc_dmabuf == sc->sc_nbufs - 1) {
1495 int i;
1496 switch (sc->sc_encoding) {
1497 case AUDIO_ENCODING_SLINEAR_LE:
1498 case AUDIO_ENCODING_SLINEAR_BE:
1499 if (sc->sc_precision == 8)
1500 goto byte;
1501 /* we have the native format */
1502 for (i = 1; i <= 2; i++)
1503 guspoke(iot, ioh2, sc->sc_gusaddr -
1504 (sc->sc_nbufs - 1) * sc->sc_chanblocksize - i,
1505 sc->sc_dmaoutaddr[sc->sc_dmaoutcnt-i]);
1506 break;
1507 case AUDIO_ENCODING_ULINEAR_LE:
1508 case AUDIO_ENCODING_ULINEAR_BE:
1509 guspoke(iot, ioh2, sc->sc_gusaddr -
1510 (sc->sc_nbufs - 1) * sc->sc_chanblocksize - 2,
1511 guspeek(iot, ioh2,
1512 sc->sc_gusaddr + sc->sc_chanblocksize - 2));
1513 case AUDIO_ENCODING_ALAW:
1514 case AUDIO_ENCODING_ULAW:
1515 byte:
1516 /* we need to fetch the translated byte, then stuff it. */
1517 guspoke(iot, ioh2, sc->sc_gusaddr -
1518 (sc->sc_nbufs - 1) * sc->sc_chanblocksize - 1,
1519 guspeek(iot, ioh2,
1520 sc->sc_gusaddr + sc->sc_chanblocksize - 1));
1521 break;
1522 }
1523 }
1524 /*
1525 * If this is the first half of stereo, "ignore" this one
1526 * and copy out the second half.
1527 */
1528 if (sc->sc_dmaoutintr == stereo_dmaintr) {
1529 (*sc->sc_dmaoutintr)(sc->sc_outarg);
1530 return;
1531 }
1532 /*
1533 * If the voice is stopped, then start it. Reset the loop
1534 * and roll bits. Call the audio layer routine, since if
1535 * we're starting a stopped voice, that means that the next
1536 * buffer can be filled
1537 */
1538
1539 sc->sc_flags &= ~GUS_LOCKED;
1540 if (sc->sc_voc[GUS_VOICE_LEFT].voccntl &
1541 GUSMASK_VOICE_STOPPED) {
1542 if (sc->sc_flags & GUS_PLAYING) {
1543 printf("%s: playing yet stopped?\n", sc->sc_dev.dv_xname);
1544 }
1545 sc->sc_bufcnt++; /* another yet to be played */
1546 gus_start_playing(sc, sc->sc_dmabuf);
1547 gus_restart++;
1548 } else {
1549 /*
1550 * set the sound action based on which buffer we
1551 * just transferred. If we just transferred buffer 0
1552 * we want the sound to loop when it gets to the nth
1553 * buffer; if we just transferred
1554 * any other buffer, we want the sound to roll over
1555 * at least one more time. The voice interrupt
1556 * handlers will take care of accounting &
1557 * setting control bits if it's not caught up to us
1558 * yet.
1559 */
1560 if (++sc->sc_bufcnt == 2) {
1561 /*
1562 * XXX
1563 * If we're too slow in reaction here,
1564 * the voice could be just approaching the
1565 * end of its run. It should be set to stop,
1566 * so these adjustments might not DTRT.
1567 */
1568 if (sc->sc_dmabuf == 0 &&
1569 sc->sc_playbuf == sc->sc_nbufs - 1) {
1570 /* player is just at the last buf, we're at the
1571 first. Turn on looping, turn off rolling. */
1572 sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_LOOP_ENABLE;
1573 sc->sc_voc[GUS_VOICE_LEFT].volcntl &= ~GUSMASK_VOICE_ROLL;
1574 playstats[playcntr].vaction = 3;
1575 } else {
1576 /* player is at previous buf:
1577 turn on rolling, turn off looping */
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 = 4;
1581 }
1582 #ifdef GUSPLAYDEBUG
1583 if (gusstats) {
1584 microtime(&playstats[playcntr].tv);
1585 playstats[playcntr].endaddr = sc->sc_voc[GUS_VOICE_LEFT].end_addr;
1586 playstats[playcntr].voccntl = sc->sc_voc[GUS_VOICE_LEFT].voccntl;
1587 playstats[playcntr].volcntl = sc->sc_voc[GUS_VOICE_LEFT].volcntl;
1588 playstats[playcntr].playbuf = sc->sc_playbuf;
1589 playstats[playcntr].dmabuf = sc->sc_dmabuf;
1590 playstats[playcntr].bufcnt = sc->sc_bufcnt;
1591 playstats[playcntr].curaddr = gus_get_curaddr(sc, GUS_VOICE_LEFT);
1592 playcntr = ++playcntr % NDMARECS;
1593 }
1594 #endif
1595 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, GUS_VOICE_LEFT);
1596 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
1597 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_LEFT].voccntl);
1598 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
1599 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_LEFT].volcntl);
1600 }
1601 }
1602 gus_bufcnt[sc->sc_bufcnt-1]++;
1603 /*
1604 * flip to the next DMA buffer
1605 */
1606
1607 sc->sc_dmabuf = ++sc->sc_dmabuf % sc->sc_nbufs;
1608 /*
1609 * See comments below about DMA admission control strategy.
1610 * We can call the upper level here if we have an
1611 * idle buffer (not currently playing) to DMA into.
1612 */
1613 if (sc->sc_dmaoutintr && sc->sc_bufcnt < sc->sc_nbufs) {
1614 /* clean out to prevent double calls */
1615 void (*pfunc) __P((void *)) = sc->sc_dmaoutintr;
1616 void *arg = sc->sc_outarg;
1617
1618 sc->sc_outarg = 0;
1619 sc->sc_dmaoutintr = 0;
1620 (*pfunc)(arg);
1621 }
1622 }
1623
1624 /*
1625 * Service voice interrupts
1626 */
1627
1628 STATIC int
1629 gus_voice_intr(sc)
1630 struct gus_softc *sc;
1631 {
1632 bus_space_tag_t iot = sc->sc_iot;
1633 bus_space_handle_t ioh2 = sc->sc_ioh2;
1634 int ignore = 0, voice, rval = 0;
1635 unsigned char intr, status;
1636
1637 /*
1638 * The point of this may not be obvious at first. A voice can
1639 * interrupt more than once; according to the GUS SDK we are supposed
1640 * to ignore multiple interrupts for the same voice.
1641 */
1642
1643 while(1) {
1644 SELECT_GUS_REG(iot, ioh2, GUSREG_IRQ_STATUS);
1645 intr = bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
1646
1647 if ((intr & (GUSMASK_WIRQ_VOLUME | GUSMASK_WIRQ_VOICE))
1648 == (GUSMASK_WIRQ_VOLUME | GUSMASK_WIRQ_VOICE))
1649 /*
1650 * No more interrupts, time to return
1651 */
1652 return rval;
1653
1654 if ((intr & GUSMASK_WIRQ_VOICE) == 0) {
1655
1656 /*
1657 * We've got a voice interrupt. Ignore previous
1658 * interrupts by the same voice.
1659 */
1660
1661 rval = 1;
1662 voice = intr & GUSMASK_WIRQ_VOICEMASK;
1663
1664 if ((1 << voice) & ignore)
1665 break;
1666
1667 ignore |= 1 << voice;
1668
1669 /*
1670 * If the voice is stopped, then force it to stop
1671 * (this stops it from continuously generating IRQs)
1672 */
1673
1674 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL+0x80);
1675 status = bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
1676 if (status & GUSMASK_VOICE_STOPPED) {
1677 if (voice != GUS_VOICE_LEFT) {
1678 DMAPRINTF(("%s: spurious voice %d stop?\n",
1679 sc->sc_dev.dv_xname, voice));
1680 gus_stop_voice(sc, voice, 0);
1681 continue;
1682 }
1683 gus_stop_voice(sc, voice, 1);
1684 /* also kill right voice */
1685 gus_stop_voice(sc, GUS_VOICE_RIGHT, 0);
1686 sc->sc_bufcnt--; /* it finished a buffer */
1687 if (sc->sc_bufcnt > 0) {
1688 /*
1689 * probably a race to get here: the voice
1690 * stopped while the DMA code was just trying to
1691 * get the next buffer in place.
1692 * Start the voice again.
1693 */
1694 printf("%s: stopped voice not drained? (%x)\n",
1695 sc->sc_dev.dv_xname, sc->sc_bufcnt);
1696 gus_falsestops++;
1697
1698 sc->sc_playbuf = ++sc->sc_playbuf % sc->sc_nbufs;
1699 gus_start_playing(sc, sc->sc_playbuf);
1700 } else if (sc->sc_bufcnt < 0) {
1701 panic("%s: negative bufcnt in stopped voice",
1702 sc->sc_dev.dv_xname);
1703 } else {
1704 sc->sc_playbuf = -1; /* none are active */
1705 gus_stops++;
1706 }
1707 /* fall through to callback and admit another
1708 buffer.... */
1709 } else if (sc->sc_bufcnt != 0) {
1710 /*
1711 * This should always be taken if the voice
1712 * is not stopped.
1713 */
1714 gus_continues++;
1715 if (gus_continue_playing(sc, voice)) {
1716 /*
1717 * we shouldn't have continued--active DMA
1718 * is in the way in the ring, for
1719 * some as-yet undebugged reason.
1720 */
1721 gus_stop_voice(sc, GUS_VOICE_LEFT, 1);
1722 /* also kill right voice */
1723 gus_stop_voice(sc, GUS_VOICE_RIGHT, 0);
1724 sc->sc_playbuf = -1;
1725 gus_stops++;
1726 }
1727 }
1728 /*
1729 * call the upper level to send on down another
1730 * block. We do admission rate control as follows:
1731 *
1732 * When starting up output (in the first N
1733 * blocks), call the upper layer after the DMA is
1734 * complete (see above in gus_dmaout_intr()).
1735 *
1736 * When output is already in progress and we have
1737 * no more GUS buffers to use for DMA, the DMA
1738 * output routines do not call the upper layer.
1739 * Instead, we call the DMA completion routine
1740 * here, after the voice interrupts indicating
1741 * that it's finished with a buffer.
1742 *
1743 * However, don't call anything here if the DMA
1744 * output flag is set, (which shouldn't happen)
1745 * because we'll squish somebody else's DMA if
1746 * that's the case. When DMA is done, it will
1747 * call back if there is a spare buffer.
1748 */
1749 if (sc->sc_dmaoutintr && !(sc->sc_flags & GUS_LOCKED)) {
1750 if (sc->sc_dmaoutintr == stereo_dmaintr)
1751 printf("gusdmaout botch?\n");
1752 else {
1753 /* clean out to avoid double calls */
1754 void (*pfunc) __P((void *)) = sc->sc_dmaoutintr;
1755 void *arg = sc->sc_outarg;
1756
1757 sc->sc_outarg = 0;
1758 sc->sc_dmaoutintr = 0;
1759 (*pfunc)(arg);
1760 }
1761 }
1762 }
1763
1764 /*
1765 * Ignore other interrupts for now
1766 */
1767 }
1768 return 0;
1769 }
1770
1771 STATIC void
1772 gus_start_playing(sc, bufno)
1773 struct gus_softc *sc;
1774 int bufno;
1775 {
1776 bus_space_tag_t iot = sc->sc_iot;
1777 bus_space_handle_t ioh2 = sc->sc_ioh2;
1778 /*
1779 * Start the voices playing, with buffer BUFNO.
1780 */
1781
1782 /*
1783 * Loop or roll if we have buffers ready.
1784 */
1785
1786 if (sc->sc_bufcnt == 1) {
1787 sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~(GUSMASK_LOOP_ENABLE);
1788 sc->sc_voc[GUS_VOICE_LEFT].volcntl &= ~(GUSMASK_VOICE_ROLL);
1789 } else {
1790 if (bufno == sc->sc_nbufs - 1) {
1791 sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_LOOP_ENABLE;
1792 sc->sc_voc[GUS_VOICE_LEFT].volcntl &= ~(GUSMASK_VOICE_ROLL);
1793 } else {
1794 sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~GUSMASK_LOOP_ENABLE;
1795 sc->sc_voc[GUS_VOICE_LEFT].volcntl |= GUSMASK_VOICE_ROLL;
1796 }
1797 }
1798
1799 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, GUS_VOICE_LEFT);
1800
1801 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
1802 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_LEFT].voccntl);
1803
1804 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
1805 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_LEFT].volcntl);
1806
1807 sc->sc_voc[GUS_VOICE_LEFT].current_addr =
1808 GUS_MEM_OFFSET + sc->sc_chanblocksize * bufno;
1809 sc->sc_voc[GUS_VOICE_LEFT].end_addr =
1810 sc->sc_voc[GUS_VOICE_LEFT].current_addr + sc->sc_chanblocksize - 1;
1811 sc->sc_voc[GUS_VOICE_RIGHT].current_addr =
1812 sc->sc_voc[GUS_VOICE_LEFT].current_addr +
1813 (gus_dostereo && sc->sc_channels == 2 ? GUS_LEFT_RIGHT_OFFSET : 0);
1814 /*
1815 * set up right channel to just loop forever, no interrupts,
1816 * starting at the buffer we just filled. We'll feed it data
1817 * at the same time as left channel.
1818 */
1819 sc->sc_voc[GUS_VOICE_RIGHT].voccntl |= GUSMASK_LOOP_ENABLE;
1820 sc->sc_voc[GUS_VOICE_RIGHT].volcntl &= ~(GUSMASK_VOICE_ROLL);
1821
1822 #ifdef GUSPLAYDEBUG
1823 if (gusstats) {
1824 microtime(&playstats[playcntr].tv);
1825 playstats[playcntr].curaddr = sc->sc_voc[GUS_VOICE_LEFT].current_addr;
1826
1827 playstats[playcntr].voccntl = sc->sc_voc[GUS_VOICE_LEFT].voccntl;
1828 playstats[playcntr].volcntl = sc->sc_voc[GUS_VOICE_LEFT].volcntl;
1829 playstats[playcntr].endaddr = sc->sc_voc[GUS_VOICE_LEFT].end_addr;
1830 playstats[playcntr].playbuf = bufno;
1831 playstats[playcntr].dmabuf = sc->sc_dmabuf;
1832 playstats[playcntr].bufcnt = sc->sc_bufcnt;
1833 playstats[playcntr].vaction = 5;
1834 playcntr = ++playcntr % NDMARECS;
1835 }
1836 #endif
1837
1838 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, GUS_VOICE_RIGHT);
1839 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
1840 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_RIGHT].voccntl);
1841 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
1842 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_RIGHT].volcntl);
1843
1844 gus_start_voice(sc, GUS_VOICE_RIGHT, 0);
1845 gus_start_voice(sc, GUS_VOICE_LEFT, 1);
1846 if (sc->sc_playbuf == -1)
1847 /* mark start of playing */
1848 sc->sc_playbuf = bufno;
1849 }
1850
1851 STATIC int
1852 gus_continue_playing(sc, voice)
1853 struct gus_softc *sc;
1854 int voice;
1855 {
1856 bus_space_tag_t iot = sc->sc_iot;
1857 bus_space_handle_t ioh2 = sc->sc_ioh2;
1858
1859 /*
1860 * stop this voice from interrupting while we work.
1861 */
1862
1863 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
1864 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl & ~(GUSMASK_VOICE_IRQ));
1865
1866 /*
1867 * update playbuf to point to the buffer the hardware just started
1868 * playing
1869 */
1870 sc->sc_playbuf = ++sc->sc_playbuf % sc->sc_nbufs;
1871
1872 /*
1873 * account for buffer just finished
1874 */
1875 if (--sc->sc_bufcnt == 0) {
1876 DPRINTF(("gus: bufcnt 0 on continuing voice?\n"));
1877 }
1878 if (sc->sc_playbuf == sc->sc_dmabuf && (sc->sc_flags & GUS_LOCKED)) {
1879 printf("%s: continue into active dmabuf?\n", sc->sc_dev.dv_xname);
1880 return 1;
1881 }
1882
1883 /*
1884 * Select the end of the buffer based on the currently active
1885 * buffer, [plus extra contiguous buffers (if ready)].
1886 */
1887
1888 /*
1889 * set endpoint at end of buffer we just started playing.
1890 *
1891 * The total gets -1 because end addrs are one less than you might
1892 * think (the end_addr is the address of the last sample to play)
1893 */
1894 gus_set_endaddr(sc, voice, GUS_MEM_OFFSET +
1895 sc->sc_chanblocksize * (sc->sc_playbuf + 1) - 1);
1896
1897 if (sc->sc_bufcnt < 2) {
1898 /*
1899 * Clear out the loop and roll flags, and rotate the currently
1900 * playing buffer. That way, if we don't manage to get more
1901 * data before this buffer finishes, we'll just stop.
1902 */
1903 sc->sc_voc[voice].voccntl &= ~GUSMASK_LOOP_ENABLE;
1904 sc->sc_voc[voice].volcntl &= ~GUSMASK_VOICE_ROLL;
1905 playstats[playcntr].vaction = 0;
1906 } else {
1907 /*
1908 * We have some buffers to play. set LOOP if we're on the
1909 * last buffer in the ring, otherwise set ROLL.
1910 */
1911 if (sc->sc_playbuf == sc->sc_nbufs - 1) {
1912 sc->sc_voc[voice].voccntl |= GUSMASK_LOOP_ENABLE;
1913 sc->sc_voc[voice].volcntl &= ~GUSMASK_VOICE_ROLL;
1914 playstats[playcntr].vaction = 1;
1915 } else {
1916 sc->sc_voc[voice].voccntl &= ~GUSMASK_LOOP_ENABLE;
1917 sc->sc_voc[voice].volcntl |= GUSMASK_VOICE_ROLL;
1918 playstats[playcntr].vaction = 2;
1919 }
1920 }
1921 #ifdef GUSPLAYDEBUG
1922 if (gusstats) {
1923 microtime(&playstats[playcntr].tv);
1924 playstats[playcntr].curaddr = gus_get_curaddr(sc, voice);
1925
1926 playstats[playcntr].voccntl = sc->sc_voc[voice].voccntl;
1927 playstats[playcntr].volcntl = sc->sc_voc[voice].volcntl;
1928 playstats[playcntr].endaddr = sc->sc_voc[voice].end_addr;
1929 playstats[playcntr].playbuf = sc->sc_playbuf;
1930 playstats[playcntr].dmabuf = sc->sc_dmabuf;
1931 playstats[playcntr].bufcnt = sc->sc_bufcnt;
1932 playcntr = ++playcntr % NDMARECS;
1933 }
1934 #endif
1935
1936 /*
1937 * (re-)set voice parameters. This will reenable interrupts from this
1938 * voice.
1939 */
1940
1941 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
1942 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
1943 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
1944 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].volcntl);
1945 return 0;
1946 }
1947
1948 /*
1949 * Send/receive data into GUS's DRAM using DMA. Called at splgus()
1950 */
1951
1952 STATIC void
1953 gusdmaout(sc, flags, gusaddr, buffaddr, length)
1954 struct gus_softc *sc;
1955 int flags, length;
1956 u_long gusaddr;
1957 caddr_t buffaddr;
1958 {
1959 unsigned char c = (unsigned char) flags;
1960 bus_space_tag_t iot = sc->sc_iot;
1961 bus_space_handle_t ioh2 = sc->sc_ioh2;
1962
1963 DMAPRINTF(("gusdmaout flags=%x scflags=%x\n", flags, sc->sc_flags));
1964
1965 sc->sc_gusaddr = gusaddr;
1966
1967 /*
1968 * If we're using a 16 bit DMA channel, we have to jump through some
1969 * extra hoops; this includes translating the DRAM address a bit
1970 */
1971
1972 if (sc->sc_playdrq >= 4) {
1973 c |= GUSMASK_DMA_WIDTH;
1974 gusaddr = convert_to_16bit(gusaddr);
1975 }
1976
1977 /*
1978 * Add flag bits that we always set - fast DMA, enable IRQ
1979 */
1980
1981 c |= GUSMASK_DMA_ENABLE | GUSMASK_DMA_R0 | GUSMASK_DMA_IRQ;
1982
1983 /*
1984 * Make sure the GUS _isn't_ setup for DMA
1985 */
1986
1987 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
1988 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0);
1989
1990 /*
1991 * Tell the PC DMA controller to start doing DMA
1992 */
1993
1994 sc->sc_dmaoutaddr = (u_char *) buffaddr;
1995 sc->sc_dmaoutcnt = length;
1996 isa_dmastart(sc->sc_ic, sc->sc_playdrq, buffaddr, length,
1997 NULL, DMAMODE_WRITE, BUS_DMA_NOWAIT);
1998
1999 /*
2000 * Set up DMA address - use the upper 16 bits ONLY
2001 */
2002
2003 sc->sc_flags |= GUS_DMAOUT_ACTIVE;
2004
2005 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_START);
2006 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, (int) (gusaddr >> 4));
2007
2008 /*
2009 * Tell the GUS to start doing DMA
2010 */
2011
2012 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
2013 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, c);
2014
2015 /*
2016 * XXX If we don't finish in one second, give up...
2017 */
2018 callout_reset(&sc->sc_dmaout_ch, hz, gus_dmaout_timeout, sc);
2019 }
2020
2021 /*
2022 * Start a voice playing on the GUS. Called from interrupt handler at
2023 * splgus().
2024 */
2025
2026 STATIC void
2027 gus_start_voice(sc, voice, intrs)
2028 struct gus_softc *sc;
2029 int voice;
2030 int intrs;
2031 {
2032 bus_space_tag_t iot = sc->sc_iot;
2033 bus_space_handle_t ioh2 = sc->sc_ioh2;
2034 u_long start;
2035 u_long current;
2036 u_long end;
2037
2038 /*
2039 * Pick all the values for the voice out of the gus_voice struct
2040 * and use those to program the voice
2041 */
2042
2043 start = sc->sc_voc[voice].start_addr;
2044 current = sc->sc_voc[voice].current_addr;
2045 end = sc->sc_voc[voice].end_addr;
2046
2047 /*
2048 * If we're using 16 bit data, mangle the addresses a bit
2049 */
2050
2051 if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16) {
2052 /* -1 on start so that we get onto sample boundary--other
2053 code always sets it for 1-byte rollover protection */
2054 start = convert_to_16bit(start-1);
2055 current = convert_to_16bit(current);
2056 end = convert_to_16bit(end);
2057 }
2058
2059 /*
2060 * Select the voice we want to use, and program the data addresses
2061 */
2062
2063 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
2064
2065 SELECT_GUS_REG(iot, ioh2, GUSREG_START_ADDR_HIGH);
2066 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(start));
2067 SELECT_GUS_REG(iot, ioh2, GUSREG_START_ADDR_LOW);
2068 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(start));
2069
2070 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH);
2071 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(current));
2072 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW);
2073 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(current));
2074
2075 SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_HIGH);
2076 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(end));
2077 SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_LOW);
2078 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(end));
2079
2080 /*
2081 * (maybe) enable interrupts, disable voice stopping
2082 */
2083
2084 if (intrs) {
2085 sc->sc_flags |= GUS_PLAYING; /* playing is about to start */
2086 sc->sc_voc[voice].voccntl |= GUSMASK_VOICE_IRQ;
2087 DMAPRINTF(("gus voice playing=%x\n", sc->sc_flags));
2088 } else
2089 sc->sc_voc[voice].voccntl &= ~GUSMASK_VOICE_IRQ;
2090 sc->sc_voc[voice].voccntl &= ~(GUSMASK_VOICE_STOPPED |
2091 GUSMASK_STOP_VOICE);
2092
2093 /*
2094 * Tell the GUS about it. Note that we're doing volume ramping here
2095 * from 0 up to the set volume to help reduce clicks.
2096 */
2097
2098 SELECT_GUS_REG(iot, ioh2, GUSREG_START_VOLUME);
2099 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
2100 SELECT_GUS_REG(iot, ioh2, GUSREG_END_VOLUME);
2101 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].current_volume >> 4);
2102 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME);
2103 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x00);
2104 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_RATE);
2105 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 63);
2106
2107 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
2108 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
2109 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
2110 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
2111 delay(50);
2112 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
2113 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
2114 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
2115 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
2116
2117 }
2118
2119 /*
2120 * Stop a given voice. called at splgus()
2121 */
2122
2123 STATIC void
2124 gus_stop_voice(sc, voice, intrs_too)
2125 struct gus_softc *sc;
2126 int voice;
2127 int intrs_too;
2128 {
2129 bus_space_tag_t iot = sc->sc_iot;
2130 bus_space_handle_t ioh2 = sc->sc_ioh2;
2131
2132 sc->sc_voc[voice].voccntl |= GUSMASK_VOICE_STOPPED |
2133 GUSMASK_STOP_VOICE;
2134 if (intrs_too) {
2135 sc->sc_voc[voice].voccntl &= ~(GUSMASK_VOICE_IRQ);
2136 /* no more DMA to do */
2137 sc->sc_flags &= ~GUS_PLAYING;
2138 }
2139 DMAPRINTF(("gusintr voice notplaying=%x\n", sc->sc_flags));
2140
2141 guspoke(iot, ioh2, 0L, 0);
2142
2143 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
2144
2145 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME);
2146 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2147 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
2148 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
2149 delay(100);
2150 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME);
2151 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2152 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
2153 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
2154
2155 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH);
2156 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2157 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW);
2158 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2159
2160 }
2161
2162
2163 /*
2164 * Set the volume of a given voice. Called at splgus().
2165 */
2166 STATIC void
2167 gus_set_volume(sc, voice, volume)
2168 struct gus_softc *sc;
2169 int voice, volume;
2170 {
2171 bus_space_tag_t iot = sc->sc_iot;
2172 bus_space_handle_t ioh2 = sc->sc_ioh2;
2173 unsigned int gusvol;
2174
2175 gusvol = gus_log_volumes[volume < 512 ? volume : 511];
2176
2177 sc->sc_voc[voice].current_volume = gusvol;
2178
2179 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
2180
2181 SELECT_GUS_REG(iot, ioh2, GUSREG_START_VOLUME);
2182 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (unsigned char) (gusvol >> 4));
2183
2184 SELECT_GUS_REG(iot, ioh2, GUSREG_END_VOLUME);
2185 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (unsigned char) (gusvol >> 4));
2186
2187 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME);
2188 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, gusvol << 4);
2189 delay(500);
2190 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, gusvol << 4);
2191
2192 }
2193
2194 /*
2195 * Interface to the audio layer.
2196 */
2197
2198 int
2199 gusmax_set_params(addr, setmode, usemode, p, r)
2200 void *addr;
2201 int setmode, usemode;
2202 struct audio_params *p, *r;
2203 {
2204 struct ad1848_isa_softc *ac = addr;
2205 struct gus_softc *sc = ac->sc_ad1848.parent;
2206 int error;
2207
2208 error = ad1848_set_params(ac, setmode, usemode, p, r);
2209 if (error)
2210 return error;
2211 error = gus_set_params(sc, setmode, usemode, p, r);
2212 return error;
2213 }
2214
2215 int
2216 gus_set_params(addr, setmode, usemode, p, r)
2217 void *addr;
2218 int setmode, usemode;
2219 struct audio_params *p, *r;
2220 {
2221 struct gus_softc *sc = addr;
2222 int s;
2223
2224 switch (p->encoding) {
2225 case AUDIO_ENCODING_ULAW:
2226 case AUDIO_ENCODING_ALAW:
2227 case AUDIO_ENCODING_SLINEAR_LE:
2228 case AUDIO_ENCODING_ULINEAR_LE:
2229 case AUDIO_ENCODING_SLINEAR_BE:
2230 case AUDIO_ENCODING_ULINEAR_BE:
2231 break;
2232 default:
2233 return (EINVAL);
2234 }
2235
2236 s = splaudio();
2237
2238 if (p->precision == 8) {
2239 sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~GUSMASK_DATA_SIZE16;
2240 sc->sc_voc[GUS_VOICE_RIGHT].voccntl &= ~GUSMASK_DATA_SIZE16;
2241 } else {
2242 sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_DATA_SIZE16;
2243 sc->sc_voc[GUS_VOICE_RIGHT].voccntl |= GUSMASK_DATA_SIZE16;
2244 }
2245
2246 sc->sc_encoding = p->encoding;
2247 sc->sc_precision = p->precision;
2248 sc->sc_channels = p->channels;
2249
2250 splx(s);
2251
2252 if (p->sample_rate > gus_max_frequency[sc->sc_voices - GUS_MIN_VOICES])
2253 p->sample_rate = gus_max_frequency[sc->sc_voices - GUS_MIN_VOICES];
2254 if (setmode & AUMODE_RECORD)
2255 sc->sc_irate = p->sample_rate;
2256 if (setmode & AUMODE_PLAY)
2257 sc->sc_orate = p->sample_rate;
2258
2259 switch (p->encoding) {
2260 case AUDIO_ENCODING_ULAW:
2261 p->sw_code = mulaw_to_ulinear8;
2262 r->sw_code = ulinear8_to_mulaw;
2263 break;
2264 case AUDIO_ENCODING_ALAW:
2265 p->sw_code = alaw_to_ulinear8;
2266 r->sw_code = ulinear8_to_alaw;
2267 break;
2268 case AUDIO_ENCODING_ULINEAR_BE:
2269 case AUDIO_ENCODING_SLINEAR_BE:
2270 r->sw_code = p->sw_code = swap_bytes;
2271 break;
2272 }
2273
2274 return 0;
2275 }
2276
2277 /*
2278 * Interface to the audio layer - set the blocksize to the correct number
2279 * of units
2280 */
2281
2282 int
2283 gusmax_round_blocksize(addr, blocksize)
2284 void * addr;
2285 int blocksize;
2286 {
2287 struct ad1848_isa_softc *ac = addr;
2288 struct gus_softc *sc = ac->sc_ad1848.parent;
2289
2290 /* blocksize = ad1848_round_blocksize(ac, blocksize);*/
2291 return gus_round_blocksize(sc, blocksize);
2292 }
2293
2294 int
2295 gus_round_blocksize(addr, blocksize)
2296 void * addr;
2297 int blocksize;
2298 {
2299 struct gus_softc *sc = addr;
2300
2301 DPRINTF(("gus_round_blocksize called\n"));
2302
2303 if ((sc->sc_encoding == AUDIO_ENCODING_ULAW ||
2304 sc->sc_encoding == AUDIO_ENCODING_ALAW) && blocksize > 32768)
2305 blocksize = 32768;
2306 else if (blocksize > 65536)
2307 blocksize = 65536;
2308
2309 if ((blocksize % GUS_BUFFER_MULTIPLE) != 0)
2310 blocksize = (blocksize / GUS_BUFFER_MULTIPLE + 1) *
2311 GUS_BUFFER_MULTIPLE;
2312
2313 /* set up temporary buffer to hold the deinterleave, if necessary
2314 for stereo output */
2315 if (sc->sc_deintr_buf) {
2316 FREE(sc->sc_deintr_buf, M_DEVBUF);
2317 sc->sc_deintr_buf = NULL;
2318 }
2319 MALLOC(sc->sc_deintr_buf, void *, blocksize>>1, M_DEVBUF, M_WAITOK);
2320
2321 sc->sc_blocksize = blocksize;
2322 /* multi-buffering not quite working yet. */
2323 sc->sc_nbufs = /*GUS_MEM_FOR_BUFFERS / blocksize*/ 2;
2324
2325 gus_set_chan_addrs(sc);
2326
2327 return blocksize;
2328 }
2329
2330 int
2331 gus_get_out_gain(addr)
2332 caddr_t addr;
2333 {
2334 struct gus_softc *sc = (struct gus_softc *) addr;
2335
2336 DPRINTF(("gus_get_out_gain called\n"));
2337 return sc->sc_ogain / 2;
2338 }
2339
2340 STATIC inline void gus_set_voices(sc, voices)
2341 struct gus_softc *sc;
2342 int voices;
2343 {
2344 bus_space_tag_t iot = sc->sc_iot;
2345 bus_space_handle_t ioh2 = sc->sc_ioh2;
2346 /*
2347 * Select the active number of voices
2348 */
2349
2350 SELECT_GUS_REG(iot, ioh2, GUSREG_ACTIVE_VOICES);
2351 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (voices-1) | 0xc0);
2352
2353 sc->sc_voices = voices;
2354 }
2355
2356 /*
2357 * Actually set the settings of various values on the card
2358 */
2359
2360 int
2361 gusmax_commit_settings(addr)
2362 void * addr;
2363 {
2364 struct ad1848_isa_softc *ac = addr;
2365 struct gus_softc *sc = ac->sc_ad1848.parent;
2366 int error;
2367
2368 error = ad1848_commit_settings(ac);
2369 if (error)
2370 return error;
2371 return gus_commit_settings(sc);
2372 }
2373
2374 /*
2375 * Commit the settings. Called at normal IPL.
2376 */
2377 int
2378 gus_commit_settings(addr)
2379 void * addr;
2380 {
2381 struct gus_softc *sc = addr;
2382 int s;
2383
2384 DPRINTF(("gus_commit_settings called (gain = %d)\n",sc->sc_ogain));
2385
2386
2387 s = splgus();
2388
2389 gus_set_recrate(sc, sc->sc_irate);
2390 gus_set_volume(sc, GUS_VOICE_LEFT, sc->sc_ogain);
2391 gus_set_volume(sc, GUS_VOICE_RIGHT, sc->sc_ogain);
2392 gus_set_samprate(sc, GUS_VOICE_LEFT, sc->sc_orate);
2393 gus_set_samprate(sc, GUS_VOICE_RIGHT, sc->sc_orate);
2394 splx(s);
2395 gus_set_chan_addrs(sc);
2396
2397 return 0;
2398 }
2399
2400 STATIC void
2401 gus_set_chan_addrs(sc)
2402 struct gus_softc *sc;
2403 {
2404 /*
2405 * We use sc_nbufs * blocksize bytes of storage in the on-board GUS
2406 * ram.
2407 * For mono, each of the sc_nbufs buffers is DMA'd to in one chunk,
2408 * and both left & right channels play the same buffer.
2409 *
2410 * For stereo, each channel gets a contiguous half of the memory,
2411 * and each has sc_nbufs buffers of size blocksize/2.
2412 * Stereo data are deinterleaved in main memory before the DMA out
2413 * routines are called to queue the output.
2414 *
2415 * The blocksize per channel is kept in sc_chanblocksize.
2416 */
2417 if (sc->sc_channels == 2)
2418 sc->sc_chanblocksize = sc->sc_blocksize/2;
2419 else
2420 sc->sc_chanblocksize = sc->sc_blocksize;
2421
2422 sc->sc_voc[GUS_VOICE_LEFT].start_addr = GUS_MEM_OFFSET - 1;
2423 sc->sc_voc[GUS_VOICE_RIGHT].start_addr =
2424 (gus_dostereo && sc->sc_channels == 2 ? GUS_LEFT_RIGHT_OFFSET : 0)
2425 + GUS_MEM_OFFSET - 1;
2426 sc->sc_voc[GUS_VOICE_RIGHT].current_addr =
2427 sc->sc_voc[GUS_VOICE_RIGHT].start_addr + 1;
2428 sc->sc_voc[GUS_VOICE_RIGHT].end_addr =
2429 sc->sc_voc[GUS_VOICE_RIGHT].start_addr +
2430 sc->sc_nbufs * sc->sc_chanblocksize;
2431
2432 }
2433
2434 /*
2435 * Set the sample rate of the given voice. Called at splgus().
2436 */
2437
2438 STATIC void
2439 gus_set_samprate(sc, voice, freq)
2440 struct gus_softc *sc;
2441 int voice, freq;
2442 {
2443 bus_space_tag_t iot = sc->sc_iot;
2444 bus_space_handle_t ioh2 = sc->sc_ioh2;
2445 unsigned int fc;
2446 u_long temp, f = (u_long) freq;
2447
2448 /*
2449 * calculate fc based on the number of active voices;
2450 * we need to use longs to preserve enough bits
2451 */
2452
2453 temp = (u_long) gus_max_frequency[sc->sc_voices-GUS_MIN_VOICES];
2454
2455 fc = (unsigned int)(((f << 9L) + (temp >> 1L)) / temp);
2456
2457 fc <<= 1;
2458
2459
2460 /*
2461 * Program the voice frequency, and set it in the voice data record
2462 */
2463
2464 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
2465 SELECT_GUS_REG(iot, ioh2, GUSREG_FREQ_CONTROL);
2466 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, fc);
2467
2468 sc->sc_voc[voice].rate = freq;
2469
2470 }
2471
2472 /*
2473 * Set the sample rate of the recording frequency. Formula is from the GUS
2474 * SDK. Called at splgus().
2475 */
2476
2477 STATIC void
2478 gus_set_recrate(sc, rate)
2479 struct gus_softc *sc;
2480 u_long rate;
2481 {
2482 bus_space_tag_t iot = sc->sc_iot;
2483 bus_space_handle_t ioh2 = sc->sc_ioh2;
2484 u_char realrate;
2485 DPRINTF(("gus_set_recrate %lu\n", rate));
2486
2487 #if 0
2488 realrate = 9878400/(16*(rate+2)); /* formula from GUS docs */
2489 #endif
2490 realrate = (9878400 >> 4)/rate - 2; /* formula from code, sigh. */
2491
2492 SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_FREQ);
2493 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, realrate);
2494 }
2495
2496 /*
2497 * Interface to the audio layer - turn the output on or off. Note that some
2498 * of these bits are flipped in the register
2499 */
2500
2501 int
2502 gusmax_speaker_ctl(addr, newstate)
2503 void * addr;
2504 int newstate;
2505 {
2506 struct ad1848_isa_softc *sc = addr;
2507 return gus_speaker_ctl(sc->sc_ad1848.parent, newstate);
2508 }
2509
2510 int
2511 gus_speaker_ctl(addr, newstate)
2512 void * addr;
2513 int newstate;
2514 {
2515 struct gus_softc *sc = (struct gus_softc *) addr;
2516 bus_space_tag_t iot = sc->sc_iot;
2517 bus_space_handle_t ioh1 = sc->sc_ioh1;
2518
2519 /* Line out bit is flipped: 0 enables, 1 disables */
2520 if ((newstate == SPKR_ON) &&
2521 (sc->sc_mixcontrol & GUSMASK_LINE_OUT)) {
2522 sc->sc_mixcontrol &= ~GUSMASK_LINE_OUT;
2523 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
2524 }
2525 if ((newstate == SPKR_OFF) &&
2526 (sc->sc_mixcontrol & GUSMASK_LINE_OUT) == 0) {
2527 sc->sc_mixcontrol |= GUSMASK_LINE_OUT;
2528 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
2529 }
2530
2531 return 0;
2532 }
2533
2534 STATIC int
2535 gus_linein_ctl(addr, newstate)
2536 void * addr;
2537 int newstate;
2538 {
2539 struct gus_softc *sc = (struct gus_softc *) addr;
2540 bus_space_tag_t iot = sc->sc_iot;
2541 bus_space_handle_t ioh1 = sc->sc_ioh1;
2542
2543 /* Line in bit is flipped: 0 enables, 1 disables */
2544 if ((newstate == SPKR_ON) &&
2545 (sc->sc_mixcontrol & GUSMASK_LINE_IN)) {
2546 sc->sc_mixcontrol &= ~GUSMASK_LINE_IN;
2547 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
2548 }
2549 if ((newstate == SPKR_OFF) &&
2550 (sc->sc_mixcontrol & GUSMASK_LINE_IN) == 0) {
2551 sc->sc_mixcontrol |= GUSMASK_LINE_IN;
2552 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
2553 }
2554
2555 return 0;
2556 }
2557
2558 STATIC int
2559 gus_mic_ctl(addr, newstate)
2560 void * addr;
2561 int newstate;
2562 {
2563 struct gus_softc *sc = (struct gus_softc *) addr;
2564 bus_space_tag_t iot = sc->sc_iot;
2565 bus_space_handle_t ioh1 = sc->sc_ioh1;
2566
2567 /* Mic bit is normal: 1 enables, 0 disables */
2568 if ((newstate == SPKR_ON) &&
2569 (sc->sc_mixcontrol & GUSMASK_MIC_IN) == 0) {
2570 sc->sc_mixcontrol |= GUSMASK_MIC_IN;
2571 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
2572 }
2573 if ((newstate == SPKR_OFF) &&
2574 (sc->sc_mixcontrol & GUSMASK_MIC_IN)) {
2575 sc->sc_mixcontrol &= ~GUSMASK_MIC_IN;
2576 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
2577 }
2578
2579 return 0;
2580 }
2581
2582 /*
2583 * Set the end address of a give voice. Called at splgus()
2584 */
2585
2586 STATIC void
2587 gus_set_endaddr(sc, voice, addr)
2588 struct gus_softc *sc;
2589 int voice;
2590 u_long addr;
2591 {
2592 bus_space_tag_t iot = sc->sc_iot;
2593 bus_space_handle_t ioh2 = sc->sc_ioh2;
2594
2595 sc->sc_voc[voice].end_addr = addr;
2596
2597 if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16)
2598 addr = convert_to_16bit(addr);
2599
2600 SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_HIGH);
2601 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(addr));
2602 SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_LOW);
2603 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(addr));
2604
2605 }
2606
2607 #ifdef GUSPLAYDEBUG
2608 /*
2609 * Set current address. called at splgus()
2610 */
2611 STATIC void
2612 gus_set_curaddr(sc, voice, addr)
2613 struct gus_softc *sc;
2614 int voice;
2615 u_long addr;
2616 {
2617 bus_space_tag_t iot = sc->sc_iot;
2618 bus_space_handle_t ioh2 = sc->sc_ioh2;
2619
2620 sc->sc_voc[voice].current_addr = addr;
2621
2622 if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16)
2623 addr = convert_to_16bit(addr);
2624
2625 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
2626
2627 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH);
2628 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(addr));
2629 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW);
2630 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(addr));
2631
2632 }
2633
2634 /*
2635 * Get current GUS playback address. Called at splgus().
2636 */
2637 STATIC u_long
2638 gus_get_curaddr(sc, voice)
2639 struct gus_softc *sc;
2640 int voice;
2641 {
2642 bus_space_tag_t iot = sc->sc_iot;
2643 bus_space_handle_t ioh2 = sc->sc_ioh2;
2644 u_long addr;
2645
2646 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
2647 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH|GUSREG_READ);
2648 addr = (bus_space_read_2(iot, ioh2, GUS_DATA_LOW) & 0x1fff) << 7;
2649 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW|GUSREG_READ);
2650 addr |= (bus_space_read_2(iot, ioh2, GUS_DATA_LOW) >> 9L) & 0x7f;
2651
2652 if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16)
2653 addr = (addr & 0xc0000) | ((addr & 0x1ffff) << 1); /* undo 16-bit change */
2654 DPRINTF(("gus voice %d curaddr %ld end_addr %ld\n",
2655 voice, addr, sc->sc_voc[voice].end_addr));
2656 /* XXX sanity check the address? */
2657
2658 return(addr);
2659 }
2660 #endif
2661
2662 /*
2663 * Convert an address value to a "16 bit" value - why this is necessary I
2664 * have NO idea
2665 */
2666
2667 STATIC u_long
2668 convert_to_16bit(address)
2669 u_long address;
2670 {
2671 u_long old_address;
2672
2673 old_address = address;
2674 address >>= 1;
2675 address &= 0x0001ffffL;
2676 address |= (old_address & 0x000c0000L);
2677
2678 return (address);
2679 }
2680
2681 /*
2682 * Write a value into the GUS's DRAM
2683 */
2684
2685 STATIC void
2686 guspoke(iot, ioh2, address, value)
2687 bus_space_tag_t iot;
2688 bus_space_handle_t ioh2;
2689 long address;
2690 unsigned char value;
2691 {
2692
2693 /*
2694 * Select the DRAM address
2695 */
2696
2697 SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_LOW);
2698 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, (unsigned int) (address & 0xffff));
2699 SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_HIGH);
2700 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (unsigned char) ((address >> 16) & 0xff));
2701
2702 /*
2703 * Actually write the data
2704 */
2705
2706 bus_space_write_1(iot, ioh2, GUS_DRAM_DATA, value);
2707 }
2708
2709 /*
2710 * Read a value from the GUS's DRAM
2711 */
2712
2713 STATIC unsigned char
2714 guspeek(iot, ioh2, address)
2715 bus_space_tag_t iot;
2716 bus_space_handle_t ioh2;
2717 u_long address;
2718 {
2719
2720 /*
2721 * Select the DRAM address
2722 */
2723
2724 SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_LOW);
2725 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, (unsigned int) (address & 0xffff));
2726 SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_HIGH);
2727 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (unsigned char) ((address >> 16) & 0xff));
2728
2729 /*
2730 * Read in the data from the board
2731 */
2732
2733 return (unsigned char) bus_space_read_1(iot, ioh2, GUS_DRAM_DATA);
2734 }
2735
2736 /*
2737 * Reset the Gravis UltraSound card, completely
2738 */
2739
2740 STATIC void
2741 gusreset(sc, voices)
2742 struct gus_softc *sc;
2743 int voices;
2744 {
2745 bus_space_tag_t iot = sc->sc_iot;
2746 bus_space_handle_t ioh1 = sc->sc_ioh1;
2747 bus_space_handle_t ioh2 = sc->sc_ioh2;
2748 bus_space_handle_t ioh4 = sc->sc_ioh4;
2749 int i,s;
2750
2751 s = splgus();
2752
2753 /*
2754 * Reset the GF1 chip
2755 */
2756
2757 SELECT_GUS_REG(iot, ioh2, GUSREG_RESET);
2758 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
2759
2760 delay(500);
2761
2762 /*
2763 * Release reset
2764 */
2765
2766 SELECT_GUS_REG(iot, ioh2, GUSREG_RESET);
2767 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, GUSMASK_MASTER_RESET);
2768
2769 delay(500);
2770
2771 /*
2772 * Reset MIDI port as well
2773 */
2774
2775 bus_space_write_1(iot, ioh4, GUS_MIDI_CONTROL, MIDI_RESET);
2776
2777 delay(500);
2778
2779 bus_space_write_1(iot, ioh4, GUS_MIDI_CONTROL, 0x00);
2780
2781 /*
2782 * Clear interrupts
2783 */
2784
2785 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
2786 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
2787 SELECT_GUS_REG(iot, ioh2, GUSREG_TIMER_CONTROL);
2788 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
2789 SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
2790 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
2791
2792 gus_set_voices(sc, voices);
2793
2794 bus_space_read_1(iot, ioh1, GUS_IRQ_STATUS);
2795 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
2796 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
2797 SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
2798 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
2799 SELECT_GUS_REG(iot, ioh2, GUSREG_IRQ_STATUS);
2800 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
2801
2802 /*
2803 * Reset voice specific information
2804 */
2805
2806 for(i = 0; i < voices; i++) {
2807 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) i);
2808
2809 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
2810
2811 sc->sc_voc[i].voccntl = GUSMASK_VOICE_STOPPED |
2812 GUSMASK_STOP_VOICE;
2813
2814 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[i].voccntl);
2815
2816 sc->sc_voc[i].volcntl = GUSMASK_VOLUME_STOPPED |
2817 GUSMASK_STOP_VOLUME;
2818
2819 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
2820 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[i].volcntl);
2821
2822 delay(100);
2823
2824 gus_set_samprate(sc, i, 8000);
2825 SELECT_GUS_REG(iot, ioh2, GUSREG_START_ADDR_HIGH);
2826 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2827 SELECT_GUS_REG(iot, ioh2, GUSREG_START_ADDR_LOW);
2828 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2829 SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_HIGH);
2830 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2831 SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_LOW);
2832 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2833 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_RATE);
2834 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x01);
2835 SELECT_GUS_REG(iot, ioh2, GUSREG_START_VOLUME);
2836 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x10);
2837 SELECT_GUS_REG(iot, ioh2, GUSREG_END_VOLUME);
2838 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0xe0);
2839 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME);
2840 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2841
2842 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH);
2843 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2844 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW);
2845 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
2846 SELECT_GUS_REG(iot, ioh2, GUSREG_PAN_POS);
2847 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x07);
2848 }
2849
2850 /*
2851 * Clear out any pending IRQs
2852 */
2853
2854 bus_space_read_1(iot, ioh1, GUS_IRQ_STATUS);
2855 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
2856 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
2857 SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
2858 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
2859 SELECT_GUS_REG(iot, ioh2, GUSREG_IRQ_STATUS);
2860 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
2861
2862 SELECT_GUS_REG(iot, ioh2, GUSREG_RESET);
2863 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, GUSMASK_MASTER_RESET | GUSMASK_DAC_ENABLE |
2864 GUSMASK_IRQ_ENABLE);
2865
2866 splx(s);
2867 }
2868
2869
2870 STATIC int
2871 gus_init_cs4231(sc)
2872 struct gus_softc *sc;
2873 {
2874 bus_space_tag_t iot = sc->sc_iot;
2875 bus_space_handle_t ioh1 = sc->sc_ioh1;
2876 int port = sc->sc_iobase;
2877 u_char ctrl;
2878
2879 ctrl = (port & 0xf0) >> 4; /* set port address middle nibble */
2880 /*
2881 * The codec is a bit weird--swapped dma channels.
2882 */
2883 ctrl |= GUS_MAX_CODEC_ENABLE;
2884 if (sc->sc_playdrq >= 4)
2885 ctrl |= GUS_MAX_RECCHAN16;
2886 if (sc->sc_recdrq >= 4)
2887 ctrl |= GUS_MAX_PLAYCHAN16;
2888
2889 bus_space_write_1(iot, ioh1, GUS_MAX_CTRL, ctrl);
2890
2891 sc->sc_codec.sc_ad1848.sc_iot = sc->sc_iot;
2892 sc->sc_codec.sc_iobase = port+GUS_MAX_CODEC_BASE;
2893
2894 if (ad1848_isa_mapprobe(&sc->sc_codec, sc->sc_codec.sc_iobase) == 0) {
2895 sc->sc_flags &= ~GUS_CODEC_INSTALLED;
2896 return (0);
2897 } else {
2898 struct ad1848_volume vol = {AUDIO_MAX_GAIN, AUDIO_MAX_GAIN};
2899 sc->sc_flags |= GUS_CODEC_INSTALLED;
2900 sc->sc_codec.sc_ad1848.parent = sc;
2901 sc->sc_codec.sc_playdrq = sc->sc_recdrq;
2902 sc->sc_codec.sc_play_maxsize = sc->sc_req_maxsize;
2903 sc->sc_codec.sc_recdrq = sc->sc_playdrq;
2904 sc->sc_codec.sc_rec_maxsize = sc->sc_play_maxsize;
2905 gus_hw_if = gusmax_hw_if;
2906 /* enable line in and mic in the GUS mixer; the codec chip
2907 will do the real mixing for them. */
2908 sc->sc_mixcontrol &= ~GUSMASK_LINE_IN; /* 0 enables. */
2909 sc->sc_mixcontrol |= GUSMASK_MIC_IN; /* 1 enables. */
2910 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
2911
2912 ad1848_isa_attach(&sc->sc_codec);
2913 /* turn on pre-MUX microphone gain. */
2914 ad1848_set_mic_gain(&sc->sc_codec.sc_ad1848, &vol);
2915
2916 return (1);
2917 }
2918 }
2919
2920
2921 /*
2922 * Return info about the audio device, for the AUDIO_GETINFO ioctl
2923 */
2924
2925 int
2926 gus_getdev(addr, dev)
2927 void * addr;
2928 struct audio_device *dev;
2929 {
2930 *dev = gus_device;
2931 return 0;
2932 }
2933
2934 /*
2935 * stubs (XXX)
2936 */
2937
2938 int
2939 gus_set_in_gain(addr, gain, balance)
2940 caddr_t addr;
2941 u_int gain;
2942 u_char balance;
2943 {
2944 DPRINTF(("gus_set_in_gain called\n"));
2945 return 0;
2946 }
2947
2948 int
2949 gus_get_in_gain(addr)
2950 caddr_t addr;
2951 {
2952 DPRINTF(("gus_get_in_gain called\n"));
2953 return 0;
2954 }
2955
2956 int
2957 gusmax_dma_input(addr, buf, size, callback, arg)
2958 void * addr;
2959 void *buf;
2960 int size;
2961 void (*callback) __P((void *));
2962 void *arg;
2963 {
2964 struct ad1848_isa_softc *sc = addr;
2965 return gus_dma_input(sc->sc_ad1848.parent, buf, size, callback, arg);
2966 }
2967
2968 /*
2969 * Start sampling the input source into the requested DMA buffer.
2970 * Called at splgus(), either from top-half or from interrupt handler.
2971 */
2972 int
2973 gus_dma_input(addr, buf, size, callback, arg)
2974 void * addr;
2975 void *buf;
2976 int size;
2977 void (*callback) __P((void *));
2978 void *arg;
2979 {
2980 struct gus_softc *sc = addr;
2981 bus_space_tag_t iot = sc->sc_iot;
2982 bus_space_handle_t ioh2 = sc->sc_ioh2;
2983 u_char dmac;
2984 DMAPRINTF(("gus_dma_input called\n"));
2985
2986 /*
2987 * Sample SIZE bytes of data from the card, into buffer at BUF.
2988 */
2989
2990 if (sc->sc_precision == 16)
2991 return EINVAL; /* XXX */
2992
2993 /* set DMA modes */
2994 dmac = GUSMASK_SAMPLE_IRQ|GUSMASK_SAMPLE_START;
2995 if (sc->sc_recdrq >= 4)
2996 dmac |= GUSMASK_SAMPLE_DATA16;
2997 if (sc->sc_encoding == AUDIO_ENCODING_ULAW ||
2998 sc->sc_encoding == AUDIO_ENCODING_ALAW ||
2999 sc->sc_encoding == AUDIO_ENCODING_ULINEAR_LE ||
3000 sc->sc_encoding == AUDIO_ENCODING_ULINEAR_BE)
3001 dmac |= GUSMASK_SAMPLE_INVBIT;
3002 if (sc->sc_channels == 2)
3003 dmac |= GUSMASK_SAMPLE_STEREO;
3004 isa_dmastart(sc->sc_ic, sc->sc_recdrq, buf, size,
3005 NULL, DMAMODE_READ, BUS_DMA_NOWAIT);
3006
3007 DMAPRINTF(("gus_dma_input isa_dmastarted\n"));
3008 sc->sc_flags |= GUS_DMAIN_ACTIVE;
3009 sc->sc_dmainintr = callback;
3010 sc->sc_inarg = arg;
3011 sc->sc_dmaincnt = size;
3012 sc->sc_dmainaddr = buf;
3013
3014 SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
3015 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, dmac); /* Go! */
3016
3017
3018 DMAPRINTF(("gus_dma_input returning\n"));
3019
3020 return 0;
3021 }
3022
3023 STATIC int
3024 gus_dmain_intr(sc)
3025 struct gus_softc *sc;
3026 {
3027 void (*callback) __P((void *));
3028 void *arg;
3029
3030 DMAPRINTF(("gus_dmain_intr called\n"));
3031 if (sc->sc_dmainintr) {
3032 isa_dmadone(sc->sc_ic, sc->sc_recdrq);
3033 callback = sc->sc_dmainintr;
3034 arg = sc->sc_inarg;
3035
3036 sc->sc_dmainaddr = 0;
3037 sc->sc_dmaincnt = 0;
3038 sc->sc_dmainintr = 0;
3039 sc->sc_inarg = 0;
3040
3041 sc->sc_flags &= ~GUS_DMAIN_ACTIVE;
3042 DMAPRINTF(("calling dmain_intr callback %p(%p)\n", callback, arg));
3043 (*callback)(arg);
3044 return 1;
3045 } else {
3046 DMAPRINTF(("gus_dmain_intr false?\n"));
3047 return 0; /* XXX ??? */
3048 }
3049 }
3050
3051 int
3052 gusmax_halt_out_dma(addr)
3053 void * addr;
3054 {
3055 struct ad1848_isa_softc *sc = addr;
3056 return gus_halt_out_dma(sc->sc_ad1848.parent);
3057 }
3058
3059
3060 int
3061 gusmax_halt_in_dma(addr)
3062 void * addr;
3063 {
3064 struct ad1848_isa_softc *sc = addr;
3065 return gus_halt_in_dma(sc->sc_ad1848.parent);
3066 }
3067
3068 /*
3069 * Stop any DMA output. Called at splgus().
3070 */
3071 int
3072 gus_halt_out_dma(addr)
3073 void * addr;
3074 {
3075 struct gus_softc *sc = addr;
3076 bus_space_tag_t iot = sc->sc_iot;
3077 bus_space_handle_t ioh2 = sc->sc_ioh2;
3078
3079 DMAPRINTF(("gus_halt_out_dma called\n"));
3080 /*
3081 * Make sure the GUS _isn't_ setup for DMA
3082 */
3083
3084 SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
3085 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0);
3086
3087 callout_stop(&sc->sc_dmaout_ch);
3088 isa_dmaabort(sc->sc_ic, sc->sc_playdrq);
3089 sc->sc_flags &= ~(GUS_DMAOUT_ACTIVE|GUS_LOCKED);
3090 sc->sc_dmaoutintr = 0;
3091 sc->sc_outarg = 0;
3092 sc->sc_dmaoutaddr = 0;
3093 sc->sc_dmaoutcnt = 0;
3094 sc->sc_dmabuf = 0;
3095 sc->sc_bufcnt = 0;
3096 sc->sc_playbuf = -1;
3097 /* also stop playing */
3098 gus_stop_voice(sc, GUS_VOICE_LEFT, 1);
3099 gus_stop_voice(sc, GUS_VOICE_RIGHT, 0);
3100
3101 return 0;
3102 }
3103
3104 /*
3105 * Stop any DMA output. Called at splgus().
3106 */
3107 int
3108 gus_halt_in_dma(addr)
3109 void * addr;
3110 {
3111 struct gus_softc *sc = addr;
3112 bus_space_tag_t iot = sc->sc_iot;
3113 bus_space_handle_t ioh2 = sc->sc_ioh2;
3114 DMAPRINTF(("gus_halt_in_dma called\n"));
3115
3116 /*
3117 * Make sure the GUS _isn't_ setup for DMA
3118 */
3119
3120 SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
3121 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH,
3122 bus_space_read_1(iot, ioh2, GUS_DATA_HIGH) & ~(GUSMASK_SAMPLE_START|GUSMASK_SAMPLE_IRQ));
3123
3124 isa_dmaabort(sc->sc_ic, sc->sc_recdrq);
3125 sc->sc_flags &= ~GUS_DMAIN_ACTIVE;
3126 sc->sc_dmainintr = 0;
3127 sc->sc_inarg = 0;
3128 sc->sc_dmainaddr = 0;
3129 sc->sc_dmaincnt = 0;
3130
3131 return 0;
3132 }
3133
3134
3135 static ad1848_devmap_t gusmapping[] = {
3136 { GUSMAX_DAC_LVL, AD1848_KIND_LVL, AD1848_AUX1_CHANNEL },
3137 { GUSMAX_LINE_IN_LVL, AD1848_KIND_LVL, AD1848_LINE_CHANNEL },
3138 { GUSMAX_MONO_LVL, AD1848_KIND_LVL, AD1848_MONO_CHANNEL },
3139 { GUSMAX_CD_LVL, AD1848_KIND_LVL, AD1848_AUX2_CHANNEL },
3140 { GUSMAX_MONITOR_LVL, AD1848_KIND_LVL, AD1848_MONITOR_CHANNEL },
3141 { GUSMAX_OUT_LVL, AD1848_KIND_LVL, AD1848_DAC_CHANNEL },
3142 { GUSMAX_DAC_MUTE, AD1848_KIND_MUTE, AD1848_AUX1_CHANNEL },
3143 { GUSMAX_LINE_IN_MUTE, AD1848_KIND_MUTE, AD1848_LINE_CHANNEL },
3144 { GUSMAX_MONO_MUTE, AD1848_KIND_MUTE, AD1848_MONO_CHANNEL },
3145 { GUSMAX_CD_MUTE, AD1848_KIND_MUTE, AD1848_AUX2_CHANNEL },
3146 { GUSMAX_MONITOR_MUTE, AD1848_KIND_MUTE, AD1848_MONITOR_CHANNEL },
3147 { GUSMAX_REC_LVL, AD1848_KIND_RECORDGAIN, -1 },
3148 { GUSMAX_RECORD_SOURCE, AD1848_KIND_RECORDSOURCE, -1 }
3149 };
3150
3151 static int nummap = sizeof(gusmapping) / sizeof(gusmapping[0]);
3152
3153 STATIC int
3154 gusmax_mixer_get_port(addr, cp)
3155 void *addr;
3156 mixer_ctrl_t *cp;
3157 {
3158 struct ad1848_isa_softc *ac = addr;
3159 struct gus_softc *sc = ac->sc_ad1848.parent;
3160 struct ad1848_volume vol;
3161 int error = ad1848_mixer_get_port(&ac->sc_ad1848, gusmapping,
3162 nummap, cp);
3163
3164 if (error != ENXIO)
3165 return (error);
3166
3167 error = EINVAL;
3168
3169 switch (cp->dev) {
3170 case GUSMAX_SPEAKER_LVL: /* fake speaker for mute naming */
3171 if (cp->type == AUDIO_MIXER_VALUE) {
3172 if (sc->sc_mixcontrol & GUSMASK_LINE_OUT)
3173 vol.left = vol.right = AUDIO_MAX_GAIN;
3174 else
3175 vol.left = vol.right = AUDIO_MIN_GAIN;
3176 error = 0;
3177 ad1848_from_vol(cp, &vol);
3178 }
3179 break;
3180
3181 case GUSMAX_SPEAKER_MUTE:
3182 if (cp->type == AUDIO_MIXER_ENUM) {
3183 cp->un.ord = sc->sc_mixcontrol & GUSMASK_LINE_OUT ? 1 : 0;
3184 error = 0;
3185 }
3186 break;
3187 default:
3188 error = ENXIO;
3189 break;
3190 }
3191
3192 return(error);
3193 }
3194
3195 STATIC int
3196 gus_mixer_get_port(addr, cp)
3197 void *addr;
3198 mixer_ctrl_t *cp;
3199 {
3200 struct gus_softc *sc = addr;
3201 struct ics2101_softc *ic = &sc->sc_mixer;
3202 struct ad1848_volume vol;
3203 int error = EINVAL;
3204
3205 DPRINTF(("gus_mixer_get_port: dev=%d type=%d\n", cp->dev, cp->type));
3206
3207 if (!HAS_MIXER(sc) && cp->dev > GUSICS_MASTER_MUTE)
3208 return ENXIO;
3209
3210 switch (cp->dev) {
3211
3212 case GUSICS_MIC_IN_MUTE: /* Microphone */
3213 if (cp->type == AUDIO_MIXER_ENUM) {
3214 if (HAS_MIXER(sc))
3215 cp->un.ord = ic->sc_mute[GUSMIX_CHAN_MIC][ICSMIX_LEFT];
3216 else
3217 cp->un.ord =
3218 sc->sc_mixcontrol & GUSMASK_MIC_IN ? 0 : 1;
3219 error = 0;
3220 }
3221 break;
3222
3223 case GUSICS_LINE_IN_MUTE:
3224 if (cp->type == AUDIO_MIXER_ENUM) {
3225 if (HAS_MIXER(sc))
3226 cp->un.ord = ic->sc_mute[GUSMIX_CHAN_LINE][ICSMIX_LEFT];
3227 else
3228 cp->un.ord =
3229 sc->sc_mixcontrol & GUSMASK_LINE_IN ? 1 : 0;
3230 error = 0;
3231 }
3232 break;
3233
3234 case GUSICS_MASTER_MUTE:
3235 if (cp->type == AUDIO_MIXER_ENUM) {
3236 if (HAS_MIXER(sc))
3237 cp->un.ord = ic->sc_mute[GUSMIX_CHAN_MASTER][ICSMIX_LEFT];
3238 else
3239 cp->un.ord =
3240 sc->sc_mixcontrol & GUSMASK_LINE_OUT ? 1 : 0;
3241 error = 0;
3242 }
3243 break;
3244
3245 case GUSICS_DAC_MUTE:
3246 if (cp->type == AUDIO_MIXER_ENUM) {
3247 cp->un.ord = ic->sc_mute[GUSMIX_CHAN_DAC][ICSMIX_LEFT];
3248 error = 0;
3249 }
3250 break;
3251
3252 case GUSICS_CD_MUTE:
3253 if (cp->type == AUDIO_MIXER_ENUM) {
3254 cp->un.ord = ic->sc_mute[GUSMIX_CHAN_CD][ICSMIX_LEFT];
3255 error = 0;
3256 }
3257 break;
3258
3259 case GUSICS_MASTER_LVL:
3260 if (cp->type == AUDIO_MIXER_VALUE) {
3261 vol.left = ic->sc_setting[GUSMIX_CHAN_MASTER][ICSMIX_LEFT];
3262 vol.right = ic->sc_setting[GUSMIX_CHAN_MASTER][ICSMIX_RIGHT];
3263 if (ad1848_from_vol(cp, &vol))
3264 error = 0;
3265 }
3266 break;
3267
3268 case GUSICS_MIC_IN_LVL: /* Microphone */
3269 if (cp->type == AUDIO_MIXER_VALUE) {
3270 vol.left = ic->sc_setting[GUSMIX_CHAN_MIC][ICSMIX_LEFT];
3271 vol.right = ic->sc_setting[GUSMIX_CHAN_MIC][ICSMIX_RIGHT];
3272 if (ad1848_from_vol(cp, &vol))
3273 error = 0;
3274 }
3275 break;
3276
3277 case GUSICS_LINE_IN_LVL: /* line in */
3278 if (cp->type == AUDIO_MIXER_VALUE) {
3279 vol.left = ic->sc_setting[GUSMIX_CHAN_LINE][ICSMIX_LEFT];
3280 vol.right = ic->sc_setting[GUSMIX_CHAN_LINE][ICSMIX_RIGHT];
3281 if (ad1848_from_vol(cp, &vol))
3282 error = 0;
3283 }
3284 break;
3285
3286
3287 case GUSICS_CD_LVL:
3288 if (cp->type == AUDIO_MIXER_VALUE) {
3289 vol.left = ic->sc_setting[GUSMIX_CHAN_CD][ICSMIX_LEFT];
3290 vol.right = ic->sc_setting[GUSMIX_CHAN_CD][ICSMIX_RIGHT];
3291 if (ad1848_from_vol(cp, &vol))
3292 error = 0;
3293 }
3294 break;
3295
3296 case GUSICS_DAC_LVL: /* dac out */
3297 if (cp->type == AUDIO_MIXER_VALUE) {
3298 vol.left = ic->sc_setting[GUSMIX_CHAN_DAC][ICSMIX_LEFT];
3299 vol.right = ic->sc_setting[GUSMIX_CHAN_DAC][ICSMIX_RIGHT];
3300 if (ad1848_from_vol(cp, &vol))
3301 error = 0;
3302 }
3303 break;
3304
3305
3306 case GUSICS_RECORD_SOURCE:
3307 if (cp->type == AUDIO_MIXER_ENUM) {
3308 /* Can't set anything else useful, sigh. */
3309 cp->un.ord = 0;
3310 }
3311 break;
3312
3313 default:
3314 return ENXIO;
3315 /*NOTREACHED*/
3316 }
3317 return error;
3318 }
3319
3320 STATIC void
3321 gusics_master_mute(ic, mute)
3322 struct ics2101_softc *ic;
3323 int mute;
3324 {
3325 ics2101_mix_mute(ic, GUSMIX_CHAN_MASTER, ICSMIX_LEFT, mute);
3326 ics2101_mix_mute(ic, GUSMIX_CHAN_MASTER, ICSMIX_RIGHT, mute);
3327 }
3328
3329 STATIC void
3330 gusics_mic_mute(ic, mute)
3331 struct ics2101_softc *ic;
3332 int mute;
3333 {
3334 ics2101_mix_mute(ic, GUSMIX_CHAN_MIC, ICSMIX_LEFT, mute);
3335 ics2101_mix_mute(ic, GUSMIX_CHAN_MIC, ICSMIX_RIGHT, mute);
3336 }
3337
3338 STATIC void
3339 gusics_linein_mute(ic, mute)
3340 struct ics2101_softc *ic;
3341 int mute;
3342 {
3343 ics2101_mix_mute(ic, GUSMIX_CHAN_LINE, ICSMIX_LEFT, mute);
3344 ics2101_mix_mute(ic, GUSMIX_CHAN_LINE, ICSMIX_RIGHT, mute);
3345 }
3346
3347 STATIC void
3348 gusics_cd_mute(ic, mute)
3349 struct ics2101_softc *ic;
3350 int mute;
3351 {
3352 ics2101_mix_mute(ic, GUSMIX_CHAN_CD, ICSMIX_LEFT, mute);
3353 ics2101_mix_mute(ic, GUSMIX_CHAN_CD, ICSMIX_RIGHT, mute);
3354 }
3355
3356 STATIC void
3357 gusics_dac_mute(ic, mute)
3358 struct ics2101_softc *ic;
3359 int mute;
3360 {
3361 ics2101_mix_mute(ic, GUSMIX_CHAN_DAC, ICSMIX_LEFT, mute);
3362 ics2101_mix_mute(ic, GUSMIX_CHAN_DAC, ICSMIX_RIGHT, mute);
3363 }
3364
3365 STATIC int
3366 gusmax_mixer_set_port(addr, cp)
3367 void *addr;
3368 mixer_ctrl_t *cp;
3369 {
3370 struct ad1848_isa_softc *ac = addr;
3371 struct gus_softc *sc = ac->sc_ad1848.parent;
3372 struct ad1848_volume vol;
3373 int error = ad1848_mixer_set_port(&ac->sc_ad1848, gusmapping,
3374 nummap, cp);
3375
3376 if (error != ENXIO)
3377 return (error);
3378
3379 DPRINTF(("gusmax_mixer_set_port: dev=%d type=%d\n", cp->dev, cp->type));
3380
3381 switch (cp->dev) {
3382 case GUSMAX_SPEAKER_LVL:
3383 if (cp->type == AUDIO_MIXER_VALUE &&
3384 cp->un.value.num_channels == 1) {
3385 if (ad1848_to_vol(cp, &vol)) {
3386 gus_speaker_ctl(sc, vol.left > AUDIO_MIN_GAIN ?
3387 SPKR_ON : SPKR_OFF);
3388 error = 0;
3389 }
3390 }
3391 break;
3392
3393 case GUSMAX_SPEAKER_MUTE:
3394 if (cp->type == AUDIO_MIXER_ENUM) {
3395 gus_speaker_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON);
3396 error = 0;
3397 }
3398 break;
3399
3400 default:
3401 return ENXIO;
3402 /*NOTREACHED*/
3403 }
3404 return error;
3405 }
3406
3407 STATIC int
3408 gus_mixer_set_port(addr, cp)
3409 void *addr;
3410 mixer_ctrl_t *cp;
3411 {
3412 struct gus_softc *sc = addr;
3413 struct ics2101_softc *ic = &sc->sc_mixer;
3414 struct ad1848_volume vol;
3415 int error = EINVAL;
3416
3417 DPRINTF(("gus_mixer_set_port: dev=%d type=%d\n", cp->dev, cp->type));
3418
3419 if (!HAS_MIXER(sc) && cp->dev > GUSICS_MASTER_MUTE)
3420 return ENXIO;
3421
3422 switch (cp->dev) {
3423
3424 case GUSICS_MIC_IN_MUTE: /* Microphone */
3425 if (cp->type == AUDIO_MIXER_ENUM) {
3426 DPRINTF(("mic mute %d\n", cp->un.ord));
3427 if (HAS_MIXER(sc)) {
3428 gusics_mic_mute(ic, cp->un.ord);
3429 }
3430 gus_mic_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON);
3431 error = 0;
3432 }
3433 break;
3434
3435 case GUSICS_LINE_IN_MUTE:
3436 if (cp->type == AUDIO_MIXER_ENUM) {
3437 DPRINTF(("linein mute %d\n", cp->un.ord));
3438 if (HAS_MIXER(sc)) {
3439 gusics_linein_mute(ic, cp->un.ord);
3440 }
3441 gus_linein_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON);
3442 error = 0;
3443 }
3444 break;
3445
3446 case GUSICS_MASTER_MUTE:
3447 if (cp->type == AUDIO_MIXER_ENUM) {
3448 DPRINTF(("master mute %d\n", cp->un.ord));
3449 if (HAS_MIXER(sc)) {
3450 gusics_master_mute(ic, cp->un.ord);
3451 }
3452 gus_speaker_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON);
3453 error = 0;
3454 }
3455 break;
3456
3457 case GUSICS_DAC_MUTE:
3458 if (cp->type == AUDIO_MIXER_ENUM) {
3459 gusics_dac_mute(ic, cp->un.ord);
3460 error = 0;
3461 }
3462 break;
3463
3464 case GUSICS_CD_MUTE:
3465 if (cp->type == AUDIO_MIXER_ENUM) {
3466 gusics_cd_mute(ic, cp->un.ord);
3467 error = 0;
3468 }
3469 break;
3470
3471 case GUSICS_MASTER_LVL:
3472 if (cp->type == AUDIO_MIXER_VALUE) {
3473 if (ad1848_to_vol(cp, &vol)) {
3474 ics2101_mix_attenuate(ic,
3475 GUSMIX_CHAN_MASTER,
3476 ICSMIX_LEFT,
3477 vol.left);
3478 ics2101_mix_attenuate(ic,
3479 GUSMIX_CHAN_MASTER,
3480 ICSMIX_RIGHT,
3481 vol.right);
3482 error = 0;
3483 }
3484 }
3485 break;
3486
3487 case GUSICS_MIC_IN_LVL: /* Microphone */
3488 if (cp->type == AUDIO_MIXER_VALUE) {
3489 if (ad1848_to_vol(cp, &vol)) {
3490 ics2101_mix_attenuate(ic,
3491 GUSMIX_CHAN_MIC,
3492 ICSMIX_LEFT,
3493 vol.left);
3494 ics2101_mix_attenuate(ic,
3495 GUSMIX_CHAN_MIC,
3496 ICSMIX_RIGHT,
3497 vol.right);
3498 error = 0;
3499 }
3500 }
3501 break;
3502
3503 case GUSICS_LINE_IN_LVL: /* line in */
3504 if (cp->type == AUDIO_MIXER_VALUE) {
3505 if (ad1848_to_vol(cp, &vol)) {
3506 ics2101_mix_attenuate(ic,
3507 GUSMIX_CHAN_LINE,
3508 ICSMIX_LEFT,
3509 vol.left);
3510 ics2101_mix_attenuate(ic,
3511 GUSMIX_CHAN_LINE,
3512 ICSMIX_RIGHT,
3513 vol.right);
3514 error = 0;
3515 }
3516 }
3517 break;
3518
3519
3520 case GUSICS_CD_LVL:
3521 if (cp->type == AUDIO_MIXER_VALUE) {
3522 if (ad1848_to_vol(cp, &vol)) {
3523 ics2101_mix_attenuate(ic,
3524 GUSMIX_CHAN_CD,
3525 ICSMIX_LEFT,
3526 vol.left);
3527 ics2101_mix_attenuate(ic,
3528 GUSMIX_CHAN_CD,
3529 ICSMIX_RIGHT,
3530 vol.right);
3531 error = 0;
3532 }
3533 }
3534 break;
3535
3536 case GUSICS_DAC_LVL: /* dac out */
3537 if (cp->type == AUDIO_MIXER_VALUE) {
3538 if (ad1848_to_vol(cp, &vol)) {
3539 ics2101_mix_attenuate(ic,
3540 GUSMIX_CHAN_DAC,
3541 ICSMIX_LEFT,
3542 vol.left);
3543 ics2101_mix_attenuate(ic,
3544 GUSMIX_CHAN_DAC,
3545 ICSMIX_RIGHT,
3546 vol.right);
3547 error = 0;
3548 }
3549 }
3550 break;
3551
3552
3553 case GUSICS_RECORD_SOURCE:
3554 if (cp->type == AUDIO_MIXER_ENUM && cp->un.ord == 0) {
3555 /* Can't set anything else useful, sigh. */
3556 error = 0;
3557 }
3558 break;
3559
3560 default:
3561 return ENXIO;
3562 /*NOTREACHED*/
3563 }
3564 return error;
3565 }
3566
3567 STATIC int
3568 gus_get_props(addr)
3569 void *addr;
3570 {
3571 struct gus_softc *sc = addr;
3572 return (AUDIO_PROP_MMAP |
3573 (sc->sc_recdrq == sc->sc_playdrq ? 0 : AUDIO_PROP_FULLDUPLEX));
3574 }
3575
3576 STATIC int
3577 gusmax_get_props(addr)
3578 void *addr;
3579 {
3580 struct ad1848_isa_softc *ac = addr;
3581 return gus_get_props(ac->sc_ad1848.parent);
3582 }
3583
3584 STATIC int
3585 gusmax_mixer_query_devinfo(addr, dip)
3586 void *addr;
3587 mixer_devinfo_t *dip;
3588 {
3589 DPRINTF(("gusmax_query_devinfo: index=%d\n", dip->index));
3590
3591 switch(dip->index) {
3592 #if 0
3593 case GUSMAX_MIC_IN_LVL: /* Microphone */
3594 dip->type = AUDIO_MIXER_VALUE;
3595 dip->mixer_class = GUSMAX_INPUT_CLASS;
3596 dip->prev = AUDIO_MIXER_LAST;
3597 dip->next = GUSMAX_MIC_IN_MUTE;
3598 strcpy(dip->label.name, AudioNmicrophone);
3599 dip->un.v.num_channels = 2;
3600 strcpy(dip->un.v.units.name, AudioNvolume);
3601 break;
3602 #endif
3603
3604 case GUSMAX_MONO_LVL: /* mono/microphone mixer */
3605 dip->type = AUDIO_MIXER_VALUE;
3606 dip->mixer_class = GUSMAX_INPUT_CLASS;
3607 dip->prev = AUDIO_MIXER_LAST;
3608 dip->next = GUSMAX_MONO_MUTE;
3609 strcpy(dip->label.name, AudioNmicrophone);
3610 dip->un.v.num_channels = 1;
3611 strcpy(dip->un.v.units.name, AudioNvolume);
3612 break;
3613
3614 case GUSMAX_DAC_LVL: /* dacout */
3615 dip->type = AUDIO_MIXER_VALUE;
3616 dip->mixer_class = GUSMAX_INPUT_CLASS;
3617 dip->prev = AUDIO_MIXER_LAST;
3618 dip->next = GUSMAX_DAC_MUTE;
3619 strcpy(dip->label.name, AudioNdac);
3620 dip->un.v.num_channels = 2;
3621 strcpy(dip->un.v.units.name, AudioNvolume);
3622 break;
3623
3624 case GUSMAX_LINE_IN_LVL: /* line */
3625 dip->type = AUDIO_MIXER_VALUE;
3626 dip->mixer_class = GUSMAX_INPUT_CLASS;
3627 dip->prev = AUDIO_MIXER_LAST;
3628 dip->next = GUSMAX_LINE_IN_MUTE;
3629 strcpy(dip->label.name, AudioNline);
3630 dip->un.v.num_channels = 2;
3631 strcpy(dip->un.v.units.name, AudioNvolume);
3632 break;
3633
3634 case GUSMAX_CD_LVL: /* cd */
3635 dip->type = AUDIO_MIXER_VALUE;
3636 dip->mixer_class = GUSMAX_INPUT_CLASS;
3637 dip->prev = AUDIO_MIXER_LAST;
3638 dip->next = GUSMAX_CD_MUTE;
3639 strcpy(dip->label.name, AudioNcd);
3640 dip->un.v.num_channels = 2;
3641 strcpy(dip->un.v.units.name, AudioNvolume);
3642 break;
3643
3644
3645 case GUSMAX_MONITOR_LVL: /* monitor level */
3646 dip->type = AUDIO_MIXER_VALUE;
3647 dip->mixer_class = GUSMAX_MONITOR_CLASS;
3648 dip->next = GUSMAX_MONITOR_MUTE;
3649 dip->prev = AUDIO_MIXER_LAST;
3650 strcpy(dip->label.name, AudioNmonitor);
3651 dip->un.v.num_channels = 1;
3652 strcpy(dip->un.v.units.name, AudioNvolume);
3653 break;
3654
3655 case GUSMAX_OUT_LVL: /* cs4231 output volume: not useful? */
3656 dip->type = AUDIO_MIXER_VALUE;
3657 dip->mixer_class = GUSMAX_MONITOR_CLASS;
3658 dip->prev = dip->next = AUDIO_MIXER_LAST;
3659 strcpy(dip->label.name, AudioNoutput);
3660 dip->un.v.num_channels = 2;
3661 strcpy(dip->un.v.units.name, AudioNvolume);
3662 break;
3663
3664 case GUSMAX_SPEAKER_LVL: /* fake speaker volume */
3665 dip->type = AUDIO_MIXER_VALUE;
3666 dip->mixer_class = GUSMAX_MONITOR_CLASS;
3667 dip->prev = AUDIO_MIXER_LAST;
3668 dip->next = GUSMAX_SPEAKER_MUTE;
3669 strcpy(dip->label.name, AudioNmaster);
3670 dip->un.v.num_channels = 2;
3671 strcpy(dip->un.v.units.name, AudioNvolume);
3672 break;
3673
3674 case GUSMAX_LINE_IN_MUTE:
3675 dip->mixer_class = GUSMAX_INPUT_CLASS;
3676 dip->type = AUDIO_MIXER_ENUM;
3677 dip->prev = GUSMAX_LINE_IN_LVL;
3678 dip->next = AUDIO_MIXER_LAST;
3679 goto mute;
3680
3681 case GUSMAX_DAC_MUTE:
3682 dip->mixer_class = GUSMAX_INPUT_CLASS;
3683 dip->type = AUDIO_MIXER_ENUM;
3684 dip->prev = GUSMAX_DAC_LVL;
3685 dip->next = AUDIO_MIXER_LAST;
3686 goto mute;
3687
3688 case GUSMAX_CD_MUTE:
3689 dip->mixer_class = GUSMAX_INPUT_CLASS;
3690 dip->type = AUDIO_MIXER_ENUM;
3691 dip->prev = GUSMAX_CD_LVL;
3692 dip->next = AUDIO_MIXER_LAST;
3693 goto mute;
3694
3695 case GUSMAX_MONO_MUTE:
3696 dip->mixer_class = GUSMAX_INPUT_CLASS;
3697 dip->type = AUDIO_MIXER_ENUM;
3698 dip->prev = GUSMAX_MONO_LVL;
3699 dip->next = AUDIO_MIXER_LAST;
3700 goto mute;
3701
3702 case GUSMAX_MONITOR_MUTE:
3703 dip->mixer_class = GUSMAX_OUTPUT_CLASS;
3704 dip->type = AUDIO_MIXER_ENUM;
3705 dip->prev = GUSMAX_MONITOR_LVL;
3706 dip->next = AUDIO_MIXER_LAST;
3707 goto mute;
3708
3709 case GUSMAX_SPEAKER_MUTE:
3710 dip->mixer_class = GUSMAX_OUTPUT_CLASS;
3711 dip->type = AUDIO_MIXER_ENUM;
3712 dip->prev = GUSMAX_SPEAKER_LVL;
3713 dip->next = AUDIO_MIXER_LAST;
3714 mute:
3715 strcpy(dip->label.name, AudioNmute);
3716 dip->un.e.num_mem = 2;
3717 strcpy(dip->un.e.member[0].label.name, AudioNoff);
3718 dip->un.e.member[0].ord = 0;
3719 strcpy(dip->un.e.member[1].label.name, AudioNon);
3720 dip->un.e.member[1].ord = 1;
3721 break;
3722
3723 case GUSMAX_REC_LVL: /* record level */
3724 dip->type = AUDIO_MIXER_VALUE;
3725 dip->mixer_class = GUSMAX_RECORD_CLASS;
3726 dip->prev = AUDIO_MIXER_LAST;
3727 dip->next = GUSMAX_RECORD_SOURCE;
3728 strcpy(dip->label.name, AudioNrecord);
3729 dip->un.v.num_channels = 2;
3730 strcpy(dip->un.v.units.name, AudioNvolume);
3731 break;
3732
3733 case GUSMAX_RECORD_SOURCE:
3734 dip->mixer_class = GUSMAX_RECORD_CLASS;
3735 dip->type = AUDIO_MIXER_ENUM;
3736 dip->prev = GUSMAX_REC_LVL;
3737 dip->next = AUDIO_MIXER_LAST;
3738 strcpy(dip->label.name, AudioNsource);
3739 dip->un.e.num_mem = 4;
3740 strcpy(dip->un.e.member[0].label.name, AudioNoutput);
3741 dip->un.e.member[0].ord = DAC_IN_PORT;
3742 strcpy(dip->un.e.member[1].label.name, AudioNmicrophone);
3743 dip->un.e.member[1].ord = MIC_IN_PORT;
3744 strcpy(dip->un.e.member[2].label.name, AudioNdac);
3745 dip->un.e.member[2].ord = AUX1_IN_PORT;
3746 strcpy(dip->un.e.member[3].label.name, AudioNline);
3747 dip->un.e.member[3].ord = LINE_IN_PORT;
3748 break;
3749
3750 case GUSMAX_INPUT_CLASS: /* input class descriptor */
3751 dip->type = AUDIO_MIXER_CLASS;
3752 dip->mixer_class = GUSMAX_INPUT_CLASS;
3753 dip->next = dip->prev = AUDIO_MIXER_LAST;
3754 strcpy(dip->label.name, AudioCinputs);
3755 break;
3756
3757 case GUSMAX_OUTPUT_CLASS: /* output class descriptor */
3758 dip->type = AUDIO_MIXER_CLASS;
3759 dip->mixer_class = GUSMAX_OUTPUT_CLASS;
3760 dip->next = dip->prev = AUDIO_MIXER_LAST;
3761 strcpy(dip->label.name, AudioCoutputs);
3762 break;
3763
3764 case GUSMAX_MONITOR_CLASS: /* monitor class descriptor */
3765 dip->type = AUDIO_MIXER_CLASS;
3766 dip->mixer_class = GUSMAX_MONITOR_CLASS;
3767 dip->next = dip->prev = AUDIO_MIXER_LAST;
3768 strcpy(dip->label.name, AudioCmonitor);
3769 break;
3770
3771 case GUSMAX_RECORD_CLASS: /* record source class */
3772 dip->type = AUDIO_MIXER_CLASS;
3773 dip->mixer_class = GUSMAX_RECORD_CLASS;
3774 dip->next = dip->prev = AUDIO_MIXER_LAST;
3775 strcpy(dip->label.name, AudioCrecord);
3776 break;
3777
3778 default:
3779 return ENXIO;
3780 /*NOTREACHED*/
3781 }
3782 DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name));
3783 return 0;
3784 }
3785
3786 STATIC int
3787 gus_mixer_query_devinfo(addr, dip)
3788 void *addr;
3789 mixer_devinfo_t *dip;
3790 {
3791 struct gus_softc *sc = addr;
3792
3793 DPRINTF(("gusmax_query_devinfo: index=%d\n", dip->index));
3794
3795 if (!HAS_MIXER(sc) && dip->index > GUSICS_MASTER_MUTE)
3796 return ENXIO;
3797
3798 switch(dip->index) {
3799
3800 case GUSICS_MIC_IN_LVL: /* Microphone */
3801 dip->type = AUDIO_MIXER_VALUE;
3802 dip->mixer_class = GUSICS_INPUT_CLASS;
3803 dip->prev = AUDIO_MIXER_LAST;
3804 dip->next = GUSICS_MIC_IN_MUTE;
3805 strcpy(dip->label.name, AudioNmicrophone);
3806 dip->un.v.num_channels = 2;
3807 strcpy(dip->un.v.units.name, AudioNvolume);
3808 break;
3809
3810 case GUSICS_LINE_IN_LVL: /* line */
3811 dip->type = AUDIO_MIXER_VALUE;
3812 dip->mixer_class = GUSICS_INPUT_CLASS;
3813 dip->prev = AUDIO_MIXER_LAST;
3814 dip->next = GUSICS_LINE_IN_MUTE;
3815 strcpy(dip->label.name, AudioNline);
3816 dip->un.v.num_channels = 2;
3817 strcpy(dip->un.v.units.name, AudioNvolume);
3818 break;
3819
3820 case GUSICS_CD_LVL: /* cd */
3821 dip->type = AUDIO_MIXER_VALUE;
3822 dip->mixer_class = GUSICS_INPUT_CLASS;
3823 dip->prev = AUDIO_MIXER_LAST;
3824 dip->next = GUSICS_CD_MUTE;
3825 strcpy(dip->label.name, AudioNcd);
3826 dip->un.v.num_channels = 2;
3827 strcpy(dip->un.v.units.name, AudioNvolume);
3828 break;
3829
3830 case GUSICS_DAC_LVL: /* dacout */
3831 dip->type = AUDIO_MIXER_VALUE;
3832 dip->mixer_class = GUSICS_INPUT_CLASS;
3833 dip->prev = AUDIO_MIXER_LAST;
3834 dip->next = GUSICS_DAC_MUTE;
3835 strcpy(dip->label.name, AudioNdac);
3836 dip->un.v.num_channels = 2;
3837 strcpy(dip->un.v.units.name, AudioNvolume);
3838 break;
3839
3840 case GUSICS_MASTER_LVL: /* master output */
3841 dip->type = AUDIO_MIXER_VALUE;
3842 dip->mixer_class = GUSICS_OUTPUT_CLASS;
3843 dip->prev = AUDIO_MIXER_LAST;
3844 dip->next = GUSICS_MASTER_MUTE;
3845 strcpy(dip->label.name, AudioNmaster);
3846 dip->un.v.num_channels = 2;
3847 strcpy(dip->un.v.units.name, AudioNvolume);
3848 break;
3849
3850
3851 case GUSICS_LINE_IN_MUTE:
3852 dip->mixer_class = GUSICS_INPUT_CLASS;
3853 dip->type = AUDIO_MIXER_ENUM;
3854 dip->prev = GUSICS_LINE_IN_LVL;
3855 dip->next = AUDIO_MIXER_LAST;
3856 goto mute;
3857
3858 case GUSICS_DAC_MUTE:
3859 dip->mixer_class = GUSICS_INPUT_CLASS;
3860 dip->type = AUDIO_MIXER_ENUM;
3861 dip->prev = GUSICS_DAC_LVL;
3862 dip->next = AUDIO_MIXER_LAST;
3863 goto mute;
3864
3865 case GUSICS_CD_MUTE:
3866 dip->mixer_class = GUSICS_INPUT_CLASS;
3867 dip->type = AUDIO_MIXER_ENUM;
3868 dip->prev = GUSICS_CD_LVL;
3869 dip->next = AUDIO_MIXER_LAST;
3870 goto mute;
3871
3872 case GUSICS_MIC_IN_MUTE:
3873 dip->mixer_class = GUSICS_INPUT_CLASS;
3874 dip->type = AUDIO_MIXER_ENUM;
3875 dip->prev = GUSICS_MIC_IN_LVL;
3876 dip->next = AUDIO_MIXER_LAST;
3877 goto mute;
3878
3879 case GUSICS_MASTER_MUTE:
3880 dip->mixer_class = GUSICS_OUTPUT_CLASS;
3881 dip->type = AUDIO_MIXER_ENUM;
3882 dip->prev = GUSICS_MASTER_LVL;
3883 dip->next = AUDIO_MIXER_LAST;
3884 mute:
3885 strcpy(dip->label.name, AudioNmute);
3886 dip->un.e.num_mem = 2;
3887 strcpy(dip->un.e.member[0].label.name, AudioNoff);
3888 dip->un.e.member[0].ord = 0;
3889 strcpy(dip->un.e.member[1].label.name, AudioNon);
3890 dip->un.e.member[1].ord = 1;
3891 break;
3892
3893 case GUSICS_RECORD_SOURCE:
3894 dip->mixer_class = GUSICS_RECORD_CLASS;
3895 dip->type = AUDIO_MIXER_ENUM;
3896 dip->prev = dip->next = AUDIO_MIXER_LAST;
3897 strcpy(dip->label.name, AudioNsource);
3898 dip->un.e.num_mem = 1;
3899 strcpy(dip->un.e.member[0].label.name, AudioNoutput);
3900 dip->un.e.member[0].ord = GUSICS_MASTER_LVL;
3901 break;
3902
3903 case GUSICS_INPUT_CLASS:
3904 dip->type = AUDIO_MIXER_CLASS;
3905 dip->mixer_class = GUSICS_INPUT_CLASS;
3906 dip->next = dip->prev = AUDIO_MIXER_LAST;
3907 strcpy(dip->label.name, AudioCinputs);
3908 break;
3909
3910 case GUSICS_OUTPUT_CLASS:
3911 dip->type = AUDIO_MIXER_CLASS;
3912 dip->mixer_class = GUSICS_OUTPUT_CLASS;
3913 dip->next = dip->prev = AUDIO_MIXER_LAST;
3914 strcpy(dip->label.name, AudioCoutputs);
3915 break;
3916
3917 case GUSICS_RECORD_CLASS:
3918 dip->type = AUDIO_MIXER_CLASS;
3919 dip->mixer_class = GUSICS_RECORD_CLASS;
3920 dip->next = dip->prev = AUDIO_MIXER_LAST;
3921 strcpy(dip->label.name, AudioCrecord);
3922 break;
3923
3924 default:
3925 return ENXIO;
3926 /*NOTREACHED*/
3927 }
3928 DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name));
3929 return 0;
3930 }
3931
3932 STATIC int
3933 gus_query_encoding(addr, fp)
3934 void *addr;
3935 struct audio_encoding *fp;
3936 {
3937 switch (fp->index) {
3938 case 0:
3939 strcpy(fp->name, AudioEmulaw);
3940 fp->encoding = AUDIO_ENCODING_ULAW;
3941 fp->precision = 8;
3942 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
3943 break;
3944 case 1:
3945 strcpy(fp->name, AudioEslinear);
3946 fp->encoding = AUDIO_ENCODING_SLINEAR;
3947 fp->precision = 8;
3948 fp->flags = 0;
3949 break;
3950 case 2:
3951 strcpy(fp->name, AudioEslinear_le);
3952 fp->encoding = AUDIO_ENCODING_SLINEAR_LE;
3953 fp->precision = 16;
3954 fp->flags = 0;
3955 break;
3956 case 3:
3957 strcpy(fp->name, AudioEulinear);
3958 fp->encoding = AUDIO_ENCODING_ULINEAR;
3959 fp->precision = 8;
3960 fp->flags = 0;
3961 break;
3962 case 4:
3963 strcpy(fp->name, AudioEulinear_le);
3964 fp->encoding = AUDIO_ENCODING_ULINEAR_LE;
3965 fp->precision = 16;
3966 fp->flags = 0;
3967 break;
3968 case 5:
3969 strcpy(fp->name, AudioEslinear_be);
3970 fp->encoding = AUDIO_ENCODING_SLINEAR_BE;
3971 fp->precision = 16;
3972 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
3973 break;
3974 case 6:
3975 strcpy(fp->name, AudioEulinear_be);
3976 fp->encoding = AUDIO_ENCODING_ULINEAR_BE;
3977 fp->precision = 16;
3978 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
3979 break;
3980 case 7:
3981 strcpy(fp->name, AudioEalaw);
3982 fp->encoding = AUDIO_ENCODING_ALAW;
3983 fp->precision = 8;
3984 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
3985 break;
3986
3987 default:
3988 return(EINVAL);
3989 /*NOTREACHED*/
3990 }
3991 return (0);
3992 }
3993
3994 /*
3995 * Setup the ICS mixer in "transparent" mode: reset everything to a sensible
3996 * level. Levels as suggested by GUS SDK code.
3997 */
3998
3999 STATIC void
4000 gus_init_ics2101(sc)
4001 struct gus_softc *sc;
4002 {
4003 struct ics2101_softc *ic = &sc->sc_mixer;
4004 sc->sc_mixer.sc_iot = sc->sc_iot;
4005 sc->sc_mixer.sc_selio = GUS_MIXER_SELECT;
4006 sc->sc_mixer.sc_selio_ioh = sc->sc_ioh3;
4007 sc->sc_mixer.sc_dataio = GUS_MIXER_DATA;
4008 sc->sc_mixer.sc_dataio_ioh = sc->sc_ioh2;
4009 sc->sc_mixer.sc_flags = (sc->sc_revision == 5) ? ICS_FLIP : 0;
4010
4011 ics2101_mix_attenuate(ic,
4012 GUSMIX_CHAN_MIC,
4013 ICSMIX_LEFT,
4014 ICSMIX_MIN_ATTN);
4015 ics2101_mix_attenuate(ic,
4016 GUSMIX_CHAN_MIC,
4017 ICSMIX_RIGHT,
4018 ICSMIX_MIN_ATTN);
4019 /*
4020 * Start with microphone muted by the mixer...
4021 */
4022 gusics_mic_mute(ic, 1);
4023
4024 /* ... and enabled by the GUS master mix control */
4025 gus_mic_ctl(sc, SPKR_ON);
4026
4027 ics2101_mix_attenuate(ic,
4028 GUSMIX_CHAN_LINE,
4029 ICSMIX_LEFT,
4030 ICSMIX_MIN_ATTN);
4031 ics2101_mix_attenuate(ic,
4032 GUSMIX_CHAN_LINE,
4033 ICSMIX_RIGHT,
4034 ICSMIX_MIN_ATTN);
4035
4036 ics2101_mix_attenuate(ic,
4037 GUSMIX_CHAN_CD,
4038 ICSMIX_LEFT,
4039 ICSMIX_MIN_ATTN);
4040 ics2101_mix_attenuate(ic,
4041 GUSMIX_CHAN_CD,
4042 ICSMIX_RIGHT,
4043 ICSMIX_MIN_ATTN);
4044
4045 ics2101_mix_attenuate(ic,
4046 GUSMIX_CHAN_DAC,
4047 ICSMIX_LEFT,
4048 ICSMIX_MIN_ATTN);
4049 ics2101_mix_attenuate(ic,
4050 GUSMIX_CHAN_DAC,
4051 ICSMIX_RIGHT,
4052 ICSMIX_MIN_ATTN);
4053
4054 ics2101_mix_attenuate(ic,
4055 ICSMIX_CHAN_4,
4056 ICSMIX_LEFT,
4057 ICSMIX_MAX_ATTN);
4058 ics2101_mix_attenuate(ic,
4059 ICSMIX_CHAN_4,
4060 ICSMIX_RIGHT,
4061 ICSMIX_MAX_ATTN);
4062
4063 ics2101_mix_attenuate(ic,
4064 GUSMIX_CHAN_MASTER,
4065 ICSMIX_LEFT,
4066 ICSMIX_MIN_ATTN);
4067 ics2101_mix_attenuate(ic,
4068 GUSMIX_CHAN_MASTER,
4069 ICSMIX_RIGHT,
4070 ICSMIX_MIN_ATTN);
4071 /* unmute other stuff: */
4072 gusics_cd_mute(ic, 0);
4073 gusics_dac_mute(ic, 0);
4074 gusics_linein_mute(ic, 0);
4075 return;
4076 }
4077
4078
4079 #endif /* NGUS */
4080