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