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