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