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