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