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