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