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