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