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