gus.c revision 1.32 1 /* $NetBSD: gus.c,v 1.32 1997/07/15 07:46:16 augustss 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/bus.h>
115 #include <machine/pio.h>
116 #include <machine/cpufunc.h>
117 #include <sys/audioio.h>
118 #include <dev/audio_if.h>
119 #include <dev/mulaw.h>
120
121 #include <dev/isa/isavar.h>
122 #include <dev/isa/isadmavar.h>
123 #include <i386/isa/icu.h>
124
125 #include <dev/ic/ics2101reg.h>
126 #include <dev/ic/cs4231reg.h>
127 #include <dev/ic/ad1848reg.h>
128 #include <dev/isa/ics2101var.h>
129 #include <dev/isa/ad1848var.h>
130 #include <dev/isa/cs4231var.h>
131 #include "gusreg.h"
132
133 #ifdef AUDIO_DEBUG
134 #define STATIC /* empty; for debugging symbols */
135 #else
136 #define STATIC static
137 #endif
138
139 /*
140 * Software state of a single "voice" on the GUS
141 */
142
143 struct gus_voice {
144
145 /*
146 * Various control bits
147 */
148
149 unsigned char voccntl; /* State of voice control register */
150 unsigned char volcntl; /* State of volume control register */
151 unsigned char pan_pos; /* Position of volume panning (4 bits) */
152 int rate; /* Sample rate of voice being played back */
153
154 /*
155 * Address of the voice data into the GUS's DRAM. 20 bits each
156 */
157
158 u_long start_addr; /* Starting address of voice data loop area */
159 u_long end_addr; /* Ending address of voice data loop */
160 u_long current_addr; /* Beginning address of voice data
161 (start playing here) */
162
163 /*
164 * linear volume values for the GUS's volume ramp. 0-511 (9 bits).
165 * These values must be translated into the logarithmic values using
166 * gus_log_volumes[]
167 */
168
169 int start_volume; /* Starting position of volume ramp */
170 int current_volume; /* Current position of volume on volume ramp */
171 int end_volume; /* Ending position of volume on volume ramp */
172 };
173
174 /*
175 * Software state of GUS
176 */
177
178 struct gus_softc {
179 struct device sc_dev; /* base device */
180 struct isadev sc_id; /* ISA device */
181 void *sc_ih; /* interrupt vector */
182 bus_space_tag_t sc_iot; /* tag */
183 bus_space_handle_t sc_ioh; /* handle */
184
185 int sc_iobase; /* I/O base address */
186 int sc_irq; /* IRQ used */
187 int sc_drq; /* DMA channel for play */
188 int sc_recdrq; /* DMA channel for recording */
189
190 int sc_flags; /* Various flags about the GUS */
191 #define GUS_MIXER_INSTALLED 0x01 /* An ICS mixer is installed */
192 #define GUS_LOCKED 0x02 /* GUS is busy doing multi-phase DMA */
193 #define GUS_CODEC_INSTALLED 0x04 /* CS4231 installed/MAX */
194 #define GUS_PLAYING 0x08 /* GUS is playing a voice */
195 #define GUS_DMAOUT_ACTIVE 0x10 /* GUS is busy doing audio DMA */
196 #define GUS_DMAIN_ACTIVE 0x20 /* GUS is busy sampling */
197 #define GUS_OPEN 0x100 /* GUS is open */
198 int sc_dsize; /* Size of GUS DRAM */
199 int sc_voices; /* Number of active voices */
200 u_char sc_revision; /* Board revision of GUS */
201 u_char sc_mixcontrol; /* Value of GUS_MIX_CONTROL register */
202
203 u_long sc_orate; /* Output sampling rate */
204 u_long sc_irate; /* Input sampling rate */
205
206 int sc_encoding; /* Current data encoding type */
207 int sc_precision; /* # of bits of precision */
208 int sc_channels; /* Number of active channels */
209 int sc_blocksize; /* Current blocksize */
210 int sc_chanblocksize; /* Current blocksize for each in-use
211 channel */
212 short sc_nbufs; /* how many on-GUS bufs per-channel */
213 short sc_bufcnt; /* how many need to be played */
214 void *sc_deintr_buf; /* deinterleave buffer for stereo */
215
216 int sc_ogain; /* Output gain control */
217 u_char sc_out_port; /* Current out port (generic only) */
218 u_char sc_in_port; /* keep track of it when no codec */
219
220 void (*sc_dmaoutintr) __P((void*)); /* DMA completion intr handler */
221 void *sc_outarg; /* argument for sc_dmaoutintr() */
222 u_char *sc_dmaoutaddr; /* for isa_dmadone */
223 u_long sc_gusaddr; /* where did we just put it? */
224 int sc_dmaoutcnt; /* for isa_dmadone */
225
226 void (*sc_dmainintr) __P((void*)); /* DMA completion intr handler */
227 void *sc_inarg; /* argument for sc_dmaoutintr() */
228 u_char *sc_dmainaddr; /* for isa_dmadone */
229 int sc_dmaincnt; /* for isa_dmadone */
230
231 struct stereo_dma_intr {
232 void (*intr)__P((void *));
233 void *arg;
234 u_char *buffer;
235 u_long dmabuf;
236 int size;
237 int flags;
238 } sc_stereo;
239
240 /*
241 * State information for linear audio layer
242 */
243
244 int sc_dmabuf; /* Which ring buffer we're DMA'ing to */
245 int sc_playbuf; /* Which ring buffer we're playing */
246
247 /*
248 * Voice information array. All voice-specific information is stored
249 * here
250 */
251
252 struct gus_voice sc_voc[32]; /* Voice data for each voice */
253 union {
254 struct ics2101_softc sc_mixer_u;
255 struct ad1848_softc sc_codec_u;
256 } u;
257 #define sc_mixer u.sc_mixer_u
258 #define sc_codec u.sc_codec_u
259 };
260
261 struct ics2101_volume {
262 u_char left;
263 u_char right;
264 };
265
266 #define HAS_CODEC(sc) ((sc)->sc_flags & GUS_CODEC_INSTALLED)
267 #define HAS_MIXER(sc) ((sc)->sc_flags & GUS_MIXER_INSTALLED)
268
269 /*
270 * Mixer devices for ICS2101
271 */
272 /* MIC IN mute, line in mute, line out mute are first since they can be done
273 even if no ICS mixer. */
274 #define GUSICS_MIC_IN_MUTE 0
275 #define GUSICS_LINE_IN_MUTE 1
276 #define GUSICS_MASTER_MUTE 2
277 #define GUSICS_CD_MUTE 3
278 #define GUSICS_DAC_MUTE 4
279 #define GUSICS_MIC_IN_LVL 5
280 #define GUSICS_LINE_IN_LVL 6
281 #define GUSICS_CD_LVL 7
282 #define GUSICS_DAC_LVL 8
283 #define GUSICS_MASTER_LVL 9
284
285 #define GUSICS_RECORD_SOURCE 10
286
287 /* Classes */
288 #define GUSICS_INPUT_CLASS 11
289 #define GUSICS_OUTPUT_CLASS 12
290 #define GUSICS_RECORD_CLASS 13
291
292 /*
293 * Mixer & MUX devices for CS4231
294 */
295 #define GUSMAX_MONO_LVL 0 /* mic input to MUX;
296 also mono mixer input */
297 #define GUSMAX_DAC_LVL 1 /* input to MUX; also mixer input */
298 #define GUSMAX_LINE_IN_LVL 2 /* input to MUX; also mixer input */
299 #define GUSMAX_CD_LVL 3 /* mixer input only */
300 #define GUSMAX_MONITOR_LVL 4 /* digital mix (?) */
301 #define GUSMAX_OUT_LVL 5 /* output level. (?) */
302 #define GUSMAX_SPEAKER_LVL 6 /* pseudo-device for mute */
303 #define GUSMAX_LINE_IN_MUTE 7 /* pre-mixer */
304 #define GUSMAX_DAC_MUTE 8 /* pre-mixer */
305 #define GUSMAX_CD_MUTE 9 /* pre-mixer */
306 #define GUSMAX_MONO_MUTE 10 /* pre-mixer--microphone/mono */
307 #define GUSMAX_MONITOR_MUTE 11 /* post-mixer level/mute */
308 #define GUSMAX_SPEAKER_MUTE 12 /* speaker mute */
309
310 #define GUSMAX_REC_LVL 13 /* post-MUX gain */
311
312 #define GUSMAX_RECORD_SOURCE 14
313
314 /* Classes */
315 #define GUSMAX_INPUT_CLASS 15
316 #define GUSMAX_RECORD_CLASS 16
317 #define GUSMAX_MONITOR_CLASS 17
318 #define GUSMAX_OUTPUT_CLASS 18
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 /* XXX WILL THIS ALWAYS WORK THE WAY THEY'RE OVERLAYED?! */
845 sc->sc_codec.sc_isa = sc->sc_dev.dv_parent;
846
847 if (sc->sc_revision >= 5 && sc->sc_revision <= 9) {
848 sc->sc_flags |= GUS_MIXER_INSTALLED;
849 gus_init_ics2101(sc);
850 }
851 if (sc->sc_revision >= 0xa) {
852 gus_init_cs4231(sc);
853 }
854
855 SELECT_GUS_REG(port, GUSREG_RESET);
856 /*
857 * Check to see how much memory we have on this card; see if any
858 * "mirroring" occurs. We're assuming at least 256K already exists
859 * on the card; otherwise the initial probe would have failed
860 */
861
862 guspoke(port, 0L, 0x00);
863 for(i = 1; i < 1024; i++) {
864 u_long loc;
865
866 /*
867 * See if we've run into mirroring yet
868 */
869
870 if (guspeek(port, 0L) != 0)
871 break;
872
873 loc = i << 10;
874
875 guspoke(port, loc, 0xaa);
876 if (guspeek(port, loc) != 0xaa)
877 break;
878 }
879
880 sc->sc_dsize = i;
881 sprintf(gus_device.version, "3.%d", sc->sc_revision);
882
883 printf("\n <Gravis UltraSound version 3.%d, %dKB DRAM, ",
884 sc->sc_revision, sc->sc_dsize);
885 if (HAS_MIXER(sc))
886 printf("ICS2101 mixer, ");
887 if (HAS_CODEC(sc))
888 printf("%s codec/mixer, ", sc->sc_codec.chip_name);
889 if (sc->sc_recdrq == sc->sc_drq) {
890 printf("half-duplex");
891 gus_hw_if.full_duplex = 0;
892 } else {
893 printf("full-duplex, record drq %d", sc->sc_recdrq);
894 gus_hw_if.full_duplex = 1;
895 }
896
897 printf(">\n");
898
899 /*
900 * Setup a default interrupt handler
901 */
902
903 /* XXX we shouldn't have to use splgus == splclock, nor should
904 * we use IPL_CLOCK.
905 */
906 sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq, IST_EDGE,
907 IPL_AUDIO, gusintr, sc /* sc->sc_gusdsp */);
908
909 /*
910 * Set some default values
911 */
912
913 sc->sc_irate = sc->sc_orate = 44100;
914 sc->sc_encoding = AUDIO_ENCODING_SLINEAR_LE;
915 sc->sc_precision = 16;
916 sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_DATA_SIZE16;
917 sc->sc_voc[GUS_VOICE_RIGHT].voccntl |= GUSMASK_DATA_SIZE16;
918 sc->sc_channels = 1;
919 sc->sc_ogain = 340;
920 gus_commit_settings(sc);
921
922 /*
923 * We always put the left channel full left & right channel
924 * full right.
925 * For mono playback, we set up both voices playing the same buffer.
926 */
927 outb(sc->sc_iobase+GUS_VOICE_SELECT, (unsigned char) GUS_VOICE_LEFT);
928 SELECT_GUS_REG(sc->sc_iobase, GUSREG_PAN_POS);
929 outb(sc->sc_iobase+GUS_DATA_HIGH, GUS_PAN_FULL_LEFT);
930
931 outb(sc->sc_iobase+GUS_VOICE_SELECT, (unsigned char) GUS_VOICE_RIGHT);
932 SELECT_GUS_REG(sc->sc_iobase, GUSREG_PAN_POS);
933 outb(sc->sc_iobase+GUS_DATA_HIGH, GUS_PAN_FULL_RIGHT);
934
935 /*
936 * Attach to the generic audio layer
937 */
938
939 if (audio_hardware_attach(&gus_hw_if, HAS_CODEC(sc) ? (void *)&sc->sc_codec : (void *)sc) != 0)
940 printf("gus: could not attach to audio pseudo-device driver\n");
941 }
942
943 int
944 gusopen(dev, flags)
945 dev_t dev;
946 int flags;
947 {
948 int unit = AUDIOUNIT(dev);
949 struct gus_softc *sc;
950
951 DPRINTF(("gusopen() called\n"));
952
953 if (unit >= gus_cd.cd_ndevs)
954 return ENXIO;
955 sc = gus_cd.cd_devs[unit];
956 if (!sc)
957 return ENXIO;
958
959 if (sc->sc_flags & GUS_OPEN)
960 return EBUSY;
961
962 /*
963 * Some initialization
964 */
965
966 sc->sc_flags |= GUS_OPEN;
967 sc->sc_dmabuf = 0;
968 sc->sc_playbuf = -1;
969 sc->sc_bufcnt = 0;
970 sc->sc_voc[GUS_VOICE_LEFT].start_addr = GUS_MEM_OFFSET - 1;
971 sc->sc_voc[GUS_VOICE_LEFT].current_addr = GUS_MEM_OFFSET;
972
973 if (HAS_CODEC(sc)) {
974 ad1848_open(&sc->sc_codec, dev, flags);
975 sc->sc_codec.aux1_mute = 0;
976 ad1848_mute_aux1(&sc->sc_codec, 0); /* turn on DAC output */
977 if (flags & FREAD) {
978 sc->sc_codec.mono_mute = 0;
979 cs4231_mute_mono(&sc->sc_codec, 0);
980 }
981 } else if (flags & FREAD) {
982 /* enable/unmute the microphone */
983 if (HAS_MIXER(sc)) {
984 gusics_mic_mute(&sc->sc_mixer, 0);
985 } else
986 gus_mic_ctl(sc, SPKR_ON);
987 }
988 if (sc->sc_nbufs == 0)
989 gus_round_blocksize(sc, GUS_BUFFER_MULTIPLE); /* default blksiz */
990 return 0;
991 }
992
993 STATIC void
994 gus_deinterleave(sc, buf, size)
995 register struct gus_softc *sc;
996 void *buf;
997 int size;
998 {
999 /* deinterleave the stereo data. We can use sc->sc_deintr_buf
1000 for scratch space. */
1001 register int i;
1002
1003 if (size > sc->sc_blocksize) {
1004 printf("gus: deinterleave %d > %d\n", size, sc->sc_blocksize);
1005 return;
1006 } else if (size < sc->sc_blocksize) {
1007 DPRINTF(("gus: deinterleave %d < %d\n", size, sc->sc_blocksize));
1008 }
1009
1010 /*
1011 * size is in bytes.
1012 */
1013 if (sc->sc_precision == 16) {
1014 register u_short *dei = sc->sc_deintr_buf;
1015 register u_short *sbuf = buf;
1016 size >>= 1; /* bytecnt to shortcnt */
1017 /* copy 2nd of each pair of samples to the staging area, while
1018 compacting the 1st of each pair into the original area. */
1019 for (i = 0; i < size/2-1; i++) {
1020 dei[i] = sbuf[i*2+1];
1021 sbuf[i+1] = sbuf[i*2+2];
1022 }
1023 /*
1024 * this has copied one less sample than half of the
1025 * buffer. The first sample of the 1st stream was
1026 * already in place and didn't need copying.
1027 * Therefore, we've moved all of the 1st stream's
1028 * samples into place. We have one sample from 2nd
1029 * stream in the last slot of original area, not
1030 * copied to the staging area (But we don't need to!).
1031 * Copy the remainder of the original stream into place.
1032 */
1033 bcopy(dei, &sbuf[size/2], i * sizeof(short));
1034 } else {
1035 register u_char *dei = sc->sc_deintr_buf;
1036 register u_char *sbuf = buf;
1037 for (i = 0; i < size/2-1; i++) {
1038 dei[i] = sbuf[i*2+1];
1039 sbuf[i+1] = sbuf[i*2+2];
1040 }
1041 bcopy(dei, &sbuf[size/2], i);
1042 }
1043 }
1044
1045 /*
1046 * Actually output a buffer to the DSP chip
1047 */
1048
1049 int
1050 gusmax_dma_output(addr, buf, size, intr, arg)
1051 void * addr;
1052 void *buf;
1053 int size;
1054 void (*intr) __P((void *));
1055 void *arg;
1056 {
1057 register struct ad1848_softc *ac = addr;
1058 return gus_dma_output(ac->parent, buf, size, intr, arg);
1059 }
1060
1061 /*
1062 * called at splgus() from interrupt handler.
1063 */
1064 void
1065 stereo_dmaintr(arg)
1066 void *arg;
1067 {
1068 struct gus_softc *sc = arg;
1069 struct stereo_dma_intr *sa = &sc->sc_stereo;
1070
1071 DMAPRINTF(("stereo_dmaintr"));
1072
1073 /*
1074 * Put other half in its place, then call the real interrupt routine :)
1075 */
1076
1077 sc->sc_dmaoutintr = sa->intr;
1078 sc->sc_outarg = sa->arg;
1079
1080 #ifdef GUSPLAYDEBUG
1081 if (gusstats) {
1082 microtime(&dmarecords[dmarecord_index].tv);
1083 dmarecords[dmarecord_index].gusaddr = sa->dmabuf;
1084 dmarecords[dmarecord_index].bsdaddr = sa->buffer;
1085 dmarecords[dmarecord_index].count = sa->size;
1086 dmarecords[dmarecord_index].channel = 1;
1087 dmarecords[dmarecord_index].direction = 1;
1088 dmarecord_index = ++dmarecord_index % NDMARECS;
1089 }
1090 #endif
1091
1092 gusdmaout(sc, sa->flags, sa->dmabuf, (caddr_t) sa->buffer, sa->size);
1093
1094 sa->flags = 0;
1095 sa->dmabuf = 0;
1096 sa->buffer = 0;
1097 sa->size = 0;
1098 sa->intr = 0;
1099 sa->arg = 0;
1100 }
1101
1102 /*
1103 * Start up DMA output to the card.
1104 * Called at splgus/splaudio already, either from intr handler or from
1105 * generic audio code.
1106 */
1107 int
1108 gus_dma_output(addr, buf, size, intr, arg)
1109 void * addr;
1110 void *buf;
1111 int size;
1112 void (*intr) __P((void *));
1113 void *arg;
1114 {
1115 struct gus_softc *sc = addr;
1116 u_char *buffer = buf;
1117 u_long boarddma;
1118 int flags;
1119
1120 DMAPRINTF(("gus_dma_output %d @ %x\n", size, buf));
1121
1122 if (size != sc->sc_blocksize) {
1123 DPRINTF(("gus_dma_output reqsize %d not sc_blocksize %d\n",
1124 size, sc->sc_blocksize));
1125 return EINVAL;
1126 }
1127
1128 flags = GUSMASK_DMA_WRITE;
1129 if (sc->sc_precision == 16)
1130 flags |= GUSMASK_DMA_DATA_SIZE;
1131 if (sc->sc_encoding == AUDIO_ENCODING_ULAW ||
1132 sc->sc_encoding == AUDIO_ENCODING_ULINEAR_BE ||
1133 sc->sc_encoding == AUDIO_ENCODING_ULINEAR_LE)
1134 flags |= GUSMASK_DMA_INVBIT;
1135
1136 if (sc->sc_channels == 2) {
1137 if (sc->sc_precision == 16) {
1138 if (size & 3) {
1139 DPRINTF(("gus_dma_output: unpaired 16bit samples"));
1140 size &= 3;
1141 }
1142 } else if (size & 1) {
1143 DPRINTF(("gus_dma_output: unpaired samples"));
1144 size &= 1;
1145 }
1146 if (size == 0)
1147 return 0;
1148
1149 gus_deinterleave(sc, (void *)buffer, size);
1150
1151 size >>= 1;
1152
1153 boarddma = size * sc->sc_dmabuf + GUS_MEM_OFFSET;
1154
1155 sc->sc_stereo.intr = intr;
1156 sc->sc_stereo.arg = arg;
1157 sc->sc_stereo.size = size;
1158 sc->sc_stereo.dmabuf = boarddma + GUS_LEFT_RIGHT_OFFSET;
1159 sc->sc_stereo.buffer = buffer + size;
1160 sc->sc_stereo.flags = flags;
1161 if (gus_dostereo) {
1162 intr = stereo_dmaintr;
1163 arg = sc;
1164 }
1165 } else
1166 boarddma = size * sc->sc_dmabuf + GUS_MEM_OFFSET;
1167
1168
1169 sc->sc_flags |= GUS_LOCKED;
1170 sc->sc_dmaoutintr = intr;
1171 sc->sc_outarg = arg;
1172
1173 #ifdef GUSPLAYDEBUG
1174 if (gusstats) {
1175 microtime(&dmarecords[dmarecord_index].tv);
1176 dmarecords[dmarecord_index].gusaddr = boarddma;
1177 dmarecords[dmarecord_index].bsdaddr = buffer;
1178 dmarecords[dmarecord_index].count = size;
1179 dmarecords[dmarecord_index].channel = 0;
1180 dmarecords[dmarecord_index].direction = 1;
1181 dmarecord_index = ++dmarecord_index % NDMARECS;
1182 }
1183 #endif
1184
1185 gusdmaout(sc, flags, boarddma, (caddr_t) buffer, size);
1186
1187 return 0;
1188 }
1189
1190 void
1191 gusmax_close(addr)
1192 void *addr;
1193 {
1194 register struct ad1848_softc *ac = addr;
1195 register struct gus_softc *sc = ac->parent;
1196 #if 0
1197 ac->aux1_mute = 1;
1198 ad1848_mute_aux1(ac, 1); /* turn off DAC output */
1199 #endif
1200 ad1848_close(ac);
1201 gusclose(sc);
1202 }
1203
1204 /*
1205 * Close out device stuff. Called at splgus() from generic audio layer.
1206 */
1207 void
1208 gusclose(addr)
1209 void *addr;
1210 {
1211 struct gus_softc *sc = addr;
1212
1213 DPRINTF(("gus_close: sc=0x%x\n", sc));
1214
1215
1216 /* if (sc->sc_flags & GUS_DMAOUT_ACTIVE) */ {
1217 gus_halt_out_dma(sc);
1218 }
1219 /* if (sc->sc_flags & GUS_DMAIN_ACTIVE) */ {
1220 gus_halt_in_dma(sc);
1221 }
1222 sc->sc_flags &= ~(GUS_OPEN|GUS_LOCKED|GUS_DMAOUT_ACTIVE|GUS_DMAIN_ACTIVE);
1223
1224 if (sc->sc_deintr_buf) {
1225 FREE(sc->sc_deintr_buf, M_DEVBUF);
1226 sc->sc_deintr_buf = NULL;
1227 }
1228 /* turn off speaker, etc. */
1229
1230 /* make sure the voices shut up: */
1231 gus_stop_voice(sc, GUS_VOICE_LEFT, 1);
1232 gus_stop_voice(sc, GUS_VOICE_RIGHT, 0);
1233 }
1234
1235 /*
1236 * Service interrupts. Farm them off to helper routines if we are using the
1237 * GUS for simple playback/record
1238 */
1239
1240 #ifdef DIAGNOSTIC
1241 int gusintrcnt;
1242 int gusdmaintrcnt;
1243 int gusvocintrcnt;
1244 #endif
1245
1246 int
1247 gusintr(arg)
1248 void *arg;
1249 {
1250 register struct gus_softc *sc = arg;
1251 unsigned char intr;
1252 register int port = sc->sc_iobase;
1253 int retval = 0;
1254
1255 DPRINTF(("gusintr\n"));
1256 #ifdef DIAGNOSTIC
1257 gusintrcnt++;
1258 #endif
1259 if (HAS_CODEC(sc))
1260 retval = ad1848_intr(&sc->sc_codec);
1261 if ((intr = inb(port+GUS_IRQ_STATUS)) & GUSMASK_IRQ_DMATC) {
1262 DMAPRINTF(("gusintr dma flags=%x\n", sc->sc_flags));
1263 #ifdef DIAGNOSTIC
1264 gusdmaintrcnt++;
1265 #endif
1266 retval += gus_dmaout_intr(sc);
1267 if (sc->sc_flags & GUS_DMAIN_ACTIVE) {
1268 SELECT_GUS_REG(port, GUSREG_SAMPLE_CONTROL);
1269 intr = inb(port+GUS_DATA_HIGH);
1270 if (intr & GUSMASK_SAMPLE_DMATC) {
1271 retval += gus_dmain_intr(sc);
1272 }
1273 }
1274 }
1275 if (intr & (GUSMASK_IRQ_VOICE | GUSMASK_IRQ_VOLUME)) {
1276 DMAPRINTF(("gusintr voice flags=%x\n", sc->sc_flags));
1277 #ifdef DIAGNOSTIC
1278 gusvocintrcnt++;
1279 #endif
1280 retval += gus_voice_intr(sc);
1281 }
1282 if (retval)
1283 return 1;
1284 return retval;
1285 }
1286
1287 int gus_bufcnt[GUS_MEM_FOR_BUFFERS / GUS_BUFFER_MULTIPLE];
1288 int gus_restart; /* how many restarts? */
1289 int gus_stops; /* how many times did voice stop? */
1290 int gus_falsestops; /* stopped but not done? */
1291 int gus_continues;
1292
1293 struct playcont {
1294 struct timeval tv;
1295 u_int playbuf;
1296 u_int dmabuf;
1297 u_char bufcnt;
1298 u_char vaction;
1299 u_char voccntl;
1300 u_char volcntl;
1301 u_long curaddr;
1302 u_long endaddr;
1303 } playstats[NDMARECS];
1304
1305 int playcntr;
1306
1307 STATIC void
1308 gus_dmaout_timeout(arg)
1309 void *arg;
1310 {
1311 register struct gus_softc *sc = arg;
1312 register int port = sc->sc_iobase;
1313 int s;
1314
1315 printf("%s: dmaout timeout\n", sc->sc_dev.dv_xname);
1316 /*
1317 * Stop any DMA.
1318 */
1319
1320 s = splgus();
1321 SELECT_GUS_REG(port, GUSREG_DMA_CONTROL);
1322 outb(sc->sc_iobase+GUS_DATA_HIGH, 0);
1323
1324 #if 0
1325 /* XXX we will dmadone below? */
1326 isa_dmaabort(sc->sc_dev.dv_parent, sc->sc_drq);
1327 #endif
1328
1329 gus_dmaout_dointr(sc);
1330 splx(s);
1331 }
1332
1333
1334 /*
1335 * Service DMA interrupts. This routine will only get called if we're doing
1336 * a DMA transfer for playback/record requests from the audio layer.
1337 */
1338
1339 STATIC int
1340 gus_dmaout_intr(sc)
1341 struct gus_softc *sc;
1342 {
1343 register int port = sc->sc_iobase;
1344
1345 /*
1346 * If we got a DMA transfer complete from the GUS DRAM, then deal
1347 * with it.
1348 */
1349
1350 SELECT_GUS_REG(port, GUSREG_DMA_CONTROL);
1351 if (inb(port+GUS_DATA_HIGH) & GUSMASK_DMA_IRQPEND) {
1352 untimeout(gus_dmaout_timeout, sc);
1353 gus_dmaout_dointr(sc);
1354 return 1;
1355 }
1356 return 0;
1357 }
1358
1359 STATIC void
1360 gus_dmaout_dointr(sc)
1361 struct gus_softc *sc;
1362 {
1363 register int port = sc->sc_iobase;
1364
1365 /* sc->sc_dmaoutcnt - 1 because DMA controller counts from zero?. */
1366 isa_dmadone(sc->sc_dev.dv_parent, 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_SLINEAR_LE:
1382 case AUDIO_ENCODING_SLINEAR_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(sc->sc_dev.dv_parent, sc->sc_drq, buffaddr, length,
1882 NULL, DMAMODE_WRITE, BUS_DMA_NOWAIT);
1883
1884 /*
1885 * Set up DMA address - use the upper 16 bits ONLY
1886 */
1887
1888 sc->sc_flags |= GUS_DMAOUT_ACTIVE;
1889
1890 SELECT_GUS_REG(port, GUSREG_DMA_START);
1891 outw(port+GUS_DATA_LOW, (int) (gusaddr >> 4));
1892
1893 /*
1894 * Tell the GUS to start doing DMA
1895 */
1896
1897 SELECT_GUS_REG(port, GUSREG_DMA_CONTROL);
1898 outb(port+GUS_DATA_HIGH, c);
1899
1900 /*
1901 * XXX If we don't finish in one second, give up...
1902 */
1903 untimeout(gus_dmaout_timeout, sc); /* flush old one, if there is one */
1904 timeout(gus_dmaout_timeout, sc, hz);
1905 }
1906
1907 /*
1908 * Start a voice playing on the GUS. Called from interrupt handler at
1909 * splgus().
1910 */
1911
1912 STATIC void
1913 gus_start_voice(sc, voice, intrs)
1914 struct gus_softc *sc;
1915 int voice;
1916 int intrs;
1917 {
1918 register int port = sc->sc_iobase;
1919 u_long start;
1920 u_long current;
1921 u_long end;
1922
1923 /*
1924 * Pick all the values for the voice out of the gus_voice struct
1925 * and use those to program the voice
1926 */
1927
1928 start = sc->sc_voc[voice].start_addr;
1929 current = sc->sc_voc[voice].current_addr;
1930 end = sc->sc_voc[voice].end_addr;
1931
1932 /*
1933 * If we're using 16 bit data, mangle the addresses a bit
1934 */
1935
1936 if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16) {
1937 /* -1 on start so that we get onto sample boundary--other
1938 code always sets it for 1-byte rollover protection */
1939 start = convert_to_16bit(start-1);
1940 current = convert_to_16bit(current);
1941 end = convert_to_16bit(end);
1942 }
1943
1944 /*
1945 * Select the voice we want to use, and program the data addresses
1946 */
1947
1948 outb(port+GUS_VOICE_SELECT, (unsigned char) voice);
1949
1950 SELECT_GUS_REG(port, GUSREG_START_ADDR_HIGH);
1951 outw(port+GUS_DATA_LOW, ADDR_HIGH(start));
1952 SELECT_GUS_REG(port, GUSREG_START_ADDR_LOW);
1953 outw(port+GUS_DATA_LOW, ADDR_LOW(start));
1954
1955 SELECT_GUS_REG(port, GUSREG_CUR_ADDR_HIGH);
1956 outw(port+GUS_DATA_LOW, ADDR_HIGH(current));
1957 SELECT_GUS_REG(port, GUSREG_CUR_ADDR_LOW);
1958 outw(port+GUS_DATA_LOW, ADDR_LOW(current));
1959
1960 SELECT_GUS_REG(port, GUSREG_END_ADDR_HIGH);
1961 outw(port+GUS_DATA_LOW, ADDR_HIGH(end));
1962 SELECT_GUS_REG(port, GUSREG_END_ADDR_LOW);
1963 outw(port+GUS_DATA_LOW, ADDR_LOW(end));
1964
1965 /*
1966 * (maybe) enable interrupts, disable voice stopping
1967 */
1968
1969 if (intrs) {
1970 sc->sc_flags |= GUS_PLAYING; /* playing is about to start */
1971 sc->sc_voc[voice].voccntl |= GUSMASK_VOICE_IRQ;
1972 DMAPRINTF(("gus voice playing=%x\n", sc->sc_flags));
1973 } else
1974 sc->sc_voc[voice].voccntl &= ~GUSMASK_VOICE_IRQ;
1975 sc->sc_voc[voice].voccntl &= ~(GUSMASK_VOICE_STOPPED |
1976 GUSMASK_STOP_VOICE);
1977
1978 /*
1979 * Tell the GUS about it. Note that we're doing volume ramping here
1980 * from 0 up to the set volume to help reduce clicks.
1981 */
1982
1983 SELECT_GUS_REG(port, GUSREG_START_VOLUME);
1984 outb(port+GUS_DATA_HIGH, 0x00);
1985 SELECT_GUS_REG(port, GUSREG_END_VOLUME);
1986 outb(port+GUS_DATA_HIGH, sc->sc_voc[voice].current_volume >> 4);
1987 SELECT_GUS_REG(port, GUSREG_CUR_VOLUME);
1988 outw(port+GUS_DATA_LOW, 0x00);
1989 SELECT_GUS_REG(port, GUSREG_VOLUME_RATE);
1990 outb(port+GUS_DATA_HIGH, 63);
1991
1992 SELECT_GUS_REG(port, GUSREG_VOICE_CNTL);
1993 outb(port+GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
1994 SELECT_GUS_REG(port, GUSREG_VOLUME_CONTROL);
1995 outb(port+GUS_DATA_HIGH, 0x00);
1996 delay(50);
1997 SELECT_GUS_REG(port, GUSREG_VOICE_CNTL);
1998 outb(port+GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
1999 SELECT_GUS_REG(port, GUSREG_VOLUME_CONTROL);
2000 outb(port+GUS_DATA_HIGH, 0x00);
2001
2002 }
2003
2004 /*
2005 * Stop a given voice. called at splgus()
2006 */
2007
2008 STATIC void
2009 gus_stop_voice(sc, voice, intrs_too)
2010 struct gus_softc *sc;
2011 int voice;
2012 int intrs_too;
2013 {
2014 register int port = sc->sc_iobase;
2015
2016 sc->sc_voc[voice].voccntl |= GUSMASK_VOICE_STOPPED |
2017 GUSMASK_STOP_VOICE;
2018 if (intrs_too) {
2019 sc->sc_voc[voice].voccntl &= ~(GUSMASK_VOICE_IRQ);
2020 /* no more DMA to do */
2021 sc->sc_flags &= ~GUS_PLAYING;
2022 }
2023 DMAPRINTF(("gusintr voice notplaying=%x\n", sc->sc_flags));
2024
2025 guspoke(port, 0L, 0);
2026
2027 outb(port+GUS_VOICE_SELECT, (unsigned char) voice);
2028
2029 SELECT_GUS_REG(port, GUSREG_CUR_VOLUME);
2030 outw(port+GUS_DATA_LOW, 0x0000);
2031 SELECT_GUS_REG(port, GUSREG_VOICE_CNTL);
2032 outb(port+GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
2033 delay(100);
2034 SELECT_GUS_REG(port, GUSREG_CUR_VOLUME);
2035 outw(port+GUS_DATA_LOW, 0x0000);
2036 SELECT_GUS_REG(port, GUSREG_VOICE_CNTL);
2037 outb(port+GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
2038
2039 SELECT_GUS_REG(port, GUSREG_CUR_ADDR_HIGH);
2040 outw(port+GUS_DATA_LOW, 0x0000);
2041 SELECT_GUS_REG(port, GUSREG_CUR_ADDR_LOW);
2042 outw(port+GUS_DATA_LOW, 0x0000);
2043
2044 }
2045
2046
2047 /*
2048 * Set the volume of a given voice. Called at splgus().
2049 */
2050 STATIC void
2051 gus_set_volume(sc, voice, volume)
2052 struct gus_softc *sc;
2053 int voice, volume;
2054 {
2055 register int port = sc->sc_iobase;
2056 unsigned int gusvol;
2057
2058 gusvol = gus_log_volumes[volume < 512 ? volume : 511];
2059
2060 sc->sc_voc[voice].current_volume = gusvol;
2061
2062 outb(port+GUS_VOICE_SELECT, (unsigned char) voice);
2063
2064 SELECT_GUS_REG(port, GUSREG_START_VOLUME);
2065 outb(port+GUS_DATA_HIGH, (unsigned char) (gusvol >> 4));
2066
2067 SELECT_GUS_REG(port, GUSREG_END_VOLUME);
2068 outb(port+GUS_DATA_HIGH, (unsigned char) (gusvol >> 4));
2069
2070 SELECT_GUS_REG(port, GUSREG_CUR_VOLUME);
2071 outw(port+GUS_DATA_LOW, gusvol << 4);
2072 delay(500);
2073 outw(port+GUS_DATA_LOW, gusvol << 4);
2074
2075 }
2076
2077 /*
2078 * Interface to the audio layer.
2079 */
2080
2081 int
2082 gusmax_set_params(addr, mode, p, q)
2083 void *addr;
2084 int mode;
2085 struct audio_params *p, *q;
2086 {
2087 register struct ad1848_softc *ac = addr;
2088 register struct gus_softc *sc = ac->parent;
2089 int error;
2090
2091 error = ad1848_set_params(ac, mode, p, q);
2092 if (error)
2093 return error;
2094 error = gus_set_params(sc, mode, p, q);
2095 return error;
2096 }
2097
2098 int
2099 gus_set_params(addr, mode, p, q)
2100 void *addr;
2101 int mode;
2102 struct audio_params *p, *q;
2103 {
2104 register struct gus_softc *sc = addr;
2105 int s;
2106
2107 switch (p->encoding) {
2108 case AUDIO_ENCODING_ULAW:
2109 case AUDIO_ENCODING_SLINEAR_LE:
2110 case AUDIO_ENCODING_ULINEAR_LE:
2111 case AUDIO_ENCODING_SLINEAR_BE:
2112 case AUDIO_ENCODING_ULINEAR_BE:
2113 break;
2114 default:
2115 return (EINVAL);
2116 }
2117
2118 s = splaudio();
2119
2120 if (p->precision == 8) {
2121 sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~GUSMASK_DATA_SIZE16;
2122 sc->sc_voc[GUS_VOICE_RIGHT].voccntl &= ~GUSMASK_DATA_SIZE16;
2123 } else {
2124 sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_DATA_SIZE16;
2125 sc->sc_voc[GUS_VOICE_RIGHT].voccntl |= GUSMASK_DATA_SIZE16;
2126 }
2127
2128 sc->sc_encoding = p->encoding;
2129 sc->sc_precision = p->precision;
2130 sc->sc_channels = p->channels;
2131
2132 splx(s);
2133
2134 if (p->sample_rate > gus_max_frequency[sc->sc_voices - GUS_MIN_VOICES])
2135 p->sample_rate = gus_max_frequency[sc->sc_voices - GUS_MIN_VOICES];
2136 if (mode == AUMODE_RECORD)
2137 sc->sc_irate = p->sample_rate;
2138 else
2139 sc->sc_orate = p->sample_rate;
2140
2141 switch (p->encoding) {
2142 case AUDIO_ENCODING_ULAW:
2143 p->sw_code = mode == AUMODE_PLAY ?
2144 mulaw_to_ulinear8 : ulinear8_to_mulaw;
2145 break;
2146 case AUDIO_ENCODING_ULINEAR_BE:
2147 case AUDIO_ENCODING_SLINEAR_BE:
2148 p->sw_code = swap_bytes;
2149 break;
2150 default:
2151 p->sw_code = 0;
2152 }
2153
2154 /* Update setting for the other mode. */
2155 q->encoding = p->encoding;
2156 q->channels = p->channels;
2157 q->precision = p->precision;
2158 return 0;
2159 }
2160
2161 /*
2162 * Interface to the audio layer - set the blocksize to the correct number
2163 * of units
2164 */
2165
2166 int
2167 gusmax_round_blocksize(addr, blocksize)
2168 void * addr;
2169 int blocksize;
2170 {
2171 register struct ad1848_softc *ac = addr;
2172 register struct gus_softc *sc = ac->parent;
2173
2174 /* blocksize = ad1848_round_blocksize(ac, blocksize);*/
2175 return gus_round_blocksize(sc, blocksize);
2176 }
2177
2178 int
2179 gus_round_blocksize(addr, blocksize)
2180 void * addr;
2181 int blocksize;
2182 {
2183 register struct gus_softc *sc = addr;
2184
2185 DPRINTF(("gus_round_blocksize called\n"));
2186
2187 if (sc->sc_encoding == AUDIO_ENCODING_ULAW && blocksize > 32768)
2188 blocksize = 32768;
2189 else if (blocksize > 65536)
2190 blocksize = 65536;
2191
2192 if ((blocksize % GUS_BUFFER_MULTIPLE) != 0)
2193 blocksize = (blocksize / GUS_BUFFER_MULTIPLE + 1) *
2194 GUS_BUFFER_MULTIPLE;
2195
2196 /* set up temporary buffer to hold the deinterleave, if necessary
2197 for stereo output */
2198 if (sc->sc_deintr_buf) {
2199 FREE(sc->sc_deintr_buf, M_DEVBUF);
2200 sc->sc_deintr_buf = NULL;
2201 }
2202 MALLOC(sc->sc_deintr_buf, void *, blocksize>>1, M_DEVBUF, M_WAITOK);
2203
2204 sc->sc_blocksize = blocksize;
2205 /* multi-buffering not quite working yet. */
2206 sc->sc_nbufs = /*GUS_MEM_FOR_BUFFERS / blocksize*/ 2;
2207
2208 gus_set_chan_addrs(sc);
2209
2210 return blocksize;
2211 }
2212
2213 int
2214 gus_get_out_gain(addr)
2215 caddr_t addr;
2216 {
2217 register struct gus_softc *sc = (struct gus_softc *) addr;
2218
2219 DPRINTF(("gus_get_out_gain called\n"));
2220 return sc->sc_ogain / 2;
2221 }
2222
2223 STATIC inline void gus_set_voices(sc, voices)
2224 struct gus_softc *sc;
2225 int voices;
2226 {
2227 register int port = sc->sc_iobase;
2228 /*
2229 * Select the active number of voices
2230 */
2231
2232 SELECT_GUS_REG(port, GUSREG_ACTIVE_VOICES);
2233 outb(port+GUS_DATA_HIGH, (voices-1) | 0xc0);
2234
2235 sc->sc_voices = voices;
2236 }
2237
2238 /*
2239 * Actually set the settings of various values on the card
2240 */
2241
2242 int
2243 gusmax_commit_settings(addr)
2244 void * addr;
2245 {
2246 register struct ad1848_softc *ac = addr;
2247 register struct gus_softc *sc = ac->parent;
2248
2249 (void) ad1848_commit_settings(ac);
2250 return gus_commit_settings(sc);
2251 }
2252
2253 /*
2254 * Commit the settings. Called at normal IPL.
2255 */
2256 int
2257 gus_commit_settings(addr)
2258 void * addr;
2259 {
2260 register struct gus_softc *sc = addr;
2261 int s;
2262
2263 DPRINTF(("gus_commit_settings called (gain = %d)\n",sc->sc_ogain));
2264
2265
2266 s = splgus();
2267
2268 gus_set_recrate(sc, sc->sc_irate);
2269 gus_set_volume(sc, GUS_VOICE_LEFT, sc->sc_ogain);
2270 gus_set_volume(sc, GUS_VOICE_RIGHT, sc->sc_ogain);
2271 gus_set_samprate(sc, GUS_VOICE_LEFT, sc->sc_orate);
2272 gus_set_samprate(sc, GUS_VOICE_RIGHT, sc->sc_orate);
2273 splx(s);
2274 gus_set_chan_addrs(sc);
2275
2276 return 0;
2277 }
2278
2279 STATIC void
2280 gus_set_chan_addrs(sc)
2281 struct gus_softc *sc;
2282 {
2283 /*
2284 * We use sc_nbufs * blocksize bytes of storage in the on-board GUS
2285 * ram.
2286 * For mono, each of the sc_nbufs buffers is DMA'd to in one chunk,
2287 * and both left & right channels play the same buffer.
2288 *
2289 * For stereo, each channel gets a contiguous half of the memory,
2290 * and each has sc_nbufs buffers of size blocksize/2.
2291 * Stereo data are deinterleaved in main memory before the DMA out
2292 * routines are called to queue the output.
2293 *
2294 * The blocksize per channel is kept in sc_chanblocksize.
2295 */
2296 if (sc->sc_channels == 2)
2297 sc->sc_chanblocksize = sc->sc_blocksize/2;
2298 else
2299 sc->sc_chanblocksize = sc->sc_blocksize;
2300
2301 sc->sc_voc[GUS_VOICE_LEFT].start_addr = GUS_MEM_OFFSET - 1;
2302 sc->sc_voc[GUS_VOICE_RIGHT].start_addr =
2303 (gus_dostereo && sc->sc_channels == 2 ? GUS_LEFT_RIGHT_OFFSET : 0)
2304 + GUS_MEM_OFFSET - 1;
2305 sc->sc_voc[GUS_VOICE_RIGHT].current_addr =
2306 sc->sc_voc[GUS_VOICE_RIGHT].start_addr + 1;
2307 sc->sc_voc[GUS_VOICE_RIGHT].end_addr =
2308 sc->sc_voc[GUS_VOICE_RIGHT].start_addr +
2309 sc->sc_nbufs * sc->sc_chanblocksize;
2310
2311 }
2312
2313 /*
2314 * Set the sample rate of the given voice. Called at splgus().
2315 */
2316
2317 STATIC void
2318 gus_set_samprate(sc, voice, freq)
2319 struct gus_softc *sc;
2320 int voice, freq;
2321 {
2322 register int port = sc->sc_iobase;
2323 unsigned int fc;
2324 u_long temp, f = (u_long) freq;
2325
2326 /*
2327 * calculate fc based on the number of active voices;
2328 * we need to use longs to preserve enough bits
2329 */
2330
2331 temp = (u_long) gus_max_frequency[sc->sc_voices-GUS_MIN_VOICES];
2332
2333 fc = (unsigned int)(((f << 9L) + (temp >> 1L)) / temp);
2334
2335 fc <<= 1;
2336
2337
2338 /*
2339 * Program the voice frequency, and set it in the voice data record
2340 */
2341
2342 outb(port+GUS_VOICE_SELECT, (unsigned char) voice);
2343 SELECT_GUS_REG(port, GUSREG_FREQ_CONTROL);
2344 outw(port+GUS_DATA_LOW, fc);
2345
2346 sc->sc_voc[voice].rate = freq;
2347
2348 }
2349
2350 /*
2351 * Set the sample rate of the recording frequency. Formula is from the GUS
2352 * SDK. Called at splgus().
2353 */
2354
2355 STATIC void
2356 gus_set_recrate(sc, rate)
2357 struct gus_softc *sc;
2358 u_long rate;
2359 {
2360 register int port = sc->sc_iobase;
2361 u_char realrate;
2362 DPRINTF(("gus_set_recrate %lu\n", rate));
2363
2364 #if 0
2365 realrate = 9878400/(16*(rate+2)); /* formula from GUS docs */
2366 #endif
2367 realrate = (9878400 >> 4)/rate - 2; /* formula from code, sigh. */
2368
2369 SELECT_GUS_REG(port, GUSREG_SAMPLE_FREQ);
2370 outb(port+GUS_DATA_HIGH, realrate);
2371 }
2372
2373 /*
2374 * Interface to the audio layer - turn the output on or off. Note that some
2375 * of these bits are flipped in the register
2376 */
2377
2378 int
2379 gusmax_speaker_ctl(addr, newstate)
2380 void * addr;
2381 int newstate;
2382 {
2383 register struct ad1848_softc *sc = addr;
2384 return gus_speaker_ctl(sc->parent, newstate);
2385 }
2386
2387 int
2388 gus_speaker_ctl(addr, newstate)
2389 void * addr;
2390 int newstate;
2391 {
2392 register struct gus_softc *sc = (struct gus_softc *) addr;
2393
2394 /* Line out bit is flipped: 0 enables, 1 disables */
2395 if ((newstate == SPKR_ON) &&
2396 (sc->sc_mixcontrol & GUSMASK_LINE_OUT)) {
2397 sc->sc_mixcontrol &= ~GUSMASK_LINE_OUT;
2398 outb(sc->sc_iobase+GUS_MIX_CONTROL, sc->sc_mixcontrol);
2399 }
2400 if ((newstate == SPKR_OFF) &&
2401 (sc->sc_mixcontrol & GUSMASK_LINE_OUT) == 0) {
2402 sc->sc_mixcontrol |= GUSMASK_LINE_OUT;
2403 outb(sc->sc_iobase+GUS_MIX_CONTROL, sc->sc_mixcontrol);
2404 }
2405
2406 return 0;
2407 }
2408
2409 STATIC int
2410 gus_linein_ctl(addr, newstate)
2411 void * addr;
2412 int newstate;
2413 {
2414 register struct gus_softc *sc = (struct gus_softc *) addr;
2415
2416 /* Line in bit is flipped: 0 enables, 1 disables */
2417 if ((newstate == SPKR_ON) &&
2418 (sc->sc_mixcontrol & GUSMASK_LINE_IN)) {
2419 sc->sc_mixcontrol &= ~GUSMASK_LINE_IN;
2420 outb(sc->sc_iobase+GUS_MIX_CONTROL, sc->sc_mixcontrol);
2421 }
2422 if ((newstate == SPKR_OFF) &&
2423 (sc->sc_mixcontrol & GUSMASK_LINE_IN) == 0) {
2424 sc->sc_mixcontrol |= GUSMASK_LINE_IN;
2425 outb(sc->sc_iobase+GUS_MIX_CONTROL, sc->sc_mixcontrol);
2426 }
2427
2428 return 0;
2429 }
2430
2431 STATIC int
2432 gus_mic_ctl(addr, newstate)
2433 void * addr;
2434 int newstate;
2435 {
2436 register struct gus_softc *sc = (struct gus_softc *) addr;
2437
2438 /* Mic bit is normal: 1 enables, 0 disables */
2439 if ((newstate == SPKR_ON) &&
2440 (sc->sc_mixcontrol & GUSMASK_MIC_IN) == 0) {
2441 sc->sc_mixcontrol |= GUSMASK_MIC_IN;
2442 outb(sc->sc_iobase+GUS_MIX_CONTROL, sc->sc_mixcontrol);
2443 }
2444 if ((newstate == SPKR_OFF) &&
2445 (sc->sc_mixcontrol & GUSMASK_MIC_IN)) {
2446 sc->sc_mixcontrol &= ~GUSMASK_MIC_IN;
2447 outb(sc->sc_iobase+GUS_MIX_CONTROL, sc->sc_mixcontrol);
2448 }
2449
2450 return 0;
2451 }
2452
2453 /*
2454 * Set the end address of a give voice. Called at splgus()
2455 */
2456
2457 STATIC void
2458 gus_set_endaddr(sc, voice, addr)
2459 struct gus_softc *sc;
2460 int voice;
2461 u_long addr;
2462 {
2463 register int port = sc->sc_iobase;
2464
2465 sc->sc_voc[voice].end_addr = addr;
2466
2467 if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16)
2468 addr = convert_to_16bit(addr);
2469
2470 SELECT_GUS_REG(port, GUSREG_END_ADDR_HIGH);
2471 outw(port+GUS_DATA_LOW, ADDR_HIGH(addr));
2472 SELECT_GUS_REG(port, GUSREG_END_ADDR_LOW);
2473 outw(port+GUS_DATA_LOW, ADDR_LOW(addr));
2474
2475 }
2476
2477 #ifdef GUSPLAYDEBUG
2478 /*
2479 * Set current address. called at splgus()
2480 */
2481 STATIC void
2482 gus_set_curaddr(sc, voice, addr)
2483 struct gus_softc *sc;
2484 int voice;
2485 u_long addr;
2486 {
2487 register int port = sc->sc_iobase;
2488
2489 sc->sc_voc[voice].current_addr = addr;
2490
2491 if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16)
2492 addr = convert_to_16bit(addr);
2493
2494 outb(port+GUS_VOICE_SELECT, (unsigned char) voice);
2495
2496 SELECT_GUS_REG(port, GUSREG_CUR_ADDR_HIGH);
2497 outw(port+GUS_DATA_LOW, ADDR_HIGH(addr));
2498 SELECT_GUS_REG(port, GUSREG_CUR_ADDR_LOW);
2499 outw(port+GUS_DATA_LOW, ADDR_LOW(addr));
2500
2501 }
2502
2503 /*
2504 * Get current GUS playback address. Called at splgus().
2505 */
2506 STATIC u_long
2507 gus_get_curaddr(sc, voice)
2508 struct gus_softc *sc;
2509 int voice;
2510 {
2511 register int port = sc->sc_iobase;
2512 u_long addr;
2513
2514 outb(port+GUS_VOICE_SELECT, (unsigned char) voice);
2515 SELECT_GUS_REG(port, GUSREG_CUR_ADDR_HIGH|GUSREG_READ);
2516 addr = (inw(port+GUS_DATA_LOW) & 0x1fff) << 7;
2517 SELECT_GUS_REG(port, GUSREG_CUR_ADDR_LOW|GUSREG_READ);
2518 addr |= (inw(port+GUS_DATA_LOW) >> 9L) & 0x7f;
2519
2520 if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16)
2521 addr = (addr & 0xc0000) | ((addr & 0x1ffff) << 1); /* undo 16-bit change */
2522 DPRINTF(("gus voice %d curaddr %d end_addr %d\n",
2523 voice, addr, sc->sc_voc[voice].end_addr));
2524 /* XXX sanity check the address? */
2525
2526 return(addr);
2527 }
2528 #endif
2529
2530 /*
2531 * Convert an address value to a "16 bit" value - why this is necessary I
2532 * have NO idea
2533 */
2534
2535 STATIC u_long
2536 convert_to_16bit(address)
2537 u_long address;
2538 {
2539 u_long old_address;
2540
2541 old_address = address;
2542 address >>= 1;
2543 address &= 0x0001ffffL;
2544 address |= (old_address & 0x000c0000L);
2545
2546 return (address);
2547 }
2548
2549 /*
2550 * Write a value into the GUS's DRAM
2551 */
2552
2553 STATIC void
2554 guspoke(port, address, value)
2555 int port;
2556 long address;
2557 unsigned char value;
2558 {
2559
2560 /*
2561 * Select the DRAM address
2562 */
2563
2564 SELECT_GUS_REG(port, GUSREG_DRAM_ADDR_LOW);
2565 outw(port+GUS_DATA_LOW, (unsigned int) (address & 0xffff));
2566 SELECT_GUS_REG(port, GUSREG_DRAM_ADDR_HIGH);
2567 outb(port+GUS_DATA_HIGH, (unsigned char) ((address >> 16) & 0xff));
2568
2569 /*
2570 * Actually write the data
2571 */
2572
2573 outb(port+GUS_DRAM_DATA, value);
2574 }
2575
2576 /*
2577 * Read a value from the GUS's DRAM
2578 */
2579
2580 STATIC unsigned char
2581 guspeek(port, address)
2582 int port;
2583 u_long address;
2584 {
2585
2586 /*
2587 * Select the DRAM address
2588 */
2589
2590 SELECT_GUS_REG(port, GUSREG_DRAM_ADDR_LOW);
2591 outw(port+GUS_DATA_LOW, (unsigned int) (address & 0xffff));
2592 SELECT_GUS_REG(port, GUSREG_DRAM_ADDR_HIGH);
2593 outb(port+GUS_DATA_HIGH, (unsigned char) ((address >> 16) & 0xff));
2594
2595 /*
2596 * Read in the data from the board
2597 */
2598
2599 return (unsigned char) inb(port+GUS_DRAM_DATA);
2600 }
2601
2602 /*
2603 * Reset the Gravis UltraSound card, completely
2604 */
2605
2606 STATIC void
2607 gusreset(sc, voices)
2608 struct gus_softc *sc;
2609 int voices;
2610 {
2611 register int port = sc->sc_iobase;
2612 int i,s;
2613
2614 s = splgus();
2615
2616 /*
2617 * Reset the GF1 chip
2618 */
2619
2620 SELECT_GUS_REG(port, GUSREG_RESET);
2621 outb(port+GUS_DATA_HIGH, 0x00);
2622
2623 delay(500);
2624
2625 /*
2626 * Release reset
2627 */
2628
2629 SELECT_GUS_REG(port, GUSREG_RESET);
2630 outb(port+GUS_DATA_HIGH, GUSMASK_MASTER_RESET);
2631
2632 delay(500);
2633
2634 /*
2635 * Reset MIDI port as well
2636 */
2637
2638 outb(GUS_MIDI_CONTROL,MIDI_RESET);
2639
2640 delay(500);
2641
2642 outb(GUS_MIDI_CONTROL,0x00);
2643
2644 /*
2645 * Clear interrupts
2646 */
2647
2648 SELECT_GUS_REG(port, GUSREG_DMA_CONTROL);
2649 outb(port+GUS_DATA_HIGH, 0x00);
2650 SELECT_GUS_REG(port, GUSREG_TIMER_CONTROL);
2651 outb(port+GUS_DATA_HIGH, 0x00);
2652 SELECT_GUS_REG(port, GUSREG_SAMPLE_CONTROL);
2653 outb(port+GUS_DATA_HIGH, 0x00);
2654
2655 gus_set_voices(sc, voices);
2656
2657 inb(port+GUS_IRQ_STATUS);
2658 SELECT_GUS_REG(port, GUSREG_DMA_CONTROL);
2659 inb(port+GUS_DATA_HIGH);
2660 SELECT_GUS_REG(port, GUSREG_SAMPLE_CONTROL);
2661 inb(port+GUS_DATA_HIGH);
2662 SELECT_GUS_REG(port, GUSREG_IRQ_STATUS);
2663 inb(port+GUS_DATA_HIGH);
2664
2665 /*
2666 * Reset voice specific information
2667 */
2668
2669 for(i = 0; i < voices; i++) {
2670 outb(port+GUS_VOICE_SELECT, (unsigned char) i);
2671
2672 SELECT_GUS_REG(port, GUSREG_VOICE_CNTL);
2673
2674 sc->sc_voc[i].voccntl = GUSMASK_VOICE_STOPPED |
2675 GUSMASK_STOP_VOICE;
2676
2677 outb(port+GUS_DATA_HIGH, sc->sc_voc[i].voccntl);
2678
2679 sc->sc_voc[i].volcntl = GUSMASK_VOLUME_STOPPED |
2680 GUSMASK_STOP_VOLUME;
2681
2682 SELECT_GUS_REG(port, GUSREG_VOLUME_CONTROL);
2683 outb(port+GUS_DATA_HIGH, sc->sc_voc[i].volcntl);
2684
2685 delay(100);
2686
2687 gus_set_samprate(sc, i, 8000);
2688 SELECT_GUS_REG(port, GUSREG_START_ADDR_HIGH);
2689 outw(port+GUS_DATA_LOW, 0x0000);
2690 SELECT_GUS_REG(port, GUSREG_START_ADDR_LOW);
2691 outw(port+GUS_DATA_LOW, 0x0000);
2692 SELECT_GUS_REG(port, GUSREG_END_ADDR_HIGH);
2693 outw(port+GUS_DATA_LOW, 0x0000);
2694 SELECT_GUS_REG(port, GUSREG_END_ADDR_LOW);
2695 outw(port+GUS_DATA_LOW, 0x0000);
2696 SELECT_GUS_REG(port, GUSREG_VOLUME_RATE);
2697 outb(port+GUS_DATA_HIGH, 0x01);
2698 SELECT_GUS_REG(port, GUSREG_START_VOLUME);
2699 outb(port+GUS_DATA_HIGH, 0x10);
2700 SELECT_GUS_REG(port, GUSREG_END_VOLUME);
2701 outb(port+GUS_DATA_HIGH, 0xe0);
2702 SELECT_GUS_REG(port, GUSREG_CUR_VOLUME);
2703 outw(port+GUS_DATA_LOW, 0x0000);
2704
2705 SELECT_GUS_REG(port, GUSREG_CUR_ADDR_HIGH);
2706 outw(port+GUS_DATA_LOW, 0x0000);
2707 SELECT_GUS_REG(port, GUSREG_CUR_ADDR_LOW);
2708 outw(port+GUS_DATA_LOW, 0x0000);
2709 SELECT_GUS_REG(port, GUSREG_PAN_POS);
2710 outb(port+GUS_DATA_HIGH, 0x07);
2711 }
2712
2713 /*
2714 * Clear out any pending IRQs
2715 */
2716
2717 inb(port+GUS_IRQ_STATUS);
2718 SELECT_GUS_REG(port, GUSREG_DMA_CONTROL);
2719 inb(port+GUS_DATA_HIGH);
2720 SELECT_GUS_REG(port, GUSREG_SAMPLE_CONTROL);
2721 inb(port+GUS_DATA_HIGH);
2722 SELECT_GUS_REG(port, GUSREG_IRQ_STATUS);
2723 inb(port+GUS_DATA_HIGH);
2724
2725 SELECT_GUS_REG(port, GUSREG_RESET);
2726 outb(port+GUS_DATA_HIGH, GUSMASK_MASTER_RESET | GUSMASK_DAC_ENABLE |
2727 GUSMASK_IRQ_ENABLE);
2728
2729 splx(s);
2730 }
2731
2732
2733 STATIC void
2734 gus_init_cs4231(sc)
2735 struct gus_softc *sc;
2736 {
2737 register int port = sc->sc_iobase;
2738 u_char ctrl;
2739
2740 ctrl = (port & 0xf0) >> 4; /* set port address middle nibble */
2741 /*
2742 * The codec is a bit weird--swapped dma channels.
2743 */
2744 ctrl |= GUS_MAX_CODEC_ENABLE;
2745 if (sc->sc_drq >= 4)
2746 ctrl |= GUS_MAX_RECCHAN16;
2747 if (sc->sc_recdrq >= 4)
2748 ctrl |= GUS_MAX_PLAYCHAN16;
2749
2750 outb(port+GUS_MAX_CTRL, ctrl);
2751
2752 sc->sc_codec.sc_iot = sc->sc_iot;
2753 sc->sc_codec.sc_iobase = port+GUS_MAX_CODEC_BASE;
2754
2755 if (ad1848_probe(&sc->sc_codec) == 0) {
2756 sc->sc_flags &= ~GUS_CODEC_INSTALLED;
2757 } else {
2758 struct ad1848_volume vol = {AUDIO_MAX_GAIN, AUDIO_MAX_GAIN};
2759 struct audio_hw_if gusmax_hw_if = {
2760 gusopen,
2761 gusmax_close,
2762 NULL, /* drain */
2763
2764 gus_query_encoding, /* query encoding */
2765
2766 gusmax_set_params,
2767
2768 gusmax_round_blocksize,
2769
2770 gusmax_set_out_port,
2771 gusmax_get_out_port,
2772 gusmax_set_in_port,
2773 gusmax_get_in_port,
2774
2775 gusmax_commit_settings,
2776
2777 gusmax_dma_output,
2778 gusmax_dma_input,
2779 gusmax_halt_out_dma,
2780 gusmax_halt_in_dma,
2781 gusmax_cont_out_dma,
2782 gusmax_cont_in_dma,
2783
2784 gusmax_speaker_ctl,
2785
2786 gus_getdev,
2787 gus_setfd,
2788 gusmax_mixer_set_port,
2789 gusmax_mixer_get_port,
2790 gusmax_mixer_query_devinfo,
2791 1, /* full-duplex */
2792 0,
2793 };
2794 sc->sc_flags |= GUS_CODEC_INSTALLED;
2795 sc->sc_codec.parent = sc;
2796 sc->sc_codec.sc_drq = sc->sc_recdrq;
2797 sc->sc_codec.sc_recdrq = sc->sc_drq;
2798 gus_hw_if = gusmax_hw_if;
2799 /* enable line in and mic in the GUS mixer; the codec chip
2800 will do the real mixing for them. */
2801 sc->sc_mixcontrol &= ~GUSMASK_LINE_IN; /* 0 enables. */
2802 sc->sc_mixcontrol |= GUSMASK_MIC_IN; /* 1 enables. */
2803 outb(sc->sc_iobase+GUS_MIX_CONTROL, sc->sc_mixcontrol);
2804
2805 ad1848_attach(&sc->sc_codec);
2806 /* turn on pre-MUX microphone gain. */
2807 ad1848_set_mic_gain(&sc->sc_codec, &vol);
2808 }
2809 }
2810
2811
2812 /*
2813 * Return info about the audio device, for the AUDIO_GETINFO ioctl
2814 */
2815
2816 int
2817 gus_getdev(addr, dev)
2818 void * addr;
2819 struct audio_device *dev;
2820 {
2821 *dev = gus_device;
2822 return 0;
2823 }
2824
2825 /*
2826 * stubs (XXX)
2827 */
2828
2829 int
2830 gus_set_in_gain(addr, gain, balance)
2831 caddr_t addr;
2832 u_int gain;
2833 u_char balance;
2834 {
2835 DPRINTF(("gus_set_in_gain called\n"));
2836 return 0;
2837 }
2838
2839 int
2840 gus_get_in_gain(addr)
2841 caddr_t addr;
2842 {
2843 DPRINTF(("gus_get_in_gain called\n"));
2844 return 0;
2845 }
2846
2847 int
2848 gusmax_set_out_port(addr, port)
2849 void * addr;
2850 int port;
2851 {
2852 register struct ad1848_softc *sc = addr;
2853 return gus_set_out_port(sc->parent, port);
2854 }
2855
2856 int
2857 gus_set_out_port(addr, port)
2858 void * addr;
2859 int port;
2860 {
2861 register struct gus_softc *sc = addr;
2862 DPRINTF(("gus_set_out_port called\n"));
2863 sc->sc_out_port = port;
2864
2865 return 0;
2866 }
2867
2868 int
2869 gusmax_get_out_port(addr)
2870 void * addr;
2871 {
2872 register struct ad1848_softc *sc = addr;
2873 return gus_get_out_port(sc->parent);
2874 }
2875
2876 int
2877 gus_get_out_port(addr)
2878 void * addr;
2879 {
2880 register struct gus_softc *sc = addr;
2881 DPRINTF(("gus_get_out_port() called\n"));
2882 return sc->sc_out_port;
2883 }
2884
2885 int
2886 gusmax_set_in_port(addr, port)
2887 void * addr;
2888 int port;
2889 {
2890 register struct ad1848_softc *sc = addr;
2891 DPRINTF(("gusmax_set_in_port: %d\n", port));
2892
2893 switch(port) {
2894 case MIC_IN_PORT:
2895 case LINE_IN_PORT:
2896 case AUX1_IN_PORT:
2897 case DAC_IN_PORT:
2898 break;
2899 default:
2900 return(EINVAL);
2901 /*NOTREACHED*/
2902 }
2903 return(ad1848_set_rec_port(sc, port));
2904 }
2905
2906 int
2907 gusmax_get_in_port(addr)
2908 void * addr;
2909 {
2910 register struct ad1848_softc *sc = addr;
2911 int port;
2912
2913 port = ad1848_get_rec_port(sc);
2914 DPRINTF(("gusmax_get_in_port: %d\n", port));
2915
2916 return(port);
2917 }
2918
2919 int
2920 gus_set_in_port(addr, port)
2921 void * addr;
2922 int port;
2923 {
2924 register struct gus_softc *sc = addr;
2925 DPRINTF(("gus_set_in_port called\n"));
2926 /*
2927 * On the GUS with ICS mixer, the ADC input is after the mixer stage,
2928 * so we can't set the input port.
2929 *
2930 * On the GUS with CS4231 codec/mixer, see gusmax_set_in_port().
2931 */
2932 sc->sc_in_port = port;
2933
2934 return 0;
2935 }
2936
2937
2938 int
2939 gus_get_in_port(addr)
2940 void * addr;
2941 {
2942 register struct gus_softc *sc = addr;
2943 DPRINTF(("gus_get_in_port called\n"));
2944 return sc->sc_in_port;
2945 }
2946
2947
2948 int
2949 gusmax_dma_input(addr, buf, size, callback, arg)
2950 void * addr;
2951 void *buf;
2952 int size;
2953 void (*callback) __P((void *));
2954 void *arg;
2955 {
2956 register struct ad1848_softc *sc = addr;
2957 return gus_dma_input(sc->parent, buf, size, callback, arg);
2958 }
2959
2960 /*
2961 * Start sampling the input source into the requested DMA buffer.
2962 * Called at splgus(), either from top-half or from interrupt handler.
2963 */
2964 int
2965 gus_dma_input(addr, buf, size, callback, arg)
2966 void * addr;
2967 void *buf;
2968 int size;
2969 void (*callback) __P((void *));
2970 void *arg;
2971 {
2972 register struct gus_softc *sc = addr;
2973 register int port = sc->sc_iobase;
2974 register u_char dmac;
2975 DMAPRINTF(("gus_dma_input called\n"));
2976
2977 /*
2978 * Sample SIZE bytes of data from the card, into buffer at BUF.
2979 */
2980
2981 if (sc->sc_precision == 16)
2982 return EINVAL; /* XXX */
2983
2984 /* set DMA modes */
2985 dmac = GUSMASK_SAMPLE_IRQ|GUSMASK_SAMPLE_START;
2986 if (sc->sc_recdrq >= 4)
2987 dmac |= GUSMASK_SAMPLE_DATA16;
2988 if (sc->sc_encoding == AUDIO_ENCODING_ULAW ||
2989 sc->sc_encoding == AUDIO_ENCODING_ULINEAR_LE ||
2990 sc->sc_encoding == AUDIO_ENCODING_ULINEAR_BE)
2991 dmac |= GUSMASK_SAMPLE_INVBIT;
2992 if (sc->sc_channels == 2)
2993 dmac |= GUSMASK_SAMPLE_STEREO;
2994 isa_dmastart(sc->sc_dev.dv_parent, sc->sc_recdrq, buf, size,
2995 NULL, DMAMODE_READ, BUS_DMA_NOWAIT);
2996
2997 DMAPRINTF(("gus_dma_input isa_dmastarted\n"));
2998 sc->sc_flags |= GUS_DMAIN_ACTIVE;
2999 sc->sc_dmainintr = callback;
3000 sc->sc_inarg = arg;
3001 sc->sc_dmaincnt = size;
3002 sc->sc_dmainaddr = buf;
3003
3004 SELECT_GUS_REG(port, GUSREG_SAMPLE_CONTROL);
3005 outb(port+GUS_DATA_HIGH, dmac); /* Go! */
3006
3007
3008 DMAPRINTF(("gus_dma_input returning\n"));
3009
3010 return 0;
3011 }
3012
3013 STATIC int
3014 gus_dmain_intr(sc)
3015 struct gus_softc *sc;
3016 {
3017 void (*callback) __P((void *));
3018 void *arg;
3019
3020 DMAPRINTF(("gus_dmain_intr called\n"));
3021 if (sc->sc_dmainintr) {
3022 isa_dmadone(sc->sc_dev.dv_parent, sc->sc_recdrq);
3023 callback = sc->sc_dmainintr;
3024 arg = sc->sc_inarg;
3025
3026 sc->sc_dmainaddr = 0;
3027 sc->sc_dmaincnt = 0;
3028 sc->sc_dmainintr = 0;
3029 sc->sc_inarg = 0;
3030
3031 sc->sc_flags &= ~GUS_DMAIN_ACTIVE;
3032 DMAPRINTF(("calling dmain_intr callback %x(%x)\n", callback, arg));
3033 (*callback)(arg);
3034 return 1;
3035 } else {
3036 DMAPRINTF(("gus_dmain_intr false?\n"));
3037 return 0; /* XXX ??? */
3038 }
3039 }
3040
3041 int
3042 gusmax_halt_out_dma(addr)
3043 void * addr;
3044 {
3045 register struct ad1848_softc *sc = addr;
3046 return gus_halt_out_dma(sc->parent);
3047 }
3048
3049
3050 int
3051 gusmax_halt_in_dma(addr)
3052 void * addr;
3053 {
3054 register struct ad1848_softc *sc = addr;
3055 return gus_halt_in_dma(sc->parent);
3056 }
3057
3058 int
3059 gusmax_cont_out_dma(addr)
3060 void * addr;
3061 {
3062 register struct ad1848_softc *sc = addr;
3063 return gus_cont_out_dma(sc->parent);
3064 }
3065
3066 int
3067 gusmax_cont_in_dma(addr)
3068 void * addr;
3069 {
3070 register struct ad1848_softc *sc = addr;
3071 return gus_cont_in_dma(sc->parent);
3072 }
3073
3074 /*
3075 * Stop any DMA output. Called at splgus().
3076 */
3077 int
3078 gus_halt_out_dma(addr)
3079 void * addr;
3080 {
3081 register struct gus_softc *sc = addr;
3082 register int port = sc->sc_iobase;
3083
3084 DMAPRINTF(("gus_halt_out_dma called\n"));
3085 /*
3086 * Make sure the GUS _isn't_ setup for DMA
3087 */
3088
3089 SELECT_GUS_REG(port, GUSREG_DMA_CONTROL);
3090 outb(sc->sc_iobase+GUS_DATA_HIGH, 0);
3091
3092 untimeout(gus_dmaout_timeout, sc);
3093 isa_dmaabort(sc->sc_dev.dv_parent, sc->sc_drq);
3094 sc->sc_flags &= ~(GUS_DMAOUT_ACTIVE|GUS_LOCKED);
3095 sc->sc_dmaoutintr = 0;
3096 sc->sc_outarg = 0;
3097 sc->sc_dmaoutaddr = 0;
3098 sc->sc_dmaoutcnt = 0;
3099 sc->sc_dmabuf = 0;
3100 sc->sc_bufcnt = 0;
3101 sc->sc_playbuf = -1;
3102 /* also stop playing */
3103 gus_stop_voice(sc, GUS_VOICE_LEFT, 1);
3104 gus_stop_voice(sc, GUS_VOICE_RIGHT, 0);
3105
3106 return 0;
3107 }
3108
3109 /*
3110 * Stop any DMA output. Called at splgus().
3111 */
3112 int
3113 gus_halt_in_dma(addr)
3114 void * addr;
3115 {
3116 register struct gus_softc *sc = addr;
3117 register int port = sc->sc_iobase;
3118 DMAPRINTF(("gus_halt_in_dma called\n"));
3119
3120 /*
3121 * Make sure the GUS _isn't_ setup for DMA
3122 */
3123
3124 SELECT_GUS_REG(port, GUSREG_SAMPLE_CONTROL);
3125 outb(port+GUS_DATA_HIGH,
3126 inb(port+GUS_DATA_HIGH) & ~(GUSMASK_SAMPLE_START|GUSMASK_SAMPLE_IRQ));
3127
3128 isa_dmaabort(sc->sc_dev.dv_parent, sc->sc_recdrq);
3129 sc->sc_flags &= ~GUS_DMAIN_ACTIVE;
3130 sc->sc_dmainintr = 0;
3131 sc->sc_inarg = 0;
3132 sc->sc_dmainaddr = 0;
3133 sc->sc_dmaincnt = 0;
3134
3135 return 0;
3136 }
3137
3138 int
3139 gus_cont_out_dma(addr)
3140 void * addr;
3141 {
3142 DPRINTF(("gus_cont_out_dma called\n"));
3143 return EOPNOTSUPP;
3144 }
3145
3146 int
3147 gus_cont_in_dma(addr)
3148 void * addr;
3149 {
3150 DPRINTF(("gus_cont_in_dma called\n"));
3151 return EOPNOTSUPP;
3152 }
3153
3154
3155 STATIC int
3156 gus_setfd(addr, flag)
3157 void *addr;
3158 int flag;
3159 {
3160 if (gus_hw_if.full_duplex == 0)
3161 return ENOTTY;
3162
3163 return(0); /* nothing fancy to do. */
3164 }
3165
3166 STATIC __inline int
3167 gus_to_vol(cp, vol)
3168 mixer_ctrl_t *cp;
3169 struct ad1848_volume *vol;
3170 {
3171 if (cp->un.value.num_channels == 1) {
3172 vol->left = vol->right = cp->un.value.level[AUDIO_MIXER_LEVEL_MONO];
3173 return(1);
3174 }
3175 else if (cp->un.value.num_channels == 2) {
3176 vol->left = cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT];
3177 vol->right = cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT];
3178 return(1);
3179 }
3180 return(0);
3181 }
3182
3183 STATIC __inline int
3184 gus_from_vol(cp, vol)
3185 mixer_ctrl_t *cp;
3186 struct ad1848_volume *vol;
3187 {
3188 if (cp->un.value.num_channels == 1) {
3189 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = vol->left;
3190 return(1);
3191 }
3192 else if (cp->un.value.num_channels == 2) {
3193 cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = vol->left;
3194 cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = vol->right;
3195 return(1);
3196 }
3197 return(0);
3198 }
3199
3200 STATIC int
3201 gusmax_mixer_get_port(addr, cp)
3202 void *addr;
3203 mixer_ctrl_t *cp;
3204 {
3205 register struct ad1848_softc *ac = addr;
3206 register struct gus_softc *sc = ac->parent;
3207 struct ad1848_volume vol;
3208 int error = EINVAL;
3209
3210 DPRINTF(("gusmax_mixer_get_port: port=%d\n", cp->dev));
3211
3212 switch (cp->dev) {
3213 #if 0 /* use mono level instead */
3214 case GUSMAX_MIC_IN_LVL: /* Microphone */
3215 if (cp->type == AUDIO_MIXER_VALUE) {
3216 error = ad1848_get_mic_gain(ac, &vol);
3217 if (!error)
3218 gus_from_vol(cp, &vol);
3219 }
3220 break;
3221 #endif
3222
3223 case GUSMAX_DAC_LVL: /* dac out */
3224 if (cp->type == AUDIO_MIXER_VALUE) {
3225 error = ad1848_get_aux1_gain(ac, &vol);
3226 if (!error)
3227 gus_from_vol(cp, &vol);
3228 }
3229 break;
3230
3231 case GUSMAX_LINE_IN_LVL: /* line in */
3232 if (cp->type == AUDIO_MIXER_VALUE) {
3233 error = cs4231_get_linein_gain(ac, &vol);
3234 if (!error)
3235 gus_from_vol(cp, &vol);
3236 }
3237 break;
3238
3239 case GUSMAX_MONO_LVL: /* mono */
3240 if (cp->type == AUDIO_MIXER_VALUE &&
3241 cp->un.value.num_channels == 1) {
3242 error = cs4231_get_mono_gain(ac, &vol);
3243 if (!error)
3244 gus_from_vol(cp, &vol);
3245 }
3246 break;
3247
3248 case GUSMAX_CD_LVL: /* CD */
3249 if (cp->type == AUDIO_MIXER_VALUE) {
3250 error = ad1848_get_aux2_gain(ac, &vol);
3251 if (!error)
3252 gus_from_vol(cp, &vol);
3253 }
3254 break;
3255
3256 case GUSMAX_MONITOR_LVL: /* monitor level */
3257 if (cp->type == AUDIO_MIXER_VALUE &&
3258 cp->un.value.num_channels == 1) {
3259 error = ad1848_get_mon_gain(ac, &vol);
3260 if (!error)
3261 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
3262 vol.left;
3263 }
3264 break;
3265
3266 case GUSMAX_OUT_LVL: /* output level */
3267 if (cp->type == AUDIO_MIXER_VALUE) {
3268 error = ad1848_get_out_gain(ac, &vol);
3269 if (!error)
3270 gus_from_vol(cp, &vol);
3271 }
3272 break;
3273
3274 case GUSMAX_SPEAKER_LVL: /* fake speaker for mute naming */
3275 if (cp->type == AUDIO_MIXER_VALUE) {
3276 if (sc->sc_mixcontrol & GUSMASK_LINE_OUT)
3277 vol.left = vol.right = AUDIO_MAX_GAIN;
3278 else
3279 vol.left = vol.right = AUDIO_MIN_GAIN;
3280 error = 0;
3281 gus_from_vol(cp, &vol);
3282 }
3283 break;
3284
3285 case GUSMAX_LINE_IN_MUTE:
3286 if (cp->type == AUDIO_MIXER_ENUM) {
3287 cp->un.ord = ac->line_mute;
3288 error = 0;
3289 }
3290 break;
3291
3292
3293 case GUSMAX_DAC_MUTE:
3294 if (cp->type == AUDIO_MIXER_ENUM) {
3295 cp->un.ord = ac->aux1_mute;
3296 error = 0;
3297 }
3298 break;
3299
3300 case GUSMAX_CD_MUTE:
3301 if (cp->type == AUDIO_MIXER_ENUM) {
3302 cp->un.ord = ac->aux2_mute;
3303 error = 0;
3304 }
3305 break;
3306
3307 case GUSMAX_MONO_MUTE:
3308 if (cp->type == AUDIO_MIXER_ENUM) {
3309 cp->un.ord = ac->mono_mute;
3310 error = 0;
3311 }
3312 break;
3313
3314 case GUSMAX_MONITOR_MUTE:
3315 if (cp->type == AUDIO_MIXER_ENUM) {
3316 cp->un.ord = ac->mon_mute;
3317 error = 0;
3318 }
3319 break;
3320
3321 case GUSMAX_SPEAKER_MUTE:
3322 if (cp->type == AUDIO_MIXER_ENUM) {
3323 cp->un.ord = sc->sc_mixcontrol & GUSMASK_LINE_OUT ? 1 : 0;
3324 error = 0;
3325 }
3326 break;
3327
3328 case GUSMAX_REC_LVL: /* record level */
3329 if (cp->type == AUDIO_MIXER_VALUE) {
3330 error = ad1848_get_rec_gain(ac, &vol);
3331 if (!error)
3332 gus_from_vol(cp, &vol);
3333 }
3334 break;
3335
3336 case GUSMAX_RECORD_SOURCE:
3337 if (cp->type == AUDIO_MIXER_ENUM) {
3338 cp->un.ord = ad1848_get_rec_port(ac);
3339 error = 0;
3340 }
3341 break;
3342
3343 default:
3344 error = ENXIO;
3345 break;
3346 }
3347
3348 return(error);
3349 }
3350
3351 STATIC int
3352 gus_mixer_get_port(addr, cp)
3353 void *addr;
3354 mixer_ctrl_t *cp;
3355 {
3356 register struct gus_softc *sc = addr;
3357 register struct ics2101_softc *ic = &sc->sc_mixer;
3358 struct ad1848_volume vol;
3359 int error = EINVAL;
3360
3361 DPRINTF(("gus_mixer_get_port: dev=%d type=%d\n", cp->dev, cp->type));
3362
3363 if (!HAS_MIXER(sc) && cp->dev > GUSICS_MASTER_MUTE)
3364 return ENXIO;
3365
3366 switch (cp->dev) {
3367
3368 case GUSICS_MIC_IN_MUTE: /* Microphone */
3369 if (cp->type == AUDIO_MIXER_ENUM) {
3370 if (HAS_MIXER(sc))
3371 cp->un.ord = ic->sc_mute[GUSMIX_CHAN_MIC][ICSMIX_LEFT];
3372 else
3373 cp->un.ord =
3374 sc->sc_mixcontrol & GUSMASK_MIC_IN ? 0 : 1;
3375 error = 0;
3376 }
3377 break;
3378
3379 case GUSICS_LINE_IN_MUTE:
3380 if (cp->type == AUDIO_MIXER_ENUM) {
3381 if (HAS_MIXER(sc))
3382 cp->un.ord = ic->sc_mute[GUSMIX_CHAN_LINE][ICSMIX_LEFT];
3383 else
3384 cp->un.ord =
3385 sc->sc_mixcontrol & GUSMASK_LINE_IN ? 1 : 0;
3386 error = 0;
3387 }
3388 break;
3389
3390 case GUSICS_MASTER_MUTE:
3391 if (cp->type == AUDIO_MIXER_ENUM) {
3392 if (HAS_MIXER(sc))
3393 cp->un.ord = ic->sc_mute[GUSMIX_CHAN_MASTER][ICSMIX_LEFT];
3394 else
3395 cp->un.ord =
3396 sc->sc_mixcontrol & GUSMASK_LINE_OUT ? 1 : 0;
3397 error = 0;
3398 }
3399 break;
3400
3401 case GUSICS_DAC_MUTE:
3402 if (cp->type == AUDIO_MIXER_ENUM) {
3403 cp->un.ord = ic->sc_mute[GUSMIX_CHAN_DAC][ICSMIX_LEFT];
3404 error = 0;
3405 }
3406 break;
3407
3408 case GUSICS_CD_MUTE:
3409 if (cp->type == AUDIO_MIXER_ENUM) {
3410 cp->un.ord = ic->sc_mute[GUSMIX_CHAN_CD][ICSMIX_LEFT];
3411 error = 0;
3412 }
3413 break;
3414
3415 case GUSICS_MASTER_LVL:
3416 if (cp->type == AUDIO_MIXER_VALUE) {
3417 vol.left = ic->sc_setting[GUSMIX_CHAN_MASTER][ICSMIX_LEFT];
3418 vol.right = ic->sc_setting[GUSMIX_CHAN_MASTER][ICSMIX_RIGHT];
3419 if (gus_from_vol(cp, &vol))
3420 error = 0;
3421 }
3422 break;
3423
3424 case GUSICS_MIC_IN_LVL: /* Microphone */
3425 if (cp->type == AUDIO_MIXER_VALUE) {
3426 vol.left = ic->sc_setting[GUSMIX_CHAN_MIC][ICSMIX_LEFT];
3427 vol.right = ic->sc_setting[GUSMIX_CHAN_MIC][ICSMIX_RIGHT];
3428 if (gus_from_vol(cp, &vol))
3429 error = 0;
3430 }
3431 break;
3432
3433 case GUSICS_LINE_IN_LVL: /* line in */
3434 if (cp->type == AUDIO_MIXER_VALUE) {
3435 vol.left = ic->sc_setting[GUSMIX_CHAN_LINE][ICSMIX_LEFT];
3436 vol.right = ic->sc_setting[GUSMIX_CHAN_LINE][ICSMIX_RIGHT];
3437 if (gus_from_vol(cp, &vol))
3438 error = 0;
3439 }
3440 break;
3441
3442
3443 case GUSICS_CD_LVL:
3444 if (cp->type == AUDIO_MIXER_VALUE) {
3445 vol.left = ic->sc_setting[GUSMIX_CHAN_CD][ICSMIX_LEFT];
3446 vol.right = ic->sc_setting[GUSMIX_CHAN_CD][ICSMIX_RIGHT];
3447 if (gus_from_vol(cp, &vol))
3448 error = 0;
3449 }
3450 break;
3451
3452 case GUSICS_DAC_LVL: /* dac out */
3453 if (cp->type == AUDIO_MIXER_VALUE) {
3454 vol.left = ic->sc_setting[GUSMIX_CHAN_DAC][ICSMIX_LEFT];
3455 vol.right = ic->sc_setting[GUSMIX_CHAN_DAC][ICSMIX_RIGHT];
3456 if (gus_from_vol(cp, &vol))
3457 error = 0;
3458 }
3459 break;
3460
3461
3462 case GUSICS_RECORD_SOURCE:
3463 if (cp->type == AUDIO_MIXER_ENUM) {
3464 /* Can't set anything else useful, sigh. */
3465 cp->un.ord = 0;
3466 }
3467 break;
3468
3469 default:
3470 return ENXIO;
3471 /*NOTREACHED*/
3472 }
3473 return error;
3474 }
3475
3476 STATIC void
3477 gusics_master_mute(ic, mute)
3478 struct ics2101_softc *ic;
3479 int mute;
3480 {
3481 ics2101_mix_mute(ic, GUSMIX_CHAN_MASTER, ICSMIX_LEFT, mute);
3482 ics2101_mix_mute(ic, GUSMIX_CHAN_MASTER, ICSMIX_RIGHT, mute);
3483 }
3484
3485 STATIC void
3486 gusics_mic_mute(ic, mute)
3487 struct ics2101_softc *ic;
3488 int mute;
3489 {
3490 ics2101_mix_mute(ic, GUSMIX_CHAN_MIC, ICSMIX_LEFT, mute);
3491 ics2101_mix_mute(ic, GUSMIX_CHAN_MIC, ICSMIX_RIGHT, mute);
3492 }
3493
3494 STATIC void
3495 gusics_linein_mute(ic, mute)
3496 struct ics2101_softc *ic;
3497 int mute;
3498 {
3499 ics2101_mix_mute(ic, GUSMIX_CHAN_LINE, ICSMIX_LEFT, mute);
3500 ics2101_mix_mute(ic, GUSMIX_CHAN_LINE, ICSMIX_RIGHT, mute);
3501 }
3502
3503 STATIC void
3504 gusics_cd_mute(ic, mute)
3505 struct ics2101_softc *ic;
3506 int mute;
3507 {
3508 ics2101_mix_mute(ic, GUSMIX_CHAN_CD, ICSMIX_LEFT, mute);
3509 ics2101_mix_mute(ic, GUSMIX_CHAN_CD, ICSMIX_RIGHT, mute);
3510 }
3511
3512 STATIC void
3513 gusics_dac_mute(ic, mute)
3514 struct ics2101_softc *ic;
3515 int mute;
3516 {
3517 ics2101_mix_mute(ic, GUSMIX_CHAN_DAC, ICSMIX_LEFT, mute);
3518 ics2101_mix_mute(ic, GUSMIX_CHAN_DAC, ICSMIX_RIGHT, mute);
3519 }
3520
3521 STATIC int
3522 gusmax_mixer_set_port(addr, cp)
3523 void *addr;
3524 mixer_ctrl_t *cp;
3525 {
3526 register struct ad1848_softc *ac = addr;
3527 register struct gus_softc *sc = ac->parent;
3528 struct ad1848_volume vol;
3529 int error = EINVAL;
3530
3531 DPRINTF(("gusmax_mixer_set_port: dev=%d type=%d\n", cp->dev, cp->type));
3532
3533 switch (cp->dev) {
3534 #if 0
3535 case GUSMAX_MIC_IN_LVL: /* Microphone */
3536 if (cp->type == AUDIO_MIXER_VALUE &&
3537 cp->un.value.num_channels == 1) {
3538 /* XXX enable/disable pre-MUX fixed gain */
3539 if (gus_to_vol(cp, &vol))
3540 error = ad1848_set_mic_gain(ac, &vol);
3541 }
3542 break;
3543 #endif
3544
3545 case GUSMAX_DAC_LVL: /* dac out */
3546 if (cp->type == AUDIO_MIXER_VALUE) {
3547 if (gus_to_vol(cp, &vol))
3548 error = ad1848_set_aux1_gain(ac, &vol);
3549 }
3550 break;
3551
3552 case GUSMAX_LINE_IN_LVL: /* line in */
3553 if (cp->type == AUDIO_MIXER_VALUE) {
3554 if (gus_to_vol(cp, &vol))
3555 error = cs4231_set_linein_gain(ac, &vol);
3556 }
3557 break;
3558
3559 case GUSMAX_MONO_LVL: /* mic/mono in */
3560 if (cp->type == AUDIO_MIXER_VALUE &&
3561 cp->un.value.num_channels == 1) {
3562 if (gus_to_vol(cp, &vol))
3563 error = cs4231_set_mono_gain(ac, &vol);
3564 }
3565 break;
3566
3567 case GUSMAX_CD_LVL: /* CD: AUX2 */
3568 if (cp->type == AUDIO_MIXER_VALUE) {
3569 if (gus_to_vol(cp, &vol))
3570 error = ad1848_set_aux2_gain(ac, &vol);
3571 }
3572 break;
3573
3574 case GUSMAX_MONITOR_LVL:
3575 if (cp->type == AUDIO_MIXER_VALUE &&
3576 cp->un.value.num_channels == 1) {
3577 vol.left = cp->un.value.level[AUDIO_MIXER_LEVEL_MONO];
3578 error = ad1848_set_mon_gain(ac, &vol);
3579 }
3580 break;
3581
3582 case GUSMAX_OUT_LVL: /* output volume */
3583 if (cp->type == AUDIO_MIXER_VALUE) {
3584 if (gus_to_vol(cp, &vol))
3585 error = ad1848_set_out_gain(ac, &vol);
3586 }
3587 break;
3588
3589 case GUSMAX_SPEAKER_LVL:
3590 if (cp->type == AUDIO_MIXER_VALUE &&
3591 cp->un.value.num_channels == 1) {
3592 if (gus_to_vol(cp, &vol)) {
3593 gus_speaker_ctl(sc, vol.left > AUDIO_MIN_GAIN ?
3594 SPKR_ON : SPKR_OFF);
3595 error = 0;
3596 }
3597 }
3598 break;
3599
3600 case GUSMAX_LINE_IN_MUTE:
3601 if (cp->type == AUDIO_MIXER_ENUM) {
3602 ac->line_mute = cp->un.ord ? 1 : 0;
3603 DPRINTF(("line mute %d\n", cp->un.ord));
3604 cs4231_mute_line(ac, ac->line_mute);
3605 gus_linein_ctl(sc, ac->line_mute ? SPKR_OFF : SPKR_ON);
3606 error = 0;
3607 }
3608 break;
3609
3610 case GUSMAX_DAC_MUTE:
3611 if (cp->type == AUDIO_MIXER_ENUM) {
3612 ac->aux1_mute = cp->un.ord ? 1 : 0;
3613 DPRINTF(("dac mute %d\n", cp->un.ord));
3614 ad1848_mute_aux1(ac, ac->aux1_mute);
3615 error = 0;
3616 }
3617 break;
3618
3619 case GUSMAX_CD_MUTE:
3620 if (cp->type == AUDIO_MIXER_ENUM) {
3621 ac->aux2_mute = cp->un.ord ? 1 : 0;
3622 DPRINTF(("cd mute %d\n", cp->un.ord));
3623 ad1848_mute_aux2(ac, ac->aux2_mute);
3624 error = 0;
3625 }
3626 break;
3627
3628 case GUSMAX_MONO_MUTE: /* Microphone */
3629 if (cp->type == AUDIO_MIXER_ENUM) {
3630 ac->mono_mute = cp->un.ord ? 1 : 0;
3631 DPRINTF(("mono mute %d\n", cp->un.ord));
3632 cs4231_mute_mono(ac, ac->mono_mute);
3633 gus_mic_ctl(sc, ac->mono_mute ? SPKR_OFF : SPKR_ON);
3634 error = 0;
3635 }
3636 break;
3637
3638 case GUSMAX_MONITOR_MUTE:
3639 if (cp->type == AUDIO_MIXER_ENUM) {
3640 ac->mon_mute = cp->un.ord ? 1 : 0;
3641 DPRINTF(("mono mute %d\n", cp->un.ord));
3642 cs4231_mute_monitor(ac, ac->mon_mute);
3643 error = 0;
3644 }
3645 break;
3646
3647 case GUSMAX_SPEAKER_MUTE:
3648 if (cp->type == AUDIO_MIXER_ENUM) {
3649 gus_speaker_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON);
3650 error = 0;
3651 }
3652 break;
3653
3654 case GUSMAX_REC_LVL: /* record level */
3655 if (cp->type == AUDIO_MIXER_VALUE) {
3656 if (gus_to_vol(cp, &vol))
3657 error = ad1848_set_rec_gain(ac, &vol);
3658 }
3659 break;
3660
3661 case GUSMAX_RECORD_SOURCE:
3662 if (cp->type == AUDIO_MIXER_ENUM) {
3663 error = ad1848_set_rec_port(ac, cp->un.ord);
3664 }
3665 break;
3666
3667 default:
3668 return ENXIO;
3669 /*NOTREACHED*/
3670 }
3671 return error;
3672 }
3673
3674 STATIC int
3675 gus_mixer_set_port(addr, cp)
3676 void *addr;
3677 mixer_ctrl_t *cp;
3678 {
3679 register struct gus_softc *sc = addr;
3680 register struct ics2101_softc *ic = &sc->sc_mixer;
3681 struct ad1848_volume vol;
3682 int error = EINVAL;
3683
3684 DPRINTF(("gus_mixer_set_port: dev=%d type=%d\n", cp->dev, cp->type));
3685
3686 if (!HAS_MIXER(sc) && cp->dev > GUSICS_MASTER_MUTE)
3687 return ENXIO;
3688
3689 switch (cp->dev) {
3690
3691 case GUSICS_MIC_IN_MUTE: /* Microphone */
3692 if (cp->type == AUDIO_MIXER_ENUM) {
3693 DPRINTF(("mic mute %d\n", cp->un.ord));
3694 if (HAS_MIXER(sc)) {
3695 gusics_mic_mute(ic, cp->un.ord);
3696 }
3697 gus_mic_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON);
3698 error = 0;
3699 }
3700 break;
3701
3702 case GUSICS_LINE_IN_MUTE:
3703 if (cp->type == AUDIO_MIXER_ENUM) {
3704 DPRINTF(("linein mute %d\n", cp->un.ord));
3705 if (HAS_MIXER(sc)) {
3706 gusics_linein_mute(ic, cp->un.ord);
3707 }
3708 gus_linein_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON);
3709 error = 0;
3710 }
3711 break;
3712
3713 case GUSICS_MASTER_MUTE:
3714 if (cp->type == AUDIO_MIXER_ENUM) {
3715 DPRINTF(("master mute %d\n", cp->un.ord));
3716 if (HAS_MIXER(sc)) {
3717 gusics_master_mute(ic, cp->un.ord);
3718 }
3719 gus_speaker_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON);
3720 error = 0;
3721 }
3722 break;
3723
3724 case GUSICS_DAC_MUTE:
3725 if (cp->type == AUDIO_MIXER_ENUM) {
3726 gusics_dac_mute(ic, cp->un.ord);
3727 error = 0;
3728 }
3729 break;
3730
3731 case GUSICS_CD_MUTE:
3732 if (cp->type == AUDIO_MIXER_ENUM) {
3733 gusics_cd_mute(ic, cp->un.ord);
3734 error = 0;
3735 }
3736 break;
3737
3738 case GUSICS_MASTER_LVL:
3739 if (cp->type == AUDIO_MIXER_VALUE) {
3740 if (gus_to_vol(cp, &vol)) {
3741 ics2101_mix_attenuate(ic,
3742 GUSMIX_CHAN_MASTER,
3743 ICSMIX_LEFT,
3744 vol.left);
3745 ics2101_mix_attenuate(ic,
3746 GUSMIX_CHAN_MASTER,
3747 ICSMIX_RIGHT,
3748 vol.right);
3749 error = 0;
3750 }
3751 }
3752 break;
3753
3754 case GUSICS_MIC_IN_LVL: /* Microphone */
3755 if (cp->type == AUDIO_MIXER_VALUE) {
3756 if (gus_to_vol(cp, &vol)) {
3757 ics2101_mix_attenuate(ic,
3758 GUSMIX_CHAN_MIC,
3759 ICSMIX_LEFT,
3760 vol.left);
3761 ics2101_mix_attenuate(ic,
3762 GUSMIX_CHAN_MIC,
3763 ICSMIX_RIGHT,
3764 vol.right);
3765 error = 0;
3766 }
3767 }
3768 break;
3769
3770 case GUSICS_LINE_IN_LVL: /* line in */
3771 if (cp->type == AUDIO_MIXER_VALUE) {
3772 if (gus_to_vol(cp, &vol)) {
3773 ics2101_mix_attenuate(ic,
3774 GUSMIX_CHAN_LINE,
3775 ICSMIX_LEFT,
3776 vol.left);
3777 ics2101_mix_attenuate(ic,
3778 GUSMIX_CHAN_LINE,
3779 ICSMIX_RIGHT,
3780 vol.right);
3781 error = 0;
3782 }
3783 }
3784 break;
3785
3786
3787 case GUSICS_CD_LVL:
3788 if (cp->type == AUDIO_MIXER_VALUE) {
3789 if (gus_to_vol(cp, &vol)) {
3790 ics2101_mix_attenuate(ic,
3791 GUSMIX_CHAN_CD,
3792 ICSMIX_LEFT,
3793 vol.left);
3794 ics2101_mix_attenuate(ic,
3795 GUSMIX_CHAN_CD,
3796 ICSMIX_RIGHT,
3797 vol.right);
3798 error = 0;
3799 }
3800 }
3801 break;
3802
3803 case GUSICS_DAC_LVL: /* dac out */
3804 if (cp->type == AUDIO_MIXER_VALUE) {
3805 if (gus_to_vol(cp, &vol)) {
3806 ics2101_mix_attenuate(ic,
3807 GUSMIX_CHAN_DAC,
3808 ICSMIX_LEFT,
3809 vol.left);
3810 ics2101_mix_attenuate(ic,
3811 GUSMIX_CHAN_DAC,
3812 ICSMIX_RIGHT,
3813 vol.right);
3814 error = 0;
3815 }
3816 }
3817 break;
3818
3819
3820 case GUSICS_RECORD_SOURCE:
3821 if (cp->type == AUDIO_MIXER_ENUM && cp->un.ord == 0) {
3822 /* Can't set anything else useful, sigh. */
3823 error = 0;
3824 }
3825 break;
3826
3827 default:
3828 return ENXIO;
3829 /*NOTREACHED*/
3830 }
3831 return error;
3832 }
3833
3834 STATIC int
3835 gusmax_mixer_query_devinfo(addr, dip)
3836 void *addr;
3837 register mixer_devinfo_t *dip;
3838 {
3839 DPRINTF(("gusmax_query_devinfo: index=%d\n", dip->index));
3840
3841 switch(dip->index) {
3842 #if 0
3843 case GUSMAX_MIC_IN_LVL: /* Microphone */
3844 dip->type = AUDIO_MIXER_VALUE;
3845 dip->mixer_class = GUSMAX_INPUT_CLASS;
3846 dip->prev = AUDIO_MIXER_LAST;
3847 dip->next = GUSMAX_MIC_IN_MUTE;
3848 strcpy(dip->label.name, AudioNmicrophone);
3849 dip->un.v.num_channels = 2;
3850 strcpy(dip->un.v.units.name, AudioNvolume);
3851 break;
3852 #endif
3853
3854 case GUSMAX_MONO_LVL: /* mono/microphone mixer */
3855 dip->type = AUDIO_MIXER_VALUE;
3856 dip->mixer_class = GUSMAX_INPUT_CLASS;
3857 dip->prev = AUDIO_MIXER_LAST;
3858 dip->next = GUSMAX_MONO_MUTE;
3859 strcpy(dip->label.name, AudioNmicrophone);
3860 dip->un.v.num_channels = 1;
3861 strcpy(dip->un.v.units.name, AudioNvolume);
3862 break;
3863
3864 case GUSMAX_DAC_LVL: /* dacout */
3865 dip->type = AUDIO_MIXER_VALUE;
3866 dip->mixer_class = GUSMAX_INPUT_CLASS;
3867 dip->prev = AUDIO_MIXER_LAST;
3868 dip->next = GUSMAX_DAC_MUTE;
3869 strcpy(dip->label.name, AudioNdac);
3870 dip->un.v.num_channels = 2;
3871 strcpy(dip->un.v.units.name, AudioNvolume);
3872 break;
3873
3874 case GUSMAX_LINE_IN_LVL: /* line */
3875 dip->type = AUDIO_MIXER_VALUE;
3876 dip->mixer_class = GUSMAX_INPUT_CLASS;
3877 dip->prev = AUDIO_MIXER_LAST;
3878 dip->next = GUSMAX_LINE_IN_MUTE;
3879 strcpy(dip->label.name, AudioNline);
3880 dip->un.v.num_channels = 2;
3881 strcpy(dip->un.v.units.name, AudioNvolume);
3882 break;
3883
3884 case GUSMAX_CD_LVL: /* cd */
3885 dip->type = AUDIO_MIXER_VALUE;
3886 dip->mixer_class = GUSMAX_INPUT_CLASS;
3887 dip->prev = AUDIO_MIXER_LAST;
3888 dip->next = GUSMAX_CD_MUTE;
3889 strcpy(dip->label.name, AudioNcd);
3890 dip->un.v.num_channels = 2;
3891 strcpy(dip->un.v.units.name, AudioNvolume);
3892 break;
3893
3894
3895 case GUSMAX_MONITOR_LVL: /* monitor level */
3896 dip->type = AUDIO_MIXER_VALUE;
3897 dip->mixer_class = GUSMAX_MONITOR_CLASS;
3898 dip->next = GUSMAX_MONITOR_MUTE;
3899 dip->prev = AUDIO_MIXER_LAST;
3900 strcpy(dip->label.name, AudioNmonitor);
3901 dip->un.v.num_channels = 1;
3902 strcpy(dip->un.v.units.name, AudioNvolume);
3903 break;
3904
3905 case GUSMAX_OUT_LVL: /* cs4231 output volume: not useful? */
3906 dip->type = AUDIO_MIXER_VALUE;
3907 dip->mixer_class = GUSMAX_MONITOR_CLASS;
3908 dip->prev = dip->next = AUDIO_MIXER_LAST;
3909 strcpy(dip->label.name, AudioNoutput);
3910 dip->un.v.num_channels = 2;
3911 strcpy(dip->un.v.units.name, AudioNvolume);
3912 break;
3913
3914 case GUSMAX_SPEAKER_LVL: /* fake speaker volume */
3915 dip->type = AUDIO_MIXER_VALUE;
3916 dip->mixer_class = GUSMAX_MONITOR_CLASS;
3917 dip->prev = AUDIO_MIXER_LAST;
3918 dip->next = GUSMAX_SPEAKER_MUTE;
3919 strcpy(dip->label.name, AudioNspeaker);
3920 dip->un.v.num_channels = 2;
3921 strcpy(dip->un.v.units.name, AudioNvolume);
3922 break;
3923
3924 case GUSMAX_LINE_IN_MUTE:
3925 dip->mixer_class = GUSMAX_INPUT_CLASS;
3926 dip->type = AUDIO_MIXER_ENUM;
3927 dip->prev = GUSMAX_LINE_IN_LVL;
3928 dip->next = AUDIO_MIXER_LAST;
3929 goto mute;
3930
3931 case GUSMAX_DAC_MUTE:
3932 dip->mixer_class = GUSMAX_INPUT_CLASS;
3933 dip->type = AUDIO_MIXER_ENUM;
3934 dip->prev = GUSMAX_DAC_LVL;
3935 dip->next = AUDIO_MIXER_LAST;
3936 goto mute;
3937
3938 case GUSMAX_CD_MUTE:
3939 dip->mixer_class = GUSMAX_INPUT_CLASS;
3940 dip->type = AUDIO_MIXER_ENUM;
3941 dip->prev = GUSMAX_CD_LVL;
3942 dip->next = AUDIO_MIXER_LAST;
3943 goto mute;
3944
3945 case GUSMAX_MONO_MUTE:
3946 dip->mixer_class = GUSMAX_INPUT_CLASS;
3947 dip->type = AUDIO_MIXER_ENUM;
3948 dip->prev = GUSMAX_MONO_LVL;
3949 dip->next = AUDIO_MIXER_LAST;
3950 goto mute;
3951
3952 case GUSMAX_MONITOR_MUTE:
3953 dip->mixer_class = GUSMAX_OUTPUT_CLASS;
3954 dip->type = AUDIO_MIXER_ENUM;
3955 dip->prev = GUSMAX_MONITOR_LVL;
3956 dip->next = AUDIO_MIXER_LAST;
3957 goto mute;
3958
3959 case GUSMAX_SPEAKER_MUTE:
3960 dip->mixer_class = GUSMAX_OUTPUT_CLASS;
3961 dip->type = AUDIO_MIXER_ENUM;
3962 dip->prev = GUSMAX_SPEAKER_LVL;
3963 dip->next = AUDIO_MIXER_LAST;
3964 mute:
3965 strcpy(dip->label.name, AudioNmute);
3966 dip->un.e.num_mem = 2;
3967 strcpy(dip->un.e.member[0].label.name, AudioNoff);
3968 dip->un.e.member[0].ord = 0;
3969 strcpy(dip->un.e.member[1].label.name, AudioNon);
3970 dip->un.e.member[1].ord = 1;
3971 break;
3972
3973 case GUSMAX_REC_LVL: /* record level */
3974 dip->type = AUDIO_MIXER_VALUE;
3975 dip->mixer_class = GUSMAX_RECORD_CLASS;
3976 dip->prev = AUDIO_MIXER_LAST;
3977 dip->next = GUSMAX_RECORD_SOURCE;
3978 strcpy(dip->label.name, AudioNrecord);
3979 dip->un.v.num_channels = 2;
3980 strcpy(dip->un.v.units.name, AudioNvolume);
3981 break;
3982
3983 case GUSMAX_RECORD_SOURCE:
3984 dip->mixer_class = GUSMAX_RECORD_CLASS;
3985 dip->type = AUDIO_MIXER_ENUM;
3986 dip->prev = GUSMAX_REC_LVL;
3987 dip->next = AUDIO_MIXER_LAST;
3988 strcpy(dip->label.name, AudioNsource);
3989 dip->un.e.num_mem = 4;
3990 strcpy(dip->un.e.member[0].label.name, AudioNoutput);
3991 dip->un.e.member[0].ord = DAC_IN_PORT;
3992 strcpy(dip->un.e.member[1].label.name, AudioNmicrophone);
3993 dip->un.e.member[1].ord = MIC_IN_PORT;
3994 strcpy(dip->un.e.member[2].label.name, AudioNdac);
3995 dip->un.e.member[2].ord = AUX1_IN_PORT;
3996 strcpy(dip->un.e.member[3].label.name, AudioNline);
3997 dip->un.e.member[3].ord = LINE_IN_PORT;
3998 break;
3999
4000 case GUSMAX_INPUT_CLASS: /* input class descriptor */
4001 dip->type = AUDIO_MIXER_CLASS;
4002 dip->mixer_class = GUSMAX_INPUT_CLASS;
4003 dip->next = dip->prev = AUDIO_MIXER_LAST;
4004 strcpy(dip->label.name, AudioCInputs);
4005 break;
4006
4007 case GUSMAX_OUTPUT_CLASS: /* output class descriptor */
4008 dip->type = AUDIO_MIXER_CLASS;
4009 dip->mixer_class = GUSMAX_OUTPUT_CLASS;
4010 dip->next = dip->prev = AUDIO_MIXER_LAST;
4011 strcpy(dip->label.name, AudioCOutputs);
4012 break;
4013
4014 case GUSMAX_MONITOR_CLASS: /* monitor class descriptor */
4015 dip->type = AUDIO_MIXER_CLASS;
4016 dip->mixer_class = GUSMAX_MONITOR_CLASS;
4017 dip->next = dip->prev = AUDIO_MIXER_LAST;
4018 strcpy(dip->label.name, AudioCMonitor);
4019 break;
4020
4021 case GUSMAX_RECORD_CLASS: /* record source class */
4022 dip->type = AUDIO_MIXER_CLASS;
4023 dip->mixer_class = GUSMAX_RECORD_CLASS;
4024 dip->next = dip->prev = AUDIO_MIXER_LAST;
4025 strcpy(dip->label.name, AudioCRecord);
4026 break;
4027
4028 default:
4029 return ENXIO;
4030 /*NOTREACHED*/
4031 }
4032 DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name));
4033 return 0;
4034 }
4035
4036 STATIC int
4037 gus_mixer_query_devinfo(addr, dip)
4038 void *addr;
4039 register mixer_devinfo_t *dip;
4040 {
4041 register struct gus_softc *sc = addr;
4042
4043 DPRINTF(("gusmax_query_devinfo: index=%d\n", dip->index));
4044
4045 if (!HAS_MIXER(sc) && dip->index > GUSICS_MASTER_MUTE)
4046 return ENXIO;
4047
4048 switch(dip->index) {
4049
4050 case GUSICS_MIC_IN_LVL: /* Microphone */
4051 dip->type = AUDIO_MIXER_VALUE;
4052 dip->mixer_class = GUSICS_INPUT_CLASS;
4053 dip->prev = AUDIO_MIXER_LAST;
4054 dip->next = GUSICS_MIC_IN_MUTE;
4055 strcpy(dip->label.name, AudioNmicrophone);
4056 dip->un.v.num_channels = 2;
4057 strcpy(dip->un.v.units.name, AudioNvolume);
4058 break;
4059
4060 case GUSICS_LINE_IN_LVL: /* line */
4061 dip->type = AUDIO_MIXER_VALUE;
4062 dip->mixer_class = GUSICS_INPUT_CLASS;
4063 dip->prev = AUDIO_MIXER_LAST;
4064 dip->next = GUSICS_LINE_IN_MUTE;
4065 strcpy(dip->label.name, AudioNline);
4066 dip->un.v.num_channels = 2;
4067 strcpy(dip->un.v.units.name, AudioNvolume);
4068 break;
4069
4070 case GUSICS_CD_LVL: /* cd */
4071 dip->type = AUDIO_MIXER_VALUE;
4072 dip->mixer_class = GUSICS_INPUT_CLASS;
4073 dip->prev = AUDIO_MIXER_LAST;
4074 dip->next = GUSICS_CD_MUTE;
4075 strcpy(dip->label.name, AudioNcd);
4076 dip->un.v.num_channels = 2;
4077 strcpy(dip->un.v.units.name, AudioNvolume);
4078 break;
4079
4080 case GUSICS_DAC_LVL: /* dacout */
4081 dip->type = AUDIO_MIXER_VALUE;
4082 dip->mixer_class = GUSICS_INPUT_CLASS;
4083 dip->prev = AUDIO_MIXER_LAST;
4084 dip->next = GUSICS_DAC_MUTE;
4085 strcpy(dip->label.name, AudioNdac);
4086 dip->un.v.num_channels = 2;
4087 strcpy(dip->un.v.units.name, AudioNvolume);
4088 break;
4089
4090 case GUSICS_MASTER_LVL: /* master output */
4091 dip->type = AUDIO_MIXER_VALUE;
4092 dip->mixer_class = GUSICS_OUTPUT_CLASS;
4093 dip->prev = AUDIO_MIXER_LAST;
4094 dip->next = GUSICS_MASTER_MUTE;
4095 strcpy(dip->label.name, AudioNvolume);
4096 dip->un.v.num_channels = 2;
4097 strcpy(dip->un.v.units.name, AudioNvolume);
4098 break;
4099
4100
4101 case GUSICS_LINE_IN_MUTE:
4102 dip->mixer_class = GUSICS_INPUT_CLASS;
4103 dip->type = AUDIO_MIXER_ENUM;
4104 dip->prev = GUSICS_LINE_IN_LVL;
4105 dip->next = AUDIO_MIXER_LAST;
4106 goto mute;
4107
4108 case GUSICS_DAC_MUTE:
4109 dip->mixer_class = GUSICS_INPUT_CLASS;
4110 dip->type = AUDIO_MIXER_ENUM;
4111 dip->prev = GUSICS_DAC_LVL;
4112 dip->next = AUDIO_MIXER_LAST;
4113 goto mute;
4114
4115 case GUSICS_CD_MUTE:
4116 dip->mixer_class = GUSICS_INPUT_CLASS;
4117 dip->type = AUDIO_MIXER_ENUM;
4118 dip->prev = GUSICS_CD_LVL;
4119 dip->next = AUDIO_MIXER_LAST;
4120 goto mute;
4121
4122 case GUSICS_MIC_IN_MUTE:
4123 dip->mixer_class = GUSICS_INPUT_CLASS;
4124 dip->type = AUDIO_MIXER_ENUM;
4125 dip->prev = GUSICS_MIC_IN_LVL;
4126 dip->next = AUDIO_MIXER_LAST;
4127 goto mute;
4128
4129 case GUSICS_MASTER_MUTE:
4130 dip->mixer_class = GUSICS_OUTPUT_CLASS;
4131 dip->type = AUDIO_MIXER_ENUM;
4132 dip->prev = GUSICS_MASTER_LVL;
4133 dip->next = AUDIO_MIXER_LAST;
4134 mute:
4135 strcpy(dip->label.name, AudioNmute);
4136 dip->un.e.num_mem = 2;
4137 strcpy(dip->un.e.member[0].label.name, AudioNoff);
4138 dip->un.e.member[0].ord = 0;
4139 strcpy(dip->un.e.member[1].label.name, AudioNon);
4140 dip->un.e.member[1].ord = 1;
4141 break;
4142
4143 case GUSICS_RECORD_SOURCE:
4144 dip->mixer_class = GUSICS_RECORD_CLASS;
4145 dip->type = AUDIO_MIXER_ENUM;
4146 dip->prev = dip->next = AUDIO_MIXER_LAST;
4147 strcpy(dip->label.name, AudioNsource);
4148 dip->un.e.num_mem = 1;
4149 strcpy(dip->un.e.member[0].label.name, AudioNoutput);
4150 dip->un.e.member[0].ord = GUSICS_MASTER_LVL;
4151 break;
4152
4153 case GUSICS_INPUT_CLASS:
4154 dip->type = AUDIO_MIXER_CLASS;
4155 dip->mixer_class = GUSICS_INPUT_CLASS;
4156 dip->next = dip->prev = AUDIO_MIXER_LAST;
4157 strcpy(dip->label.name, AudioCInputs);
4158 break;
4159
4160 case GUSICS_OUTPUT_CLASS:
4161 dip->type = AUDIO_MIXER_CLASS;
4162 dip->mixer_class = GUSICS_OUTPUT_CLASS;
4163 dip->next = dip->prev = AUDIO_MIXER_LAST;
4164 strcpy(dip->label.name, AudioCOutputs);
4165 break;
4166
4167 case GUSICS_RECORD_CLASS:
4168 dip->type = AUDIO_MIXER_CLASS;
4169 dip->mixer_class = GUSICS_RECORD_CLASS;
4170 dip->next = dip->prev = AUDIO_MIXER_LAST;
4171 strcpy(dip->label.name, AudioCRecord);
4172 break;
4173
4174 default:
4175 return ENXIO;
4176 /*NOTREACHED*/
4177 }
4178 DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name));
4179 return 0;
4180 }
4181
4182 STATIC int
4183 gus_query_encoding(addr, fp)
4184 void *addr;
4185 struct audio_encoding *fp;
4186 {
4187 switch (fp->index) {
4188 case 0:
4189 strcpy(fp->name, AudioEmulaw);
4190 fp->encoding = AUDIO_ENCODING_ULAW;
4191 fp->precision = 8;
4192 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
4193 break;
4194 case 1:
4195 strcpy(fp->name, AudioElinear);
4196 fp->encoding = AUDIO_ENCODING_SLINEAR;
4197 fp->precision = 8;
4198 fp->flags = 0;
4199 break;
4200 case 2:
4201 strcpy(fp->name, AudioElinear_le);
4202 fp->encoding = AUDIO_ENCODING_SLINEAR_LE;
4203 fp->precision = 16;
4204 fp->flags = 0;
4205 break;
4206 case 3:
4207 strcpy(fp->name, AudioEulinear);
4208 fp->encoding = AUDIO_ENCODING_ULINEAR;
4209 fp->precision = 8;
4210 fp->flags = 0;
4211 break;
4212 case 4:
4213 strcpy(fp->name, AudioEulinear_le);
4214 fp->encoding = AUDIO_ENCODING_ULINEAR_LE;
4215 fp->precision = 16;
4216 fp->flags = 0;
4217 break;
4218 case 5:
4219 strcpy(fp->name, AudioElinear_be);
4220 fp->encoding = AUDIO_ENCODING_SLINEAR_BE;
4221 fp->precision = 16;
4222 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
4223 break;
4224 case 6:
4225 strcpy(fp->name, AudioEulinear_be);
4226 fp->encoding = AUDIO_ENCODING_ULINEAR_BE;
4227 fp->precision = 16;
4228 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
4229 break;
4230 default:
4231 return(EINVAL);
4232 /*NOTREACHED*/
4233 }
4234 return (0);
4235 }
4236
4237 /*
4238 * Setup the ICS mixer in "transparent" mode: reset everything to a sensible
4239 * level. Levels as suggested by GUS SDK code.
4240 */
4241
4242 STATIC void
4243 gus_init_ics2101(sc)
4244 struct gus_softc *sc;
4245 {
4246 register int port = sc->sc_iobase;
4247 register struct ics2101_softc *ic = &sc->sc_mixer;
4248 sc->sc_mixer.sc_selio = port+GUS_MIXER_SELECT;
4249 sc->sc_mixer.sc_dataio = port+GUS_MIXER_DATA;
4250 sc->sc_mixer.sc_flags = (sc->sc_revision == 5) ? ICS_FLIP : 0;
4251
4252 ics2101_mix_attenuate(ic,
4253 GUSMIX_CHAN_MIC,
4254 ICSMIX_LEFT,
4255 ICSMIX_MIN_ATTN);
4256 ics2101_mix_attenuate(ic,
4257 GUSMIX_CHAN_MIC,
4258 ICSMIX_RIGHT,
4259 ICSMIX_MIN_ATTN);
4260 /*
4261 * Start with microphone muted by the mixer...
4262 */
4263 gusics_mic_mute(ic, 1);
4264
4265 /* ... and enabled by the GUS master mix control */
4266 gus_mic_ctl(sc, SPKR_ON);
4267
4268 ics2101_mix_attenuate(ic,
4269 GUSMIX_CHAN_LINE,
4270 ICSMIX_LEFT,
4271 ICSMIX_MIN_ATTN);
4272 ics2101_mix_attenuate(ic,
4273 GUSMIX_CHAN_LINE,
4274 ICSMIX_RIGHT,
4275 ICSMIX_MIN_ATTN);
4276
4277 ics2101_mix_attenuate(ic,
4278 GUSMIX_CHAN_CD,
4279 ICSMIX_LEFT,
4280 ICSMIX_MIN_ATTN);
4281 ics2101_mix_attenuate(ic,
4282 GUSMIX_CHAN_CD,
4283 ICSMIX_RIGHT,
4284 ICSMIX_MIN_ATTN);
4285
4286 ics2101_mix_attenuate(ic,
4287 GUSMIX_CHAN_DAC,
4288 ICSMIX_LEFT,
4289 ICSMIX_MIN_ATTN);
4290 ics2101_mix_attenuate(ic,
4291 GUSMIX_CHAN_DAC,
4292 ICSMIX_RIGHT,
4293 ICSMIX_MIN_ATTN);
4294
4295 ics2101_mix_attenuate(ic,
4296 ICSMIX_CHAN_4,
4297 ICSMIX_LEFT,
4298 ICSMIX_MAX_ATTN);
4299 ics2101_mix_attenuate(ic,
4300 ICSMIX_CHAN_4,
4301 ICSMIX_RIGHT,
4302 ICSMIX_MAX_ATTN);
4303
4304 ics2101_mix_attenuate(ic,
4305 GUSMIX_CHAN_MASTER,
4306 ICSMIX_LEFT,
4307 ICSMIX_MIN_ATTN);
4308 ics2101_mix_attenuate(ic,
4309 GUSMIX_CHAN_MASTER,
4310 ICSMIX_RIGHT,
4311 ICSMIX_MIN_ATTN);
4312 /* unmute other stuff: */
4313 gusics_cd_mute(ic, 0);
4314 gusics_dac_mute(ic, 0);
4315 gusics_linein_mute(ic, 0);
4316 return;
4317 }
4318
4319
4320 #endif /* NGUS */
4321