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