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