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