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