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