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