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