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