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