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