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