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