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