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