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