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