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