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