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