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