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