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