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