gus.c revision 1.19 1 /* $NetBSD: gus.c,v 1.19 1997/03/13 02:19:57 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 (void) ad1848_set_encoding(ac, encoding);
2130 return gus_set_encoding(sc, encoding);
2131 }
2132
2133 int
2134 gus_set_encoding(addr, encoding)
2135 void * addr;
2136 u_int encoding;
2137 {
2138 register struct gus_softc *sc = addr;
2139
2140 DPRINTF(("gus_set_encoding called\n"));
2141
2142 /* XXX todo: add alaw for codec */
2143 if (encoding != AUDIO_ENCODING_ULAW &&
2144 encoding != AUDIO_ENCODING_PCM16 &&
2145 encoding != AUDIO_ENCODING_PCM8)
2146 return EINVAL;
2147
2148 if (encoding != AUDIO_ENCODING_PCM16)
2149 sc->sc_precision = 8; /* XXX force it. */
2150
2151 sc->sc_encoding = encoding;
2152
2153 if (sc->sc_precision == 8) {
2154 sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~GUSMASK_DATA_SIZE16;
2155 sc->sc_voc[GUS_VOICE_RIGHT].voccntl &= ~GUSMASK_DATA_SIZE16;
2156 } else {
2157 sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_DATA_SIZE16;
2158 sc->sc_voc[GUS_VOICE_RIGHT].voccntl |= GUSMASK_DATA_SIZE16;
2159 }
2160 return 0;
2161 }
2162
2163 int
2164 gusmax_set_channels(addr, channels)
2165 void * addr;
2166 int channels;
2167 {
2168 register struct ad1848_softc *ac = addr;
2169 register struct gus_softc *sc = ac->parent;
2170 (void) ad1848_set_channels(ac, channels);
2171 return gus_set_channels(sc, channels);
2172 }
2173
2174 int
2175 gus_set_channels(addr, channels)
2176 void * addr;
2177 int channels;
2178 {
2179 register struct gus_softc *sc = addr;
2180
2181 DPRINTF(("gus_set_channels called\n"));
2182
2183 if (channels != 1 && channels != 2)
2184 return EINVAL;
2185
2186 sc->sc_channels = channels;
2187
2188 return 0;
2189 }
2190
2191 /*
2192 * Interface to the audio layer - set the data precision
2193 */
2194
2195 int
2196 gusmax_set_precision(addr, bits)
2197 void * addr;
2198 u_int bits;
2199 {
2200 register struct ad1848_softc *ac = addr;
2201 register struct gus_softc *sc = ac->parent;
2202
2203 (void) ad1848_set_precision(ac, bits);
2204 return gus_set_precision(sc, bits);
2205 }
2206
2207
2208 int
2209 gus_set_precision(addr, bits)
2210 void * addr;
2211 u_int bits;
2212 {
2213 register struct gus_softc *sc = addr;
2214
2215 DPRINTF(("gus_set_precision called\n"));
2216
2217 if (bits != 8 && bits != 16)
2218 return EINVAL;
2219
2220 if (sc->sc_encoding != AUDIO_ENCODING_PCM16 && bits != 8)
2221 /* If we're doing PCM8 or MULAW, it must be 8 bits. */
2222 return EINVAL;
2223
2224 sc->sc_precision = bits;
2225
2226 if (bits == 16) {
2227 sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_DATA_SIZE16;
2228 sc->sc_voc[GUS_VOICE_RIGHT].voccntl |= GUSMASK_DATA_SIZE16;
2229 } else {
2230 sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~GUSMASK_DATA_SIZE16;
2231 sc->sc_voc[GUS_VOICE_RIGHT].voccntl &= ~GUSMASK_DATA_SIZE16;
2232 }
2233 return 0;
2234 }
2235
2236 /*
2237 * Interface to the audio layer - set the blocksize to the correct number
2238 * of units
2239 */
2240
2241 int
2242 gusmax_round_blocksize(addr, blocksize)
2243 void * addr;
2244 int blocksize;
2245 {
2246 register struct ad1848_softc *ac = addr;
2247 register struct gus_softc *sc = ac->parent;
2248
2249 /* blocksize = ad1848_round_blocksize(ac, blocksize);*/
2250 return gus_round_blocksize(sc, blocksize);
2251 }
2252
2253 int
2254 gus_round_blocksize(addr, blocksize)
2255 void * addr;
2256 int blocksize;
2257 {
2258 register struct gus_softc *sc = addr;
2259
2260 DPRINTF(("gus_round_blocksize called\n"));
2261
2262 if (sc->sc_encoding == AUDIO_ENCODING_ULAW && blocksize > 32768)
2263 blocksize = 32768;
2264 else if (blocksize > 65536)
2265 blocksize = 65536;
2266
2267 if ((blocksize % GUS_BUFFER_MULTIPLE) != 0)
2268 blocksize = (blocksize / GUS_BUFFER_MULTIPLE + 1) *
2269 GUS_BUFFER_MULTIPLE;
2270
2271 /* set up temporary buffer to hold the deinterleave, if necessary
2272 for stereo output */
2273 if (sc->sc_deintr_buf) {
2274 FREE(sc->sc_deintr_buf, M_DEVBUF);
2275 sc->sc_deintr_buf = NULL;
2276 }
2277 MALLOC(sc->sc_deintr_buf, void *, blocksize>>1, M_DEVBUF, M_WAITOK);
2278
2279 sc->sc_blocksize = blocksize;
2280 /* multi-buffering not quite working yet. */
2281 sc->sc_nbufs = /*GUS_MEM_FOR_BUFFERS / blocksize*/ 2;
2282
2283 gus_set_chan_addrs(sc);
2284
2285 return blocksize;
2286 }
2287
2288 /*
2289 * Interfaces to the audio layer - return values from the software config
2290 * struct
2291 */
2292
2293 int
2294 gusmax_get_encoding(addr)
2295 void * addr;
2296 {
2297 register struct ad1848_softc *ac = addr;
2298 register struct gus_softc *sc = ac->parent;
2299 return gus_get_encoding(sc);
2300 }
2301
2302 int
2303 gus_get_encoding(addr)
2304 void * addr;
2305 {
2306 register struct gus_softc *sc = addr;
2307
2308 DPRINTF(("gus_get_encoding called\n"));
2309
2310 /* XXX TODO: codec stuff */
2311 return sc->sc_encoding;
2312 }
2313
2314 int
2315 gusmax_get_channels(addr)
2316 void * addr;
2317 {
2318 register struct ad1848_softc *ac = addr;
2319 register struct gus_softc *sc = ac->parent;
2320 return gus_get_channels(sc);
2321 }
2322
2323 int
2324 gus_get_channels(addr)
2325 void * addr;
2326 {
2327 register struct gus_softc *sc = addr;
2328
2329 DPRINTF(("gus_get_channels called\n"));
2330
2331 return sc->sc_channels;
2332 }
2333
2334 u_long
2335 gus_get_in_sr(addr)
2336 void * addr;
2337 {
2338 register struct gus_softc *sc = addr;
2339
2340 DPRINTF(("gus_get_in_sr called\n"));
2341 return sc->sc_irate;
2342 }
2343
2344 u_long
2345 gusmax_get_in_sr(addr)
2346 void * addr;
2347 {
2348 register struct ad1848_softc *ac = addr;
2349 register struct gus_softc *sc = ac->parent;
2350 return gus_get_in_sr(sc);
2351 }
2352
2353 u_long
2354 gusmax_get_out_sr(addr)
2355 void * addr;
2356 {
2357 register struct ad1848_softc *ac = addr;
2358 register struct gus_softc *sc = ac->parent;
2359 return gus_get_out_sr(sc);
2360 }
2361
2362 u_long
2363 gus_get_out_sr(addr)
2364 void * addr;
2365 {
2366 register struct gus_softc *sc = addr;
2367
2368 DPRINTF(("gus_get_out_sr called\n"));
2369 return sc->sc_orate;
2370 }
2371
2372 int
2373 gusmax_get_precision(addr)
2374 void * addr;
2375 {
2376 register struct ad1848_softc *sc = addr;
2377 return gus_get_precision(sc->parent);
2378 }
2379
2380 int
2381 gus_get_precision(addr)
2382 void * addr;
2383 {
2384 register struct gus_softc *sc = addr;
2385
2386 DPRINTF(("gus_get_precision called\n"));
2387
2388 return sc->sc_precision;
2389 }
2390
2391 int
2392 gus_get_out_gain(addr)
2393 caddr_t addr;
2394 {
2395 register struct gus_softc *sc = (struct gus_softc *) addr;
2396
2397 DPRINTF(("gus_get_out_gain called\n"));
2398 return sc->sc_ogain / 2;
2399 }
2400
2401 /*
2402 * Interface to the audio layer - set the sample rate of the output voices
2403 */
2404
2405 int
2406 gusmax_set_out_sr(addr, rate)
2407 void * addr;
2408 u_long rate;
2409 {
2410 register struct ad1848_softc *ac = addr;
2411 register struct gus_softc *sc = ac->parent;
2412 (void) ad1848_set_out_sr(ac, rate);
2413 return gus_set_out_sr(sc, rate);
2414 }
2415
2416 int
2417 gus_set_out_sr(addr, rate)
2418 void * addr;
2419 u_long rate;
2420 {
2421 register struct gus_softc *sc = addr;
2422
2423 DPRINTF(("gus_set_out_sr called\n"));
2424
2425 if (rate > gus_max_frequency[sc->sc_voices - GUS_MIN_VOICES])
2426 rate = gus_max_frequency[sc->sc_voices - GUS_MIN_VOICES];
2427
2428 sc->sc_orate = rate;
2429
2430 return 0;
2431 }
2432
2433 STATIC inline void gus_set_voices(sc, voices)
2434 struct gus_softc *sc;
2435 int voices;
2436 {
2437 register int port = sc->sc_iobase;
2438 /*
2439 * Select the active number of voices
2440 */
2441
2442 SELECT_GUS_REG(port, GUSREG_ACTIVE_VOICES);
2443 outb(port+GUS_DATA_HIGH, (voices-1) | 0xc0);
2444
2445 sc->sc_voices = voices;
2446 }
2447
2448 /*
2449 * Actually set the settings of various values on the card
2450 */
2451
2452 int
2453 gusmax_commit_settings(addr)
2454 void * addr;
2455 {
2456 register struct ad1848_softc *ac = addr;
2457 register struct gus_softc *sc = ac->parent;
2458
2459 (void) ad1848_commit_settings(ac);
2460 return gus_commit_settings(sc);
2461 }
2462
2463 /*
2464 * Commit the settings. Called at normal IPL.
2465 */
2466 int
2467 gus_commit_settings(addr)
2468 void * addr;
2469 {
2470 register struct gus_softc *sc = addr;
2471 int s;
2472
2473 DPRINTF(("gus_commit_settings called (gain = %d)\n",sc->sc_ogain));
2474
2475
2476 s = splgus();
2477
2478 gus_set_recrate(sc, sc->sc_irate);
2479 gus_set_volume(sc, GUS_VOICE_LEFT, sc->sc_ogain);
2480 gus_set_volume(sc, GUS_VOICE_RIGHT, sc->sc_ogain);
2481 gus_set_samprate(sc, GUS_VOICE_LEFT, sc->sc_orate);
2482 gus_set_samprate(sc, GUS_VOICE_RIGHT, sc->sc_orate);
2483 splx(s);
2484 gus_set_chan_addrs(sc);
2485
2486 return 0;
2487 }
2488
2489 STATIC void
2490 gus_set_chan_addrs(sc)
2491 struct gus_softc *sc;
2492 {
2493 /*
2494 * We use sc_nbufs * blocksize bytes of storage in the on-board GUS
2495 * ram.
2496 * For mono, each of the sc_nbufs buffers is DMA'd to in one chunk,
2497 * and both left & right channels play the same buffer.
2498 *
2499 * For stereo, each channel gets a contiguous half of the memory,
2500 * and each has sc_nbufs buffers of size blocksize/2.
2501 * Stereo data are deinterleaved in main memory before the DMA out
2502 * routines are called to queue the output.
2503 *
2504 * The blocksize per channel is kept in sc_chanblocksize.
2505 */
2506 if (sc->sc_channels == 2)
2507 sc->sc_chanblocksize = sc->sc_blocksize/2;
2508 else
2509 sc->sc_chanblocksize = sc->sc_blocksize;
2510
2511 sc->sc_voc[GUS_VOICE_LEFT].start_addr = GUS_MEM_OFFSET - 1;
2512 sc->sc_voc[GUS_VOICE_RIGHT].start_addr =
2513 (gus_dostereo && sc->sc_channels == 2 ? GUS_LEFT_RIGHT_OFFSET : 0)
2514 + GUS_MEM_OFFSET - 1;
2515 sc->sc_voc[GUS_VOICE_RIGHT].current_addr =
2516 sc->sc_voc[GUS_VOICE_RIGHT].start_addr + 1;
2517 sc->sc_voc[GUS_VOICE_RIGHT].end_addr =
2518 sc->sc_voc[GUS_VOICE_RIGHT].start_addr +
2519 sc->sc_nbufs * sc->sc_chanblocksize;
2520
2521 }
2522
2523 /*
2524 * Set the sample rate of the given voice. Called at splgus().
2525 */
2526
2527 STATIC void
2528 gus_set_samprate(sc, voice, freq)
2529 struct gus_softc *sc;
2530 int voice, freq;
2531 {
2532 register int port = sc->sc_iobase;
2533 unsigned int fc;
2534 u_long temp, f = (u_long) freq;
2535
2536 /*
2537 * calculate fc based on the number of active voices;
2538 * we need to use longs to preserve enough bits
2539 */
2540
2541 temp = (u_long) gus_max_frequency[sc->sc_voices-GUS_MIN_VOICES];
2542
2543 fc = (unsigned int)(((f << 9L) + (temp >> 1L)) / temp);
2544
2545 fc <<= 1;
2546
2547
2548 /*
2549 * Program the voice frequency, and set it in the voice data record
2550 */
2551
2552 outb(port+GUS_VOICE_SELECT, (unsigned char) voice);
2553 SELECT_GUS_REG(port, GUSREG_FREQ_CONTROL);
2554 outw(port+GUS_DATA_LOW, fc);
2555
2556 sc->sc_voc[voice].rate = freq;
2557
2558 }
2559
2560 /*
2561 * Interface to the audio layer - set the recording sampling rate
2562 */
2563
2564 int
2565 gusmax_set_in_sr(addr, rate)
2566 void * addr;
2567 u_long rate;
2568 {
2569 register struct ad1848_softc *ac = addr;
2570 register struct gus_softc *sc = ac->parent;
2571 (void) ad1848_set_in_sr(ac, rate);
2572 return gus_set_in_sr(sc, rate);
2573 }
2574
2575
2576 int
2577 gus_set_in_sr(addr, rate)
2578 void *addr;
2579 u_long rate;
2580 {
2581 register struct gus_softc *sc = addr;
2582
2583 DPRINTF(("gus_set_in_sr called\n"));
2584
2585 sc->sc_irate = rate;
2586
2587 return 0;
2588 }
2589 /*
2590 * Set the sample rate of the recording frequency. Formula is from the GUS
2591 * SDK. Called at splgus().
2592 */
2593
2594 STATIC void
2595 gus_set_recrate(sc, rate)
2596 struct gus_softc *sc;
2597 u_long rate;
2598 {
2599 register int port = sc->sc_iobase;
2600 u_char realrate;
2601 DPRINTF(("gus_set_recrate %lu\n", rate));
2602
2603 #if 0
2604 realrate = 9878400/(16*(rate+2)); /* formula from GUS docs */
2605 #endif
2606 realrate = (9878400 >> 4)/rate - 2; /* formula from code, sigh. */
2607
2608 SELECT_GUS_REG(port, GUSREG_SAMPLE_FREQ);
2609 outb(port+GUS_DATA_HIGH, realrate);
2610 }
2611
2612 /*
2613 * Interface to the audio layer - turn the output on or off. Note that some
2614 * of these bits are flipped in the register
2615 */
2616
2617 int
2618 gusmax_speaker_ctl(addr, newstate)
2619 void * addr;
2620 int newstate;
2621 {
2622 register struct ad1848_softc *sc = addr;
2623 return gus_speaker_ctl(sc->parent, newstate);
2624 }
2625
2626 int
2627 gus_speaker_ctl(addr, newstate)
2628 void * addr;
2629 int newstate;
2630 {
2631 register struct gus_softc *sc = (struct gus_softc *) addr;
2632
2633 /* Line out bit is flipped: 0 enables, 1 disables */
2634 if ((newstate == SPKR_ON) &&
2635 (sc->sc_mixcontrol & GUSMASK_LINE_OUT)) {
2636 sc->sc_mixcontrol &= ~GUSMASK_LINE_OUT;
2637 outb(sc->sc_iobase+GUS_MIX_CONTROL, sc->sc_mixcontrol);
2638 }
2639 if ((newstate == SPKR_OFF) &&
2640 (sc->sc_mixcontrol & GUSMASK_LINE_OUT) == 0) {
2641 sc->sc_mixcontrol |= GUSMASK_LINE_OUT;
2642 outb(sc->sc_iobase+GUS_MIX_CONTROL, sc->sc_mixcontrol);
2643 }
2644
2645 return 0;
2646 }
2647
2648 STATIC int
2649 gus_linein_ctl(addr, newstate)
2650 void * addr;
2651 int newstate;
2652 {
2653 register struct gus_softc *sc = (struct gus_softc *) addr;
2654
2655 /* Line in bit is flipped: 0 enables, 1 disables */
2656 if ((newstate == SPKR_ON) &&
2657 (sc->sc_mixcontrol & GUSMASK_LINE_IN)) {
2658 sc->sc_mixcontrol &= ~GUSMASK_LINE_IN;
2659 outb(sc->sc_iobase+GUS_MIX_CONTROL, sc->sc_mixcontrol);
2660 }
2661 if ((newstate == SPKR_OFF) &&
2662 (sc->sc_mixcontrol & GUSMASK_LINE_IN) == 0) {
2663 sc->sc_mixcontrol |= GUSMASK_LINE_IN;
2664 outb(sc->sc_iobase+GUS_MIX_CONTROL, sc->sc_mixcontrol);
2665 }
2666
2667 return 0;
2668 }
2669
2670 STATIC int
2671 gus_mic_ctl(addr, newstate)
2672 void * addr;
2673 int newstate;
2674 {
2675 register struct gus_softc *sc = (struct gus_softc *) addr;
2676
2677 /* Mic bit is normal: 1 enables, 0 disables */
2678 if ((newstate == SPKR_ON) &&
2679 (sc->sc_mixcontrol & GUSMASK_MIC_IN) == 0) {
2680 sc->sc_mixcontrol |= GUSMASK_MIC_IN;
2681 outb(sc->sc_iobase+GUS_MIX_CONTROL, sc->sc_mixcontrol);
2682 }
2683 if ((newstate == SPKR_OFF) &&
2684 (sc->sc_mixcontrol & GUSMASK_MIC_IN)) {
2685 sc->sc_mixcontrol &= ~GUSMASK_MIC_IN;
2686 outb(sc->sc_iobase+GUS_MIX_CONTROL, sc->sc_mixcontrol);
2687 }
2688
2689 return 0;
2690 }
2691
2692 /*
2693 * Set the end address of a give voice. Called at splgus()
2694 */
2695
2696 STATIC void
2697 gus_set_endaddr(sc, voice, addr)
2698 struct gus_softc *sc;
2699 int voice;
2700 u_long addr;
2701 {
2702 register int port = sc->sc_iobase;
2703
2704 sc->sc_voc[voice].end_addr = addr;
2705
2706 if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16)
2707 addr = convert_to_16bit(addr);
2708
2709 SELECT_GUS_REG(port, GUSREG_END_ADDR_HIGH);
2710 outw(port+GUS_DATA_LOW, ADDR_HIGH(addr));
2711 SELECT_GUS_REG(port, GUSREG_END_ADDR_LOW);
2712 outw(port+GUS_DATA_LOW, ADDR_LOW(addr));
2713
2714 }
2715
2716 #ifdef GUSPLAYDEBUG
2717 /*
2718 * Set current address. called at splgus()
2719 */
2720 STATIC void
2721 gus_set_curaddr(sc, voice, addr)
2722 struct gus_softc *sc;
2723 int voice;
2724 u_long addr;
2725 {
2726 register int port = sc->sc_iobase;
2727
2728 sc->sc_voc[voice].current_addr = addr;
2729
2730 if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16)
2731 addr = convert_to_16bit(addr);
2732
2733 outb(port+GUS_VOICE_SELECT, (unsigned char) voice);
2734
2735 SELECT_GUS_REG(port, GUSREG_CUR_ADDR_HIGH);
2736 outw(port+GUS_DATA_LOW, ADDR_HIGH(addr));
2737 SELECT_GUS_REG(port, GUSREG_CUR_ADDR_LOW);
2738 outw(port+GUS_DATA_LOW, ADDR_LOW(addr));
2739
2740 }
2741
2742 /*
2743 * Get current GUS playback address. Called at splgus().
2744 */
2745 STATIC u_long
2746 gus_get_curaddr(sc, voice)
2747 struct gus_softc *sc;
2748 int voice;
2749 {
2750 register int port = sc->sc_iobase;
2751 u_long addr;
2752
2753 outb(port+GUS_VOICE_SELECT, (unsigned char) voice);
2754 SELECT_GUS_REG(port, GUSREG_CUR_ADDR_HIGH|GUSREG_READ);
2755 addr = (inw(port+GUS_DATA_LOW) & 0x1fff) << 7;
2756 SELECT_GUS_REG(port, GUSREG_CUR_ADDR_LOW|GUSREG_READ);
2757 addr |= (inw(port+GUS_DATA_LOW) >> 9L) & 0x7f;
2758
2759 if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16)
2760 addr = (addr & 0xc0000) | ((addr & 0x1ffff) << 1); /* undo 16-bit change */
2761 DPRINTF(("gus voice %d curaddr %d end_addr %d\n",
2762 voice, addr, sc->sc_voc[voice].end_addr));
2763 /* XXX sanity check the address? */
2764
2765 return(addr);
2766 }
2767 #endif
2768
2769 /*
2770 * Convert an address value to a "16 bit" value - why this is necessary I
2771 * have NO idea
2772 */
2773
2774 STATIC u_long
2775 convert_to_16bit(address)
2776 u_long address;
2777 {
2778 u_long old_address;
2779
2780 old_address = address;
2781 address >>= 1;
2782 address &= 0x0001ffffL;
2783 address |= (old_address & 0x000c0000L);
2784
2785 return (address);
2786 }
2787
2788 /*
2789 * Write a value into the GUS's DRAM
2790 */
2791
2792 STATIC void
2793 guspoke(port, address, value)
2794 int port;
2795 long address;
2796 unsigned char value;
2797 {
2798
2799 /*
2800 * Select the DRAM address
2801 */
2802
2803 SELECT_GUS_REG(port, GUSREG_DRAM_ADDR_LOW);
2804 outw(port+GUS_DATA_LOW, (unsigned int) (address & 0xffff));
2805 SELECT_GUS_REG(port, GUSREG_DRAM_ADDR_HIGH);
2806 outb(port+GUS_DATA_HIGH, (unsigned char) ((address >> 16) & 0xff));
2807
2808 /*
2809 * Actually write the data
2810 */
2811
2812 outb(port+GUS_DRAM_DATA, value);
2813 }
2814
2815 /*
2816 * Read a value from the GUS's DRAM
2817 */
2818
2819 STATIC unsigned char
2820 guspeek(port, address)
2821 int port;
2822 u_long address;
2823 {
2824
2825 /*
2826 * Select the DRAM address
2827 */
2828
2829 SELECT_GUS_REG(port, GUSREG_DRAM_ADDR_LOW);
2830 outw(port+GUS_DATA_LOW, (unsigned int) (address & 0xffff));
2831 SELECT_GUS_REG(port, GUSREG_DRAM_ADDR_HIGH);
2832 outb(port+GUS_DATA_HIGH, (unsigned char) ((address >> 16) & 0xff));
2833
2834 /*
2835 * Read in the data from the board
2836 */
2837
2838 return (unsigned char) inb(port+GUS_DRAM_DATA);
2839 }
2840
2841 /*
2842 * Reset the Gravis UltraSound card, completely
2843 */
2844
2845 STATIC void
2846 gusreset(sc, voices)
2847 struct gus_softc *sc;
2848 int voices;
2849 {
2850 register int port = sc->sc_iobase;
2851 int i,s;
2852
2853 s = splgus();
2854
2855 /*
2856 * Reset the GF1 chip
2857 */
2858
2859 SELECT_GUS_REG(port, GUSREG_RESET);
2860 outb(port+GUS_DATA_HIGH, 0x00);
2861
2862 delay(500);
2863
2864 /*
2865 * Release reset
2866 */
2867
2868 SELECT_GUS_REG(port, GUSREG_RESET);
2869 outb(port+GUS_DATA_HIGH, GUSMASK_MASTER_RESET);
2870
2871 delay(500);
2872
2873 /*
2874 * Reset MIDI port as well
2875 */
2876
2877 outb(GUS_MIDI_CONTROL,MIDI_RESET);
2878
2879 delay(500);
2880
2881 outb(GUS_MIDI_CONTROL,0x00);
2882
2883 /*
2884 * Clear interrupts
2885 */
2886
2887 SELECT_GUS_REG(port, GUSREG_DMA_CONTROL);
2888 outb(port+GUS_DATA_HIGH, 0x00);
2889 SELECT_GUS_REG(port, GUSREG_TIMER_CONTROL);
2890 outb(port+GUS_DATA_HIGH, 0x00);
2891 SELECT_GUS_REG(port, GUSREG_SAMPLE_CONTROL);
2892 outb(port+GUS_DATA_HIGH, 0x00);
2893
2894 gus_set_voices(sc, voices);
2895
2896 inb(port+GUS_IRQ_STATUS);
2897 SELECT_GUS_REG(port, GUSREG_DMA_CONTROL);
2898 inb(port+GUS_DATA_HIGH);
2899 SELECT_GUS_REG(port, GUSREG_SAMPLE_CONTROL);
2900 inb(port+GUS_DATA_HIGH);
2901 SELECT_GUS_REG(port, GUSREG_IRQ_STATUS);
2902 inb(port+GUS_DATA_HIGH);
2903
2904 /*
2905 * Reset voice specific information
2906 */
2907
2908 for(i = 0; i < voices; i++) {
2909 outb(port+GUS_VOICE_SELECT, (unsigned char) i);
2910
2911 SELECT_GUS_REG(port, GUSREG_VOICE_CNTL);
2912
2913 sc->sc_voc[i].voccntl = GUSMASK_VOICE_STOPPED |
2914 GUSMASK_STOP_VOICE;
2915
2916 outb(port+GUS_DATA_HIGH, sc->sc_voc[i].voccntl);
2917
2918 sc->sc_voc[i].volcntl = GUSMASK_VOLUME_STOPPED |
2919 GUSMASK_STOP_VOLUME;
2920
2921 SELECT_GUS_REG(port, GUSREG_VOLUME_CONTROL);
2922 outb(port+GUS_DATA_HIGH, sc->sc_voc[i].volcntl);
2923
2924 delay(100);
2925
2926 gus_set_samprate(sc, i, 8000);
2927 SELECT_GUS_REG(port, GUSREG_START_ADDR_HIGH);
2928 outw(port+GUS_DATA_LOW, 0x0000);
2929 SELECT_GUS_REG(port, GUSREG_START_ADDR_LOW);
2930 outw(port+GUS_DATA_LOW, 0x0000);
2931 SELECT_GUS_REG(port, GUSREG_END_ADDR_HIGH);
2932 outw(port+GUS_DATA_LOW, 0x0000);
2933 SELECT_GUS_REG(port, GUSREG_END_ADDR_LOW);
2934 outw(port+GUS_DATA_LOW, 0x0000);
2935 SELECT_GUS_REG(port, GUSREG_VOLUME_RATE);
2936 outb(port+GUS_DATA_HIGH, 0x01);
2937 SELECT_GUS_REG(port, GUSREG_START_VOLUME);
2938 outb(port+GUS_DATA_HIGH, 0x10);
2939 SELECT_GUS_REG(port, GUSREG_END_VOLUME);
2940 outb(port+GUS_DATA_HIGH, 0xe0);
2941 SELECT_GUS_REG(port, GUSREG_CUR_VOLUME);
2942 outw(port+GUS_DATA_LOW, 0x0000);
2943
2944 SELECT_GUS_REG(port, GUSREG_CUR_ADDR_HIGH);
2945 outw(port+GUS_DATA_LOW, 0x0000);
2946 SELECT_GUS_REG(port, GUSREG_CUR_ADDR_LOW);
2947 outw(port+GUS_DATA_LOW, 0x0000);
2948 SELECT_GUS_REG(port, GUSREG_PAN_POS);
2949 outb(port+GUS_DATA_HIGH, 0x07);
2950 }
2951
2952 /*
2953 * Clear out any pending IRQs
2954 */
2955
2956 inb(port+GUS_IRQ_STATUS);
2957 SELECT_GUS_REG(port, GUSREG_DMA_CONTROL);
2958 inb(port+GUS_DATA_HIGH);
2959 SELECT_GUS_REG(port, GUSREG_SAMPLE_CONTROL);
2960 inb(port+GUS_DATA_HIGH);
2961 SELECT_GUS_REG(port, GUSREG_IRQ_STATUS);
2962 inb(port+GUS_DATA_HIGH);
2963
2964 SELECT_GUS_REG(port, GUSREG_RESET);
2965 outb(port+GUS_DATA_HIGH, GUSMASK_MASTER_RESET | GUSMASK_DAC_ENABLE |
2966 GUSMASK_IRQ_ENABLE);
2967
2968 splx(s);
2969 }
2970
2971
2972 STATIC void
2973 gus_init_cs4231(sc)
2974 struct gus_softc *sc;
2975 {
2976 register int port = sc->sc_iobase;
2977 u_char ctrl;
2978
2979 ctrl = (port & 0xf0) >> 4; /* set port address middle nibble */
2980 /*
2981 * The codec is a bit weird--swapped dma channels.
2982 */
2983 ctrl |= GUS_MAX_CODEC_ENABLE;
2984 if (sc->sc_drq >= 4)
2985 ctrl |= GUS_MAX_RECCHAN16;
2986 if (sc->sc_recdrq >= 4)
2987 ctrl |= GUS_MAX_PLAYCHAN16;
2988
2989 outb(port+GUS_MAX_CTRL, ctrl);
2990
2991 sc->sc_codec.sc_iobase = port+GUS_MAX_CODEC_BASE;
2992
2993 if (ad1848_probe(&sc->sc_codec) == 0) {
2994 sc->sc_flags &= ~GUS_CODEC_INSTALLED;
2995 } else {
2996 struct ad1848_volume vol = {AUDIO_MAX_GAIN, AUDIO_MAX_GAIN};
2997 struct audio_hw_if gusmax_hw_if = {
2998 gusopen,
2999 gusmax_close,
3000 NULL, /* drain */
3001 gusmax_set_in_sr,
3002 gusmax_get_in_sr,
3003 gusmax_set_out_sr,
3004 gusmax_get_out_sr,
3005
3006 ad1848_query_encoding, /* query encoding */
3007 gusmax_set_encoding,
3008 gusmax_get_encoding,
3009
3010 gusmax_set_precision,
3011 gusmax_get_precision,
3012
3013 gusmax_set_channels,
3014 gusmax_get_channels,
3015
3016 gusmax_round_blocksize,
3017
3018 gusmax_set_out_port,
3019 gusmax_get_out_port,
3020 gusmax_set_in_port,
3021 gusmax_get_in_port,
3022
3023 gusmax_commit_settings,
3024
3025 gusmax_expand, /* XXX use codec */
3026 mulaw_compress,
3027
3028 gusmax_dma_output,
3029 gusmax_dma_input,
3030 gusmax_halt_out_dma,
3031 gusmax_halt_in_dma,
3032 gusmax_cont_out_dma,
3033 gusmax_cont_in_dma,
3034
3035 gusmax_speaker_ctl,
3036
3037 gus_getdev,
3038 gus_setfd,
3039 gusmax_mixer_set_port,
3040 gusmax_mixer_get_port,
3041 gusmax_mixer_query_devinfo,
3042 1, /* full-duplex */
3043 0,
3044 };
3045 sc->sc_flags |= GUS_CODEC_INSTALLED;
3046 sc->sc_codec.parent = sc;
3047 sc->sc_codec.sc_drq = sc->sc_recdrq;
3048 sc->sc_codec.sc_recdrq = sc->sc_drq;
3049 gus_hw_if = gusmax_hw_if;
3050 /* enable line in and mic in the GUS mixer; the codec chip
3051 will do the real mixing for them. */
3052 sc->sc_mixcontrol &= ~GUSMASK_LINE_IN; /* 0 enables. */
3053 sc->sc_mixcontrol |= GUSMASK_MIC_IN; /* 1 enables. */
3054 outb(sc->sc_iobase+GUS_MIX_CONTROL, sc->sc_mixcontrol);
3055
3056 ad1848_attach(&sc->sc_codec);
3057 /* turn on pre-MUX microphone gain. */
3058 ad1848_set_mic_gain(&sc->sc_codec, &vol);
3059 }
3060 }
3061
3062
3063 /*
3064 * Return info about the audio device, for the AUDIO_GETINFO ioctl
3065 */
3066
3067 int
3068 gus_getdev(addr, dev)
3069 void * addr;
3070 struct audio_device *dev;
3071 {
3072 *dev = gus_device;
3073 return 0;
3074 }
3075
3076 /*
3077 * stubs (XXX)
3078 */
3079
3080 int
3081 gus_set_in_gain(addr, gain, balance)
3082 caddr_t addr;
3083 u_int gain;
3084 u_char balance;
3085 {
3086 DPRINTF(("gus_set_in_gain called\n"));
3087 return 0;
3088 }
3089
3090 int
3091 gus_get_in_gain(addr)
3092 caddr_t addr;
3093 {
3094 DPRINTF(("gus_get_in_gain called\n"));
3095 return 0;
3096 }
3097
3098 int
3099 gusmax_set_out_port(addr, port)
3100 void * addr;
3101 int port;
3102 {
3103 register struct ad1848_softc *sc = addr;
3104 return gus_set_out_port(sc->parent, port);
3105 }
3106
3107 int
3108 gus_set_out_port(addr, port)
3109 void * addr;
3110 int port;
3111 {
3112 register struct gus_softc *sc = addr;
3113 DPRINTF(("gus_set_out_port called\n"));
3114 sc->sc_out_port = port;
3115
3116 return 0;
3117 }
3118
3119 int
3120 gusmax_get_out_port(addr)
3121 void * addr;
3122 {
3123 register struct ad1848_softc *sc = addr;
3124 return gus_get_out_port(sc->parent);
3125 }
3126
3127 int
3128 gus_get_out_port(addr)
3129 void * addr;
3130 {
3131 register struct gus_softc *sc = addr;
3132 DPRINTF(("gus_get_out_port() called\n"));
3133 return sc->sc_out_port;
3134 }
3135
3136 int
3137 gusmax_set_in_port(addr, port)
3138 void * addr;
3139 int port;
3140 {
3141 register struct ad1848_softc *sc = addr;
3142 DPRINTF(("gusmax_set_in_port: %d\n", port));
3143
3144 switch(port) {
3145 case GUSMAX_MONO_LVL:
3146 port = MIC_IN_PORT;
3147 break;
3148 case GUSMAX_LINE_IN_LVL:
3149 port = LINE_IN_PORT;
3150 break;
3151 case GUSMAX_DAC_LVL:
3152 port = AUX1_IN_PORT;
3153 break;
3154 case GUSMAX_MIX_IN:
3155 port = DAC_IN_PORT;
3156 break;
3157 default:
3158 return(EINVAL);
3159 /*NOTREACHED*/
3160 }
3161 return(ad1848_set_rec_port(sc, port));
3162 }
3163
3164 int
3165 gusmax_get_in_port(addr)
3166 void * addr;
3167 {
3168 register struct ad1848_softc *sc = addr;
3169 int port = GUSMAX_MONO_LVL;
3170
3171 switch(ad1848_get_rec_port(sc)) {
3172 case MIC_IN_PORT:
3173 port = GUSMAX_MONO_LVL;
3174 break;
3175 case LINE_IN_PORT:
3176 port = GUSMAX_LINE_IN_LVL;
3177 break;
3178 case DAC_IN_PORT:
3179 port = GUSMAX_MIX_IN;
3180 break;
3181 case AUX1_IN_PORT:
3182 port = GUSMAX_DAC_LVL;
3183 break;
3184 }
3185
3186 DPRINTF(("gusmax_get_in_port: %d\n", port));
3187
3188 return(port);
3189 }
3190
3191 int
3192 gus_set_in_port(addr, port)
3193 void * addr;
3194 int port;
3195 {
3196 register struct gus_softc *sc = addr;
3197 DPRINTF(("gus_set_in_port called\n"));
3198 /*
3199 * On the GUS with ICS mixer, the ADC input is after the mixer stage,
3200 * so we can't set the input port.
3201 *
3202 * On the GUS with CS4231 codec/mixer, see gusmax_set_in_port().
3203 */
3204 sc->sc_in_port = port;
3205
3206 return 0;
3207 }
3208
3209
3210 int
3211 gus_get_in_port(addr)
3212 void * addr;
3213 {
3214 register struct gus_softc *sc = addr;
3215 DPRINTF(("gus_get_in_port called\n"));
3216 return sc->sc_in_port;
3217 }
3218
3219
3220 int
3221 gusmax_dma_input(addr, buf, size, callback, arg)
3222 void * addr;
3223 void *buf;
3224 int size;
3225 void (*callback) __P((void *));
3226 void *arg;
3227 {
3228 register struct ad1848_softc *sc = addr;
3229 return gus_dma_input(sc->parent, buf, size, callback, arg);
3230 }
3231
3232 /*
3233 * Start sampling the input source into the requested DMA buffer.
3234 * Called at splgus(), either from top-half or from interrupt handler.
3235 */
3236 int
3237 gus_dma_input(addr, buf, size, callback, arg)
3238 void * addr;
3239 void *buf;
3240 int size;
3241 void (*callback) __P((void *));
3242 void *arg;
3243 {
3244 register struct gus_softc *sc = addr;
3245 register int port = sc->sc_iobase;
3246 register u_char dmac;
3247 DMAPRINTF(("gus_dma_input called\n"));
3248
3249 /*
3250 * Sample SIZE bytes of data from the card, into buffer at BUF.
3251 */
3252
3253 if (sc->sc_precision == 16)
3254 return EINVAL; /* XXX */
3255
3256 /* set DMA modes */
3257 dmac = GUSMASK_SAMPLE_IRQ|GUSMASK_SAMPLE_START;
3258 if (sc->sc_recdrq >= 4)
3259 dmac |= GUSMASK_SAMPLE_DATA16;
3260 if (sc->sc_encoding == AUDIO_ENCODING_ULAW ||
3261 sc->sc_encoding == AUDIO_ENCODING_PCM8)
3262 dmac |= GUSMASK_SAMPLE_INVBIT;
3263 if (sc->sc_channels == 2)
3264 dmac |= GUSMASK_SAMPLE_STEREO;
3265 isa_dmastart(DMAMODE_READ, (caddr_t) buf, size, sc->sc_recdrq);
3266
3267 DMAPRINTF(("gus_dma_input isa_dmastarted\n"));
3268 sc->sc_flags |= GUS_DMAIN_ACTIVE;
3269 sc->sc_dmainintr = callback;
3270 sc->sc_inarg = arg;
3271 sc->sc_dmaincnt = size;
3272 sc->sc_dmainaddr = buf;
3273
3274 SELECT_GUS_REG(port, GUSREG_SAMPLE_CONTROL);
3275 outb(port+GUS_DATA_HIGH, dmac); /* Go! */
3276
3277
3278 DMAPRINTF(("gus_dma_input returning\n"));
3279
3280 return 0;
3281 }
3282
3283 STATIC int
3284 gus_dmain_intr(sc)
3285 struct gus_softc *sc;
3286 {
3287 void (*callback) __P((void *));
3288 void *arg;
3289
3290 DMAPRINTF(("gus_dmain_intr called\n"));
3291 if (sc->sc_dmainintr) {
3292 isa_dmadone(DMAMODE_READ, sc->sc_dmainaddr, sc->sc_dmaincnt - 1,
3293 sc->sc_recdrq);
3294 callback = sc->sc_dmainintr;
3295 arg = sc->sc_inarg;
3296
3297 sc->sc_dmainaddr = 0;
3298 sc->sc_dmaincnt = 0;
3299 sc->sc_dmainintr = 0;
3300 sc->sc_inarg = 0;
3301
3302 sc->sc_flags &= ~GUS_DMAIN_ACTIVE;
3303 DMAPRINTF(("calling dmain_intr callback %x(%x)\n", callback, arg));
3304 (*callback)(arg);
3305 return 1;
3306 } else {
3307 DMAPRINTF(("gus_dmain_intr false?\n"));
3308 return 0; /* XXX ??? */
3309 }
3310 }
3311
3312 int
3313 gusmax_halt_out_dma(addr)
3314 void * addr;
3315 {
3316 register struct ad1848_softc *sc = addr;
3317 return gus_halt_out_dma(sc->parent);
3318 }
3319
3320
3321 int
3322 gusmax_halt_in_dma(addr)
3323 void * addr;
3324 {
3325 register struct ad1848_softc *sc = addr;
3326 return gus_halt_in_dma(sc->parent);
3327 }
3328
3329 int
3330 gusmax_cont_out_dma(addr)
3331 void * addr;
3332 {
3333 register struct ad1848_softc *sc = addr;
3334 return gus_cont_out_dma(sc->parent);
3335 }
3336
3337 int
3338 gusmax_cont_in_dma(addr)
3339 void * addr;
3340 {
3341 register struct ad1848_softc *sc = addr;
3342 return gus_cont_in_dma(sc->parent);
3343 }
3344
3345 /*
3346 * Stop any DMA output. Called at splgus().
3347 */
3348 int
3349 gus_halt_out_dma(addr)
3350 void * addr;
3351 {
3352 register struct gus_softc *sc = addr;
3353 register int port = sc->sc_iobase;
3354
3355 DMAPRINTF(("gus_halt_out_dma called\n"));
3356 /*
3357 * Make sure the GUS _isn't_ setup for DMA
3358 */
3359
3360 SELECT_GUS_REG(port, GUSREG_DMA_CONTROL);
3361 outb(sc->sc_iobase+GUS_DATA_HIGH, 0);
3362
3363 untimeout(gus_dmaout_timeout, sc);
3364 isa_dmaabort(sc->sc_drq);
3365 sc->sc_flags &= ~(GUS_DMAOUT_ACTIVE|GUS_LOCKED);
3366 sc->sc_dmaoutintr = 0;
3367 sc->sc_outarg = 0;
3368 sc->sc_dmaoutaddr = 0;
3369 sc->sc_dmaoutcnt = 0;
3370 sc->sc_dmabuf = 0;
3371 sc->sc_bufcnt = 0;
3372 sc->sc_playbuf = -1;
3373 /* also stop playing */
3374 gus_stop_voice(sc, GUS_VOICE_LEFT, 1);
3375 gus_stop_voice(sc, GUS_VOICE_RIGHT, 0);
3376
3377 return 0;
3378 }
3379
3380 /*
3381 * Stop any DMA output. Called at splgus().
3382 */
3383 int
3384 gus_halt_in_dma(addr)
3385 void * addr;
3386 {
3387 register struct gus_softc *sc = addr;
3388 register int port = sc->sc_iobase;
3389 DMAPRINTF(("gus_halt_in_dma called\n"));
3390
3391 /*
3392 * Make sure the GUS _isn't_ setup for DMA
3393 */
3394
3395 SELECT_GUS_REG(port, GUSREG_SAMPLE_CONTROL);
3396 outb(port+GUS_DATA_HIGH,
3397 inb(port+GUS_DATA_HIGH) & ~(GUSMASK_SAMPLE_START|GUSMASK_SAMPLE_IRQ));
3398
3399 isa_dmaabort(sc->sc_recdrq);
3400 sc->sc_flags &= ~GUS_DMAIN_ACTIVE;
3401 sc->sc_dmainintr = 0;
3402 sc->sc_inarg = 0;
3403 sc->sc_dmainaddr = 0;
3404 sc->sc_dmaincnt = 0;
3405
3406 return 0;
3407 }
3408
3409 int
3410 gus_cont_out_dma(addr)
3411 void * addr;
3412 {
3413 DPRINTF(("gus_cont_out_dma called\n"));
3414 return EOPNOTSUPP;
3415 }
3416
3417 int
3418 gus_cont_in_dma(addr)
3419 void * addr;
3420 {
3421 DPRINTF(("gus_cont_in_dma called\n"));
3422 return EOPNOTSUPP;
3423 }
3424
3425
3426 STATIC int
3427 gus_setfd(addr, flag)
3428 void *addr;
3429 int flag;
3430 {
3431 if (gus_hw_if.full_duplex == 0)
3432 return ENOTTY;
3433
3434 return(0); /* nothing fancy to do. */
3435 }
3436
3437 STATIC __inline int
3438 gus_to_vol(cp, vol)
3439 mixer_ctrl_t *cp;
3440 struct ad1848_volume *vol;
3441 {
3442 if (cp->un.value.num_channels == 1) {
3443 vol->left = vol->right = cp->un.value.level[AUDIO_MIXER_LEVEL_MONO];
3444 return(1);
3445 }
3446 else if (cp->un.value.num_channels == 2) {
3447 vol->left = cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT];
3448 vol->right = cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT];
3449 return(1);
3450 }
3451 return(0);
3452 }
3453
3454 STATIC __inline int
3455 gus_from_vol(cp, vol)
3456 mixer_ctrl_t *cp;
3457 struct ad1848_volume *vol;
3458 {
3459 if (cp->un.value.num_channels == 1) {
3460 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = vol->left;
3461 return(1);
3462 }
3463 else if (cp->un.value.num_channels == 2) {
3464 cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = vol->left;
3465 cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = vol->right;
3466 return(1);
3467 }
3468 return(0);
3469 }
3470
3471 STATIC int
3472 gusmax_mixer_get_port(addr, cp)
3473 void *addr;
3474 mixer_ctrl_t *cp;
3475 {
3476 register struct ad1848_softc *ac = addr;
3477 register struct gus_softc *sc = ac->parent;
3478 struct ad1848_volume vol;
3479 int error = EINVAL;
3480
3481 DPRINTF(("gusmax_mixer_get_port: port=%d\n", cp->dev));
3482
3483 switch (cp->dev) {
3484 #if 0 /* use mono level instead */
3485 case GUSMAX_MIC_IN_LVL: /* Microphone */
3486 if (cp->type == AUDIO_MIXER_VALUE) {
3487 error = ad1848_get_mic_gain(ac, &vol);
3488 if (!error)
3489 gus_from_vol(cp, &vol);
3490 }
3491 break;
3492 #endif
3493
3494 case GUSMAX_DAC_LVL: /* dac out */
3495 if (cp->type == AUDIO_MIXER_VALUE) {
3496 error = ad1848_get_aux1_gain(ac, &vol);
3497 if (!error)
3498 gus_from_vol(cp, &vol);
3499 }
3500 break;
3501
3502 case GUSMAX_LINE_IN_LVL: /* line in */
3503 if (cp->type == AUDIO_MIXER_VALUE) {
3504 error = cs4231_get_linein_gain(ac, &vol);
3505 if (!error)
3506 gus_from_vol(cp, &vol);
3507 }
3508 break;
3509
3510 case GUSMAX_MONO_LVL: /* mono */
3511 if (cp->type == AUDIO_MIXER_VALUE &&
3512 cp->un.value.num_channels == 1) {
3513 error = cs4231_get_mono_gain(ac, &vol);
3514 if (!error)
3515 gus_from_vol(cp, &vol);
3516 }
3517 break;
3518
3519 case GUSMAX_CD_LVL: /* CD */
3520 if (cp->type == AUDIO_MIXER_VALUE) {
3521 error = ad1848_get_aux2_gain(ac, &vol);
3522 if (!error)
3523 gus_from_vol(cp, &vol);
3524 }
3525 break;
3526
3527 case GUSMAX_MONITOR_LVL: /* monitor level */
3528 if (cp->type == AUDIO_MIXER_VALUE &&
3529 cp->un.value.num_channels == 1) {
3530 error = ad1848_get_mon_gain(ac, &vol);
3531 if (!error)
3532 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
3533 vol.left;
3534 }
3535 break;
3536
3537 case GUSMAX_OUT_LVL: /* output level */
3538 if (cp->type == AUDIO_MIXER_VALUE) {
3539 error = ad1848_get_out_gain(ac, &vol);
3540 if (!error)
3541 gus_from_vol(cp, &vol);
3542 }
3543 break;
3544
3545 case GUSMAX_SPEAKER_LVL: /* fake speaker for mute naming */
3546 if (cp->type == AUDIO_MIXER_VALUE) {
3547 if (sc->sc_mixcontrol & GUSMASK_LINE_OUT)
3548 vol.left = vol.right = AUDIO_MAX_GAIN;
3549 else
3550 vol.left = vol.right = AUDIO_MIN_GAIN;
3551 error = 0;
3552 gus_from_vol(cp, &vol);
3553 }
3554 break;
3555
3556 case GUSMAX_LINE_IN_MUTE:
3557 if (cp->type == AUDIO_MIXER_ENUM) {
3558 cp->un.ord = ac->line_mute;
3559 error = 0;
3560 }
3561 break;
3562
3563
3564 case GUSMAX_DAC_MUTE:
3565 if (cp->type == AUDIO_MIXER_ENUM) {
3566 cp->un.ord = ac->aux1_mute;
3567 error = 0;
3568 }
3569 break;
3570
3571 case GUSMAX_CD_MUTE:
3572 if (cp->type == AUDIO_MIXER_ENUM) {
3573 cp->un.ord = ac->aux2_mute;
3574 error = 0;
3575 }
3576 break;
3577
3578 case GUSMAX_MONO_MUTE:
3579 if (cp->type == AUDIO_MIXER_ENUM) {
3580 cp->un.ord = ac->mono_mute;
3581 error = 0;
3582 }
3583 break;
3584
3585 case GUSMAX_MONITOR_MUTE:
3586 if (cp->type == AUDIO_MIXER_ENUM) {
3587 cp->un.ord = ac->mon_mute;
3588 error = 0;
3589 }
3590 break;
3591
3592 case GUSMAX_SPEAKER_MUTE:
3593 if (cp->type == AUDIO_MIXER_ENUM) {
3594 cp->un.ord = sc->sc_mixcontrol & GUSMASK_LINE_OUT ? 1 : 0;
3595 error = 0;
3596 }
3597 break;
3598
3599 case GUSMAX_REC_LVL: /* record level */
3600 if (cp->type == AUDIO_MIXER_VALUE) {
3601 error = ad1848_get_rec_gain(ac, &vol);
3602 if (!error)
3603 gus_from_vol(cp, &vol);
3604 }
3605 break;
3606
3607 case GUSMAX_RECORD_SOURCE:
3608 if (cp->type == AUDIO_MIXER_ENUM) {
3609 cp->un.ord = ad1848_get_rec_port(ac);
3610 error = 0;
3611 }
3612 break;
3613
3614 default:
3615 error = ENXIO;
3616 break;
3617 }
3618
3619 return(error);
3620 }
3621
3622 STATIC int
3623 gus_mixer_get_port(addr, cp)
3624 void *addr;
3625 mixer_ctrl_t *cp;
3626 {
3627 register struct gus_softc *sc = addr;
3628 register struct ics2101_softc *ic = &sc->sc_mixer;
3629 struct ad1848_volume vol;
3630 int error = EINVAL;
3631
3632 DPRINTF(("gus_mixer_get_port: dev=%d type=%d\n", cp->dev, cp->type));
3633
3634 if (!HAS_MIXER(sc) && cp->dev > GUSICS_MASTER_MUTE)
3635 return ENXIO;
3636
3637 switch (cp->dev) {
3638
3639 case GUSICS_MIC_IN_MUTE: /* Microphone */
3640 if (cp->type == AUDIO_MIXER_ENUM) {
3641 if (HAS_MIXER(sc))
3642 cp->un.ord = ic->sc_mute[GUSMIX_CHAN_MIC][ICSMIX_LEFT];
3643 else
3644 cp->un.ord =
3645 sc->sc_mixcontrol & GUSMASK_MIC_IN ? 0 : 1;
3646 error = 0;
3647 }
3648 break;
3649
3650 case GUSICS_LINE_IN_MUTE:
3651 if (cp->type == AUDIO_MIXER_ENUM) {
3652 if (HAS_MIXER(sc))
3653 cp->un.ord = ic->sc_mute[GUSMIX_CHAN_LINE][ICSMIX_LEFT];
3654 else
3655 cp->un.ord =
3656 sc->sc_mixcontrol & GUSMASK_LINE_IN ? 1 : 0;
3657 error = 0;
3658 }
3659 break;
3660
3661 case GUSICS_MASTER_MUTE:
3662 if (cp->type == AUDIO_MIXER_ENUM) {
3663 if (HAS_MIXER(sc))
3664 cp->un.ord = ic->sc_mute[GUSMIX_CHAN_MASTER][ICSMIX_LEFT];
3665 else
3666 cp->un.ord =
3667 sc->sc_mixcontrol & GUSMASK_LINE_OUT ? 1 : 0;
3668 error = 0;
3669 }
3670 break;
3671
3672 case GUSICS_DAC_MUTE:
3673 if (cp->type == AUDIO_MIXER_ENUM) {
3674 cp->un.ord = ic->sc_mute[GUSMIX_CHAN_DAC][ICSMIX_LEFT];
3675 error = 0;
3676 }
3677 break;
3678
3679 case GUSICS_CD_MUTE:
3680 if (cp->type == AUDIO_MIXER_ENUM) {
3681 cp->un.ord = ic->sc_mute[GUSMIX_CHAN_CD][ICSMIX_LEFT];
3682 error = 0;
3683 }
3684 break;
3685
3686 case GUSICS_MASTER_LVL:
3687 if (cp->type == AUDIO_MIXER_VALUE) {
3688 vol.left = ic->sc_setting[GUSMIX_CHAN_MASTER][ICSMIX_LEFT];
3689 vol.right = ic->sc_setting[GUSMIX_CHAN_MASTER][ICSMIX_RIGHT];
3690 if (gus_from_vol(cp, &vol))
3691 error = 0;
3692 }
3693 break;
3694
3695 case GUSICS_MIC_IN_LVL: /* Microphone */
3696 if (cp->type == AUDIO_MIXER_VALUE) {
3697 vol.left = ic->sc_setting[GUSMIX_CHAN_MIC][ICSMIX_LEFT];
3698 vol.right = ic->sc_setting[GUSMIX_CHAN_MIC][ICSMIX_RIGHT];
3699 if (gus_from_vol(cp, &vol))
3700 error = 0;
3701 }
3702 break;
3703
3704 case GUSICS_LINE_IN_LVL: /* line in */
3705 if (cp->type == AUDIO_MIXER_VALUE) {
3706 vol.left = ic->sc_setting[GUSMIX_CHAN_LINE][ICSMIX_LEFT];
3707 vol.right = ic->sc_setting[GUSMIX_CHAN_LINE][ICSMIX_RIGHT];
3708 if (gus_from_vol(cp, &vol))
3709 error = 0;
3710 }
3711 break;
3712
3713
3714 case GUSICS_CD_LVL:
3715 if (cp->type == AUDIO_MIXER_VALUE) {
3716 vol.left = ic->sc_setting[GUSMIX_CHAN_CD][ICSMIX_LEFT];
3717 vol.right = ic->sc_setting[GUSMIX_CHAN_CD][ICSMIX_RIGHT];
3718 if (gus_from_vol(cp, &vol))
3719 error = 0;
3720 }
3721 break;
3722
3723 case GUSICS_DAC_LVL: /* dac out */
3724 if (cp->type == AUDIO_MIXER_VALUE) {
3725 vol.left = ic->sc_setting[GUSMIX_CHAN_DAC][ICSMIX_LEFT];
3726 vol.right = ic->sc_setting[GUSMIX_CHAN_DAC][ICSMIX_RIGHT];
3727 if (gus_from_vol(cp, &vol))
3728 error = 0;
3729 }
3730 break;
3731
3732
3733 case GUSICS_RECORD_SOURCE:
3734 if (cp->type == AUDIO_MIXER_ENUM) {
3735 /* Can't set anything else useful, sigh. */
3736 cp->un.ord = 0;
3737 }
3738 break;
3739
3740 default:
3741 return ENXIO;
3742 /*NOTREACHED*/
3743 }
3744 return error;
3745 }
3746
3747 STATIC void
3748 gusics_master_mute(ic, mute)
3749 struct ics2101_softc *ic;
3750 int mute;
3751 {
3752 ics2101_mix_mute(ic, GUSMIX_CHAN_MASTER, ICSMIX_LEFT, mute);
3753 ics2101_mix_mute(ic, GUSMIX_CHAN_MASTER, ICSMIX_RIGHT, mute);
3754 }
3755
3756 STATIC void
3757 gusics_mic_mute(ic, mute)
3758 struct ics2101_softc *ic;
3759 int mute;
3760 {
3761 ics2101_mix_mute(ic, GUSMIX_CHAN_MIC, ICSMIX_LEFT, mute);
3762 ics2101_mix_mute(ic, GUSMIX_CHAN_MIC, ICSMIX_RIGHT, mute);
3763 }
3764
3765 STATIC void
3766 gusics_linein_mute(ic, mute)
3767 struct ics2101_softc *ic;
3768 int mute;
3769 {
3770 ics2101_mix_mute(ic, GUSMIX_CHAN_LINE, ICSMIX_LEFT, mute);
3771 ics2101_mix_mute(ic, GUSMIX_CHAN_LINE, ICSMIX_RIGHT, mute);
3772 }
3773
3774 STATIC void
3775 gusics_cd_mute(ic, mute)
3776 struct ics2101_softc *ic;
3777 int mute;
3778 {
3779 ics2101_mix_mute(ic, GUSMIX_CHAN_CD, ICSMIX_LEFT, mute);
3780 ics2101_mix_mute(ic, GUSMIX_CHAN_CD, ICSMIX_RIGHT, mute);
3781 }
3782
3783 STATIC void
3784 gusics_dac_mute(ic, mute)
3785 struct ics2101_softc *ic;
3786 int mute;
3787 {
3788 ics2101_mix_mute(ic, GUSMIX_CHAN_DAC, ICSMIX_LEFT, mute);
3789 ics2101_mix_mute(ic, GUSMIX_CHAN_DAC, ICSMIX_RIGHT, mute);
3790 }
3791
3792 STATIC int
3793 gusmax_mixer_set_port(addr, cp)
3794 void *addr;
3795 mixer_ctrl_t *cp;
3796 {
3797 register struct ad1848_softc *ac = addr;
3798 register struct gus_softc *sc = ac->parent;
3799 struct ad1848_volume vol;
3800 int error = EINVAL;
3801
3802 DPRINTF(("gusmax_mixer_set_port: dev=%d type=%d\n", cp->dev, cp->type));
3803
3804 switch (cp->dev) {
3805 #if 0
3806 case GUSMAX_MIC_IN_LVL: /* Microphone */
3807 if (cp->type == AUDIO_MIXER_VALUE &&
3808 cp->un.value.num_channels == 1) {
3809 /* XXX enable/disable pre-MUX fixed gain */
3810 if (gus_to_vol(cp, &vol))
3811 error = ad1848_set_mic_gain(ac, &vol);
3812 }
3813 break;
3814 #endif
3815
3816 case GUSMAX_DAC_LVL: /* dac out */
3817 if (cp->type == AUDIO_MIXER_VALUE) {
3818 if (gus_to_vol(cp, &vol))
3819 error = ad1848_set_aux1_gain(ac, &vol);
3820 }
3821 break;
3822
3823 case GUSMAX_LINE_IN_LVL: /* line in */
3824 if (cp->type == AUDIO_MIXER_VALUE) {
3825 if (gus_to_vol(cp, &vol))
3826 error = cs4231_set_linein_gain(ac, &vol);
3827 }
3828 break;
3829
3830 case GUSMAX_MONO_LVL: /* mic/mono in */
3831 if (cp->type == AUDIO_MIXER_VALUE &&
3832 cp->un.value.num_channels == 1) {
3833 if (gus_to_vol(cp, &vol))
3834 error = cs4231_set_mono_gain(ac, &vol);
3835 }
3836 break;
3837
3838 case GUSMAX_CD_LVL: /* CD: AUX2 */
3839 if (cp->type == AUDIO_MIXER_VALUE) {
3840 if (gus_to_vol(cp, &vol))
3841 error = ad1848_set_aux2_gain(ac, &vol);
3842 }
3843 break;
3844
3845 case GUSMAX_MONITOR_LVL:
3846 if (cp->type == AUDIO_MIXER_VALUE &&
3847 cp->un.value.num_channels == 1) {
3848 vol.left = cp->un.value.level[AUDIO_MIXER_LEVEL_MONO];
3849 error = ad1848_set_mon_gain(ac, &vol);
3850 }
3851 break;
3852
3853 case GUSMAX_OUT_LVL: /* output volume */
3854 if (cp->type == AUDIO_MIXER_VALUE) {
3855 if (gus_to_vol(cp, &vol))
3856 error = ad1848_set_out_gain(ac, &vol);
3857 }
3858 break;
3859
3860 case GUSMAX_SPEAKER_LVL:
3861 if (cp->type == AUDIO_MIXER_VALUE &&
3862 cp->un.value.num_channels == 1) {
3863 if (gus_to_vol(cp, &vol)) {
3864 gus_speaker_ctl(sc, vol.left > AUDIO_MIN_GAIN ?
3865 SPKR_ON : SPKR_OFF);
3866 error = 0;
3867 }
3868 }
3869 break;
3870
3871 case GUSMAX_LINE_IN_MUTE:
3872 if (cp->type == AUDIO_MIXER_ENUM) {
3873 ac->line_mute = cp->un.ord ? 1 : 0;
3874 DPRINTF(("line mute %d\n", cp->un.ord));
3875 cs4231_mute_line(ac, ac->line_mute);
3876 gus_linein_ctl(sc, ac->line_mute ? SPKR_OFF : SPKR_ON);
3877 error = 0;
3878 }
3879 break;
3880
3881 case GUSMAX_DAC_MUTE:
3882 if (cp->type == AUDIO_MIXER_ENUM) {
3883 ac->aux1_mute = cp->un.ord ? 1 : 0;
3884 DPRINTF(("dac mute %d\n", cp->un.ord));
3885 ad1848_mute_aux1(ac, ac->aux1_mute);
3886 error = 0;
3887 }
3888 break;
3889
3890 case GUSMAX_CD_MUTE:
3891 if (cp->type == AUDIO_MIXER_ENUM) {
3892 ac->aux2_mute = cp->un.ord ? 1 : 0;
3893 DPRINTF(("cd mute %d\n", cp->un.ord));
3894 ad1848_mute_aux2(ac, ac->aux2_mute);
3895 error = 0;
3896 }
3897 break;
3898
3899 case GUSMAX_MONO_MUTE: /* Microphone */
3900 if (cp->type == AUDIO_MIXER_ENUM) {
3901 ac->mono_mute = cp->un.ord ? 1 : 0;
3902 DPRINTF(("mono mute %d\n", cp->un.ord));
3903 cs4231_mute_mono(ac, ac->mono_mute);
3904 gus_mic_ctl(sc, ac->mono_mute ? SPKR_OFF : SPKR_ON);
3905 error = 0;
3906 }
3907 break;
3908
3909 case GUSMAX_MONITOR_MUTE:
3910 if (cp->type == AUDIO_MIXER_ENUM) {
3911 ac->mon_mute = cp->un.ord ? 1 : 0;
3912 DPRINTF(("mono mute %d\n", cp->un.ord));
3913 cs4231_mute_monitor(ac, ac->mon_mute);
3914 error = 0;
3915 }
3916 break;
3917
3918 case GUSMAX_SPEAKER_MUTE:
3919 if (cp->type == AUDIO_MIXER_ENUM) {
3920 gus_speaker_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON);
3921 error = 0;
3922 }
3923 break;
3924
3925 case GUSMAX_REC_LVL: /* record level */
3926 if (cp->type == AUDIO_MIXER_VALUE) {
3927 if (gus_to_vol(cp, &vol))
3928 error = ad1848_set_rec_gain(ac, &vol);
3929 }
3930 break;
3931
3932 case GUSMAX_RECORD_SOURCE:
3933 if (cp->type == AUDIO_MIXER_ENUM) {
3934 error = ad1848_set_rec_port(ac, cp->un.ord);
3935 }
3936 break;
3937
3938 default:
3939 return ENXIO;
3940 /*NOTREACHED*/
3941 }
3942 return error;
3943 }
3944
3945 STATIC int
3946 gus_mixer_set_port(addr, cp)
3947 void *addr;
3948 mixer_ctrl_t *cp;
3949 {
3950 register struct gus_softc *sc = addr;
3951 register struct ics2101_softc *ic = &sc->sc_mixer;
3952 struct ad1848_volume vol;
3953 int error = EINVAL;
3954
3955 DPRINTF(("gus_mixer_set_port: dev=%d type=%d\n", cp->dev, cp->type));
3956
3957 if (!HAS_MIXER(sc) && cp->dev > GUSICS_MASTER_MUTE)
3958 return ENXIO;
3959
3960 switch (cp->dev) {
3961
3962 case GUSICS_MIC_IN_MUTE: /* Microphone */
3963 if (cp->type == AUDIO_MIXER_ENUM) {
3964 DPRINTF(("mic mute %d\n", cp->un.ord));
3965 if (HAS_MIXER(sc)) {
3966 gusics_mic_mute(ic, cp->un.ord);
3967 }
3968 gus_mic_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON);
3969 error = 0;
3970 }
3971 break;
3972
3973 case GUSICS_LINE_IN_MUTE:
3974 if (cp->type == AUDIO_MIXER_ENUM) {
3975 DPRINTF(("linein mute %d\n", cp->un.ord));
3976 if (HAS_MIXER(sc)) {
3977 gusics_linein_mute(ic, cp->un.ord);
3978 }
3979 gus_linein_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON);
3980 error = 0;
3981 }
3982 break;
3983
3984 case GUSICS_MASTER_MUTE:
3985 if (cp->type == AUDIO_MIXER_ENUM) {
3986 DPRINTF(("master mute %d\n", cp->un.ord));
3987 if (HAS_MIXER(sc)) {
3988 gusics_master_mute(ic, cp->un.ord);
3989 }
3990 gus_speaker_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON);
3991 error = 0;
3992 }
3993 break;
3994
3995 case GUSICS_DAC_MUTE:
3996 if (cp->type == AUDIO_MIXER_ENUM) {
3997 gusics_dac_mute(ic, cp->un.ord);
3998 error = 0;
3999 }
4000 break;
4001
4002 case GUSICS_CD_MUTE:
4003 if (cp->type == AUDIO_MIXER_ENUM) {
4004 gusics_cd_mute(ic, cp->un.ord);
4005 error = 0;
4006 }
4007 break;
4008
4009 case GUSICS_MASTER_LVL:
4010 if (cp->type == AUDIO_MIXER_VALUE) {
4011 if (gus_to_vol(cp, &vol)) {
4012 ics2101_mix_attenuate(ic,
4013 GUSMIX_CHAN_MASTER,
4014 ICSMIX_LEFT,
4015 vol.left);
4016 ics2101_mix_attenuate(ic,
4017 GUSMIX_CHAN_MASTER,
4018 ICSMIX_RIGHT,
4019 vol.right);
4020 error = 0;
4021 }
4022 }
4023 break;
4024
4025 case GUSICS_MIC_IN_LVL: /* Microphone */
4026 if (cp->type == AUDIO_MIXER_VALUE) {
4027 if (gus_to_vol(cp, &vol)) {
4028 ics2101_mix_attenuate(ic,
4029 GUSMIX_CHAN_MIC,
4030 ICSMIX_LEFT,
4031 vol.left);
4032 ics2101_mix_attenuate(ic,
4033 GUSMIX_CHAN_MIC,
4034 ICSMIX_RIGHT,
4035 vol.right);
4036 error = 0;
4037 }
4038 }
4039 break;
4040
4041 case GUSICS_LINE_IN_LVL: /* line in */
4042 if (cp->type == AUDIO_MIXER_VALUE) {
4043 if (gus_to_vol(cp, &vol)) {
4044 ics2101_mix_attenuate(ic,
4045 GUSMIX_CHAN_LINE,
4046 ICSMIX_LEFT,
4047 vol.left);
4048 ics2101_mix_attenuate(ic,
4049 GUSMIX_CHAN_LINE,
4050 ICSMIX_RIGHT,
4051 vol.right);
4052 error = 0;
4053 }
4054 }
4055 break;
4056
4057
4058 case GUSICS_CD_LVL:
4059 if (cp->type == AUDIO_MIXER_VALUE) {
4060 if (gus_to_vol(cp, &vol)) {
4061 ics2101_mix_attenuate(ic,
4062 GUSMIX_CHAN_CD,
4063 ICSMIX_LEFT,
4064 vol.left);
4065 ics2101_mix_attenuate(ic,
4066 GUSMIX_CHAN_CD,
4067 ICSMIX_RIGHT,
4068 vol.right);
4069 error = 0;
4070 }
4071 }
4072 break;
4073
4074 case GUSICS_DAC_LVL: /* dac out */
4075 if (cp->type == AUDIO_MIXER_VALUE) {
4076 if (gus_to_vol(cp, &vol)) {
4077 ics2101_mix_attenuate(ic,
4078 GUSMIX_CHAN_DAC,
4079 ICSMIX_LEFT,
4080 vol.left);
4081 ics2101_mix_attenuate(ic,
4082 GUSMIX_CHAN_DAC,
4083 ICSMIX_RIGHT,
4084 vol.right);
4085 error = 0;
4086 }
4087 }
4088 break;
4089
4090
4091 case GUSICS_RECORD_SOURCE:
4092 if (cp->type == AUDIO_MIXER_ENUM && cp->un.ord == 0) {
4093 /* Can't set anything else useful, sigh. */
4094 error = 0;
4095 }
4096 break;
4097
4098 default:
4099 return ENXIO;
4100 /*NOTREACHED*/
4101 }
4102 return error;
4103 }
4104
4105 STATIC int
4106 gusmax_mixer_query_devinfo(addr, dip)
4107 void *addr;
4108 register mixer_devinfo_t *dip;
4109 {
4110 DPRINTF(("gusmax_query_devinfo: index=%d\n", dip->index));
4111
4112 switch(dip->index) {
4113 case GUSMAX_MIX_IN: /* mixed MUX input */
4114 dip->type = AUDIO_MIXER_ENUM;
4115 dip->mixer_class = GUSMAX_INPUT_CLASS;
4116 dip->prev = dip->next = AUDIO_MIXER_LAST;
4117 strcpy(dip->label.name, AudioNmixerout);
4118 dip->un.e.num_mem = 0; /* XXX */
4119 break;
4120
4121 #if 0
4122 case GUSMAX_MIC_IN_LVL: /* Microphone */
4123 dip->type = AUDIO_MIXER_VALUE;
4124 dip->mixer_class = GUSMAX_INPUT_CLASS;
4125 dip->prev = AUDIO_MIXER_LAST;
4126 dip->next = GUSMAX_MIC_IN_MUTE;
4127 strcpy(dip->label.name, AudioNmicrophone);
4128 dip->un.v.num_channels = 2;
4129 strcpy(dip->un.v.units.name, AudioNvolume);
4130 break;
4131 #endif
4132
4133 case GUSMAX_MONO_LVL: /* mono/microphone mixer */
4134 dip->type = AUDIO_MIXER_VALUE;
4135 dip->mixer_class = GUSMAX_INPUT_CLASS;
4136 dip->prev = AUDIO_MIXER_LAST;
4137 dip->next = GUSMAX_MONO_MUTE;
4138 strcpy(dip->label.name, AudioNmicrophone);
4139 dip->un.v.num_channels = 1;
4140 strcpy(dip->un.v.units.name, AudioNvolume);
4141 break;
4142
4143 case GUSMAX_DAC_LVL: /* dacout */
4144 dip->type = AUDIO_MIXER_VALUE;
4145 dip->mixer_class = GUSMAX_INPUT_CLASS;
4146 dip->prev = AUDIO_MIXER_LAST;
4147 dip->next = GUSMAX_DAC_MUTE;
4148 strcpy(dip->label.name, AudioNdac);
4149 dip->un.v.num_channels = 2;
4150 strcpy(dip->un.v.units.name, AudioNvolume);
4151 break;
4152
4153 case GUSMAX_LINE_IN_LVL: /* line */
4154 dip->type = AUDIO_MIXER_VALUE;
4155 dip->mixer_class = GUSMAX_INPUT_CLASS;
4156 dip->prev = AUDIO_MIXER_LAST;
4157 dip->next = GUSMAX_LINE_IN_MUTE;
4158 strcpy(dip->label.name, AudioNline);
4159 dip->un.v.num_channels = 2;
4160 strcpy(dip->un.v.units.name, AudioNvolume);
4161 break;
4162
4163 case GUSMAX_CD_LVL: /* cd */
4164 dip->type = AUDIO_MIXER_VALUE;
4165 dip->mixer_class = GUSMAX_INPUT_CLASS;
4166 dip->prev = AUDIO_MIXER_LAST;
4167 dip->next = GUSMAX_CD_MUTE;
4168 strcpy(dip->label.name, AudioNcd);
4169 dip->un.v.num_channels = 2;
4170 strcpy(dip->un.v.units.name, AudioNvolume);
4171 break;
4172
4173
4174 case GUSMAX_MONITOR_LVL: /* monitor level */
4175 dip->type = AUDIO_MIXER_VALUE;
4176 dip->mixer_class = GUSMAX_MONITOR_CLASS;
4177 dip->next = GUSMAX_MONITOR_MUTE;
4178 dip->prev = AUDIO_MIXER_LAST;
4179 strcpy(dip->label.name, AudioNmonitor);
4180 dip->un.v.num_channels = 1;
4181 strcpy(dip->un.v.units.name, AudioNvolume);
4182 break;
4183
4184 case GUSMAX_OUT_LVL: /* cs4231 output volume: not useful? */
4185 dip->type = AUDIO_MIXER_VALUE;
4186 dip->mixer_class = GUSMAX_MONITOR_CLASS;
4187 dip->prev = dip->next = AUDIO_MIXER_LAST;
4188 strcpy(dip->label.name, AudioNoutput);
4189 dip->un.v.num_channels = 2;
4190 strcpy(dip->un.v.units.name, AudioNvolume);
4191 break;
4192
4193 case GUSMAX_SPEAKER_LVL: /* fake speaker volume */
4194 dip->type = AUDIO_MIXER_VALUE;
4195 dip->mixer_class = GUSMAX_MONITOR_CLASS;
4196 dip->prev = AUDIO_MIXER_LAST;
4197 dip->next = GUSMAX_SPEAKER_MUTE;
4198 strcpy(dip->label.name, AudioNspeaker);
4199 dip->un.v.num_channels = 2;
4200 strcpy(dip->un.v.units.name, AudioNvolume);
4201 break;
4202
4203 case GUSMAX_LINE_IN_MUTE:
4204 dip->mixer_class = GUSMAX_INPUT_CLASS;
4205 dip->type = AUDIO_MIXER_ENUM;
4206 dip->prev = GUSMAX_LINE_IN_LVL;
4207 dip->next = AUDIO_MIXER_LAST;
4208 goto mute;
4209
4210 case GUSMAX_DAC_MUTE:
4211 dip->mixer_class = GUSMAX_INPUT_CLASS;
4212 dip->type = AUDIO_MIXER_ENUM;
4213 dip->prev = GUSMAX_DAC_LVL;
4214 dip->next = AUDIO_MIXER_LAST;
4215 goto mute;
4216
4217 case GUSMAX_CD_MUTE:
4218 dip->mixer_class = GUSMAX_INPUT_CLASS;
4219 dip->type = AUDIO_MIXER_ENUM;
4220 dip->prev = GUSMAX_CD_LVL;
4221 dip->next = AUDIO_MIXER_LAST;
4222 goto mute;
4223
4224 case GUSMAX_MONO_MUTE:
4225 dip->mixer_class = GUSMAX_INPUT_CLASS;
4226 dip->type = AUDIO_MIXER_ENUM;
4227 dip->prev = GUSMAX_MONO_LVL;
4228 dip->next = AUDIO_MIXER_LAST;
4229 goto mute;
4230
4231 case GUSMAX_MONITOR_MUTE:
4232 dip->mixer_class = GUSMAX_OUTPUT_CLASS;
4233 dip->type = AUDIO_MIXER_ENUM;
4234 dip->prev = GUSMAX_MONITOR_LVL;
4235 dip->next = AUDIO_MIXER_LAST;
4236 goto mute;
4237
4238 case GUSMAX_SPEAKER_MUTE:
4239 dip->mixer_class = GUSMAX_OUTPUT_CLASS;
4240 dip->type = AUDIO_MIXER_ENUM;
4241 dip->prev = GUSMAX_SPEAKER_LVL;
4242 dip->next = AUDIO_MIXER_LAST;
4243 mute:
4244 strcpy(dip->label.name, AudioNmute);
4245 dip->un.e.num_mem = 2;
4246 strcpy(dip->un.e.member[0].label.name, AudioNoff);
4247 dip->un.e.member[0].ord = 0;
4248 strcpy(dip->un.e.member[1].label.name, AudioNon);
4249 dip->un.e.member[1].ord = 1;
4250 break;
4251
4252 case GUSMAX_REC_LVL: /* record level */
4253 dip->type = AUDIO_MIXER_VALUE;
4254 dip->mixer_class = GUSMAX_RECORD_CLASS;
4255 dip->prev = AUDIO_MIXER_LAST;
4256 dip->next = GUSMAX_RECORD_SOURCE;
4257 strcpy(dip->label.name, AudioNrecord);
4258 dip->un.v.num_channels = 2;
4259 strcpy(dip->un.v.units.name, AudioNvolume);
4260 break;
4261
4262 case GUSMAX_RECORD_SOURCE:
4263 dip->mixer_class = GUSMAX_RECORD_CLASS;
4264 dip->type = AUDIO_MIXER_ENUM;
4265 dip->prev = GUSMAX_REC_LVL;
4266 dip->next = AUDIO_MIXER_LAST;
4267 strcpy(dip->label.name, AudioNsource);
4268 dip->un.e.num_mem = 4;
4269 strcpy(dip->un.e.member[0].label.name, AudioNoutput);
4270 dip->un.e.member[0].ord = GUSMAX_MIX_IN;
4271 strcpy(dip->un.e.member[1].label.name, AudioNmicrophone);
4272 dip->un.e.member[1].ord = GUSMAX_MONO_LVL;
4273 strcpy(dip->un.e.member[2].label.name, AudioNdac);
4274 dip->un.e.member[2].ord = GUSMAX_DAC_LVL;
4275 strcpy(dip->un.e.member[3].label.name, AudioNline);
4276 dip->un.e.member[3].ord = GUSMAX_LINE_IN_LVL;
4277 break;
4278
4279 case GUSMAX_INPUT_CLASS: /* input class descriptor */
4280 dip->type = AUDIO_MIXER_CLASS;
4281 dip->mixer_class = GUSMAX_INPUT_CLASS;
4282 dip->next = dip->prev = AUDIO_MIXER_LAST;
4283 strcpy(dip->label.name, AudioCInputs);
4284 break;
4285
4286 case GUSMAX_OUTPUT_CLASS: /* output class descriptor */
4287 dip->type = AUDIO_MIXER_CLASS;
4288 dip->mixer_class = GUSMAX_OUTPUT_CLASS;
4289 dip->next = dip->prev = AUDIO_MIXER_LAST;
4290 strcpy(dip->label.name, AudioCOutputs);
4291 break;
4292
4293 case GUSMAX_MONITOR_CLASS: /* monitor class descriptor */
4294 dip->type = AUDIO_MIXER_CLASS;
4295 dip->mixer_class = GUSMAX_MONITOR_CLASS;
4296 dip->next = dip->prev = AUDIO_MIXER_LAST;
4297 strcpy(dip->label.name, AudioCMonitor);
4298 break;
4299
4300 case GUSMAX_RECORD_CLASS: /* record source class */
4301 dip->type = AUDIO_MIXER_CLASS;
4302 dip->mixer_class = GUSMAX_RECORD_CLASS;
4303 dip->next = dip->prev = AUDIO_MIXER_LAST;
4304 strcpy(dip->label.name, AudioCRecord);
4305 break;
4306
4307 default:
4308 return ENXIO;
4309 /*NOTREACHED*/
4310 }
4311 DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name));
4312 return 0;
4313 }
4314
4315 STATIC int
4316 gus_mixer_query_devinfo(addr, dip)
4317 void *addr;
4318 register mixer_devinfo_t *dip;
4319 {
4320 register struct gus_softc *sc = addr;
4321
4322 DPRINTF(("gusmax_query_devinfo: index=%d\n", dip->index));
4323
4324 if (!HAS_MIXER(sc) && dip->index > GUSICS_MASTER_MUTE)
4325 return ENXIO;
4326
4327 switch(dip->index) {
4328
4329 case GUSICS_MIC_IN_LVL: /* Microphone */
4330 dip->type = AUDIO_MIXER_VALUE;
4331 dip->mixer_class = GUSICS_INPUT_CLASS;
4332 dip->prev = AUDIO_MIXER_LAST;
4333 dip->next = GUSICS_MIC_IN_MUTE;
4334 strcpy(dip->label.name, AudioNmicrophone);
4335 dip->un.v.num_channels = 2;
4336 strcpy(dip->un.v.units.name, AudioNvolume);
4337 break;
4338
4339 case GUSICS_LINE_IN_LVL: /* line */
4340 dip->type = AUDIO_MIXER_VALUE;
4341 dip->mixer_class = GUSICS_INPUT_CLASS;
4342 dip->prev = AUDIO_MIXER_LAST;
4343 dip->next = GUSICS_LINE_IN_MUTE;
4344 strcpy(dip->label.name, AudioNline);
4345 dip->un.v.num_channels = 2;
4346 strcpy(dip->un.v.units.name, AudioNvolume);
4347 break;
4348
4349 case GUSICS_CD_LVL: /* cd */
4350 dip->type = AUDIO_MIXER_VALUE;
4351 dip->mixer_class = GUSICS_INPUT_CLASS;
4352 dip->prev = AUDIO_MIXER_LAST;
4353 dip->next = GUSICS_CD_MUTE;
4354 strcpy(dip->label.name, AudioNcd);
4355 dip->un.v.num_channels = 2;
4356 strcpy(dip->un.v.units.name, AudioNvolume);
4357 break;
4358
4359 case GUSICS_DAC_LVL: /* dacout */
4360 dip->type = AUDIO_MIXER_VALUE;
4361 dip->mixer_class = GUSICS_INPUT_CLASS;
4362 dip->prev = AUDIO_MIXER_LAST;
4363 dip->next = GUSICS_DAC_MUTE;
4364 strcpy(dip->label.name, AudioNdac);
4365 dip->un.v.num_channels = 2;
4366 strcpy(dip->un.v.units.name, AudioNvolume);
4367 break;
4368
4369 case GUSICS_MASTER_LVL: /* master output */
4370 dip->type = AUDIO_MIXER_VALUE;
4371 dip->mixer_class = GUSICS_OUTPUT_CLASS;
4372 dip->prev = AUDIO_MIXER_LAST;
4373 dip->next = GUSICS_MASTER_MUTE;
4374 strcpy(dip->label.name, AudioNvolume);
4375 dip->un.v.num_channels = 2;
4376 strcpy(dip->un.v.units.name, AudioNvolume);
4377 break;
4378
4379
4380 case GUSICS_LINE_IN_MUTE:
4381 dip->mixer_class = GUSICS_INPUT_CLASS;
4382 dip->type = AUDIO_MIXER_ENUM;
4383 dip->prev = GUSICS_LINE_IN_LVL;
4384 dip->next = AUDIO_MIXER_LAST;
4385 goto mute;
4386
4387 case GUSICS_DAC_MUTE:
4388 dip->mixer_class = GUSICS_INPUT_CLASS;
4389 dip->type = AUDIO_MIXER_ENUM;
4390 dip->prev = GUSICS_DAC_LVL;
4391 dip->next = AUDIO_MIXER_LAST;
4392 goto mute;
4393
4394 case GUSICS_CD_MUTE:
4395 dip->mixer_class = GUSICS_INPUT_CLASS;
4396 dip->type = AUDIO_MIXER_ENUM;
4397 dip->prev = GUSICS_CD_LVL;
4398 dip->next = AUDIO_MIXER_LAST;
4399 goto mute;
4400
4401 case GUSICS_MIC_IN_MUTE:
4402 dip->mixer_class = GUSICS_INPUT_CLASS;
4403 dip->type = AUDIO_MIXER_ENUM;
4404 dip->prev = GUSICS_MIC_IN_LVL;
4405 dip->next = AUDIO_MIXER_LAST;
4406 goto mute;
4407
4408 case GUSICS_MASTER_MUTE:
4409 dip->mixer_class = GUSICS_OUTPUT_CLASS;
4410 dip->type = AUDIO_MIXER_ENUM;
4411 dip->prev = GUSICS_MASTER_LVL;
4412 dip->next = AUDIO_MIXER_LAST;
4413 mute:
4414 strcpy(dip->label.name, AudioNmute);
4415 dip->un.e.num_mem = 2;
4416 strcpy(dip->un.e.member[0].label.name, AudioNoff);
4417 dip->un.e.member[0].ord = 0;
4418 strcpy(dip->un.e.member[1].label.name, AudioNon);
4419 dip->un.e.member[1].ord = 1;
4420 break;
4421
4422 case GUSICS_RECORD_SOURCE:
4423 dip->mixer_class = GUSICS_RECORD_CLASS;
4424 dip->type = AUDIO_MIXER_ENUM;
4425 dip->prev = dip->next = AUDIO_MIXER_LAST;
4426 strcpy(dip->label.name, AudioNsource);
4427 dip->un.e.num_mem = 1;
4428 strcpy(dip->un.e.member[0].label.name, AudioNoutput);
4429 dip->un.e.member[0].ord = GUSICS_MASTER_LVL;
4430 break;
4431
4432 case GUSICS_INPUT_CLASS:
4433 dip->type = AUDIO_MIXER_CLASS;
4434 dip->mixer_class = GUSICS_INPUT_CLASS;
4435 dip->next = dip->prev = AUDIO_MIXER_LAST;
4436 strcpy(dip->label.name, AudioCInputs);
4437 break;
4438
4439 case GUSICS_OUTPUT_CLASS:
4440 dip->type = AUDIO_MIXER_CLASS;
4441 dip->mixer_class = GUSICS_OUTPUT_CLASS;
4442 dip->next = dip->prev = AUDIO_MIXER_LAST;
4443 strcpy(dip->label.name, AudioCOutputs);
4444 break;
4445
4446 case GUSICS_RECORD_CLASS:
4447 dip->type = AUDIO_MIXER_CLASS;
4448 dip->mixer_class = GUSICS_RECORD_CLASS;
4449 dip->next = dip->prev = AUDIO_MIXER_LAST;
4450 strcpy(dip->label.name, AudioCRecord);
4451 break;
4452
4453 default:
4454 return ENXIO;
4455 /*NOTREACHED*/
4456 }
4457 DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name));
4458 return 0;
4459 }
4460
4461 STATIC int
4462 gus_query_encoding(addr, fp)
4463 void *addr;
4464 struct audio_encoding *fp;
4465 {
4466 switch (fp->index) {
4467 case 0:
4468 strcpy(fp->name, AudioEmulaw);
4469 fp->format_id = AUDIO_ENCODING_ULAW;
4470 break;
4471 case 1:
4472 strcpy(fp->name, AudioEpcm16);
4473 fp->format_id = AUDIO_ENCODING_PCM16;
4474 break;
4475 case 2:
4476 strcpy(fp->name, AudioEpcm8);
4477 fp->format_id = AUDIO_ENCODING_PCM8;
4478 break;
4479 default:
4480 return(EINVAL);
4481 /*NOTREACHED*/
4482 }
4483 return (0);
4484 }
4485
4486 /*
4487 * Setup the ICS mixer in "transparent" mode: reset everything to a sensible
4488 * level. Levels as suggested by GUS SDK code.
4489 */
4490
4491 STATIC void
4492 gus_init_ics2101(sc)
4493 struct gus_softc *sc;
4494 {
4495 register int port = sc->sc_iobase;
4496 register struct ics2101_softc *ic = &sc->sc_mixer;
4497 sc->sc_mixer.sc_selio = port+GUS_MIXER_SELECT;
4498 sc->sc_mixer.sc_dataio = port+GUS_MIXER_DATA;
4499 sc->sc_mixer.sc_flags = (sc->sc_revision == 5) ? ICS_FLIP : 0;
4500
4501 ics2101_mix_attenuate(ic,
4502 GUSMIX_CHAN_MIC,
4503 ICSMIX_LEFT,
4504 ICSMIX_MIN_ATTN);
4505 ics2101_mix_attenuate(ic,
4506 GUSMIX_CHAN_MIC,
4507 ICSMIX_RIGHT,
4508 ICSMIX_MIN_ATTN);
4509 /*
4510 * Start with microphone muted by the mixer...
4511 */
4512 gusics_mic_mute(ic, 1);
4513
4514 /* ... and enabled by the GUS master mix control */
4515 gus_mic_ctl(sc, SPKR_ON);
4516
4517 ics2101_mix_attenuate(ic,
4518 GUSMIX_CHAN_LINE,
4519 ICSMIX_LEFT,
4520 ICSMIX_MIN_ATTN);
4521 ics2101_mix_attenuate(ic,
4522 GUSMIX_CHAN_LINE,
4523 ICSMIX_RIGHT,
4524 ICSMIX_MIN_ATTN);
4525
4526 ics2101_mix_attenuate(ic,
4527 GUSMIX_CHAN_CD,
4528 ICSMIX_LEFT,
4529 ICSMIX_MIN_ATTN);
4530 ics2101_mix_attenuate(ic,
4531 GUSMIX_CHAN_CD,
4532 ICSMIX_RIGHT,
4533 ICSMIX_MIN_ATTN);
4534
4535 ics2101_mix_attenuate(ic,
4536 GUSMIX_CHAN_DAC,
4537 ICSMIX_LEFT,
4538 ICSMIX_MIN_ATTN);
4539 ics2101_mix_attenuate(ic,
4540 GUSMIX_CHAN_DAC,
4541 ICSMIX_RIGHT,
4542 ICSMIX_MIN_ATTN);
4543
4544 ics2101_mix_attenuate(ic,
4545 ICSMIX_CHAN_4,
4546 ICSMIX_LEFT,
4547 ICSMIX_MAX_ATTN);
4548 ics2101_mix_attenuate(ic,
4549 ICSMIX_CHAN_4,
4550 ICSMIX_RIGHT,
4551 ICSMIX_MAX_ATTN);
4552
4553 ics2101_mix_attenuate(ic,
4554 GUSMIX_CHAN_MASTER,
4555 ICSMIX_LEFT,
4556 ICSMIX_MIN_ATTN);
4557 ics2101_mix_attenuate(ic,
4558 GUSMIX_CHAN_MASTER,
4559 ICSMIX_RIGHT,
4560 ICSMIX_MIN_ATTN);
4561 /* unmute other stuff: */
4562 gusics_cd_mute(ic, 0);
4563 gusics_dac_mute(ic, 0);
4564 gusics_linein_mute(ic, 0);
4565 return;
4566 }
4567
4568
4569 #endif /* NGUS */
4570