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