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