5 * A Linux driver for Turtle Beach WaveFront Series (Maui, Tropez, Tropez Plus)
7 * This driver supports the onboard wavetable synthesizer (an ICS2115),
8 * including patch, sample and program loading and unloading, conversion
9 * of GUS patches during loading, and full user-level access to all
10 * WaveFront commands. It tries to provide semi-intelligent patch and
11 * sample management as well.
13 * It also provides support for the ICS emulation of an MPU-401. Full
14 * support for the ICS emulation's "virtual MIDI mode" is provided in
17 * Support is also provided for the Tropez Plus' onboard FX processor,
18 * a Yamaha YSS225. Currently, code exists to configure the YSS225,
19 * and there is an interface allowing tweaking of any of its memory
20 * addresses. However, I have been unable to decipher the logical
21 * positioning of the configuration info for various effects, so for
22 * now, you just get the YSS225 in the same state as Turtle Beach's
23 * "SETUPSND.EXE" utility leaves it.
25 * The boards' DAC/ADC (a Crystal CS4232) is supported by cs4232.[co],
26 * This chip also controls the configuration of the card: the wavefront
27 * synth is logical unit 4.
32 * /dev/dsp - using cs4232+ad1848 modules, OSS compatible
33 * /dev/midiNN and /dev/midiNN+1 - using wf_midi code, OSS compatible
34 * /dev/synth00 - raw synth interface
36 **********************************************************************
38 * Copyright (C) by Paul Barton-Davis 1998
40 * Some portions of this file are taken from work that is
41 * copyright (C) by Hannu Savolainen 1993-1996
43 * Although the relevant code here is all new, the handling of
44 * sample/alias/multi- samples is entirely based on a driver by Matt
45 * Martin and Rutger Nijlunsing which demonstrated how to get things
46 * to work correctly. The GUS patch loading code has been almost
47 * unaltered by me, except to fit formatting and function names in the
48 * rest of the file. Many thanks to them.
50 * Appreciation and thanks to Hannu Savolainen for his early work on the Maui
51 * driver, and answering a few questions while this one was developed.
53 * Absolutely NO thanks to Turtle Beach/Voyetra and Yamaha for their
54 * complete lack of help in developing this driver, and in particular
55 * for their utter silence in response to questions about undocumented
56 * aspects of configuring a WaveFront soundcard, particularly the
59 * $Id: wavfront.c,v 0.7 1998/09/09 15:47:36 pbd Exp $
61 * This program is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
62 * Version 2 (June 1991). See the "COPYING" file distributed with this software
66 * 11-10-2000 Bartlomiej Zolnierkiewicz <bkz@linux-ide.org>
67 * Added some __init and __initdata to entries in yss225.c
70 #include <linux/module.h>
72 #include <linux/kernel.h>
73 #include <linux/init.h>
74 #include <linux/sched.h>
75 #include <linux/smp_lock.h>
76 #include <linux/ptrace.h>
77 #include <linux/fcntl.h>
78 #include <linux/ioport.h>
80 #include <linux/interrupt.h>
81 #include <linux/config.h>
83 #include <linux/delay.h>
85 #include "sound_config.h"
87 #include <linux/wavefront.h>
89 #define _MIDI_SYNTH_C_
90 #define MIDI_SYNTH_NAME "WaveFront MIDI"
91 #define MIDI_SYNTH_CAPS SYNTH_CAP_INPUT
92 #include "midi_synth.h"
94 /* Compile-time control of the extent to which OSS is supported.
96 I consider /dev/sequencer to be an anachronism, but given its
97 widespread usage by various Linux MIDI software, it seems worth
98 offering support to it if its not too painful. Instead of using
99 /dev/sequencer, I recommend:
101 for synth programming and patch loading: /dev/synthNN
102 for kernel-synchronized MIDI sequencing: the ALSA sequencer
103 for direct MIDI control: /dev/midiNN
105 I have never tried static compilation into the kernel. The #if's
106 for this are really just notes to myself about what the code is
110 #define OSS_SUPPORT_SEQ 0x1 /* use of /dev/sequencer */
111 #define OSS_SUPPORT_STATIC_INSTALL 0x2 /* static compilation into kernel */
113 #define OSS_SUPPORT_LEVEL 0x1 /* just /dev/sequencer for now */
115 #if OSS_SUPPORT_LEVEL & OSS_SUPPORT_SEQ
116 static int (*midi_load_patch) (int devno, int format, const char *addr,
117 int offs, int count, int pmgr_flag) = NULL;
118 #endif /* OSS_SUPPORT_SEQ */
120 /* if WF_DEBUG not defined, no run-time debugging messages will
121 be available via the debug flag setting. Given the current
122 beta state of the driver, this will remain set until a future
130 /* Thank goodness for gcc's preprocessor ... */
132 #define DPRINT(cond, format, args...) \
133 if ((dev.debug & (cond)) == (cond)) { \
134 printk (KERN_DEBUG LOGNAME format, ## args); \
137 #define DPRINT(cond, format, args...)
140 #define LOGNAME "WaveFront: "
142 /* bitmasks for WaveFront status port value */
144 #define STAT_RINTR_ENABLED 0x01
145 #define STAT_CAN_READ 0x02
146 #define STAT_INTR_READ 0x04
147 #define STAT_WINTR_ENABLED 0x10
148 #define STAT_CAN_WRITE 0x20
149 #define STAT_INTR_WRITE 0x40
151 /*** Module-accessible parameters ***************************************/
153 int wf_raw; /* we normally check for "raw state" to firmware
154 loading. if set, then during driver loading, the
155 state of the board is ignored, and we reset the
156 board and load the firmware anyway.
159 int fx_raw = 1; /* if this is zero, we'll leave the FX processor in
160 whatever state it is when the driver is loaded.
161 The default is to download the microprogram and
162 associated coefficients to set it up for "default"
163 operation, whatever that means.
166 int debug_default; /* you can set this to control debugging
167 during driver loading. it takes any combination
168 of the WF_DEBUG_* flags defined in
172 /* XXX this needs to be made firmware and hardware version dependent */
174 char *ospath = "/etc/sound/wavefront.os"; /* where to find a processed
175 version of the WaveFront OS
178 int wait_polls = 2000; /* This is a number of tries we poll the status register
179 before resorting to sleeping. WaveFront being an ISA
180 card each poll takes about 1.2us. So before going to
181 sleep we wait up to 2.4ms in a loop.
184 int sleep_length = HZ/100; /* This says how long we're going to sleep between polls.
185 10ms sounds reasonable for fast response.
188 int sleep_tries = 50; /* Wait for status 0.5 seconds total. */
190 int reset_time = 2; /* hundreths of a second we wait after a HW reset for
191 the expected interrupt.
194 int ramcheck_time = 20; /* time in seconds to wait while ROM code
198 int osrun_time = 10; /* time in seconds we wait for the OS to
202 MODULE_PARM(wf_raw,"i");
203 MODULE_PARM(fx_raw,"i");
204 MODULE_PARM(debug_default,"i");
205 MODULE_PARM(wait_polls,"i");
206 MODULE_PARM(sleep_length,"i");
207 MODULE_PARM(sleep_tries,"i");
208 MODULE_PARM(ospath,"s");
209 MODULE_PARM(reset_time,"i");
210 MODULE_PARM(ramcheck_time,"i");
211 MODULE_PARM(osrun_time,"i");
213 /***************************************************************************/
215 /* Note: because this module doesn't export any symbols, this really isn't
216 a global variable, even if it looks like one. I was quite confused by
217 this when I started writing this as a (newer) module -- pbd.
221 int devno; /* device number from kernel */
222 int irq; /* "you were one, one of the few ..." */
223 int base; /* low i/o port address */
225 #define mpu_data_port base
226 #define mpu_command_port base + 1 /* write semantics */
227 #define mpu_status_port base + 1 /* read semantics */
228 #define data_port base + 2
229 #define status_port base + 3 /* read semantics */
230 #define control_port base + 3 /* write semantics */
231 #define block_port base + 4 /* 16 bit, writeonly */
232 #define last_block_port base + 6 /* 16 bit, writeonly */
234 /* FX ports. These are mapped through the ICS2115 to the YS225.
235 The ICS2115 takes care of flipping the relevant pins on the
236 YS225 so that access to each of these ports does the right
237 thing. Note: these are NOT documented by Turtle Beach.
240 #define fx_status base + 8
241 #define fx_op base + 8
242 #define fx_lcr base + 9
243 #define fx_dsp_addr base + 0xa
244 #define fx_dsp_page base + 0xb
245 #define fx_dsp_lsb base + 0xc
246 #define fx_dsp_msb base + 0xd
247 #define fx_mod_addr base + 0xe
248 #define fx_mod_data base + 0xf
250 volatile int irq_ok; /* set by interrupt handler */
251 volatile int irq_cnt; /* ditto */
252 int opened; /* flag, holds open(2) mode */
253 char debug; /* debugging flags */
254 int freemem; /* installed RAM, in bytes */
256 int synth_dev; /* devno for "raw" synth */
257 int mididev; /* devno for internal MIDI */
258 int ext_mididev; /* devno for external MIDI */
259 int fx_mididev; /* devno for FX MIDI interface */
260 #if OSS_SUPPORT_LEVEL & OSS_SUPPORT_SEQ
261 int oss_dev; /* devno for OSS sequencer synth */
262 #endif /* OSS_SUPPORT_SEQ */
264 char fw_version[2]; /* major = [0], minor = [1] */
265 char hw_version[2]; /* major = [0], minor = [1] */
266 char israw; /* needs Motorola microcode */
267 char has_fx; /* has FX processor (Tropez+) */
268 char prog_status[WF_MAX_PROGRAM]; /* WF_SLOT_* */
269 char patch_status[WF_MAX_PATCH]; /* WF_SLOT_* */
270 char sample_status[WF_MAX_SAMPLE]; /* WF_ST_* | WF_SLOT_* */
271 int samples_used; /* how many */
272 char interrupts_on; /* h/w MPU interrupts enabled ? */
273 char rom_samples_rdonly; /* can we write on ROM samples */
274 wait_queue_head_t interrupt_sleeper;
277 static int detect_wffx(void);
278 static int wffx_ioctl (wavefront_fx_info *);
279 static int wffx_init (void);
281 static int wavefront_delete_sample (int sampnum);
282 static int wavefront_find_free_sample (void);
286 extern int virtual_midi_enable (void);
287 extern int virtual_midi_disable (void);
288 extern int detect_wf_mpu (int, int);
289 extern int install_wf_mpu (void);
290 extern int uninstall_wf_mpu (void);
295 unsigned int read_cnt;
296 unsigned int write_cnt;
303 } wavefront_errors[] = {
304 { 0x01, "Bad sample number" },
305 { 0x02, "Out of sample memory" },
306 { 0x03, "Bad patch number" },
307 { 0x04, "Error in number of voices" },
308 { 0x06, "Sample load already in progress" },
309 { 0x0B, "No sample load request pending" },
310 { 0x0E, "Bad MIDI channel number" },
311 { 0x10, "Download Record Error" },
318 static wavefront_command wavefront_commands[] = {
319 { WFC_SET_SYNTHVOL, "set synthesizer volume", 0, 1, NEEDS_ACK },
320 { WFC_GET_SYNTHVOL, "get synthesizer volume", 1, 0, 0},
321 { WFC_SET_NVOICES, "set number of voices", 0, 1, NEEDS_ACK },
322 { WFC_GET_NVOICES, "get number of voices", 1, 0, 0 },
323 { WFC_SET_TUNING, "set synthesizer tuning", 0, 2, NEEDS_ACK },
324 { WFC_GET_TUNING, "get synthesizer tuning", 2, 0, 0 },
325 { WFC_DISABLE_CHANNEL, "disable synth channel", 0, 1, NEEDS_ACK },
326 { WFC_ENABLE_CHANNEL, "enable synth channel", 0, 1, NEEDS_ACK },
327 { WFC_GET_CHANNEL_STATUS, "get synth channel status", 3, 0, 0 },
328 { WFC_MISYNTH_OFF, "disable midi-in to synth", 0, 0, NEEDS_ACK },
329 { WFC_MISYNTH_ON, "enable midi-in to synth", 0, 0, NEEDS_ACK },
330 { WFC_VMIDI_ON, "enable virtual midi mode", 0, 0, NEEDS_ACK },
331 { WFC_VMIDI_OFF, "disable virtual midi mode", 0, 0, NEEDS_ACK },
332 { WFC_MIDI_STATUS, "report midi status", 1, 0, 0 },
333 { WFC_FIRMWARE_VERSION, "report firmware version", 2, 0, 0 },
334 { WFC_HARDWARE_VERSION, "report hardware version", 2, 0, 0 },
335 { WFC_GET_NSAMPLES, "report number of samples", 2, 0, 0 },
336 { WFC_INSTOUT_LEVELS, "report instantaneous output levels", 7, 0, 0 },
337 { WFC_PEAKOUT_LEVELS, "report peak output levels", 7, 0, 0 },
338 { WFC_DOWNLOAD_SAMPLE, "download sample",
339 0, WF_SAMPLE_BYTES, NEEDS_ACK },
340 { WFC_DOWNLOAD_BLOCK, "download block", 0, 0, NEEDS_ACK},
341 { WFC_DOWNLOAD_SAMPLE_HEADER, "download sample header",
342 0, WF_SAMPLE_HDR_BYTES, NEEDS_ACK },
343 { WFC_UPLOAD_SAMPLE_HEADER, "upload sample header", 13, 2, 0 },
345 /* This command requires a variable number of bytes to be written.
346 There is a hack in wavefront_cmd() to support this. The actual
347 count is passed in as the read buffer ptr, cast appropriately.
351 { WFC_DOWNLOAD_MULTISAMPLE, "download multisample", 0, 0, NEEDS_ACK },
353 /* This one is a hack as well. We just read the first byte of the
354 response, don't fetch an ACK, and leave the rest to the
355 calling function. Ugly, ugly, ugly.
358 { WFC_UPLOAD_MULTISAMPLE, "upload multisample", 2, 1, 0 },
359 { WFC_DOWNLOAD_SAMPLE_ALIAS, "download sample alias",
360 0, WF_ALIAS_BYTES, NEEDS_ACK },
361 { WFC_UPLOAD_SAMPLE_ALIAS, "upload sample alias", WF_ALIAS_BYTES, 2, 0},
362 { WFC_DELETE_SAMPLE, "delete sample", 0, 2, NEEDS_ACK },
363 { WFC_IDENTIFY_SAMPLE_TYPE, "identify sample type", 5, 2, 0 },
364 { WFC_UPLOAD_SAMPLE_PARAMS, "upload sample parameters" },
365 { WFC_REPORT_FREE_MEMORY, "report free memory", 4, 0, 0 },
366 { WFC_DOWNLOAD_PATCH, "download patch", 0, 134, NEEDS_ACK },
367 { WFC_UPLOAD_PATCH, "upload patch", 132, 2, 0 },
368 { WFC_DOWNLOAD_PROGRAM, "download program", 0, 33, NEEDS_ACK },
369 { WFC_UPLOAD_PROGRAM, "upload program", 32, 1, 0 },
370 { WFC_DOWNLOAD_EDRUM_PROGRAM, "download enhanced drum program", 0, 9,
372 { WFC_UPLOAD_EDRUM_PROGRAM, "upload enhanced drum program", 8, 1, 0},
373 { WFC_SET_EDRUM_CHANNEL, "set enhanced drum program channel",
375 { WFC_DISABLE_DRUM_PROGRAM, "disable drum program", 0, 1, NEEDS_ACK },
376 { WFC_REPORT_CHANNEL_PROGRAMS, "report channel program numbers",
378 { WFC_NOOP, "the no-op command", 0, 0, NEEDS_ACK },
383 wavefront_errorstr (int errnum)
388 for (i = 0; wavefront_errors[i].errstr; i++) {
389 if (wavefront_errors[i].errno == errnum) {
390 return wavefront_errors[i].errstr;
394 return "Unknown WaveFront error";
397 static wavefront_command *
398 wavefront_get_command (int cmd)
403 for (i = 0; wavefront_commands[i].cmd != 0; i++) {
404 if (cmd == wavefront_commands[i].cmd) {
405 return &wavefront_commands[i];
409 return (wavefront_command *) 0;
413 wavefront_status (void)
416 return inb (dev.status_port);
420 wavefront_wait (int mask)
425 for (i = 0; i < wait_polls; i++)
426 if (wavefront_status() & mask)
429 for (i = 0; i < sleep_tries; i++) {
431 if (wavefront_status() & mask) {
432 set_current_state(TASK_RUNNING);
436 set_current_state(TASK_INTERRUPTIBLE);
437 schedule_timeout(sleep_length);
438 if (signal_pending(current))
442 set_current_state(TASK_RUNNING);
447 wavefront_read (void)
450 if (wavefront_wait (STAT_CAN_READ))
451 return inb (dev.data_port);
453 DPRINT (WF_DEBUG_DATA, "read timeout.\n");
459 wavefront_write (unsigned char data)
462 if (wavefront_wait (STAT_CAN_WRITE)) {
463 outb (data, dev.data_port);
467 DPRINT (WF_DEBUG_DATA, "write timeout.\n");
473 wavefront_cmd (int cmd, unsigned char *rbuf, unsigned char *wbuf)
479 wavefront_command *wfcmd;
481 if ((wfcmd = wavefront_get_command (cmd)) == (wavefront_command *) 0) {
482 printk (KERN_WARNING LOGNAME "command 0x%x not supported.\n",
487 /* Hack to handle the one variable-size write command. See
488 wavefront_send_multisample() for the other half of this
489 gross and ugly strategy.
492 if (cmd == WFC_DOWNLOAD_MULTISAMPLE) {
493 wfcmd->write_cnt = (unsigned int) rbuf;
497 DPRINT (WF_DEBUG_CMD, "0x%x [%s] (%d,%d,%d)\n",
498 cmd, wfcmd->action, wfcmd->read_cnt,
499 wfcmd->write_cnt, wfcmd->need_ack);
501 if (wavefront_write (cmd)) {
502 DPRINT ((WF_DEBUG_IO|WF_DEBUG_CMD), "cannot request "
508 if (wfcmd->write_cnt > 0) {
509 DPRINT (WF_DEBUG_DATA, "writing %d bytes "
511 wfcmd->write_cnt, cmd);
513 for (i = 0; i < wfcmd->write_cnt; i++) {
514 if (wavefront_write (wbuf[i])) {
515 DPRINT (WF_DEBUG_IO, "bad write for byte "
516 "%d of 0x%x [%s].\n",
517 i, cmd, wfcmd->action);
521 DPRINT (WF_DEBUG_DATA, "write[%d] = 0x%x\n",
526 if (wfcmd->read_cnt > 0) {
527 DPRINT (WF_DEBUG_DATA, "reading %d ints "
529 wfcmd->read_cnt, cmd);
531 for (i = 0; i < wfcmd->read_cnt; i++) {
533 if ((c = wavefront_read()) == -1) {
534 DPRINT (WF_DEBUG_IO, "bad read for byte "
535 "%d of 0x%x [%s].\n",
536 i, cmd, wfcmd->action);
540 /* Now handle errors. Lots of special cases here */
543 if ((c = wavefront_read ()) == -1) {
544 DPRINT (WF_DEBUG_IO, "bad read for "
553 /* Can you believe this madness ? */
556 wfcmd->cmd == WFC_IDENTIFY_SAMPLE_TYPE) {
557 rbuf[0] = WF_ST_EMPTY;
561 wfcmd->cmd == WFC_UPLOAD_PATCH) {
566 wfcmd->cmd == WFC_UPLOAD_PROGRAM) {
572 DPRINT (WF_DEBUG_IO, "error %d (%s) "
578 wavefront_errorstr (c),
589 DPRINT (WF_DEBUG_DATA, "read[%d] = 0x%x\n",i, rbuf[i]);
593 if ((wfcmd->read_cnt == 0 && wfcmd->write_cnt == 0) || wfcmd->need_ack) {
595 DPRINT (WF_DEBUG_CMD, "reading ACK for 0x%x\n", cmd);
597 /* Some commands need an ACK, but return zero instead
598 of the standard value.
601 if ((ack = wavefront_read()) == 0) {
607 DPRINT (WF_DEBUG_IO, "cannot read ack for "
613 int err = -1; /* something unknown */
615 if (ack == 0xff) { /* explicit error */
617 if ((err = wavefront_read ()) == -1) {
618 DPRINT (WF_DEBUG_DATA,
625 DPRINT (WF_DEBUG_IO, "0x%x [%s] "
626 "failed (0x%x, 0x%x, %s)\n",
627 cmd, wfcmd->action, ack, err,
628 wavefront_errorstr (err));
634 DPRINT (WF_DEBUG_DATA, "ack received "
639 DPRINT (WF_DEBUG_CMD, "0x%x [%s] does not need "
641 cmd, wfcmd->action, wfcmd->read_cnt,
642 wfcmd->write_cnt, wfcmd->need_ack);
649 /***********************************************************************
650 WaveFront: data munging
652 Things here are weird. All data written to the board cannot
653 have its most significant bit set. Any data item with values
654 potentially > 0x7F (127) must be split across multiple bytes.
656 Sometimes, we need to munge numeric values that are represented on
657 the x86 side as 8-32 bit values. Sometimes, we need to munge data
658 that is represented on the x86 side as an array of bytes. The most
659 efficient approach to handling both cases seems to be to use 2
660 different functions for munging and 2 for de-munging. This avoids
661 weird casting and worrying about bit-level offsets.
663 **********************************************************************/
667 munge_int32 (unsigned int src,
669 unsigned int dst_size)
673 for (i = 0;i < dst_size; i++) {
674 *dst = src & 0x7F; /* Mask high bit of LSB */
675 src = src >> 7; /* Rotate Right 7 bits */
676 /* Note: we leave the upper bits in place */
684 demunge_int32 (unsigned char* src, int src_size)
690 for (i = src_size - 1; i >= 0; i--) {
691 outval=(outval<<7)+src[i];
699 munge_buf (unsigned char *src, unsigned char *dst, unsigned int dst_size)
703 unsigned int last = dst_size / 2;
705 for (i = 0; i < last; i++) {
706 *dst++ = src[i] & 0x7f;
707 *dst++ = src[i] >> 7;
714 demunge_buf (unsigned char *src, unsigned char *dst, unsigned int src_bytes)
718 unsigned char *end = src + src_bytes;
720 end = src + src_bytes;
722 /* NOTE: src and dst *CAN* point to the same address */
724 for (i = 0; src != end; i++) {
726 dst[i] |= (*src++)<<7;
732 /***********************************************************************
733 WaveFront: sample, patch and program management.
734 ***********************************************************************/
737 wavefront_delete_sample (int sample_num)
740 unsigned char wbuf[2];
743 wbuf[0] = sample_num & 0x7f;
744 wbuf[1] = sample_num >> 7;
746 if ((x = wavefront_cmd (WFC_DELETE_SAMPLE, 0, wbuf)) == 0) {
747 dev.sample_status[sample_num] = WF_ST_EMPTY;
754 wavefront_get_sample_status (int assume_rom)
758 unsigned char rbuf[32], wbuf[32];
759 unsigned int sc_real, sc_alias, sc_multi;
761 /* check sample status */
763 if (wavefront_cmd (WFC_GET_NSAMPLES, rbuf, wbuf)) {
764 printk (KERN_WARNING LOGNAME "cannot request sample count.\n");
768 sc_real = sc_alias = sc_multi = dev.samples_used = 0;
770 for (i = 0; i < WF_MAX_SAMPLE; i++) {
775 if (wavefront_cmd (WFC_IDENTIFY_SAMPLE_TYPE, rbuf, wbuf)) {
776 printk (KERN_WARNING LOGNAME
777 "cannot identify sample "
778 "type of slot %d\n", i);
779 dev.sample_status[i] = WF_ST_EMPTY;
783 dev.sample_status[i] = (WF_SLOT_FILLED|rbuf[0]);
786 dev.sample_status[i] |= WF_SLOT_ROM;
789 switch (rbuf[0] & WF_ST_MASK) {
793 case WF_ST_MULTISAMPLE:
803 printk (KERN_WARNING LOGNAME "unknown sample type for "
808 if (rbuf[0] != WF_ST_EMPTY) {
813 printk (KERN_INFO LOGNAME
814 "%d samples used (%d real, %d aliases, %d multi), "
815 "%d empty\n", dev.samples_used, sc_real, sc_alias, sc_multi,
816 WF_MAX_SAMPLE - dev.samples_used);
824 wavefront_get_patch_status (void)
827 unsigned char patchbuf[WF_PATCH_BYTES];
828 unsigned char patchnum[2];
832 for (i = 0; i < WF_MAX_PATCH; i++) {
833 patchnum[0] = i & 0x7f;
834 patchnum[1] = i >> 7;
836 if ((x = wavefront_cmd (WFC_UPLOAD_PATCH, patchbuf,
839 dev.patch_status[i] |= WF_SLOT_FILLED;
840 p = (wavefront_patch *) patchbuf;
842 [p->sample_number|(p->sample_msb<<7)] |=
845 } else if (x == 3) { /* Bad patch number */
846 dev.patch_status[i] = 0;
848 printk (KERN_ERR LOGNAME "upload patch "
850 dev.patch_status[i] = 0;
855 /* program status has already filled in slot_used bits */
857 for (i = 0, cnt = 0, cnt2 = 0; i < WF_MAX_PATCH; i++) {
858 if (dev.patch_status[i] & WF_SLOT_FILLED) {
861 if (dev.patch_status[i] & WF_SLOT_USED) {
866 printk (KERN_INFO LOGNAME
867 "%d patch slots filled, %d in use\n", cnt, cnt2);
873 wavefront_get_program_status (void)
876 unsigned char progbuf[WF_PROGRAM_BYTES];
877 wavefront_program prog;
878 unsigned char prognum;
881 for (i = 0; i < WF_MAX_PROGRAM; i++) {
884 if ((x = wavefront_cmd (WFC_UPLOAD_PROGRAM, progbuf,
887 dev.prog_status[i] |= WF_SLOT_USED;
889 demunge_buf (progbuf, (unsigned char *) &prog,
892 for (l = 0; l < WF_NUM_LAYERS; l++) {
893 if (prog.layer[l].mute) {
895 [prog.layer[l].patch_number] |=
899 } else if (x == 1) { /* Bad program number */
900 dev.prog_status[i] = 0;
902 printk (KERN_ERR LOGNAME "upload program "
904 dev.prog_status[i] = 0;
908 for (i = 0, cnt = 0; i < WF_MAX_PROGRAM; i++) {
909 if (dev.prog_status[i]) {
914 printk (KERN_INFO LOGNAME "%d programs slots in use\n", cnt);
920 wavefront_send_patch (wavefront_patch_info *header)
923 unsigned char buf[WF_PATCH_BYTES+2];
926 DPRINT (WF_DEBUG_LOAD_PATCH, "downloading patch %d\n",
929 dev.patch_status[header->number] |= WF_SLOT_FILLED;
932 bptr = munge_int32 (header->number, buf, 2);
933 munge_buf ((unsigned char *)&header->hdr.p, bptr, WF_PATCH_BYTES);
935 if (wavefront_cmd (WFC_DOWNLOAD_PATCH, 0, buf)) {
936 printk (KERN_ERR LOGNAME "download patch failed\n");
944 wavefront_send_program (wavefront_patch_info *header)
947 unsigned char buf[WF_PROGRAM_BYTES+1];
950 DPRINT (WF_DEBUG_LOAD_PATCH, "downloading program %d\n",
953 dev.prog_status[header->number] = WF_SLOT_USED;
955 /* XXX need to zero existing SLOT_USED bit for program_status[i]
956 where `i' is the program that's being (potentially) overwritten.
959 for (i = 0; i < WF_NUM_LAYERS; i++) {
960 if (header->hdr.pr.layer[i].mute) {
961 dev.patch_status[header->hdr.pr.layer[i].patch_number] |=
964 /* XXX need to mark SLOT_USED for sample used by
965 patch_number, but this means we have to load it. Ick.
970 buf[0] = header->number;
971 munge_buf ((unsigned char *)&header->hdr.pr, &buf[1], WF_PROGRAM_BYTES);
973 if (wavefront_cmd (WFC_DOWNLOAD_PROGRAM, 0, buf)) {
974 printk (KERN_WARNING LOGNAME "download patch failed\n");
982 wavefront_freemem (void)
987 if (wavefront_cmd (WFC_REPORT_FREE_MEMORY, rbuf, 0)) {
988 printk (KERN_WARNING LOGNAME "can't get memory stats.\n");
991 return demunge_int32 (rbuf, 4);
996 wavefront_send_sample (wavefront_patch_info *header,
998 int data_is_unsigned)
1001 /* samples are downloaded via a 16-bit wide i/o port
1002 (you could think of it as 2 adjacent 8-bit wide ports
1003 but its less efficient that way). therefore, all
1004 the blocksizes and so forth listed in the documentation,
1005 and used conventionally to refer to sample sizes,
1006 which are given in 8-bit units (bytes), need to be
1010 UINT16 sample_short;
1012 UINT16 *data_end = 0;
1014 const int max_blksize = 4096/2;
1015 unsigned int written;
1016 unsigned int blocksize;
1019 unsigned char sample_hdr[WF_SAMPLE_HDR_BYTES];
1020 unsigned char *shptr;
1022 int initial_skip = 0;
1024 DPRINT (WF_DEBUG_LOAD_PATCH, "sample %sdownload for slot %d, "
1025 "type %d, %d bytes from 0x%x\n",
1026 header->size ? "" : "header ",
1027 header->number, header->subkey,
1029 (int) header->dataptr);
1031 if (header->number == WAVEFRONT_FIND_FREE_SAMPLE_SLOT) {
1034 if ((x = wavefront_find_free_sample ()) < 0) {
1037 printk (KERN_DEBUG LOGNAME "unspecified sample => %d\n", x);
1043 /* XXX its a debatable point whether or not RDONLY semantics
1044 on the ROM samples should cover just the sample data or
1045 the sample header. For now, it only covers the sample data,
1046 so anyone is free at all times to rewrite sample headers.
1048 My reason for this is that we have the sample headers
1049 available in the WFB file for General MIDI, and so these
1050 can always be reset if needed. The sample data, however,
1051 cannot be recovered without a complete reset and firmware
1052 reload of the ICS2115, which is a very expensive operation.
1054 So, doing things this way allows us to honor the notion of
1055 "RESETSAMPLES" reasonably cheaply. Note however, that this
1056 is done purely at user level: there is no WFB parser in
1057 this driver, and so a complete reset (back to General MIDI,
1058 or theoretically some other configuration) is the
1059 responsibility of the user level library.
1061 To try to do this in the kernel would be a little
1062 crazy: we'd need 158K of kernel space just to hold
1063 a copy of the patch/program/sample header data.
1066 if (dev.rom_samples_rdonly) {
1067 if (dev.sample_status[header->number] & WF_SLOT_ROM) {
1068 printk (KERN_ERR LOGNAME "sample slot %d "
1069 "write protected\n",
1075 wavefront_delete_sample (header->number);
1079 dev.freemem = wavefront_freemem ();
1081 if (dev.freemem < header->size) {
1082 printk (KERN_ERR LOGNAME
1083 "insufficient memory to "
1084 "load %d byte sample.\n",
1091 skip = WF_GET_CHANNEL(&header->hdr.s);
1093 if (skip > 0 && header->hdr.s.SampleResolution != LINEAR_16BIT) {
1094 printk (KERN_ERR LOGNAME "channel selection only "
1095 "possible on 16-bit samples");
1130 DPRINT (WF_DEBUG_LOAD_PATCH, "channel selection: %d => "
1131 "initial skip = %d, skip = %d\n",
1132 WF_GET_CHANNEL (&header->hdr.s),
1133 initial_skip, skip);
1135 /* Be safe, and zero the "Unused" bits ... */
1137 WF_SET_CHANNEL(&header->hdr.s, 0);
1139 /* adjust size for 16 bit samples by dividing by two. We always
1140 send 16 bits per write, even for 8 bit samples, so the length
1141 is always half the size of the sample data in bytes.
1144 length = header->size / 2;
1146 /* the data we're sent has not been munged, and in fact, the
1147 header we have to send isn't just a munged copy either.
1148 so, build the sample header right here.
1151 shptr = &sample_hdr[0];
1153 shptr = munge_int32 (header->number, shptr, 2);
1156 shptr = munge_int32 (length, shptr, 4);
1159 /* Yes, a 4 byte result doesn't contain all of the offset bits,
1160 but the offset only uses 24 bits.
1163 shptr = munge_int32 (*((UINT32 *) &header->hdr.s.sampleStartOffset),
1165 shptr = munge_int32 (*((UINT32 *) &header->hdr.s.loopStartOffset),
1167 shptr = munge_int32 (*((UINT32 *) &header->hdr.s.loopEndOffset),
1169 shptr = munge_int32 (*((UINT32 *) &header->hdr.s.sampleEndOffset),
1172 /* This one is truly weird. What kind of weirdo decided that in
1173 a system dominated by 16 and 32 bit integers, they would use
1177 shptr = munge_int32 (header->hdr.s.FrequencyBias, shptr, 3);
1179 /* Why is this nybblified, when the MSB is *always* zero ?
1180 Anyway, we can't take address of bitfield, so make a
1181 good-faith guess at where it starts.
1184 shptr = munge_int32 (*(&header->hdr.s.FrequencyBias+1),
1187 if (wavefront_cmd (header->size ?
1188 WFC_DOWNLOAD_SAMPLE : WFC_DOWNLOAD_SAMPLE_HEADER,
1190 printk (KERN_WARNING LOGNAME "sample %sdownload refused.\n",
1191 header->size ? "" : "header ");
1195 if (header->size == 0) {
1196 goto sent; /* Sorry. Just had to have one somewhere */
1199 data_end = dataptr + length;
1201 /* Do any initial skip over an unused channel's data */
1203 dataptr += initial_skip;
1205 for (written = 0, blocknum = 0;
1206 written < length; written += max_blksize, blocknum++) {
1208 if ((length - written) > max_blksize) {
1209 blocksize = max_blksize;
1211 /* round to nearest 16-byte value */
1212 blocksize = ((length-written+7)&~0x7);
1215 if (wavefront_cmd (WFC_DOWNLOAD_BLOCK, 0, 0)) {
1216 printk (KERN_WARNING LOGNAME "download block "
1217 "request refused.\n");
1221 for (i = 0; i < blocksize; i++) {
1223 if (dataptr < data_end) {
1225 __get_user (sample_short, dataptr);
1228 if (data_is_unsigned) { /* GUS ? */
1230 if (WF_SAMPLE_IS_8BIT(&header->hdr.s)) {
1238 &sample_short)[0] += 0x7f;
1240 &sample_short)[1] += 0x7f;
1249 sample_short += 0x7fff;
1255 /* In padding section of final block:
1257 Don't fetch unsupplied data from
1258 user space, just continue with
1259 whatever the final value was.
1263 if (i < blocksize - 1) {
1264 outw (sample_short, dev.block_port);
1266 outw (sample_short, dev.last_block_port);
1270 /* Get "DMA page acknowledge", even though its really
1271 nothing to do with DMA at all.
1274 if ((dma_ack = wavefront_read ()) != WF_DMA_ACK) {
1275 if (dma_ack == -1) {
1276 printk (KERN_ERR LOGNAME "upload sample "
1277 "DMA ack timeout\n");
1280 printk (KERN_ERR LOGNAME "upload sample "
1281 "DMA ack error 0x%x\n",
1288 dev.sample_status[header->number] = (WF_SLOT_FILLED|WF_ST_SAMPLE);
1290 /* Note, label is here because sending the sample header shouldn't
1291 alter the sample_status info at all.
1299 wavefront_send_alias (wavefront_patch_info *header)
1302 unsigned char alias_hdr[WF_ALIAS_BYTES];
1304 DPRINT (WF_DEBUG_LOAD_PATCH, "download alias, %d is "
1307 header->hdr.a.OriginalSample);
1309 munge_int32 (header->number, &alias_hdr[0], 2);
1310 munge_int32 (header->hdr.a.OriginalSample, &alias_hdr[2], 2);
1311 munge_int32 (*((unsigned int *)&header->hdr.a.sampleStartOffset),
1313 munge_int32 (*((unsigned int *)&header->hdr.a.loopStartOffset),
1315 munge_int32 (*((unsigned int *)&header->hdr.a.loopEndOffset),
1317 munge_int32 (*((unsigned int *)&header->hdr.a.sampleEndOffset),
1319 munge_int32 (header->hdr.a.FrequencyBias, &alias_hdr[20], 3);
1320 munge_int32 (*(&header->hdr.a.FrequencyBias+1), &alias_hdr[23], 2);
1322 if (wavefront_cmd (WFC_DOWNLOAD_SAMPLE_ALIAS, 0, alias_hdr)) {
1323 printk (KERN_ERR LOGNAME "download alias failed.\n");
1327 dev.sample_status[header->number] = (WF_SLOT_FILLED|WF_ST_ALIAS);
1333 wavefront_send_multisample (wavefront_patch_info *header)
1337 unsigned char msample_hdr[WF_MSAMPLE_BYTES];
1339 munge_int32 (header->number, &msample_hdr[0], 2);
1341 /* You'll recall at this point that the "number of samples" value
1342 in a wavefront_multisample struct is actually the log2 of the
1343 real number of samples.
1346 num_samples = (1<<(header->hdr.ms.NumberOfSamples&7));
1347 msample_hdr[2] = (unsigned char) header->hdr.ms.NumberOfSamples;
1349 DPRINT (WF_DEBUG_LOAD_PATCH, "multi %d with %d=%d samples\n",
1351 header->hdr.ms.NumberOfSamples,
1354 for (i = 0; i < num_samples; i++) {
1355 DPRINT(WF_DEBUG_LOAD_PATCH|WF_DEBUG_DATA, "sample[%d] = %d\n",
1356 i, header->hdr.ms.SampleNumber[i]);
1357 munge_int32 (header->hdr.ms.SampleNumber[i],
1358 &msample_hdr[3+(i*2)], 2);
1361 /* Need a hack here to pass in the number of bytes
1362 to be written to the synth. This is ugly, and perhaps
1363 one day, I'll fix it.
1366 if (wavefront_cmd (WFC_DOWNLOAD_MULTISAMPLE,
1367 (unsigned char *) ((num_samples*2)+3),
1369 printk (KERN_ERR LOGNAME "download of multisample failed.\n");
1373 dev.sample_status[header->number] = (WF_SLOT_FILLED|WF_ST_MULTISAMPLE);
1379 wavefront_fetch_multisample (wavefront_patch_info *header)
1382 unsigned char log_ns[1];
1383 unsigned char number[2];
1386 munge_int32 (header->number, number, 2);
1388 if (wavefront_cmd (WFC_UPLOAD_MULTISAMPLE, log_ns, number)) {
1389 printk (KERN_ERR LOGNAME "upload multisample failed.\n");
1393 DPRINT (WF_DEBUG_DATA, "msample %d has %d samples\n",
1394 header->number, log_ns[0]);
1396 header->hdr.ms.NumberOfSamples = log_ns[0];
1398 /* get the number of samples ... */
1400 num_samples = (1 << log_ns[0]);
1402 for (i = 0; i < num_samples; i++) {
1405 if ((d[0] = wavefront_read ()) == -1) {
1406 printk (KERN_ERR LOGNAME "upload multisample failed "
1407 "during sample loop.\n");
1411 if ((d[1] = wavefront_read ()) == -1) {
1412 printk (KERN_ERR LOGNAME "upload multisample failed "
1413 "during sample loop.\n");
1417 header->hdr.ms.SampleNumber[i] =
1418 demunge_int32 ((unsigned char *) d, 2);
1420 DPRINT (WF_DEBUG_DATA, "msample sample[%d] = %d\n",
1421 i, header->hdr.ms.SampleNumber[i]);
1429 wavefront_send_drum (wavefront_patch_info *header)
1432 unsigned char drumbuf[WF_DRUM_BYTES];
1433 wavefront_drum *drum = &header->hdr.d;
1436 DPRINT (WF_DEBUG_LOAD_PATCH, "downloading edrum for MIDI "
1437 "note %d, patch = %d\n",
1438 header->number, drum->PatchNumber);
1440 drumbuf[0] = header->number & 0x7f;
1442 for (i = 0; i < 4; i++) {
1443 munge_int32 (((unsigned char *)drum)[i], &drumbuf[1+(i*2)], 2);
1446 if (wavefront_cmd (WFC_DOWNLOAD_EDRUM_PROGRAM, 0, drumbuf)) {
1447 printk (KERN_ERR LOGNAME "download drum failed.\n");
1455 wavefront_find_free_sample (void)
1460 for (i = 0; i < WF_MAX_SAMPLE; i++) {
1461 if (!(dev.sample_status[i] & WF_SLOT_FILLED)) {
1465 printk (KERN_WARNING LOGNAME "no free sample slots!\n");
1470 wavefront_find_free_patch (void)
1475 for (i = 0; i < WF_MAX_PATCH; i++) {
1476 if (!(dev.patch_status[i] & WF_SLOT_FILLED)) {
1480 printk (KERN_WARNING LOGNAME "no free patch slots!\n");
1488 int tbl[]={0, 0, 2048, 3246, 4096, 4755, 5294, 5749, 6143,
1489 6492, 6803, 7084, 7342, 7578, 7797, 8001, 8192,
1490 8371, 8540, 8699, 8851, 8995, 9132, 9264, 9390,
1491 9510, 9626, 9738, 9845, 9949, 10049, 10146};
1494 /* Returns 2048*log2(n) */
1496 /* FIXME: this is like doing integer math
1497 on quantum particles (RuN) */
1513 wavefront_load_gus_patch (int devno, int format, const char *addr,
1514 int offs, int count, int pmgr_flag)
1516 struct patch_info guspatch;
1517 wavefront_patch_info samp, pat, prog;
1518 wavefront_patch *patp;
1519 wavefront_sample *sampp;
1520 wavefront_program *progp;
1525 /* Copy in the header of the GUS patch */
1527 sizeof_patch = (long) &guspatch.data[0] - (long) &guspatch;
1528 copy_from_user (&((char *) &guspatch)[offs],
1529 &(addr)[offs], sizeof_patch - offs);
1531 if ((i = wavefront_find_free_patch ()) == -1) {
1535 pat.subkey = WF_ST_PATCH;
1538 if ((i = wavefront_find_free_sample ()) == -1) {
1542 samp.subkey = WF_ST_SAMPLE;
1543 samp.size = guspatch.len;
1544 sampp = &samp.hdr.s;
1546 prog.number = guspatch.instr_no;
1547 progp = &prog.hdr.pr;
1549 /* Setup the patch structure */
1551 patp->amplitude_bias=guspatch.volume;
1553 patp->sample_number= samp.number & 0xff;
1554 patp->sample_msb= samp.number>>8;
1555 patp->pitch_bend= /*12*/ 0;
1558 patp->nohold=(guspatch.mode & WAVE_SUSTAIN_ON) ? 0:1;
1559 patp->frequency_bias=0;
1564 patp->fm_src1=WF_MOD_MOD_WHEEL;
1565 patp->am_src=WF_MOD_PRESSURE;
1566 patp->am_amount=127;
1567 patp->fc1_mod_amount=0;
1568 patp->fc2_mod_amount=0;
1571 patp->envelope1.attack_level=127;
1572 patp->envelope1.decay1_level=127;
1573 patp->envelope1.decay2_level=127;
1574 patp->envelope1.sustain_level=127;
1575 patp->envelope1.release_level=0;
1576 patp->envelope2.attack_velocity=127;
1577 patp->envelope2.attack_level=127;
1578 patp->envelope2.decay1_level=127;
1579 patp->envelope2.decay2_level=127;
1580 patp->envelope2.sustain_level=127;
1581 patp->envelope2.release_level=0;
1582 patp->envelope2.attack_velocity=127;
1585 /* Program for this patch */
1587 progp->layer[0].patch_number= pat.number; /* XXX is this right ? */
1588 progp->layer[0].mute=1;
1589 progp->layer[0].pan_or_mod=1;
1590 progp->layer[0].pan=7;
1591 progp->layer[0].mix_level=127 /* guspatch.volume */;
1592 progp->layer[0].split_type=0;
1593 progp->layer[0].split_point=0;
1594 progp->layer[0].play_below=0;
1596 for (i = 1; i < 4; i++) {
1597 progp->layer[i].mute=0;
1602 sampp->SampleResolution=((~guspatch.mode & WAVE_16_BITS)<<1);
1605 note_to_freq (base_note) < guspatch.base_note;
1608 if ((guspatch.base_note-note_to_freq(base_note))
1609 >(note_to_freq(base_note)-guspatch.base_note))
1612 printk(KERN_DEBUG "ref freq=%d,base note=%d\n",
1616 sampp->FrequencyBias = (29550 - log2_2048(guspatch.base_freq)
1618 printk(KERN_DEBUG "Freq Bias is %d\n", sampp->FrequencyBias);
1619 sampp->Loop=(guspatch.mode & WAVE_LOOPING) ? 1:0;
1620 sampp->sampleStartOffset.Fraction=0;
1621 sampp->sampleStartOffset.Integer=0;
1622 sampp->loopStartOffset.Fraction=0;
1623 sampp->loopStartOffset.Integer=guspatch.loop_start
1624 >>((guspatch.mode&WAVE_16_BITS) ? 1:0);
1625 sampp->loopEndOffset.Fraction=0;
1626 sampp->loopEndOffset.Integer=guspatch.loop_end
1627 >>((guspatch.mode&WAVE_16_BITS) ? 1:0);
1628 sampp->sampleEndOffset.Fraction=0;
1629 sampp->sampleEndOffset.Integer=guspatch.len >> (guspatch.mode&1);
1630 sampp->Bidirectional=(guspatch.mode&WAVE_BIDIR_LOOP) ? 1:0;
1631 sampp->Reverse=(guspatch.mode&WAVE_LOOP_BACK) ? 1:0;
1633 /* Now ship it down */
1635 wavefront_send_sample (&samp,
1636 (unsigned short *) &(addr)[sizeof_patch],
1637 (guspatch.mode & WAVE_UNSIGNED) ? 1:0);
1638 wavefront_send_patch (&pat);
1639 wavefront_send_program (&prog);
1641 /* Now pan as best we can ... use the slave/internal MIDI device
1642 number if it exists (since it talks to the WaveFront), or the
1646 if (dev.mididev > 0) {
1647 midi_synth_controller (dev.mididev, guspatch.instr_no, 10,
1648 ((guspatch.panning << 4) > 127) ?
1649 127 : (guspatch.panning << 4));
1656 wavefront_load_patch (const char *addr)
1660 wavefront_patch_info header;
1662 if (copy_from_user (&header, addr, sizeof(wavefront_patch_info) -
1663 sizeof(wavefront_any))) {
1664 printk (KERN_WARNING LOGNAME "bad address for load patch.\n");
1668 DPRINT (WF_DEBUG_LOAD_PATCH, "download "
1670 "Sample number: %d "
1671 "Sample size: %d\n",
1676 switch (header.subkey) {
1677 case WF_ST_SAMPLE: /* sample or sample_header, based on patch->size */
1679 copy_from_user ((unsigned char *) &header.hdr.s,
1680 (unsigned char *) header.hdrptr,
1681 sizeof (wavefront_sample));
1683 return wavefront_send_sample (&header, header.dataptr, 0);
1685 case WF_ST_MULTISAMPLE:
1687 copy_from_user ((unsigned char *) &header.hdr.s,
1688 (unsigned char *) header.hdrptr,
1689 sizeof (wavefront_multisample));
1691 return wavefront_send_multisample (&header);
1696 copy_from_user ((unsigned char *) &header.hdr.a,
1697 (unsigned char *) header.hdrptr,
1698 sizeof (wavefront_alias));
1700 return wavefront_send_alias (&header);
1703 copy_from_user ((unsigned char *) &header.hdr.d,
1704 (unsigned char *) header.hdrptr,
1705 sizeof (wavefront_drum));
1707 return wavefront_send_drum (&header);
1710 copy_from_user ((unsigned char *) &header.hdr.p,
1711 (unsigned char *) header.hdrptr,
1712 sizeof (wavefront_patch));
1714 return wavefront_send_patch (&header);
1717 copy_from_user ((unsigned char *) &header.hdr.pr,
1718 (unsigned char *) header.hdrptr,
1719 sizeof (wavefront_program));
1721 return wavefront_send_program (&header);
1724 printk (KERN_ERR LOGNAME "unknown patch type %d.\n",
1732 /***********************************************************************
1733 WaveFront: /dev/sequencer{,2} and other hardware-dependent interfaces
1734 ***********************************************************************/
1737 process_sample_hdr (UCHAR8 *buf)
1745 /* The board doesn't send us an exact copy of a "wavefront_sample"
1746 in response to an Upload Sample Header command. Instead, we
1747 have to convert the data format back into our data structure,
1748 just as in the Download Sample command, where we have to do
1749 something very similar in the reverse direction.
1752 *((UINT32 *) &s.sampleStartOffset) = demunge_int32 (ptr, 4); ptr += 4;
1753 *((UINT32 *) &s.loopStartOffset) = demunge_int32 (ptr, 4); ptr += 4;
1754 *((UINT32 *) &s.loopEndOffset) = demunge_int32 (ptr, 4); ptr += 4;
1755 *((UINT32 *) &s.sampleEndOffset) = demunge_int32 (ptr, 4); ptr += 4;
1756 *((UINT32 *) &s.FrequencyBias) = demunge_int32 (ptr, 3); ptr += 3;
1758 s.SampleResolution = *ptr & 0x3;
1759 s.Loop = *ptr & 0x8;
1760 s.Bidirectional = *ptr & 0x10;
1761 s.Reverse = *ptr & 0x40;
1763 /* Now copy it back to where it came from */
1765 memcpy (buf, (unsigned char *) &s, sizeof (wavefront_sample));
1769 wavefront_synth_control (int cmd, wavefront_control *wc)
1772 unsigned char patchnumbuf[2];
1775 DPRINT (WF_DEBUG_CMD, "synth control with "
1776 "cmd 0x%x\n", wc->cmd);
1778 /* Pre-handling of or for various commands */
1781 case WFC_DISABLE_INTERRUPTS:
1782 printk (KERN_INFO LOGNAME "interrupts disabled.\n");
1783 outb (0x80|0x20, dev.control_port);
1784 dev.interrupts_on = 0;
1787 case WFC_ENABLE_INTERRUPTS:
1788 printk (KERN_INFO LOGNAME "interrupts enabled.\n");
1789 outb (0x80|0x40|0x20, dev.control_port);
1790 dev.interrupts_on = 1;
1793 case WFC_INTERRUPT_STATUS:
1794 wc->rbuf[0] = dev.interrupts_on;
1797 case WFC_ROMSAMPLES_RDONLY:
1798 dev.rom_samples_rdonly = wc->wbuf[0];
1802 case WFC_IDENTIFY_SLOT_TYPE:
1803 i = wc->wbuf[0] | (wc->wbuf[1] << 7);
1804 if (i <0 || i >= WF_MAX_SAMPLE) {
1805 printk (KERN_WARNING LOGNAME "invalid slot ID %d\n",
1807 wc->status = EINVAL;
1810 wc->rbuf[0] = dev.sample_status[i];
1814 case WFC_DEBUG_DRIVER:
1815 dev.debug = wc->wbuf[0];
1816 printk (KERN_INFO LOGNAME "debug = 0x%x\n", dev.debug);
1820 wffx_ioctl ((wavefront_fx_info *) &wc->wbuf[0]);
1823 case WFC_UPLOAD_PATCH:
1824 munge_int32 (*((UINT32 *) wc->wbuf), patchnumbuf, 2);
1825 memcpy (wc->wbuf, patchnumbuf, 2);
1828 case WFC_UPLOAD_MULTISAMPLE:
1829 /* multisamples have to be handled differently, and
1830 cannot be dealt with properly by wavefront_cmd() alone.
1832 wc->status = wavefront_fetch_multisample
1833 ((wavefront_patch_info *) wc->rbuf);
1836 case WFC_UPLOAD_SAMPLE_ALIAS:
1837 printk (KERN_INFO LOGNAME "support for sample alias upload "
1838 "being considered.\n");
1839 wc->status = EINVAL;
1843 wc->status = wavefront_cmd (wc->cmd, wc->rbuf, wc->wbuf);
1845 /* Post-handling of certain commands.
1847 In particular, if the command was an upload, demunge the data
1848 so that the user-level doesn't have to think about it.
1851 if (wc->status == 0) {
1853 /* intercept any freemem requests so that we know
1854 we are always current with the user-level view
1858 case WFC_REPORT_FREE_MEMORY:
1859 dev.freemem = demunge_int32 (wc->rbuf, 4);
1862 case WFC_UPLOAD_PATCH:
1863 demunge_buf (wc->rbuf, wc->rbuf, WF_PATCH_BYTES);
1866 case WFC_UPLOAD_PROGRAM:
1867 demunge_buf (wc->rbuf, wc->rbuf, WF_PROGRAM_BYTES);
1870 case WFC_UPLOAD_EDRUM_PROGRAM:
1871 demunge_buf (wc->rbuf, wc->rbuf, WF_DRUM_BYTES - 1);
1874 case WFC_UPLOAD_SAMPLE_HEADER:
1875 process_sample_hdr (wc->rbuf);
1878 case WFC_UPLOAD_SAMPLE_ALIAS:
1879 printk (KERN_INFO LOGNAME "support for "
1880 "sample aliases still "
1881 "being considered.\n");
1885 if (virtual_midi_disable () < 0) {
1891 if (virtual_midi_enable () < 0) {
1902 /***********************************************************************/
1903 /* WaveFront: Linux file system interface (for access via raw synth) */
1904 /***********************************************************************/
1907 wavefront_open (struct inode *inode, struct file *file)
1910 dev.opened = file->f_flags;
1915 wavefront_release(struct inode *inode, struct file *file)
1925 wavefront_ioctl(struct inode *inode, struct file *file,
1926 unsigned int cmd, unsigned long arg)
1928 wavefront_control wc;
1934 copy_from_user (&wc, (void *) arg, sizeof (wc));
1936 if ((err = wavefront_synth_control (cmd, &wc)) == 0) {
1937 copy_to_user ((void *) arg, &wc, sizeof (wc));
1942 case WFCTL_LOAD_SPP:
1943 return wavefront_load_patch ((const char *) arg);
1946 printk (KERN_WARNING LOGNAME "invalid ioctl %#x\n", cmd);
1953 static /*const*/ struct file_operations wavefront_fops = {
1956 ioctl: wavefront_ioctl,
1957 open: wavefront_open,
1958 release: wavefront_release,
1962 /***********************************************************************/
1963 /* WaveFront: OSS installation and support interface */
1964 /***********************************************************************/
1966 #if OSS_SUPPORT_LEVEL & OSS_SUPPORT_SEQ
1968 static struct synth_info wavefront_info =
1969 {"Turtle Beach WaveFront", 0, SYNTH_TYPE_SAMPLE, SAMPLE_TYPE_WAVEFRONT,
1970 0, 32, 0, 0, SYNTH_CAP_INPUT};
1973 wavefront_oss_open (int devno, int mode)
1981 wavefront_oss_close (int devno)
1990 wavefront_oss_ioctl (int devno, unsigned int cmd, caddr_t arg)
1993 wavefront_control wc;
1997 case SNDCTL_SYNTH_INFO:
1998 if(copy_to_user(&((char *) arg)[0], &wavefront_info,
1999 sizeof (wavefront_info)))
2003 case SNDCTL_SEQ_RESETSAMPLES:
2004 // printk (KERN_WARNING LOGNAME "driver cannot reset samples.\n");
2005 return 0; /* don't force an error */
2007 case SNDCTL_SEQ_PERCMODE:
2008 return 0; /* don't force an error */
2010 case SNDCTL_SYNTH_MEMAVL:
2011 if ((dev.freemem = wavefront_freemem ()) < 0) {
2012 printk (KERN_ERR LOGNAME "cannot get memory size\n");
2019 case SNDCTL_SYNTH_CONTROL:
2020 if(copy_from_user (&wc, arg, sizeof (wc)))
2022 else if ((err = wavefront_synth_control (cmd, &wc)) == 0) {
2023 if(copy_to_user (arg, &wc, sizeof (wc)))
2035 wavefront_oss_load_patch (int devno, int format, const char *addr,
2036 int offs, int count, int pmgr_flag)
2039 if (format == SYSEX_PATCH) { /* Handled by midi_synth.c */
2040 if (midi_load_patch == NULL) {
2041 printk (KERN_ERR LOGNAME
2042 "SYSEX not loadable: "
2043 "no midi patch loader!\n");
2047 return midi_load_patch (devno, format, addr,
2048 offs, count, pmgr_flag);
2050 } else if (format == GUS_PATCH) {
2051 return wavefront_load_gus_patch (devno, format,
2052 addr, offs, count, pmgr_flag);
2054 } else if (format != WAVEFRONT_PATCH) {
2055 printk (KERN_ERR LOGNAME "unknown patch format %d\n", format);
2059 if (count < sizeof (wavefront_patch_info)) {
2060 printk (KERN_ERR LOGNAME "sample header too short\n");
2064 /* "addr" points to a user-space wavefront_patch_info */
2066 return wavefront_load_patch (addr);
2069 static struct synth_operations wavefront_operations =
2073 info: &wavefront_info,
2075 synth_type: SYNTH_TYPE_SAMPLE,
2076 synth_subtype: SAMPLE_TYPE_WAVEFRONT,
2077 open: wavefront_oss_open,
2078 close: wavefront_oss_close,
2079 ioctl: wavefront_oss_ioctl,
2080 kill_note: midi_synth_kill_note,
2081 start_note: midi_synth_start_note,
2082 set_instr: midi_synth_set_instr,
2083 reset: midi_synth_reset,
2084 load_patch: midi_synth_load_patch,
2085 aftertouch: midi_synth_aftertouch,
2086 controller: midi_synth_controller,
2087 panning: midi_synth_panning,
2088 bender: midi_synth_bender,
2089 setup_voice: midi_synth_setup_voice
2091 #endif /* OSS_SUPPORT_SEQ */
2093 #if OSS_SUPPORT_LEVEL & OSS_SUPPORT_STATIC_INSTALL
2095 static void __init attach_wavefront (struct address_info *hw_config)
2097 (void) install_wavefront ();
2100 static int __init probe_wavefront (struct address_info *hw_config)
2102 return !detect_wavefront (hw_config->irq, hw_config->io_base);
2105 static void __exit unload_wavefront (struct address_info *hw_config)
2107 (void) uninstall_wavefront ();
2110 #endif /* OSS_SUPPORT_STATIC_INSTALL */
2112 /***********************************************************************/
2113 /* WaveFront: Linux modular sound kernel installation interface */
2114 /***********************************************************************/
2117 wavefrontintr (int irq, void *dev_id, struct pt_regs *dummy)
2119 struct wf_config *hw = dev_id;
2122 Some comments on interrupts. I attempted a version of this
2123 driver that used interrupts throughout the code instead of
2124 doing busy and/or sleep-waiting. Alas, it appears that once
2125 the Motorola firmware is downloaded, the card *never*
2126 generates an RX interrupt. These are successfully generated
2127 during firmware loading, and after that wavefront_status()
2128 reports that an interrupt is pending on the card from time
2129 to time, but it never seems to be delivered to this
2130 driver. Note also that wavefront_status() continues to
2131 report that RX interrupts are enabled, suggesting that I
2132 didn't goof up and disable them by mistake.
2134 Thus, I stepped back to a prior version of
2135 wavefront_wait(), the only place where this really
2136 matters. Its sad, but I've looked through the code to check
2137 on things, and I really feel certain that the Motorola
2138 firmware prevents RX-ready interrupts.
2141 if ((wavefront_status() & (STAT_INTR_READ|STAT_INTR_WRITE)) == 0) {
2147 wake_up_interruptible (&hw->interrupt_sleeper);
2152 0 Host Rx Interrupt Enable (1=Enabled)
2153 1 Host Rx Register Full (1=Full)
2154 2 Host Rx Interrupt Pending (1=Interrupt)
2156 4 Host Tx Interrupt (1=Enabled)
2157 5 Host Tx Register empty (1=Empty)
2158 6 Host Tx Interrupt Pending (1=Interrupt)
2163 wavefront_interrupt_bits (int irq)
2183 printk (KERN_WARNING LOGNAME "invalid IRQ %d\n", irq);
2191 wavefront_should_cause_interrupt (int val, int port, int timeout)
2194 unsigned long flags;
2200 interruptible_sleep_on_timeout (&dev.interrupt_sleeper, timeout);
2201 restore_flags (flags);
2204 static int __init wavefront_hw_reset (void)
2208 unsigned long irq_mask;
2211 /* IRQ already checked in init_module() */
2213 bits = wavefront_interrupt_bits (dev.irq);
2215 printk (KERN_DEBUG LOGNAME "autodetecting WaveFront IRQ\n");
2219 irq_mask = probe_irq_on ();
2221 outb (0x0, dev.control_port);
2222 outb (0x80 | 0x40 | bits, dev.data_port);
2223 wavefront_should_cause_interrupt(0x80|0x40|0x10|0x1,
2225 (reset_time*HZ)/100);
2227 reported_irq = probe_irq_off (irq_mask);
2229 if (reported_irq != dev.irq) {
2230 if (reported_irq == 0) {
2231 printk (KERN_ERR LOGNAME
2232 "No unassigned interrupts detected "
2233 "after h/w reset\n");
2234 } else if (reported_irq < 0) {
2235 printk (KERN_ERR LOGNAME
2236 "Multiple unassigned interrupts detected "
2237 "after h/w reset\n");
2239 printk (KERN_ERR LOGNAME "autodetected IRQ %d not the "
2240 "value provided (%d)\n", reported_irq,
2246 printk (KERN_INFO LOGNAME "autodetected IRQ at %d\n",
2250 if (request_irq (dev.irq, wavefrontintr,
2251 SA_INTERRUPT|SA_SHIRQ,
2252 "wavefront synth", &dev) < 0) {
2253 printk (KERN_WARNING LOGNAME "IRQ %d not available!\n",
2258 /* try reset of port */
2260 outb (0x0, dev.control_port);
2262 /* At this point, the board is in reset, and the H/W initialization
2263 register is accessed at the same address as the data port.
2265 Bit 7 - Enable IRQ Driver
2266 0 - Tri-state the Wave-Board drivers for the PC Bus IRQs
2267 1 - Enable IRQ selected by bits 5:3 to be driven onto the PC Bus.
2269 Bit 6 - MIDI Interface Select
2271 0 - Use the MIDI Input from the 26-pin WaveBlaster
2272 compatible header as the serial MIDI source
2273 1 - Use the MIDI Input from the 9-pin D connector as the
2276 Bits 5:3 - IRQ Selection
2287 Bit 0 - Disable Boot ROM
2288 0 - memory accesses to 03FC30-03FFFFH utilize the internal Boot ROM
2289 1 - memory accesses to 03FC30-03FFFFH are directed to external
2294 /* configure hardware: IRQ, enable interrupts,
2295 plus external 9-pin MIDI interface selected
2298 outb (0x80 | 0x40 | bits, dev.data_port);
2302 0 Host Rx Interrupt Enable (1=Enabled) 0x1
2306 4 Host Tx Interrupt Enable 0x10
2307 5 Mute (0=Mute; 1=Play) 0x20
2308 6 Master Interrupt Enable (1=Enabled) 0x40
2309 7 Master Reset (0=Reset; 1=Run) 0x80
2311 Take us out of reset, mute output, master + TX + RX interrupts on.
2313 We'll get an interrupt presumably to tell us that the TX
2317 wavefront_should_cause_interrupt(0x80|0x40|0x10|0x1,
2319 (reset_time*HZ)/100);
2321 /* Note: data port is now the data port, not the h/w initialization
2326 printk (KERN_WARNING LOGNAME
2327 "intr not received after h/w un-reset.\n");
2331 dev.interrupts_on = 1;
2333 /* Note: data port is now the data port, not the h/w initialization
2336 At this point, only "HW VERSION" or "DOWNLOAD OS" commands
2337 will work. So, issue one of them, and wait for TX
2338 interrupt. This can take a *long* time after a cold boot,
2339 while the ISC ROM does its RAM test. The SDK says up to 4
2340 seconds - with 12MB of RAM on a Tropez+, it takes a lot
2341 longer than that (~16secs). Note that the card understands
2342 the difference between a warm and a cold boot, so
2343 subsequent ISC2115 reboots (say, caused by module
2344 reloading) will get through this much faster.
2346 XXX Interesting question: why is no RX interrupt received first ?
2349 wavefront_should_cause_interrupt(WFC_HARDWARE_VERSION,
2350 dev.data_port, ramcheck_time*HZ);
2353 printk (KERN_WARNING LOGNAME
2354 "post-RAM-check interrupt not received.\n");
2358 if (!wavefront_wait (STAT_CAN_READ)) {
2359 printk (KERN_WARNING LOGNAME
2360 "no response to HW version cmd.\n");
2364 if ((hwv[0] = wavefront_read ()) == -1) {
2365 printk (KERN_WARNING LOGNAME
2366 "board not responding correctly.\n");
2370 if (hwv[0] == 0xFF) { /* NAK */
2372 /* Board's RAM test failed. Try to read error code,
2373 and tell us about it either way.
2376 if ((hwv[0] = wavefront_read ()) == -1) {
2377 printk (KERN_WARNING LOGNAME "on-board RAM test failed "
2378 "(bad error code).\n");
2380 printk (KERN_WARNING LOGNAME "on-board RAM test failed "
2381 "(error code: 0x%x).\n",
2387 /* We're OK, just get the next byte of the HW version response */
2389 if ((hwv[1] = wavefront_read ()) == -1) {
2390 printk (KERN_WARNING LOGNAME "incorrect h/w response.\n");
2394 printk (KERN_INFO LOGNAME "hardware version %d.%d\n",
2402 free_irq (dev.irq, &dev);
2408 static int __init detect_wavefront (int irq, int io_base)
2410 unsigned char rbuf[4], wbuf[4];
2412 /* TB docs say the device takes up 8 ports, but we know that
2413 if there is an FX device present (i.e. a Tropez+) it really
2417 if (check_region (io_base, 16)) {
2418 printk (KERN_ERR LOGNAME "IO address range 0x%x - 0x%x "
2419 "already in use - ignored\n", dev.base,
2427 dev.debug = debug_default;
2428 dev.interrupts_on = 0;
2430 dev.rom_samples_rdonly = 1; /* XXX default lock on ROM sample slots */
2432 if (wavefront_cmd (WFC_FIRMWARE_VERSION, rbuf, wbuf) == 0) {
2434 dev.fw_version[0] = rbuf[0];
2435 dev.fw_version[1] = rbuf[1];
2436 printk (KERN_INFO LOGNAME
2437 "firmware %d.%d already loaded.\n",
2440 /* check that a command actually works */
2442 if (wavefront_cmd (WFC_HARDWARE_VERSION,
2444 dev.hw_version[0] = rbuf[0];
2445 dev.hw_version[1] = rbuf[1];
2447 printk (KERN_WARNING LOGNAME "not raw, but no "
2448 "hardware version!\n");
2455 printk (KERN_INFO LOGNAME
2456 "reloading firmware anyway.\n");
2463 printk (KERN_INFO LOGNAME
2464 "no response to firmware probe, assume raw.\n");
2468 init_waitqueue_head (&dev.interrupt_sleeper);
2470 if (wavefront_hw_reset ()) {
2471 printk (KERN_WARNING LOGNAME "hardware reset failed\n");
2475 /* Check for FX device, present only on Tropez+ */
2477 dev.has_fx = (detect_wffx () == 0);
2483 #define __KERNEL_SYSCALLS__
2484 #include <linux/fs.h>
2485 #include <linux/mm.h>
2486 #include <linux/slab.h>
2487 static int my_errno;
2488 #define errno my_errno
2489 #include <asm/unistd.h>
2490 #include <asm/uaccess.h>
2493 wavefront_download_firmware (char *path)
2496 unsigned char section[WF_SECTION_MAX];
2497 char section_length; /* yes, just a char; max value is WF_SECTION_MAX */
2498 int section_cnt_downloaded = 0;
2504 /* This tries to be a bit cleverer than the stuff Alan Cox did for
2505 the generic sound firmware, in that it actually knows
2506 something about the structure of the Motorola firmware. In
2507 particular, it uses a version that has been stripped of the
2508 20K of useless header information, and had section lengths
2509 added, making it possible to load the entire OS without any
2510 [kv]malloc() activity, since the longest entity we ever read is
2511 42 bytes (well, WF_SECTION_MAX) long.
2517 if ((fd = open (path, 0, 0)) < 0) {
2518 printk (KERN_WARNING LOGNAME "Unable to load \"%s\".\n",
2526 if ((x = read (fd, §ion_length, sizeof (section_length))) !=
2527 sizeof (section_length)) {
2528 printk (KERN_ERR LOGNAME "firmware read error.\n");
2532 if (section_length == 0) {
2536 if (read (fd, section, section_length) != section_length) {
2537 printk (KERN_ERR LOGNAME "firmware section "
2544 if (wavefront_write (WFC_DOWNLOAD_OS)) {
2548 for (i = 0; i < section_length; i++) {
2549 if (wavefront_write (section[i])) {
2556 if (wavefront_wait (STAT_CAN_READ)) {
2558 if ((c = inb (dev.data_port)) != WF_ACK) {
2560 printk (KERN_ERR LOGNAME "download "
2561 "of section #%d not "
2562 "acknowledged, ack = 0x%x\n",
2563 section_cnt_downloaded + 1, c);
2569 printk (KERN_ERR LOGNAME "time out for firmware ACK.\n");
2582 printk (KERN_ERR "\nWaveFront: firmware download failed!!!\n");
2586 static int __init wavefront_config_midi (void)
2588 unsigned char rbuf[4], wbuf[4];
2590 if (detect_wf_mpu (dev.irq, dev.base) < 0) {
2591 printk (KERN_WARNING LOGNAME
2592 "could not find working MIDI device\n");
2596 if ((dev.mididev = install_wf_mpu ()) < 0) {
2597 printk (KERN_WARNING LOGNAME
2598 "MIDI interfaces not configured\n");
2602 /* Route external MIDI to WaveFront synth (by default) */
2604 if (wavefront_cmd (WFC_MISYNTH_ON, rbuf, wbuf)) {
2605 printk (KERN_WARNING LOGNAME
2606 "cannot enable MIDI-IN to synth routing.\n");
2611 #if OSS_SUPPORT_LEVEL & OSS_SUPPORT_SEQ
2612 /* Get the regular MIDI patch loading function, so we can
2613 use it if we ever get handed a SYSEX patch. This is
2614 unlikely, because its so damn slow, but we may as well
2615 leave this functionality from maui.c behind, since it
2616 could be useful for sequencer applications that can
2617 only use MIDI to do patch loading.
2620 if (midi_devs[dev.mididev]->converter != NULL) {
2621 midi_load_patch = midi_devs[dev.mididev]->converter->load_patch;
2622 midi_devs[dev.mididev]->converter->load_patch =
2623 &wavefront_oss_load_patch;
2626 #endif /* OSS_SUPPORT_SEQ */
2628 /* Turn on Virtual MIDI, but first *always* turn it off,
2629 since otherwise consectutive reloads of the driver will
2630 never cause the hardware to generate the initial "internal" or
2631 "external" source bytes in the MIDI data stream. This
2632 is pretty important, since the internal hardware generally will
2633 be used to generate none or very little MIDI output, and
2634 thus the only source of MIDI data is actually external. Without
2635 the switch bytes, the driver will think it all comes from
2636 the internal interface. Duh.
2639 if (wavefront_cmd (WFC_VMIDI_OFF, rbuf, wbuf)) {
2640 printk (KERN_WARNING LOGNAME
2641 "virtual MIDI mode not disabled\n");
2642 return 0; /* We're OK, but missing the external MIDI dev */
2645 if ((dev.ext_mididev = virtual_midi_enable ()) < 0) {
2646 printk (KERN_WARNING LOGNAME "no virtual MIDI access.\n");
2648 if (wavefront_cmd (WFC_VMIDI_ON, rbuf, wbuf)) {
2649 printk (KERN_WARNING LOGNAME
2650 "cannot enable virtual MIDI mode.\n");
2651 virtual_midi_disable ();
2658 static int __init wavefront_do_reset (int atboot)
2662 if (!atboot && wavefront_hw_reset ()) {
2663 printk (KERN_WARNING LOGNAME "hw reset failed.\n");
2668 if (wavefront_download_firmware (ospath)) {
2674 /* Wait for the OS to get running. The protocol for
2675 this is non-obvious, and was determined by
2676 using port-IO tracing in DOSemu and some
2677 experimentation here.
2679 Rather than using timed waits, use interrupts creatively.
2682 wavefront_should_cause_interrupt (WFC_NOOP,
2687 printk (KERN_WARNING LOGNAME
2688 "no post-OS interrupt.\n");
2692 /* Now, do it again ! */
2694 wavefront_should_cause_interrupt (WFC_NOOP,
2695 dev.data_port, (10*HZ));
2698 printk (KERN_WARNING LOGNAME
2699 "no post-OS interrupt(2).\n");
2703 /* OK, no (RX/TX) interrupts any more, but leave mute
2707 outb (0x80|0x40, dev.control_port);
2709 /* No need for the IRQ anymore */
2711 free_irq (dev.irq, &dev);
2715 if (dev.has_fx && fx_raw) {
2719 /* SETUPSND.EXE asks for sample memory config here, but since i
2720 have no idea how to interpret the result, we'll forget
2724 if ((dev.freemem = wavefront_freemem ()) < 0) {
2728 printk (KERN_INFO LOGNAME "available DRAM %dk\n", dev.freemem / 1024);
2730 if (wavefront_write (0xf0) ||
2731 wavefront_write (1) ||
2732 (wavefront_read () < 0)) {
2734 printk (KERN_WARNING LOGNAME "MPU emulation mode not set.\n");
2740 if (wavefront_cmd (WFC_SET_NVOICES, 0, voices)) {
2741 printk (KERN_WARNING LOGNAME
2742 "cannot set number of voices to 32.\n");
2750 /* reset that sucker so that it doesn't bother us. */
2752 outb (0x0, dev.control_port);
2753 dev.interrupts_on = 0;
2755 free_irq (dev.irq, &dev);
2760 static int __init wavefront_init (int atboot)
2762 int samples_are_from_rom;
2765 samples_are_from_rom = 1;
2767 /* XXX is this always true ? */
2768 samples_are_from_rom = 0;
2771 if (dev.israw || fx_raw) {
2772 if (wavefront_do_reset (atboot)) {
2777 wavefront_get_sample_status (samples_are_from_rom);
2778 wavefront_get_program_status ();
2779 wavefront_get_patch_status ();
2781 /* Start normal operation: unreset, master interrupt enabled, no mute
2784 outb (0x80|0x40|0x20, dev.control_port);
2789 static int __init install_wavefront (void)
2792 if ((dev.synth_dev = register_sound_synth (&wavefront_fops, -1)) < 0) {
2793 printk (KERN_ERR LOGNAME "cannot register raw synth\n");
2797 #if OSS_SUPPORT_LEVEL & OSS_SUPPORT_SEQ
2798 if ((dev.oss_dev = sound_alloc_synthdev()) == -1) {
2799 printk (KERN_ERR LOGNAME "Too many sequencers\n");
2802 synth_devs[dev.oss_dev] = &wavefront_operations;
2804 #endif /* OSS_SUPPORT_SEQ */
2806 if (wavefront_init (1) < 0) {
2807 printk (KERN_WARNING LOGNAME "initialization failed.\n");
2809 #if OSS_SUPPORT_LEVEL & OSS_SUPPORT_SEQ
2810 sound_unload_synthdev (dev.oss_dev);
2811 #endif /* OSS_SUPPORT_SEQ */
2816 request_region (dev.base+2, 6, "wavefront synth");
2819 request_region (dev.base+8, 8, "wavefront fx");
2822 if (wavefront_config_midi ()) {
2823 printk (KERN_WARNING LOGNAME "could not initialize MIDI.\n");
2829 static void __exit uninstall_wavefront (void)
2831 /* the first two i/o addresses are freed by the wf_mpu code */
2832 release_region (dev.base+2, 6);
2835 release_region (dev.base+8, 8);
2838 unregister_sound_synth (dev.synth_dev);
2840 #if OSS_SUPPORT_LEVEL & OSS_SUPPORT_SEQ
2841 sound_unload_synthdev (dev.oss_dev);
2842 #endif /* OSS_SUPPORT_SEQ */
2843 uninstall_wf_mpu ();
2846 /***********************************************************************/
2847 /* WaveFront FX control */
2848 /***********************************************************************/
2852 /* Control bits for the Load Control Register
2855 #define FX_LSB_TRANSFER 0x01 /* transfer after DSP LSB byte written */
2856 #define FX_MSB_TRANSFER 0x02 /* transfer after DSP MSB byte written */
2857 #define FX_AUTO_INCR 0x04 /* auto-increment DSP address after transfer */
2864 unsigned int x = 0x80;
2866 for (i = 0; i < 1000; i++) {
2867 x = inb (dev.fx_status);
2868 if ((x & 0x80) == 0) {
2874 printk (KERN_ERR LOGNAME "FX device never idle.\n");
2881 int __init detect_wffx (void)
2883 /* This is a crude check, but its the best one I have for now.
2884 Certainly on the Maui and the Tropez, wffx_idle() will
2885 report "never idle", which suggests that this test should
2889 if (inb (dev.fx_status) & 0x80) {
2890 printk (KERN_INFO LOGNAME "Hmm, probably a Maui or Tropez.\n");
2897 int __init attach_wffx (void)
2899 if ((dev.fx_mididev = sound_alloc_mididev ()) < 0) {
2900 printk (KERN_WARNING LOGNAME "cannot install FX Midi driver\n");
2908 wffx_mute (int onoff)
2915 outb (onoff ? 0x02 : 0x00, dev.fx_op);
2919 wffx_memset (int page,
2920 int addr, int cnt, unsigned short *data)
2922 if (page < 0 || page > 7) {
2923 printk (KERN_ERR LOGNAME "FX memset: "
2924 "page must be >= 0 and <= 7\n");
2928 if (addr < 0 || addr > 0x7f) {
2929 printk (KERN_ERR LOGNAME "FX memset: "
2930 "addr must be >= 0 and <= 7f\n");
2936 outb (FX_LSB_TRANSFER, dev.fx_lcr);
2937 outb (page, dev.fx_dsp_page);
2938 outb (addr, dev.fx_dsp_addr);
2939 outb ((data[0] >> 8), dev.fx_dsp_msb);
2940 outb ((data[0] & 0xff), dev.fx_dsp_lsb);
2942 printk (KERN_INFO LOGNAME "FX: addr %d:%x set to 0x%x\n",
2943 page, addr, data[0]);
2948 outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);
2949 outb (page, dev.fx_dsp_page);
2950 outb (addr, dev.fx_dsp_addr);
2952 for (i = 0; i < cnt; i++) {
2953 outb ((data[i] >> 8), dev.fx_dsp_msb);
2954 outb ((data[i] & 0xff), dev.fx_dsp_lsb);
2955 if (!wffx_idle ()) {
2961 printk (KERN_WARNING LOGNAME
2963 "(0x%x, 0x%x, 0x%x, %d) incomplete\n",
2964 page, addr, (int) data, cnt);
2973 wffx_ioctl (wavefront_fx_info *r)
2976 unsigned short page_data[256];
2979 switch (r->request) {
2981 wffx_mute (r->data[0]);
2986 if (r->data[2] <= 0) {
2987 printk (KERN_ERR LOGNAME "cannot write "
2988 "<= 0 bytes to FX\n");
2990 } else if (r->data[2] == 1) {
2991 pd = (unsigned short *) &r->data[3];
2993 if (r->data[2] > sizeof (page_data)) {
2994 printk (KERN_ERR LOGNAME "cannot write "
2995 "> 255 bytes to FX\n");
2998 copy_from_user (page_data, (unsigned char *) r->data[3],
3003 return wffx_memset (r->data[0], /* page */
3004 r->data[1], /* addr */
3005 r->data[2], /* cnt */
3009 printk (KERN_WARNING LOGNAME
3010 "FX: ioctl %d not yet supported\n",
3016 /* YSS225 initialization.
3018 This code was developed using DOSEMU. The Turtle Beach SETUPSND
3019 utility was run with I/O tracing in DOSEMU enabled, and a reconstruction
3020 of the port I/O done, using the Yamaha faxback document as a guide
3021 to add more logic to the code. Its really pretty weird.
3023 There was an alternative approach of just dumping the whole I/O
3024 sequence as a series of port/value pairs and a simple loop
3025 that output it. However, I hope that eventually I'll get more
3026 control over what this code does, and so I tried to stick with
3027 a somewhat "algorithmic" approach.
3030 static int __init wffx_init (void)
3035 /* Set all bits for all channels on the MOD unit to zero */
3036 /* XXX But why do this twice ? */
3038 for (j = 0; j < 2; j++) {
3039 for (i = 0x10; i <= 0xff; i++) {
3041 if (!wffx_idle ()) {
3045 outb (i, dev.fx_mod_addr);
3046 outb (0x0, dev.fx_mod_data);
3050 if (!wffx_idle()) return (-1);
3051 outb (0x02, dev.fx_op); /* mute on */
3053 if (!wffx_idle()) return (-1);
3054 outb (0x07, dev.fx_dsp_page);
3055 outb (0x44, dev.fx_dsp_addr);
3056 outb (0x00, dev.fx_dsp_msb);
3057 outb (0x00, dev.fx_dsp_lsb);
3058 if (!wffx_idle()) return (-1);
3059 outb (0x07, dev.fx_dsp_page);
3060 outb (0x42, dev.fx_dsp_addr);
3061 outb (0x00, dev.fx_dsp_msb);
3062 outb (0x00, dev.fx_dsp_lsb);
3063 if (!wffx_idle()) return (-1);
3064 outb (0x07, dev.fx_dsp_page);
3065 outb (0x43, dev.fx_dsp_addr);
3066 outb (0x00, dev.fx_dsp_msb);
3067 outb (0x00, dev.fx_dsp_lsb);
3068 if (!wffx_idle()) return (-1);
3069 outb (0x07, dev.fx_dsp_page);
3070 outb (0x7c, dev.fx_dsp_addr);
3071 outb (0x00, dev.fx_dsp_msb);
3072 outb (0x00, dev.fx_dsp_lsb);
3073 if (!wffx_idle()) return (-1);
3074 outb (0x07, dev.fx_dsp_page);
3075 outb (0x7e, dev.fx_dsp_addr);
3076 outb (0x00, dev.fx_dsp_msb);
3077 outb (0x00, dev.fx_dsp_lsb);
3078 if (!wffx_idle()) return (-1);
3079 outb (0x07, dev.fx_dsp_page);
3080 outb (0x46, dev.fx_dsp_addr);
3081 outb (0x00, dev.fx_dsp_msb);
3082 outb (0x00, dev.fx_dsp_lsb);
3083 if (!wffx_idle()) return (-1);
3084 outb (0x07, dev.fx_dsp_page);
3085 outb (0x49, dev.fx_dsp_addr);
3086 outb (0x00, dev.fx_dsp_msb);
3087 outb (0x00, dev.fx_dsp_lsb);
3088 if (!wffx_idle()) return (-1);
3089 outb (0x07, dev.fx_dsp_page);
3090 outb (0x47, dev.fx_dsp_addr);
3091 outb (0x00, dev.fx_dsp_msb);
3092 outb (0x00, dev.fx_dsp_lsb);
3093 if (!wffx_idle()) return (-1);
3094 outb (0x07, dev.fx_dsp_page);
3095 outb (0x4a, dev.fx_dsp_addr);
3096 outb (0x00, dev.fx_dsp_msb);
3097 outb (0x00, dev.fx_dsp_lsb);
3099 /* either because of stupidity by TB's programmers, or because it
3100 actually does something, rezero the MOD page.
3102 for (i = 0x10; i <= 0xff; i++) {
3104 if (!wffx_idle ()) {
3108 outb (i, dev.fx_mod_addr);
3109 outb (0x0, dev.fx_mod_data);
3111 /* load page zero */
3113 outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);
3114 outb (0x00, dev.fx_dsp_page);
3115 outb (0x00, dev.fx_dsp_addr);
3117 for (i = 0; i < sizeof (page_zero); i += 2) {
3118 outb (page_zero[i], dev.fx_dsp_msb);
3119 outb (page_zero[i+1], dev.fx_dsp_lsb);
3120 if (!wffx_idle()) return (-1);
3123 /* Now load page one */
3125 outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);
3126 outb (0x01, dev.fx_dsp_page);
3127 outb (0x00, dev.fx_dsp_addr);
3129 for (i = 0; i < sizeof (page_one); i += 2) {
3130 outb (page_one[i], dev.fx_dsp_msb);
3131 outb (page_one[i+1], dev.fx_dsp_lsb);
3132 if (!wffx_idle()) return (-1);
3135 outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);
3136 outb (0x02, dev.fx_dsp_page);
3137 outb (0x00, dev.fx_dsp_addr);
3139 for (i = 0; i < sizeof (page_two); i++) {
3140 outb (page_two[i], dev.fx_dsp_lsb);
3141 if (!wffx_idle()) return (-1);
3144 outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);
3145 outb (0x03, dev.fx_dsp_page);
3146 outb (0x00, dev.fx_dsp_addr);
3148 for (i = 0; i < sizeof (page_three); i++) {
3149 outb (page_three[i], dev.fx_dsp_lsb);
3150 if (!wffx_idle()) return (-1);
3153 outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);
3154 outb (0x04, dev.fx_dsp_page);
3155 outb (0x00, dev.fx_dsp_addr);
3157 for (i = 0; i < sizeof (page_four); i++) {
3158 outb (page_four[i], dev.fx_dsp_lsb);
3159 if (!wffx_idle()) return (-1);
3162 /* Load memory area (page six) */
3164 outb (FX_LSB_TRANSFER, dev.fx_lcr);
3165 outb (0x06, dev.fx_dsp_page);
3167 for (i = 0; i < sizeof (page_six); i += 3) {
3168 outb (page_six[i], dev.fx_dsp_addr);
3169 outb (page_six[i+1], dev.fx_dsp_msb);
3170 outb (page_six[i+2], dev.fx_dsp_lsb);
3171 if (!wffx_idle()) return (-1);
3174 outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);
3175 outb (0x07, dev.fx_dsp_page);
3176 outb (0x00, dev.fx_dsp_addr);
3178 for (i = 0; i < sizeof (page_seven); i += 2) {
3179 outb (page_seven[i], dev.fx_dsp_msb);
3180 outb (page_seven[i+1], dev.fx_dsp_lsb);
3181 if (!wffx_idle()) return (-1);
3184 /* Now setup the MOD area. We do this algorithmically in order to
3185 save a little data space. It could be done in the same fashion
3189 for (i = 0x00; i <= 0x0f; i++) {
3190 outb (0x01, dev.fx_mod_addr);
3191 outb (i, dev.fx_mod_data);
3192 if (!wffx_idle()) return (-1);
3193 outb (0x02, dev.fx_mod_addr);
3194 outb (0x00, dev.fx_mod_data);
3195 if (!wffx_idle()) return (-1);
3198 for (i = 0xb0; i <= 0xbf; i++) {
3199 outb (i, dev.fx_mod_addr);
3200 outb (0x20, dev.fx_mod_data);
3201 if (!wffx_idle()) return (-1);
3204 for (i = 0xf0; i <= 0xff; i++) {
3205 outb (i, dev.fx_mod_addr);
3206 outb (0x20, dev.fx_mod_data);
3207 if (!wffx_idle()) return (-1);
3210 for (i = 0x10; i <= 0x1d; i++) {
3211 outb (i, dev.fx_mod_addr);
3212 outb (0xff, dev.fx_mod_data);
3213 if (!wffx_idle()) return (-1);
3216 outb (0x1e, dev.fx_mod_addr);
3217 outb (0x40, dev.fx_mod_data);
3218 if (!wffx_idle()) return (-1);
3220 for (i = 0x1f; i <= 0x2d; i++) {
3221 outb (i, dev.fx_mod_addr);
3222 outb (0xff, dev.fx_mod_data);
3223 if (!wffx_idle()) return (-1);
3226 outb (0x2e, dev.fx_mod_addr);
3227 outb (0x00, dev.fx_mod_data);
3228 if (!wffx_idle()) return (-1);
3230 for (i = 0x2f; i <= 0x3e; i++) {
3231 outb (i, dev.fx_mod_addr);
3232 outb (0x00, dev.fx_mod_data);
3233 if (!wffx_idle()) return (-1);
3236 outb (0x3f, dev.fx_mod_addr);
3237 outb (0x20, dev.fx_mod_data);
3238 if (!wffx_idle()) return (-1);
3240 for (i = 0x40; i <= 0x4d; i++) {
3241 outb (i, dev.fx_mod_addr);
3242 outb (0x00, dev.fx_mod_data);
3243 if (!wffx_idle()) return (-1);
3246 outb (0x4e, dev.fx_mod_addr);
3247 outb (0x0e, dev.fx_mod_data);
3248 if (!wffx_idle()) return (-1);
3249 outb (0x4f, dev.fx_mod_addr);
3250 outb (0x0e, dev.fx_mod_data);
3251 if (!wffx_idle()) return (-1);
3254 for (i = 0x50; i <= 0x6b; i++) {
3255 outb (i, dev.fx_mod_addr);
3256 outb (0x00, dev.fx_mod_data);
3257 if (!wffx_idle()) return (-1);
3260 outb (0x6c, dev.fx_mod_addr);
3261 outb (0x40, dev.fx_mod_data);
3262 if (!wffx_idle()) return (-1);
3264 outb (0x6d, dev.fx_mod_addr);
3265 outb (0x00, dev.fx_mod_data);
3266 if (!wffx_idle()) return (-1);
3268 outb (0x6e, dev.fx_mod_addr);
3269 outb (0x40, dev.fx_mod_data);
3270 if (!wffx_idle()) return (-1);
3272 outb (0x6f, dev.fx_mod_addr);
3273 outb (0x40, dev.fx_mod_data);
3274 if (!wffx_idle()) return (-1);
3276 for (i = 0x70; i <= 0x7f; i++) {
3277 outb (i, dev.fx_mod_addr);
3278 outb (0xc0, dev.fx_mod_data);
3279 if (!wffx_idle()) return (-1);
3282 for (i = 0x80; i <= 0xaf; i++) {
3283 outb (i, dev.fx_mod_addr);
3284 outb (0x00, dev.fx_mod_data);
3285 if (!wffx_idle()) return (-1);
3288 for (i = 0xc0; i <= 0xdd; i++) {
3289 outb (i, dev.fx_mod_addr);
3290 outb (0x00, dev.fx_mod_data);
3291 if (!wffx_idle()) return (-1);
3294 outb (0xde, dev.fx_mod_addr);
3295 outb (0x10, dev.fx_mod_data);
3296 if (!wffx_idle()) return (-1);
3297 outb (0xdf, dev.fx_mod_addr);
3298 outb (0x10, dev.fx_mod_data);
3299 if (!wffx_idle()) return (-1);
3301 for (i = 0xe0; i <= 0xef; i++) {
3302 outb (i, dev.fx_mod_addr);
3303 outb (0x00, dev.fx_mod_data);
3304 if (!wffx_idle()) return (-1);
3307 for (i = 0x00; i <= 0x0f; i++) {
3308 outb (0x01, dev.fx_mod_addr);
3309 outb (i, dev.fx_mod_data);
3310 outb (0x02, dev.fx_mod_addr);
3311 outb (0x01, dev.fx_mod_data);
3312 if (!wffx_idle()) return (-1);
3315 outb (0x02, dev.fx_op); /* mute on */
3317 /* Now set the coefficients and so forth for the programs above */
3319 for (i = 0; i < sizeof (coefficients); i += 4) {
3320 outb (coefficients[i], dev.fx_dsp_page);
3321 outb (coefficients[i+1], dev.fx_dsp_addr);
3322 outb (coefficients[i+2], dev.fx_dsp_msb);
3323 outb (coefficients[i+3], dev.fx_dsp_lsb);
3324 if (!wffx_idle()) return (-1);
3327 /* Some settings (?) that are too small to bundle into loops */
3329 if (!wffx_idle()) return (-1);
3330 outb (0x1e, dev.fx_mod_addr);
3331 outb (0x14, dev.fx_mod_data);
3332 if (!wffx_idle()) return (-1);
3333 outb (0xde, dev.fx_mod_addr);
3334 outb (0x20, dev.fx_mod_data);
3335 if (!wffx_idle()) return (-1);
3336 outb (0xdf, dev.fx_mod_addr);
3337 outb (0x20, dev.fx_mod_data);
3339 /* some more coefficients */
3341 if (!wffx_idle()) return (-1);
3342 outb (0x06, dev.fx_dsp_page);
3343 outb (0x78, dev.fx_dsp_addr);
3344 outb (0x00, dev.fx_dsp_msb);
3345 outb (0x40, dev.fx_dsp_lsb);
3346 if (!wffx_idle()) return (-1);
3347 outb (0x07, dev.fx_dsp_page);
3348 outb (0x03, dev.fx_dsp_addr);
3349 outb (0x0f, dev.fx_dsp_msb);
3350 outb (0xff, dev.fx_dsp_lsb);
3351 if (!wffx_idle()) return (-1);
3352 outb (0x07, dev.fx_dsp_page);
3353 outb (0x0b, dev.fx_dsp_addr);
3354 outb (0x0f, dev.fx_dsp_msb);
3355 outb (0xff, dev.fx_dsp_lsb);
3356 if (!wffx_idle()) return (-1);
3357 outb (0x07, dev.fx_dsp_page);
3358 outb (0x02, dev.fx_dsp_addr);
3359 outb (0x00, dev.fx_dsp_msb);
3360 outb (0x00, dev.fx_dsp_lsb);
3361 if (!wffx_idle()) return (-1);
3362 outb (0x07, dev.fx_dsp_page);
3363 outb (0x0a, dev.fx_dsp_addr);
3364 outb (0x00, dev.fx_dsp_msb);
3365 outb (0x00, dev.fx_dsp_lsb);
3366 if (!wffx_idle()) return (-1);
3367 outb (0x07, dev.fx_dsp_page);
3368 outb (0x46, dev.fx_dsp_addr);
3369 outb (0x00, dev.fx_dsp_msb);
3370 outb (0x00, dev.fx_dsp_lsb);
3371 if (!wffx_idle()) return (-1);
3372 outb (0x07, dev.fx_dsp_page);
3373 outb (0x49, dev.fx_dsp_addr);
3374 outb (0x00, dev.fx_dsp_msb);
3375 outb (0x00, dev.fx_dsp_lsb);
3377 /* Now, for some strange reason, lets reload every page
3378 and all the coefficients over again. I have *NO* idea
3379 why this is done. I do know that no sound is produced
3380 is this phase is omitted.
3383 outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);
3384 outb (0x00, dev.fx_dsp_page);
3385 outb (0x10, dev.fx_dsp_addr);
3387 for (i = 0; i < sizeof (page_zero_v2); i += 2) {
3388 outb (page_zero_v2[i], dev.fx_dsp_msb);
3389 outb (page_zero_v2[i+1], dev.fx_dsp_lsb);
3390 if (!wffx_idle()) return (-1);
3393 outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);
3394 outb (0x01, dev.fx_dsp_page);
3395 outb (0x10, dev.fx_dsp_addr);
3397 for (i = 0; i < sizeof (page_one_v2); i += 2) {
3398 outb (page_one_v2[i], dev.fx_dsp_msb);
3399 outb (page_one_v2[i+1], dev.fx_dsp_lsb);
3400 if (!wffx_idle()) return (-1);
3403 if (!wffx_idle()) return (-1);
3404 if (!wffx_idle()) return (-1);
3406 outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);
3407 outb (0x02, dev.fx_dsp_page);
3408 outb (0x10, dev.fx_dsp_addr);
3410 for (i = 0; i < sizeof (page_two_v2); i++) {
3411 outb (page_two_v2[i], dev.fx_dsp_lsb);
3412 if (!wffx_idle()) return (-1);
3414 outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);
3415 outb (0x03, dev.fx_dsp_page);
3416 outb (0x10, dev.fx_dsp_addr);
3418 for (i = 0; i < sizeof (page_three_v2); i++) {
3419 outb (page_three_v2[i], dev.fx_dsp_lsb);
3420 if (!wffx_idle()) return (-1);
3423 outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);
3424 outb (0x04, dev.fx_dsp_page);
3425 outb (0x10, dev.fx_dsp_addr);
3427 for (i = 0; i < sizeof (page_four_v2); i++) {
3428 outb (page_four_v2[i], dev.fx_dsp_lsb);
3429 if (!wffx_idle()) return (-1);
3432 outb (FX_LSB_TRANSFER, dev.fx_lcr);
3433 outb (0x06, dev.fx_dsp_page);
3435 /* Page six v.2 is algorithmic */
3437 for (i = 0x10; i <= 0x3e; i += 2) {
3438 outb (i, dev.fx_dsp_addr);
3439 outb (0x00, dev.fx_dsp_msb);
3440 outb (0x00, dev.fx_dsp_lsb);
3441 if (!wffx_idle()) return (-1);
3444 outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);
3445 outb (0x07, dev.fx_dsp_page);
3446 outb (0x10, dev.fx_dsp_addr);
3448 for (i = 0; i < sizeof (page_seven_v2); i += 2) {
3449 outb (page_seven_v2[i], dev.fx_dsp_msb);
3450 outb (page_seven_v2[i+1], dev.fx_dsp_lsb);
3451 if (!wffx_idle()) return (-1);
3454 for (i = 0x00; i < sizeof(mod_v2); i += 2) {
3455 outb (mod_v2[i], dev.fx_mod_addr);
3456 outb (mod_v2[i+1], dev.fx_mod_data);
3457 if (!wffx_idle()) return (-1);
3460 for (i = 0; i < sizeof (coefficients2); i += 4) {
3461 outb (coefficients2[i], dev.fx_dsp_page);
3462 outb (coefficients2[i+1], dev.fx_dsp_addr);
3463 outb (coefficients2[i+2], dev.fx_dsp_msb);
3464 outb (coefficients2[i+3], dev.fx_dsp_lsb);
3465 if (!wffx_idle()) return (-1);
3468 for (i = 0; i < sizeof (coefficients3); i += 2) {
3471 outb (0x07, dev.fx_dsp_page);
3472 x = (i % 4) ? 0x4e : 0x4c;
3473 outb (x, dev.fx_dsp_addr);
3474 outb (coefficients3[i], dev.fx_dsp_msb);
3475 outb (coefficients3[i+1], dev.fx_dsp_lsb);
3478 outb (0x00, dev.fx_op); /* mute off */
3479 if (!wffx_idle()) return (-1);
3485 static int irq = -1;
3487 MODULE_AUTHOR ("Paul Barton-Davis <pbd@op.net>");
3488 MODULE_DESCRIPTION ("Turtle Beach WaveFront Linux Driver");
3489 MODULE_LICENSE("GPL");
3490 MODULE_PARM (io,"i");
3491 MODULE_PARM (irq,"i");
3493 static int __init init_wavfront (void)
3495 printk ("Turtle Beach WaveFront Driver\n"
3496 "Copyright (C) by Hannu Solvainen, "
3497 "Paul Barton-Davis 1993-1998.\n");
3499 /* XXX t'would be lovely to ask the CS4232 for these values, eh ? */
3501 if (io == -1 || irq == -1) {
3502 printk (KERN_INFO LOGNAME "irq and io options must be set.\n");
3506 if (wavefront_interrupt_bits (irq) < 0) {
3507 printk (KERN_INFO LOGNAME
3508 "IRQ must be 9, 5, 12 or 15 (not %d)\n", irq);
3512 if (detect_wavefront (irq, io) < 0) {
3516 if (install_wavefront () < 0) {
3523 static void __exit cleanup_wavfront (void)
3525 uninstall_wavefront ();
3528 module_init(init_wavfront);
3529 module_exit(cleanup_wavfront);