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