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