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