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