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