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