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