patch-2.2.0-pre5 linux/drivers/sound/wf_midi.c
Next file: linux/drivers/video/atyfb.c
Previous file: linux/drivers/sound/wavfront.c
Back to the patch index
Back to the overall index
- Lines: 940
- Date:
Mon Jan 4 11:37:30 1999
- Orig file:
v2.2.0-pre4/linux/drivers/sound/wf_midi.c
- Orig date:
Thu Nov 12 16:21:22 1998
diff -u --recursive --new-file v2.2.0-pre4/linux/drivers/sound/wf_midi.c linux/drivers/sound/wf_midi.c
@@ -40,7 +40,7 @@
/*
* Copyright (C) by Paul Barton-Davis 1998
- * Substantial portions of this file are derived from work that is:
+ * Some portions of this file are derived from work that is:
*
* Copyright (C) by Hannu Savolainen 1993-1996
*
@@ -50,17 +50,22 @@
*/
#include <linux/config.h>
+#include <linux/init.h>
#include "sound_config.h"
#include "soundmodule.h"
#include <linux/wavefront.h>
-#if (defined(CONFIG_WAVEFRONT) && defined(CONFIG_MIDI)) || defined(MODULE)
+#if defined(CONFIG_SOUND_WAVEFRONT_MODULE) && defined(MODULE)
struct wf_mpu_config {
- int base; /* I/O base */
+ int base;
+#define DATAPORT(d) (d)->base
+#define COMDPORT(d) (d)->base+1
+#define STATPORT(d) (d)->base+1
+
int irq;
- int opened; /* Open mode */
+ int opened;
int devno;
int synthno;
int mode;
@@ -68,69 +73,54 @@
#define MODE_SYNTH 2
void (*inputintr) (int dev, unsigned char data);
-
- /* Virtual MIDI support */
-
- char configured_for_virtual; /* setup for virtual completed */
char isvirtual; /* do virtual I/O stuff */
- char isexternal; /* i am an external interface */
- int internal; /* external interface midi_devno */
- int external; /* external interface midi_devno */
};
-#define DATAPORT(base) (base)
-#define COMDPORT(base) (base+1)
-#define STATPORT(base) (base+1)
+static struct wf_mpu_config devs[2];
+static struct wf_mpu_config *phys_dev = &devs[0];
+static struct wf_mpu_config *virt_dev = &devs[1];
-static void start_uart_mode (struct wf_mpu_config *devc);
+static void start_uart_mode (void);
-static int
-wf_mpu_status (struct wf_mpu_config *devc)
-{
- return inb (STATPORT (devc->base));
-}
+#define OUTPUT_READY 0x40
+#define INPUT_AVAIL 0x80
+#define MPU_ACK 0xFE
+#define UART_MODE_ON 0x3F
+
+static inline int
+wf_mpu_status (void)
-static void
-wf_mpu_cmd (struct wf_mpu_config *devc, unsigned char cmd)
{
- outb ((cmd), COMDPORT(devc->base));
+ return inb (STATPORT (phys_dev));
}
-#define input_avail(devc) (!(wf_mpu_status(devc)&INPUT_AVAIL))
-#define output_ready(devc) (!(wf_mpu_status(devc)&OUTPUT_READY))
+static inline int
+input_avail (void)
-static int
-read_data (struct wf_mpu_config *devc)
{
- return inb (DATAPORT (devc->base));
+ return !(wf_mpu_status() & INPUT_AVAIL);
}
-static void
-write_data (struct wf_mpu_config *devc, unsigned char byte)
+static inline int
+output_ready (void)
+
{
- outb (byte, DATAPORT (devc->base));
+ return !(wf_mpu_status() & OUTPUT_READY);
}
-#define OUTPUT_READY 0x40
-#define INPUT_AVAIL 0x80
-#define MPU_ACK 0xFE
-#define MPU_RESET 0xFF
-#define UART_MODE_ON 0x3F
+static inline int
+read_data (void)
-static struct wf_mpu_config dev_conf[MAX_MIDI_DEV] =
{
- {0}
-};
-
-static volatile int irq2dev[17] =
-{-1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1};
+ return inb (DATAPORT (phys_dev));
+}
-static struct synth_info wf_mpu_synth_info_proto =
-{"WaveFront MPU-401 interface", 0,
- SYNTH_TYPE_MIDI, MIDI_TYPE_MPU401, 0, 128, 0, 128, SYNTH_CAP_INPUT};
+static inline void
+write_data (unsigned char byte)
-static struct synth_info wf_mpu_synth_info[MAX_MIDI_DEV];
+{
+ outb (byte, DATAPORT (phys_dev));
+}
/*
* States for the input scanner (should be in dev_table.h)
@@ -162,11 +152,10 @@
};
static int
-wf_mpu_input_scanner (struct wf_mpu_config *devc, unsigned char midic)
-{
- struct midi_input_info *mi;
+wf_mpu_input_scanner (int devno, int synthdev, unsigned char midic)
- mi = &midi_devs[devc->devno]->in_info;
+{
+ struct midi_input_info *mi = &midi_devs[devno]->in_info;
switch (mi->m_state) {
case MST_INIT:
@@ -236,8 +225,7 @@
if (mi->m_left <= 0) {
mi->m_state = MST_INIT;
- do_midi_msg (devc->synthno, mi->m_buf,
- mi->m_ptr);
+ do_midi_msg (synthdev, mi->m_buf, mi->m_ptr);
mi->m_ptr = 0;
}
} else if (msg == 0xf) { /* MPU MARK */
@@ -266,8 +254,7 @@
if (mi->m_left <= 0) {
mi->m_state = MST_INIT;
- do_midi_msg (devc->synthno, mi->m_buf,
- mi->m_ptr);
+ do_midi_msg (synthdev, mi->m_buf, mi->m_ptr);
mi->m_ptr = 0;
}
}
@@ -362,7 +349,7 @@
mi->m_buf[mi->m_ptr++] = midic;
if ((--mi->m_left) <= 0) {
mi->m_state = MST_INIT;
- do_midi_msg (devc->synthno, mi->m_buf, mi->m_ptr);
+ do_midi_msg (synthdev, mi->m_buf, mi->m_ptr);
mi->m_ptr = 0;
}
break;
@@ -375,78 +362,65 @@
return 1;
}
-void wf_mpuintr (int irq, void *dev_id, struct pt_regs *dummy)
+void
+wf_mpuintr (int irq, void *dev_id, struct pt_regs *dummy)
+
{
- struct wf_mpu_config *devc;
- int dev;
- static struct wf_mpu_config *isrc = 0;
+ struct wf_mpu_config *physical_dev = dev_id;
+ static struct wf_mpu_config *input_dev = 0;
+ struct midi_input_info *mi = &midi_devs[physical_dev->devno]->in_info;
int n;
- struct midi_input_info *mi;
- if (irq < 0 || irq > 15)
- {
- printk (KERN_ERR "WF-MPU: bogus interrupt #%d", irq);
+ if (!input_avail()) { /* not for us */
return;
}
- dev = irq2dev[irq];
- mi = &midi_devs[dev]->in_info;
- if (mi->m_busy)
- return;
+
+ if (mi->m_busy) return;
mi->m_busy = 1;
-
sti ();
- n = 50;
-
- /* guarantee that we're working with the "real" (internal)
- interface before doing anything physical.
- */
+ if (!input_dev) {
+ input_dev = physical_dev;
+ }
- devc = &dev_conf[dev];
- devc = &dev_conf[devc->internal];
+ n = 50; /* XXX why ? */
- if (isrc == 0) {
-
- /* This is just an initial setting. If Virtual MIDI mode is
- enabled on the ICS2115, we'll get a switch char before
- anything else, and if it isn't, then the guess will be
- correct for our purposes.
- */
-
- isrc = &dev_conf[devc->internal];
- }
-
- while (input_avail (devc) && n-- > 0) {
- unsigned char c = read_data (devc);
+ do {
+ unsigned char c = read_data ();
- if (devc->isvirtual) {
+ if (phys_dev->isvirtual) {
+
if (c == WF_EXTERNAL_SWITCH) {
- isrc = &dev_conf[devc->external];
+ input_dev = virt_dev;
continue;
} else if (c == WF_INTERNAL_SWITCH) {
- isrc = &dev_conf[devc->internal];
+ input_dev = phys_dev;
continue;
} /* else just leave it as it is */
+
} else {
- isrc = &dev_conf[devc->internal];
+ input_dev = phys_dev;
}
- if (isrc->mode == MODE_SYNTH) {
+ if (input_dev->mode == MODE_SYNTH) {
- wf_mpu_input_scanner (isrc, c);
+ wf_mpu_input_scanner (input_dev->devno,
+ input_dev->synthno, c);
- } else if (isrc->opened & OPEN_READ) {
+ } else if (input_dev->opened & OPEN_READ) {
- if (isrc->inputintr) {
- isrc->inputintr (isrc->devno, c);
+ if (input_dev->inputintr) {
+ input_dev->inputintr (input_dev->devno, c);
}
}
- }
+
+ } while (input_avail() && n-- > 0);
mi->m_busy = 0;
}
-static int wf_mpu_open (int dev, int mode,
+static int
+wf_mpu_open (int dev, int mode,
void (*input) (int dev, unsigned char data),
void (*output) (int dev)
)
@@ -456,7 +430,14 @@
if (dev < 0 || dev >= num_midis || midi_devs[dev]==NULL)
return -(ENXIO);
- devc = &dev_conf[dev];
+ if (phys_dev->devno == dev) {
+ devc = phys_dev;
+ } else if (phys_dev->isvirtual && virt_dev->devno == dev) {
+ devc = virt_dev;
+ } else {
+ printk (KERN_ERR "WF-MPU: unknown device number %d\n", dev);
+ return -(EINVAL);
+ }
if (devc->opened) {
return -(EBUSY);
@@ -475,7 +456,18 @@
{
struct wf_mpu_config *devc;
- devc = &dev_conf[dev];
+ if (dev < 0 || dev >= num_midis || midi_devs[dev]==NULL)
+ return;
+
+ if (phys_dev->devno == dev) {
+ devc = phys_dev;
+ } else if (phys_dev->isvirtual && virt_dev->devno == dev) {
+ devc = virt_dev;
+ } else {
+ printk (KERN_ERR "WF-MPU: unknown device number %d\n", dev);
+ return;
+ }
+
devc->mode = 0;
devc->inputintr = NULL;
devc->opened = 0;
@@ -487,40 +479,35 @@
int timeout;
unsigned long flags;
static int lastoutdev = -1;
-
- struct wf_mpu_config *devc;
unsigned char switchch;
- /* The actual output has to occur using the "internal" config info
- */
-
- devc = &dev_conf[dev_conf[dev].internal];
-
- if (devc->isvirtual && lastoutdev != dev) {
+ if (phys_dev->isvirtual && lastoutdev != dev) {
- if (dev == devc->internal) {
+ if (dev == phys_dev->devno) {
switchch = WF_INTERNAL_SWITCH;
- } else if (dev == devc->external) {
+ } else if (dev == virt_dev->devno) {
switchch = WF_EXTERNAL_SWITCH;
} else {
printk (KERN_ERR "WF-MPU: bad device number %d", dev);
return (0);
}
+
+ /* XXX fix me */
- for (timeout = 30000; timeout > 0 && !output_ready (devc);
+ for (timeout = 30000; timeout > 0 && !output_ready ();
timeout--);
save_flags (flags);
cli ();
- if (!output_ready (devc)) {
+ if (!output_ready ()) {
printk (KERN_WARNING "WF-MPU: Send switch "
"byte timeout\n");
restore_flags (flags);
return 0;
}
- write_data (devc, switchch);
+ write_data (switchch);
restore_flags (flags);
}
@@ -531,17 +518,19 @@
* (After reset). Normally it takes just about 10 loops.
*/
- for (timeout = 30000; timeout > 0 && !output_ready (devc); timeout--);
+ /* XXX fix me */
+
+ for (timeout = 30000; timeout > 0 && !output_ready (); timeout--);
save_flags (flags);
cli ();
- if (!output_ready (devc)) {
+ if (!output_ready ()) {
printk (KERN_WARNING "WF-MPU: Send data timeout\n");
restore_flags (flags);
return 0;
}
- write_data (devc, midi_byte);
+ write_data (midi_byte);
restore_flags (flags);
return 1;
@@ -567,35 +556,63 @@
return -(EINVAL);
}
-static void
-wf_mpu_kick (int dev)
-{
-}
-
static int
wf_mpu_buffer_status (int dev)
{
- return 0; /*
- * No data in buffers
- */
+ return 0;
}
+static struct synth_operations wf_mpu_synth_operations[2];
+static struct midi_operations wf_mpu_midi_operations[2];
+
+static struct midi_operations wf_mpu_midi_proto =
+{
+ {"WF-MPU MIDI", 0, MIDI_CAP_MPU401, SNDCARD_MPU401},
+ NULL, /*converter*/
+ {0}, /* in_info */
+ wf_mpu_open,
+ wf_mpu_close,
+ wf_mpu_ioctl,
+ wf_mpu_out,
+ wf_mpu_start_read,
+ wf_mpu_end_read,
+ NULL,
+ NULL,
+ wf_mpu_buffer_status,
+ NULL
+};
+
+static struct synth_info wf_mpu_synth_info_proto =
+{"WaveFront MPU-401 interface", 0,
+ SYNTH_TYPE_MIDI, MIDI_TYPE_MPU401, 0, 128, 0, 128, SYNTH_CAP_INPUT};
+
+static struct synth_info wf_mpu_synth_info[2];
+
static int
wf_mpu_synth_ioctl (int dev,
unsigned int cmd, caddr_t arg)
{
int midi_dev;
+ int index;
midi_dev = synth_devs[dev]->midi_dev;
if (midi_dev < 0 || midi_dev > num_midis || midi_devs[midi_dev]==NULL)
return -(ENXIO);
+ if (midi_dev == phys_dev->devno) {
+ index = 0;
+ } else if (phys_dev->isvirtual && midi_dev == virt_dev->devno) {
+ index = 1;
+ } else {
+ return -(EINVAL);
+ }
+
switch (cmd) {
case SNDCTL_SYNTH_INFO:
copy_to_user (&((char *) arg)[0],
- &wf_mpu_synth_info[midi_dev],
+ &wf_mpu_synth_info[index],
sizeof (struct synth_info));
return 0;
@@ -622,7 +639,15 @@
return -(ENXIO);
}
- devc = &dev_conf[midi_dev];
+ if (phys_dev->devno == midi_dev) {
+ devc = phys_dev;
+ } else if (phys_dev->isvirtual && virt_dev->devno == midi_dev) {
+ devc = virt_dev;
+ } else {
+ printk (KERN_ERR "WF-MPU: unknown device number %d\n", dev);
+ return -(EINVAL);
+ }
+
if (devc->opened) {
return -(EBUSY);
}
@@ -642,7 +667,15 @@
midi_dev = synth_devs[dev]->midi_dev;
- devc = &dev_conf[midi_dev];
+ if (phys_dev->devno == midi_dev) {
+ devc = phys_dev;
+ } else if (phys_dev->isvirtual && virt_dev->devno == midi_dev) {
+ devc = virt_dev;
+ } else {
+ printk (KERN_ERR "WF-MPU: unknown device number %d\n", dev);
+ return;
+ }
+
devc->inputintr = NULL;
devc->opened = 0;
devc->mode = 0;
@@ -678,233 +711,145 @@
midi_synth_send_sysex
};
-static struct synth_operations wf_mpu_synth_operations[2];
-static struct midi_operations wf_mpu_midi_operations[2];
-static int wfmpu_cnt = 0;
-
-static struct midi_operations wf_mpu_midi_proto =
-{
- {"WF-MPU MIDI", 0, MIDI_CAP_MPU401, SNDCARD_MPU401},
- NULL, /*converter*/
- {0}, /* in_info */
- wf_mpu_open,
- wf_mpu_close,
- wf_mpu_ioctl,
- wf_mpu_out,
- wf_mpu_start_read,
- wf_mpu_end_read,
- wf_mpu_kick,
- NULL,
- wf_mpu_buffer_status,
- NULL
-};
-
-
static int
-config_wf_mpu (int dev, struct address_info *hw_config)
+config_wf_mpu (struct wf_mpu_config *dev)
{
- struct wf_mpu_config *devc;
- int internal;
-
- if (wfmpu_cnt >= 2) {
- printk (KERN_ERR "WF-MPU: more MPU devices than cards ?!!\n");
- return (-1);
- }
-
- /* There is no synth available on the external interface,
- so do the synth stuff to the internal interface only.
- */
-
- internal = dev_conf[dev].internal;
- devc = &dev_conf[internal];
-
- if (!dev_conf[dev].isexternal) {
- memcpy ((char *) &wf_mpu_synth_operations[wfmpu_cnt],
+ int is_external;
+ char *name;
+ int index;
+
+ if (dev == phys_dev) {
+ name = "WaveFront internal MIDI";
+ is_external = 0;
+ index = 0;
+ memcpy ((char *) &wf_mpu_synth_operations[index],
(char *) &wf_mpu_synth_proto,
sizeof (struct synth_operations));
- }
-
- memcpy ((char *) &wf_mpu_midi_operations[wfmpu_cnt],
- (char *) &wf_mpu_midi_proto,
- sizeof (struct midi_operations));
-
- if (dev_conf[dev].isexternal) {
- wf_mpu_midi_operations[wfmpu_cnt].converter = NULL;
} else {
- wf_mpu_midi_operations[wfmpu_cnt].converter =
- &wf_mpu_synth_operations[wfmpu_cnt];
+ name = "WaveFront external MIDI";
+ is_external = 1;
+ index = 1;
+ /* no synth operations for an external MIDI interface */
}
- memcpy ((char *) &wf_mpu_synth_info[dev],
+ memcpy ((char *) &wf_mpu_synth_info[dev->devno],
(char *) &wf_mpu_synth_info_proto,
sizeof (struct synth_info));
- strcpy (wf_mpu_synth_info[dev].name, hw_config->name);
- strcpy (wf_mpu_midi_operations[wfmpu_cnt].info.name, hw_config->name);
+ strcpy (wf_mpu_synth_info[index].name, name);
- conf_printf (hw_config->name, hw_config);
+ wf_mpu_synth_operations[index].midi_dev = dev->devno;
+ wf_mpu_synth_operations[index].info = &wf_mpu_synth_info[index];
- if (!dev_conf[dev].isexternal) {
- wf_mpu_synth_operations[wfmpu_cnt].midi_dev = dev;
+ memcpy ((char *) &wf_mpu_midi_operations[index],
+ (char *) &wf_mpu_midi_proto,
+ sizeof (struct midi_operations));
+
+ if (is_external) {
+ wf_mpu_midi_operations[index].converter = NULL;
+ } else {
+ wf_mpu_midi_operations[index].converter =
+ &wf_mpu_synth_operations[index];
}
- wf_mpu_synth_operations[wfmpu_cnt].info = &wf_mpu_synth_info[dev];
-
- midi_devs[dev] = &wf_mpu_midi_operations[wfmpu_cnt];
- dev_conf[dev].opened = 0;
- dev_conf[dev].mode = 0;
- dev_conf[dev].configured_for_virtual = 0;
- dev_conf[dev].devno = dev;
+ strcpy (wf_mpu_midi_operations[index].info.name, name);
- midi_devs[dev]->in_info.m_busy = 0;
- midi_devs[dev]->in_info.m_state = MST_INIT;
- midi_devs[dev]->in_info.m_ptr = 0;
- midi_devs[dev]->in_info.m_left = 0;
- midi_devs[dev]->in_info.m_prev_status = 0;
+ midi_devs[dev->devno] = &wf_mpu_midi_operations[index];
+ midi_devs[dev->devno]->in_info.m_busy = 0;
+ midi_devs[dev->devno]->in_info.m_state = MST_INIT;
+ midi_devs[dev->devno]->in_info.m_ptr = 0;
+ midi_devs[dev->devno]->in_info.m_left = 0;
+ midi_devs[dev->devno]->in_info.m_prev_status = 0;
- wfmpu_cnt++;
+ devs[index].opened = 0;
+ devs[index].mode = 0;
return (0);
}
-int
-virtual_midi_enable (int dev, struct address_info *hw_config)
+int virtual_midi_enable (void)
{
- int idev;
- int edev;
- struct wf_mpu_config *devc;
-
- devc = &dev_conf[dev];
-
- if (devc->configured_for_virtual) {
-
- idev = devc->internal;
- edev = devc->external;
-
- } else {
-
- if (hw_config == NULL) {
- printk (KERN_ERR
- "WF-MPU: virtual midi first "
- "enabled without hw_config!\n");
- return -EINVAL;
- }
+ if ((virt_dev->devno < 0) &&
+ (virt_dev->devno = sound_alloc_mididev()) == -1) {
+ printk (KERN_ERR
+ "WF-MPU: too many midi devices detected\n");
+ return -1;
+ }
- idev = devc->internal;
+ config_wf_mpu (virt_dev);
- if ((edev = sound_alloc_mididev()) == -1) {
- printk (KERN_ERR
- "WF-MPU: too many midi devices detected\n");
- return -1;
- }
+ phys_dev->isvirtual = 1;
+ return virt_dev->devno;
+}
- hw_config->slots[WF_EXTERNAL_MIDI_SLOT] = edev;
- }
+int
+virtual_midi_disable (void)
- dev_conf[edev].isvirtual = 1;
- dev_conf[idev].isvirtual = 1;
-
- if (dev_conf[idev].configured_for_virtual) {
- return 0;
- }
+{
+ unsigned long flags;
- /* Configure external interface struct */
+ save_flags (flags);
+ cli();
- devc = &dev_conf[edev];
- devc->internal = idev;
- devc->external = edev;
- devc->isexternal = 1;
+ wf_mpu_close (virt_dev->devno);
+ /* no synth on virt_dev, so no need to call wf_mpu_synth_close() */
+ phys_dev->isvirtual = 0;
- /* Configure external interface struct
- (devc->isexternal and devc->internal set in attach_wf_mpu())
- */
+ restore_flags (flags);
- devc = &dev_conf[idev];
- devc->external = edev;
+ return 0;
+}
- /* Configure the tables for the external */
+__initfunc (static int detect_wf_mpu (int irq, int io_base))
- if (config_wf_mpu (edev, hw_config)) {
- printk (KERN_WARNING "WF-MPU: configuration for MIDI "
- "device %d failed\n", edev);
- return (-1);
+{
+ if (check_region (io_base, 2)) {
+ printk (KERN_WARNING "WF-MPU: I/O port %x already in use.\n",
+ io_base);
+ return -1;
}
- /* Don't bother to do this again if we are toggled back and
- forth between virtual MIDI mode and "normal" operation.
- */
-
- dev_conf[edev].configured_for_virtual = 1;
- dev_conf[idev].configured_for_virtual = 1;
+ phys_dev->base = io_base;
+ phys_dev->irq = irq;
+ phys_dev->devno = -1;
+ virt_dev->devno = -1;
return 0;
}
-void
-virtual_midi_disable (int dev)
+__initfunc (int install_wf_mpu (void))
{
- struct wf_mpu_config *devc;
- unsigned long flags;
+ if ((phys_dev->devno = sound_alloc_mididev()) < 0){
- save_flags (flags);
- cli();
-
- /* Assumes for logical purposes that the caller has taken
- care of fiddling with WaveFront hardware commands to
- turn off Virtual MIDI mode.
- */
-
- devc = &dev_conf[dev];
+ printk (KERN_ERR "WF-MPU: Too many MIDI devices detected.\n");
+ return -1;
- devc = &dev_conf[devc->internal];
- devc->isvirtual = 0;
+ }
- devc = &dev_conf[devc->external];
- devc->isvirtual = 0;
+ request_region (phys_dev->base, 2, "wavefront midi");
+ phys_dev->isvirtual = 0;
- restore_flags (flags);
-}
+ if (config_wf_mpu (phys_dev)) {
-void
-attach_wf_mpu (struct address_info *hw_config)
-{
- int m;
- struct wf_mpu_config *devc;
-
- if (request_irq (hw_config->irq, wf_mpuintr,
- 0, "WaveFront MIDI", NULL) < 0) {
- printk (KERN_ERR "WF-MPU: Failed to allocate IRQ%d\n",
- hw_config->irq);
- return;
- }
+ printk (KERN_WARNING
+ "WF-MPU: configuration for MIDI device %d failed\n",
+ phys_dev->devno);
+ sound_unload_mididev (phys_dev->devno);
- if ((m = sound_alloc_mididev()) == -1){
- printk (KERN_ERR "WF-MPU: Too many MIDI devices detected.\n");
- free_irq (hw_config->irq, NULL);
- release_region (hw_config->io_base, 2);
- return;
}
- request_region (hw_config->io_base, 2, "WaveFront MPU");
+ /* OK, now we're configured to handle an interrupt ... */
- hw_config->slots[WF_INTERNAL_MIDI_SLOT] = m;
- devc = &dev_conf[m];
- devc->base = hw_config->io_base;
- devc->irq = hw_config->irq;
- devc->isexternal = 0;
- devc->internal = m;
- devc->external = -1;
- devc->isvirtual = 0;
+ if (request_irq (phys_dev->irq, wf_mpuintr, SA_INTERRUPT|SA_SHIRQ,
+ "wavefront midi", phys_dev) < 0) {
- irq2dev[devc->irq] = m;
+ printk (KERN_ERR "WF-MPU: Failed to allocate IRQ%d\n",
+ phys_dev->irq);
+ return -1;
- if (config_wf_mpu (m, hw_config)) {
- printk (KERN_WARNING
- "WF-MPU: configuration for MIDI device %d failed\n", m);
- sound_unload_mididev (m);
}
/* This being a WaveFront (ICS-2115) emulated MPU-401, we have
@@ -912,64 +857,43 @@
won't do anything at all.
*/
- start_uart_mode (devc);
+ start_uart_mode ();
+ return phys_dev->devno;
}
-
-int
-probe_wf_mpu (struct address_info *hw_config)
-
-{
- if (hw_config->irq < 0 || hw_config->irq > 16) {
- printk (KERN_WARNING "WF-MPU: bogus IRQ value requested (%d)\n",
- hw_config->irq);
- return 0;
- }
-
- if (check_region (hw_config->io_base, 2)) {
- printk (KERN_WARNING "WF-MPU: I/O port %x already in use\n\n",
- hw_config->io_base);
- return 0;
- }
-
- if (inb (hw_config->io_base + 1) == 0xff) { /* Just bus float? */
- printk ("WF-MPU: Port %x looks dead.\n", hw_config->io_base);
- return 0;
- }
-
- return 1;
-}
-
+
void
-unload_wf_mpu (struct address_info *hw_config)
+uninstall_wf_mpu (void)
+
{
+ release_region (phys_dev->base, 2);
+ free_irq (phys_dev->irq, phys_dev);
+ sound_unload_mididev (phys_dev->devno);
- release_region (hw_config->io_base, 2);
- sound_unload_mididev (hw_config->slots[WF_INTERNAL_MIDI_SLOT]);
- if (hw_config->irq > 0) {
- free_irq (hw_config->irq, NULL);
- }
- if (hw_config->slots[WF_EXTERNAL_MIDI_SLOT] > 0) {
- sound_unload_mididev (hw_config->slots[WF_EXTERNAL_MIDI_SLOT]);
+ if (virt_dev->devno >= 0) {
+ sound_unload_mididev (virt_dev->devno);
}
}
static void
-start_uart_mode (struct wf_mpu_config *devc)
+start_uart_mode (void)
+
{
- int ok, timeout;
+ int ok, i;
unsigned long flags;
save_flags (flags);
cli ();
- for (timeout = 30000; timeout > 0 && !output_ready (devc); timeout--);
+ /* XXX fix me */
- wf_mpu_cmd (devc, UART_MODE_ON);
+ for (i = 0; i < 30000 && !output_ready (); i++);
- for (ok = 0, timeout = 50000; timeout > 0 && !ok; timeout--) {
- if (input_avail (devc)) {
- if (read_data (devc) == MPU_ACK) {
+ outb (UART_MODE_ON, COMDPORT(phys_dev));
+
+ for (ok = 0, i = 50000; i > 0 && !ok; i--) {
+ if (input_avail ()) {
+ if (read_data () == MPU_ACK) {
ok = 1;
}
}
@@ -978,6 +902,30 @@
restore_flags (flags);
}
-#endif
+#ifdef OSS_SUPPORT
+
+int
+probe_wf_mpu (struct address_info *hw_config)
+
+{
+ return !detect_wf_mpu (hw_config->irq, hw_config->io_base);
+}
+
+void
+attach_wf_mpu (struct address_info *hw_config)
+
+{
+ (void) install_wf_mpu ();
+}
+
+void
+unload_wf_mpu (void)
+{
+ uninstall_wf_mpu ();
+}
+
+#endif OSS_SUPPORT
+
+#endif CONFIG_SOUND_WAVEFRONT_MODULE_AND_MODULE
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov