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