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