patch-2.1.67 linux/drivers/sound/uart401.c
Next file: linux/drivers/sound/uart6850.c
Previous file: linux/drivers/sound/trix.c
Back to the patch index
Back to the overall index
- Lines: 802
- Date:
Sat Nov 29 10:33:21 1997
- Orig file:
v2.1.66/linux/drivers/sound/uart401.c
- Orig date:
Wed Nov 12 13:34:27 1997
diff -u --recursive --new-file v2.1.66/linux/drivers/sound/uart401.c linux/drivers/sound/uart401.c
@@ -11,23 +11,23 @@
* for more info.
*/
#include <linux/config.h>
-
+#include <linux/module.h>
#include "sound_config.h"
+#include "soundmodule.h"
-#ifdef CONFIG_UART401
-#ifdef CONFIG_MIDI
+#if (defined(CONFIG_UART401)||defined(CONFIG_MIDI)) || defined(MODULE)
typedef struct uart401_devc
{
- int base;
- int irq;
- int *osp;
- void (*midi_input_intr) (int dev, unsigned char data);
- int opened, disabled;
- volatile unsigned char input_byte;
- int my_dev;
- int share_irq;
+ int base;
+ int irq;
+ int *osp;
+ void (*midi_input_intr) (int dev, unsigned char data);
+ int opened, disabled;
+ volatile unsigned char input_byte;
+ int my_dev;
+ int share_irq;
}
uart401_devc;
@@ -39,27 +39,27 @@
#define COMDPORT (devc->base+1)
#define STATPORT (devc->base+1)
-static int
-uart401_status (uart401_devc * devc)
+static int
+uart401_status(uart401_devc * devc)
{
- return inb (STATPORT);
+ return inb(STATPORT);
}
#define input_avail(devc) (!(uart401_status(devc)&INPUT_AVAIL))
#define output_ready(devc) (!(uart401_status(devc)&OUTPUT_READY))
-static void
-uart401_cmd (uart401_devc * devc, unsigned char cmd)
+static void
+uart401_cmd(uart401_devc * devc, unsigned char cmd)
{
- outb ((cmd), COMDPORT);
+ outb((cmd), COMDPORT);
}
-static int
-uart401_read (uart401_devc * devc)
+static int
+uart401_read(uart401_devc * devc)
{
- return inb (DATAPORT);
+ return inb(DATAPORT);
}
-static void
-uart401_write (uart401_devc * devc, unsigned char byte)
+static void
+uart401_write(uart401_devc * devc, unsigned char byte)
{
- outb ((byte), DATAPORT);
+ outb((byte), DATAPORT);
}
#define OUTPUT_READY 0x40
@@ -68,141 +68,139 @@
#define MPU_RESET 0xFF
#define UART_MODE_ON 0x3F
-static int reset_uart401 (uart401_devc * devc);
-static void enter_uart_mode (uart401_devc * devc);
+static int reset_uart401(uart401_devc * devc);
+static void enter_uart_mode(uart401_devc * devc);
static void
-uart401_input_loop (uart401_devc * devc)
+uart401_input_loop(uart401_devc * devc)
{
- while (input_avail (devc))
- {
- unsigned char c = uart401_read (devc);
-
- if (c == MPU_ACK)
- devc->input_byte = c;
- else if (devc->opened & OPEN_READ && devc->midi_input_intr)
- devc->midi_input_intr (devc->my_dev, c);
- }
+ while (input_avail(devc))
+ {
+ unsigned char c = uart401_read(devc);
+
+ if (c == MPU_ACK)
+ devc->input_byte = c;
+ else if (devc->opened & OPEN_READ && devc->midi_input_intr)
+ devc->midi_input_intr(devc->my_dev, c);
+ }
}
void
-uart401intr (int irq, void *dev_id, struct pt_regs *dummy)
+uart401intr(int irq, void *dev_id, struct pt_regs *dummy)
{
- uart401_devc *devc;
+ uart401_devc *devc;
- if (irq < 1 || irq > 15)
- return;
+ if (irq < 1 || irq > 15)
+ return;
- devc = irq2devc[irq];
+ devc = irq2devc[irq];
- if (devc == NULL)
- return;
+ if (devc == NULL)
+ return;
- if (input_avail (devc))
- uart401_input_loop (devc);
+ if (input_avail(devc))
+ uart401_input_loop(devc);
}
static int
-uart401_open (int dev, int mode,
- void (*input) (int dev, unsigned char data),
- void (*output) (int dev)
+uart401_open(int dev, int mode,
+ void (*input) (int dev, unsigned char data),
+ void (*output) (int dev)
)
{
- uart401_devc *devc = (uart401_devc *) midi_devs[dev]->devc;
+ uart401_devc *devc = (uart401_devc *) midi_devs[dev]->devc;
- if (devc->opened)
- {
- return -EBUSY;
- }
-
- while (input_avail (devc))
- uart401_read (devc);
-
- devc->midi_input_intr = input;
- devc->opened = mode;
- enter_uart_mode (devc);
- devc->disabled = 0;
+ if (devc->opened)
+ {
+ return -EBUSY;
+ }
+ while (input_avail(devc))
+ uart401_read(devc);
+
+ devc->midi_input_intr = input;
+ devc->opened = mode;
+ enter_uart_mode(devc);
+ devc->disabled = 0;
- return 0;
+ return 0;
}
static void
-uart401_close (int dev)
+uart401_close(int dev)
{
- uart401_devc *devc = (uart401_devc *) midi_devs[dev]->devc;
+ uart401_devc *devc = (uart401_devc *) midi_devs[dev]->devc;
- reset_uart401 (devc);
- devc->opened = 0;
+ reset_uart401(devc);
+ devc->opened = 0;
}
static int
-uart401_out (int dev, unsigned char midi_byte)
+uart401_out(int dev, unsigned char midi_byte)
{
- int timeout;
- unsigned long flags;
- uart401_devc *devc = (uart401_devc *) midi_devs[dev]->devc;
-
- if (devc->disabled)
- return 1;
- /*
- * Test for input since pending input seems to block the output.
- */
-
- save_flags (flags);
- cli ();
-
- if (input_avail (devc))
- uart401_input_loop (devc);
-
- restore_flags (flags);
-
- /*
- * Sometimes it takes about 13000 loops before the output becomes ready
- * (After reset). Normally it takes just about 10 loops.
- */
-
- for (timeout = 30000; timeout > 0 && !output_ready (devc); timeout--);
-
- if (!output_ready (devc))
- {
- printk ("MPU-401: Timeout - Device not responding\n");
- devc->disabled = 1;
- reset_uart401 (devc);
- enter_uart_mode (devc);
- return 1;
- }
-
- uart401_write (devc, midi_byte);
- return 1;
+ int timeout;
+ unsigned long flags;
+ uart401_devc *devc = (uart401_devc *) midi_devs[dev]->devc;
+
+ if (devc->disabled)
+ return 1;
+ /*
+ * Test for input since pending input seems to block the output.
+ */
+
+ save_flags(flags);
+ cli();
+
+ if (input_avail(devc))
+ uart401_input_loop(devc);
+
+ restore_flags(flags);
+
+ /*
+ * Sometimes it takes about 13000 loops before the output becomes ready
+ * (After reset). Normally it takes just about 10 loops.
+ */
+
+ for (timeout = 30000; timeout > 0 && !output_ready(devc); timeout--);
+
+ if (!output_ready(devc))
+ {
+ printk("MPU-401: Timeout - Device not responding\n");
+ devc->disabled = 1;
+ reset_uart401(devc);
+ enter_uart_mode(devc);
+ return 1;
+ }
+ uart401_write(devc, midi_byte);
+ return 1;
}
static int
-uart401_start_read (int dev)
+uart401_start_read(int dev)
{
- return 0;
+ return 0;
}
static int
-uart401_end_read (int dev)
+uart401_end_read(int dev)
{
- return 0;
+ return 0;
}
static int
-uart401_ioctl (int dev, unsigned cmd, caddr_t arg)
+uart401_ioctl(int dev, unsigned cmd, caddr_t arg)
{
- return -EINVAL;
+ return -EINVAL;
}
static void
-uart401_kick (int dev)
+uart401_kick(int dev)
{
}
static int
-uart401_buffer_status (int dev)
+uart401_buffer_status(int dev)
{
- return 0;
+ return 0;
}
#define MIDI_SYNTH_NAME "MPU-401 UART"
@@ -211,256 +209,300 @@
static struct midi_operations uart401_operations =
{
- {"MPU-401 (UART) MIDI", 0, 0, SNDCARD_MPU401},
- &std_midi_synth,
- {0},
- uart401_open,
- uart401_close,
- uart401_ioctl,
- uart401_out,
- uart401_start_read,
- uart401_end_read,
- uart401_kick,
- NULL,
- uart401_buffer_status,
- NULL
+ {"MPU-401 (UART) MIDI", 0, 0, SNDCARD_MPU401},
+ &std_midi_synth,
+ {0},
+ uart401_open,
+ uart401_close,
+ uart401_ioctl,
+ uart401_out,
+ uart401_start_read,
+ uart401_end_read,
+ uart401_kick,
+ NULL,
+ uart401_buffer_status,
+ NULL
};
static void
-enter_uart_mode (uart401_devc * devc)
+enter_uart_mode(uart401_devc * devc)
{
- int ok, timeout;
- unsigned long flags;
+ int ok, timeout;
+ unsigned long flags;
- save_flags (flags);
- cli ();
- for (timeout = 30000; timeout > 0 && !output_ready (devc); timeout--);
-
- devc->input_byte = 0;
- uart401_cmd (devc, UART_MODE_ON);
-
- ok = 0;
- for (timeout = 50000; timeout > 0 && !ok; timeout--)
- if (devc->input_byte == MPU_ACK)
- ok = 1;
- else if (input_avail (devc))
- if (uart401_read (devc) == MPU_ACK)
- ok = 1;
+ save_flags(flags);
+ cli();
+ for (timeout = 30000; timeout > 0 && !output_ready(devc); timeout--);
+
+ devc->input_byte = 0;
+ uart401_cmd(devc, UART_MODE_ON);
+
+ ok = 0;
+ for (timeout = 50000; timeout > 0 && !ok; timeout--)
+ if (devc->input_byte == MPU_ACK)
+ ok = 1;
+ else if (input_avail(devc))
+ if (uart401_read(devc) == MPU_ACK)
+ ok = 1;
- restore_flags (flags);
+ restore_flags(flags);
}
void
-attach_uart401 (struct address_info *hw_config)
+attach_uart401(struct address_info *hw_config)
{
- uart401_devc *devc;
- char *name = "MPU-401 (UART) MIDI";
-
- if (hw_config->name)
- name = hw_config->name;
-
- if (detected_devc == NULL)
- return;
-
-
- devc = (uart401_devc *) (sound_mem_blocks[sound_nblocks] = vmalloc (sizeof (uart401_devc)));
- sound_mem_sizes[sound_nblocks] = sizeof (uart401_devc);
- if (sound_nblocks < 1024)
- sound_nblocks++;;
- if (devc == NULL)
- {
- printk ("uart401: Can't allocate memory\n");
- return;
- }
+ uart401_devc *devc;
+ char *name = "MPU-401 (UART) MIDI";
- memcpy ((char *) devc, (char *) detected_devc, sizeof (uart401_devc));
- detected_devc = NULL;
+ if (hw_config->name)
+ name = hw_config->name;
- devc->irq = hw_config->irq;
- if (devc->irq < 0)
- {
- devc->share_irq = 1;
- devc->irq *= -1;
- }
- else
- devc->share_irq = 0;
-
- if (devc->irq < 1 || devc->irq > 15)
- return;
-
- if (!devc->share_irq)
- if (snd_set_irq_handler (devc->irq, uart401intr, "MPU-401 UART", devc->osp) < 0)
- {
- printk ("uart401: Failed to allocate IRQ%d\n", devc->irq);
- devc->share_irq = 1;
- }
-
- irq2devc[devc->irq] = devc;
- devc->my_dev = num_midis;
-
- request_region (hw_config->io_base, 4, "MPU-401 UART");
- enter_uart_mode (devc);
-
- if (num_midis >= MAX_MIDI_DEV)
- {
- printk ("Sound: Too many midi devices detected\n");
- return;
- }
-
- conf_printf (name, hw_config);
+ if (detected_devc == NULL)
+ return;
+
+
+ devc = (uart401_devc *) (sound_mem_blocks[sound_nblocks] = vmalloc(sizeof(uart401_devc)));
+ sound_mem_sizes[sound_nblocks] = sizeof(uart401_devc);
+ if (sound_nblocks < 1024)
+ sound_nblocks++;;
+ if (devc == NULL)
+ {
+ printk(KERN_WARNING "uart401: Can't allocate memory\n");
+ return;
+ }
+ memcpy((char *) devc, (char *) detected_devc, sizeof(uart401_devc));
+ detected_devc = NULL;
+
+ devc->irq = hw_config->irq;
+ if (devc->irq < 0)
+ {
+ devc->share_irq = 1;
+ devc->irq *= -1;
+ } else
+ devc->share_irq = 0;
+
+ if (devc->irq < 1 || devc->irq > 15)
+ return;
+
+ if (!devc->share_irq)
+ if (snd_set_irq_handler(devc->irq, uart401intr, "MPU-401 UART", devc->osp) < 0)
+ {
+ printk(KERN_WARNING "uart401: Failed to allocate IRQ%d\n", devc->irq);
+ devc->share_irq = 1;
+ }
+ irq2devc[devc->irq] = devc;
+ devc->my_dev = sound_alloc_mididev();
+
+ request_region(hw_config->io_base, 4, "MPU-401 UART");
+ enter_uart_mode(devc);
+
+ if (devc->my_dev == -1)
+ {
+ printk(KERN_INFO "uart401: Too many midi devices detected\n");
+ return;
+ }
+ conf_printf(name, hw_config);
+
+ std_midi_synth.midi_dev = devc->my_dev;
+
+
+ midi_devs[devc->my_dev] = (struct midi_operations *) (sound_mem_blocks[sound_nblocks] = vmalloc(sizeof(struct midi_operations)));
+ sound_mem_sizes[sound_nblocks] = sizeof(struct midi_operations);
+
+ if (sound_nblocks < 1024)
+ sound_nblocks++;;
+ if (midi_devs[devc->my_dev] == NULL)
+ {
+ printk("uart401: Failed to allocate memory\n");
+ sound_unload_mididev(devc->my_dev);
+ return;
+ }
+ memcpy((char *) midi_devs[devc->my_dev], (char *) &uart401_operations,
+ sizeof(struct midi_operations));
+
+ midi_devs[devc->my_dev]->devc = devc;
+
+
+ midi_devs[devc->my_dev]->converter = (struct synth_operations *) (sound_mem_blocks[sound_nblocks] = vmalloc(sizeof(struct synth_operations)));
+ sound_mem_sizes[sound_nblocks] = sizeof(struct synth_operations);
+
+ if (sound_nblocks < 1024)
+ sound_nblocks++;
+
+ if (midi_devs[devc->my_dev]->converter == NULL)
+ {
+ printk(KERN_WARNING "uart401: Failed to allocate memory\n");
+ sound_unload_mididev(devc->my_dev);
+ return;
+ }
+ memcpy((char *) midi_devs[devc->my_dev]->converter, (char *) &std_midi_synth,
+ sizeof(struct synth_operations));
+
+ strcpy(midi_devs[devc->my_dev]->info.name, name);
+ midi_devs[devc->my_dev]->converter->id = "UART401";
+ hw_config->slots[4] = devc->my_dev;
+ sequencer_init();
+ devc->opened = 0;
+}
- std_midi_synth.midi_dev = devc->my_dev = num_midis;
+static int
+reset_uart401(uart401_devc * devc)
+{
+ int ok, timeout, n;
+ /*
+ * Send the RESET command. Try again if no success at the first time.
+ */
- midi_devs[num_midis] = (struct midi_operations *) (sound_mem_blocks[sound_nblocks] = vmalloc (sizeof (struct midi_operations)));
- sound_mem_sizes[sound_nblocks] = sizeof (struct midi_operations);
+ ok = 0;
- if (sound_nblocks < 1024)
- sound_nblocks++;;
- if (midi_devs[num_midis] == NULL)
- {
- printk ("uart401: Failed to allocate memory\n");
- return;
- }
+ for (n = 0; n < 2 && !ok; n++)
+ {
+ for (timeout = 30000; timeout > 0 && !output_ready(devc); timeout--);
- memcpy ((char *) midi_devs[num_midis], (char *) &uart401_operations,
- sizeof (struct midi_operations));
+ devc->input_byte = 0;
+ uart401_cmd(devc, MPU_RESET);
- midi_devs[num_midis]->devc = devc;
+ /*
+ * Wait at least 25 msec. This method is not accurate so let's make the
+ * loop bit longer. Cannot sleep since this is called during boot.
+ */
+ for (timeout = 50000; timeout > 0 && !ok; timeout--)
+ if (devc->input_byte == MPU_ACK) /* Interrupt */
+ ok = 1;
+ else if (input_avail(devc))
+ if (uart401_read(devc) == MPU_ACK)
+ ok = 1;
- midi_devs[num_midis]->converter = (struct synth_operations *) (sound_mem_blocks[sound_nblocks] = vmalloc (sizeof (struct synth_operations)));
- sound_mem_sizes[sound_nblocks] = sizeof (struct synth_operations);
+ }
- if (sound_nblocks < 1024)
- sound_nblocks++;;
- if (midi_devs[num_midis]->converter == NULL)
- {
- printk ("uart401: Failed to allocate memory\n");
- return;
- }
+ if (ok)
+ {
+ DEB(printk("Reset UART401 OK\n"));
+ } else
+ DDB(printk("Reset UART401 failed - No hardware detected.\n"));
- memcpy ((char *) midi_devs[num_midis]->converter, (char *) &std_midi_synth,
- sizeof (struct synth_operations));
+ if (ok)
+ uart401_input_loop(devc); /*
+ * Flush input before enabling interrupts
+ */
- strcpy (midi_devs[num_midis]->info.name, name);
- midi_devs[num_midis]->converter->id = "UART401";
- num_midis++;
- sequencer_init ();
- devc->opened = 0;
+ return ok;
}
-static int
-reset_uart401 (uart401_devc * devc)
+int
+probe_uart401(struct address_info *hw_config)
{
- int ok, timeout, n;
-
- /*
- * Send the RESET command. Try again if no success at the first time.
- */
-
- ok = 0;
-
- for (n = 0; n < 2 && !ok; n++)
- {
- for (timeout = 30000; timeout > 0 && !output_ready (devc); timeout--);
+ int ok = 0;
+ unsigned long flags;
- devc->input_byte = 0;
- uart401_cmd (devc, MPU_RESET);
+ static uart401_devc hw_info;
+ uart401_devc *devc = &hw_info;
- /*
- * Wait at least 25 msec. This method is not accurate so let's make the
- * loop bit longer. Cannot sleep since this is called during boot.
- */
+ DDB(printk("Entered probe_uart401()\n"));
- for (timeout = 50000; timeout > 0 && !ok; timeout--)
- if (devc->input_byte == MPU_ACK) /* Interrupt */
- ok = 1;
- else if (input_avail (devc))
- if (uart401_read (devc) == MPU_ACK)
- ok = 1;
+ detected_devc = NULL;
- }
+ if (check_region(hw_config->io_base, 4))
+ return 0;
+ devc->base = hw_config->io_base;
+ devc->irq = hw_config->irq;
+ devc->osp = hw_config->osp;
+ devc->midi_input_intr = NULL;
+ devc->opened = 0;
+ devc->input_byte = 0;
+ devc->my_dev = 0;
+ devc->share_irq = 0;
- if (ok)
- {
- DEB (printk ("Reset UART401 OK\n"));
- }
- else
- DDB (printk ("Reset UART401 failed - No hardware detected.\n"));
+ save_flags(flags);
+ cli();
+ ok = reset_uart401(devc);
+ restore_flags(flags);
- if (ok)
- uart401_input_loop (devc); /*
- * Flush input before enabling interrupts
- */
+ if (ok)
+ detected_devc = devc;
- return ok;
+ return ok;
}
-int
-probe_uart401 (struct address_info *hw_config)
+void
+unload_uart401(struct address_info *hw_config)
{
- int ok = 0;
- unsigned long flags;
-
- static uart401_devc hw_info;
- uart401_devc *devc = &hw_info;
-
- DDB (printk ("Entered probe_uart401()\n"));
+ uart401_devc *devc;
- detected_devc = NULL;
+ int irq = hw_config->irq;
- if (check_region (hw_config->io_base, 4))
- return 0;
+ if (irq < 0)
+ {
+ irq *= -1;
+ }
+ if (irq < 1 || irq > 15)
+ return;
- devc->base = hw_config->io_base;
- devc->irq = hw_config->irq;
- devc->osp = hw_config->osp;
- devc->midi_input_intr = NULL;
- devc->opened = 0;
- devc->input_byte = 0;
- devc->my_dev = 0;
- devc->share_irq = 0;
+ devc = irq2devc[irq];
+ if (devc == NULL)
+ return;
- save_flags (flags);
- cli ();
- ok = reset_uart401 (devc);
- restore_flags (flags);
+ reset_uart401(devc);
+ release_region(hw_config->io_base, 4);
- if (ok)
- detected_devc = devc;
+ if (!devc->share_irq)
+ snd_release_irq(devc->irq);
- return ok;
+ /* Free device too !! - AC FIXME: CHECK THIS IS RIGHT */
+ if (devc)
+ vfree(devc);
+ sound_unload_mididev(hw_config->slots[4]);
}
-void
-unload_uart401 (struct address_info *hw_config)
-{
- uart401_devc *devc;
-
- int irq = hw_config->irq;
+#ifdef MODULE
- if (irq < 0)
- {
- irq *= -1;
- }
+int io = -1;
+int irq = -1;
- if (irq < 1 || irq > 15)
- return;
+MODULE_PARM(io, "i");
+MODULE_PARM(irq, "i");
+struct address_info hw;
- devc = irq2devc[irq];
- if (devc == NULL)
- return;
-
- reset_uart401 (devc);
- release_region (hw_config->io_base, 4);
+int
+init_module(void)
+{
+ /* Can be loaded either for module use or to provide functions
+ to others */
+ if (io != -1 && irq != -1)
+ {
+ printk("MPU-401 UART driver Copyright (C) Hannu Savolainen 1993-1997");
+ hw.irq = irq;
+ hw.io_base = io;
+ if (probe_uart401(&hw) == 0)
+ return -ENODEV;
+ attach_uart401(&hw);
+ }
+ SOUND_LOCK;
+ return 0;
+}
- if (!devc->share_irq)
- snd_release_irq (devc->irq);
+void
+cleanup_module(void)
+{
+ if (io != -1 && irq != -1)
+ {
+ unload_uart401(&hw);
+ }
+ /* FREE SYMTAB */
+ SOUND_LOCK_END;
}
+#else
#endif
+
#endif
+
+EXPORT_SYMBOL(attach_uart401);
+EXPORT_SYMBOL(probe_uart401);
+EXPORT_SYMBOL(unload_uart401);
+EXPORT_SYMBOL(uart401intr);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov