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