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