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