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