/*
 * sound/oss/mpu401.c
 *
 * The low level driver for Roland MPU-401 compatible Midi cards.
 */
/*
 * Copyright (C) by Hannu Savolainen 1993-1997
 *
 * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
 * Version 2 (June 1991). See the "COPYING" file distributed with this software
 * for more info.
 *
 *
 * Thomas Sailer	ioctl code reworked (vmalloc/vfree removed)
 * Alan Cox		modularisation, use normal request_irq, use dev_id
 * Bartlomiej Zolnierkiewicz	removed some __init to allow using many drivers
 * Chris Rankin		Update the module-usage counter for the coprocessor
 * Zwane Mwaikambo	Changed attach/unload resource freeing
 */

#include <linux/module.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#define USE_SEQ_MACROS
#define USE_SIMPLE_MACROS

#include "sound_config.h"

#include "coproc.h"
#include "mpu401.h"

static int      timer_mode = TMR_INTERNAL, timer_caps = TMR_INTERNAL;

struct mpu_config
{
	int             base;	/*
				 * I/O base
				 */
	int             irq;
	int             opened;	/*
				 * Open mode
				 */
	int             devno;
	int             synthno;
	int             uart_mode;
	int             initialized;
	int             mode;
#define MODE_MIDI	1
#define MODE_SYNTH	2
	unsigned char   version, revision;
	unsigned int    capabilities;
#define MPU_CAP_INTLG	0x10000000
#define MPU_CAP_SYNC	0x00000010
#define MPU_CAP_FSK	0x00000020
#define MPU_CAP_CLS	0x00000040
#define MPU_CAP_SMPTE 	0x00000080
#define MPU_CAP_2PORT	0x00000001
	int             timer_flag;

#define MBUF_MAX	10
#define BUFTEST(dc) if (dc->m_ptr >= MBUF_MAX || dc->m_ptr < 0) \
	{printk( "MPU: Invalid buffer pointer %d/%d, s=%d\n",  dc->m_ptr,  dc->m_left,  dc->m_state);dc->m_ptr--;}
	  int             m_busy;
	  unsigned char   m_buf[MBUF_MAX];
	  int             m_ptr;
	  int             m_state;
	  int             m_left;
	  unsigned char   last_status;
	  void            (*inputintr) (int dev, unsigned char data);
	  int             shared_irq;
	  int            *osp;
	  spinlock_t	lock;
  };

#define	DATAPORT(base)   (base)
#define	COMDPORT(base)   (base+1)
#define	STATPORT(base)   (base+1)


static void mpu401_close(int dev);

static inline int mpu401_status(struct mpu_config *devc)
{
	return inb(STATPORT(devc->base));
}

#define input_avail(devc)		(!(mpu401_status(devc)&INPUT_AVAIL))
#define output_ready(devc)		(!(mpu401_status(devc)&OUTPUT_READY))

static inline void write_command(struct mpu_config *devc, unsigned char cmd)
{
	outb(cmd, COMDPORT(devc->base));
}

static inline int read_data(struct mpu_config *devc)
{
	return inb(DATAPORT(devc->base));
}

static inline void write_data(struct mpu_config *devc, unsigned char byte)
{
	outb(byte, DATAPORT(devc->base));
}

#define	OUTPUT_READY	0x40
#define	INPUT_AVAIL	0x80
#define	MPU_ACK		0xFE
#define	MPU_RESET	0xFF
#define	UART_MODE_ON	0x3F

static struct mpu_config dev_conf[MAX_MIDI_DEV];

static int n_mpu_devs;

static int reset_mpu401(struct mpu_config *devc);
static void set_uart_mode(int dev, struct mpu_config *devc, int arg);

static int mpu_timer_init(int midi_dev);
static void mpu_timer_interrupt(void);
static void timer_ext_event(struct mpu_config *devc, int event, int parm);

static struct synth_info mpu_synth_info_proto = {
	"MPU-401 MIDI interface", 
	0, 
	SYNTH_TYPE_MIDI, 
	MIDI_TYPE_MPU401, 
	0, 128, 
	0, 128, 
	SYNTH_CAP_INPUT
};

static struct synth_info mpu_synth_info[MAX_MIDI_DEV];

/*
 * States for the input scanner
 */

#define ST_INIT			0	/* Ready for timing byte or msg */
#define ST_TIMED		1	/* Leading timing byte rcvd */
#define ST_DATABYTE		2	/* Waiting for (nr_left) data bytes */

#define ST_SYSMSG		100	/* System message (sysx etc). */
#define ST_SYSEX		101	/* System exclusive msg */
#define ST_MTC			102	/* Midi Time Code (MTC) qframe msg */
#define ST_SONGSEL		103	/* Song select */
#define ST_SONGPOS		104	/* Song position pointer */

static unsigned char len_tab[] =	/* # of data bytes following a status
					 */
{
	2,			/* 8x */
	2,			/* 9x */
	2,			/* Ax */
	2,			/* Bx */
	1,			/* Cx */
	1,			/* Dx */
	2,			/* Ex */
	0			/* Fx */
};

#define STORE(cmd) \
{ \
	int len; \
	unsigned char obuf[8]; \
	cmd; \
	seq_input_event(obuf, len); \
}

#define _seqbuf obuf
#define _seqbufptr 0
#define _SEQ_ADVBUF(x) len=x

static int mpu_input_scanner(struct mpu_config *devc, unsigned char midic)
{

	switch (devc->m_state)
	{
		case ST_INIT:
			switch (midic)
			{
				case 0xf8:
				/* Timer overflow */
					break;

				case 0xfc:
					printk("<all end>");
			 		break;

				case 0xfd:
					if (devc->timer_flag)
						mpu_timer_interrupt();
					break;

				case 0xfe:
					return MPU_ACK;

				case 0xf0:
				case 0xf1:
				case 0xf2:
				case 0xf3:
				case 0xf4:
				case 0xf5:
				case 0xf6:
				case 0xf7:
					printk("<Trk data rq #%d>", midic & 0x0f);
					break;

				case 0xf9:
					printk("<conductor rq>");
					break;

				case 0xff:
					devc->m_state = ST_SYSMSG;
					break;

				default:
					if (midic <= 0xef)
					{
						/* printk( "mpu time: %d ",  midic); */
						devc->m_state = ST_TIMED;
					}
					else
						printk("<MPU: Unknown event %02x> ", midic);
			}
			break;

		case ST_TIMED:
			{
				int msg = ((int) (midic & 0xf0) >> 4);

				devc->m_state = ST_DATABYTE;

				if (msg < 8)	/* Data byte */
				{
					/* printk( "midi msg (running status) "); */
					msg = ((int) (devc->last_status & 0xf0) >> 4);
					msg -= 8;
					devc->m_left = len_tab[msg] - 1;

					devc->m_ptr = 2;
					devc->m_buf[0] = devc->last_status;
					devc->m_buf[1] = midic;

					if (devc->m_left <= 0)
					{
						devc->m_state = ST_INIT;
						do_midi_msg(devc->synthno, devc->m_buf, devc->m_ptr);
						devc->m_ptr = 0;
					}
				}
				else if (msg == 0xf)	/* MPU MARK */
				{
					devc->m_state = ST_INIT;

					switch (midic)
					{
						case 0xf8:
							/* printk( "NOP "); */
							break;

						case 0xf9:
							/* printk( "meas end "); */
							break;

						case 0xfc:
							/* printk( "data end "); */
							break;

						default:
							printk("Unknown MPU mark %02x\n", midic);
					}
				}
				else
				{
					devc->last_status = midic;
					/* printk( "midi msg "); */
					msg -= 8;
					devc->m_left = len_tab[msg];

					devc->m_ptr = 1;
					devc->m_buf[0] = midic;

					if (devc->m_left <= 0)
					{
						devc->m_state = ST_INIT;
						do_midi_msg(devc->synthno, devc->m_buf, devc->m_ptr);
						devc->m_ptr = 0;
					}
				}
			}
			break;

		case ST_SYSMSG:
			switch (midic)
			{
				case 0xf0:
					printk("<SYX>");
					devc->m_state = ST_SYSEX;
					break;

				case 0xf1:
					devc->m_state = ST_MTC;
					break;

				case 0xf2:
					devc->m_state = ST_SONGPOS;
					devc->m_ptr = 0;
					break;

				case 0xf3:
					devc->m_state = ST_SONGSEL;
					break;

				case 0xf6:
					/* printk( "tune_request\n"); */
					devc->m_state = ST_INIT;

					/*
					 *    Real time messages
					 */
				case 0xf8:
					/* midi clock */
					devc->m_state = ST_INIT;
					timer_ext_event(devc, TMR_CLOCK, 0);
					break;

				case 0xfA:
					devc->m_state = ST_INIT;
					timer_ext_event(devc, TMR_START, 0);
					break;

				case 0xFB:
					devc->m_state = ST_INIT;
					timer_ext_event(devc, TMR_CONTINUE, 0);
					break;

				case 0xFC:
					devc->m_state = ST_INIT;
					timer_ext_event(devc, TMR_STOP, 0);
					break;

				case 0xFE:
					/* active sensing */
					devc->m_state = ST_INIT;
					break;

				case 0xff:
					/* printk( "midi hard reset"); */
					devc->m_state = ST_INIT;
					break;

				default:
					printk("unknown MIDI sysmsg %0x\n", midic);
					devc->m_state = ST_INIT;
			}
			break;

		case ST_MTC:
			devc->m_state = ST_INIT;
			printk("MTC frame %x02\n", midic);
			break;

		case ST_SYSEX:
			if (midic == 0xf7)
			{
				printk("<EOX>");
				devc->m_state = ST_INIT;
			}
			else
				printk("%02x ", midic);
			break;

		case ST_SONGPOS:
			BUFTEST(devc);
			devc->m_buf[devc->m_ptr++] = midic;
			if (devc->m_ptr == 2)
			{
				devc->m_state = ST_INIT;
				devc->m_ptr = 0;
				timer_ext_event(devc, TMR_SPP,
					((devc->m_buf[1] & 0x7f) << 7) |
					(devc->m_buf[0] & 0x7f));
			}
			break;

		case ST_DATABYTE:
			BUFTEST(devc);
			devc->m_buf[devc->m_ptr++] = midic;
			if ((--devc->m_left) <= 0)
			{
				devc->m_state = ST_INIT;
				do_midi_msg(devc->synthno, devc->m_buf, devc->m_ptr);
				devc->m_ptr = 0;
			}
			break;

		default:
			printk("Bad state %d ", devc->m_state);
			devc->m_state = ST_INIT;
	}
	return 1;
}

static void mpu401_input_loop(struct mpu_config *devc)
{
	unsigned long flags;
	int busy;
	int n;

	spin_lock_irqsave(&devc->lock,flags);
	busy = devc->m_busy;
	devc->m_busy = 1;
	spin_unlock_irqrestore(&devc->lock,flags);

	if (busy)		/* Already inside the scanner */
		return;

	n = 50;

	while (input_avail(devc) && n-- > 0)
	{
		unsigned char c = read_data(devc);

		if (devc->mode == MODE_SYNTH)
		{
			mpu_input_scanner(devc, c);
		}
		else if (devc->opened & OPEN_READ && devc->inputintr != NULL)
			devc->inputintr(devc->devno, c);
	}
	devc->m_busy = 0;
}

static irqreturn_t mpuintr(int irq, void *dev_id)
{
	struct mpu_config *devc;
	int dev = (int)(unsigned long) dev_id;
	int handled = 0;

	devc = &dev_conf[dev];

	if (input_avail(devc))
	{
		handled = 1;
		if (devc->base != 0 && (devc->opened & OPEN_READ || devc->mode == MODE_SYNTH))
			mpu401_input_loop(devc);
		else
		{
			/* Dummy read (just to acknowledge the interrupt) */
			read_data(devc);
		}
	}
	return IRQ_RETVAL(handled);
}

static int mpu401_open(int dev, int mode,
	    void            (*input) (int dev, unsigned char data),
	    void            (*output) (int dev)
)
{
	int err;
	struct mpu_config *devc;
	struct coproc_operations *coprocessor;

	if (dev < 0 || dev >= num_midis || midi_devs[dev] == NULL)
		return -ENXIO;

	devc = &dev_conf[dev];

	if (devc->opened)
		  return -EBUSY;
	/*
	 *  Verify that the device is really running.
	 *  Some devices (such as Ensoniq SoundScape don't
	 *  work before the on board processor (OBP) is initialized
	 *  by downloading its microcode.
	 */

	if (!devc->initialized)
	{
		if (mpu401_status(devc) == 0xff)	/* Bus float */
		{
			printk(KERN_ERR "mpu401: Device not initialized properly\n");
			return -EIO;
		}
		reset_mpu401(devc);
	}

	if ( (coprocessor = midi_devs[dev]->coproc) != NULL )
	{
		if (!try_module_get(coprocessor->owner)) {
			mpu401_close(dev);
			return -ENODEV;
		}

		if ((err = coprocessor->open(coprocessor->devc, COPR_MIDI)) < 0)
		{
			printk(KERN_WARNING "MPU-401: Can't access coprocessor device\n");
			mpu401_close(dev);
			return err;
		}
	}
	
	set_uart_mode(dev, devc, 1);
	devc->mode = MODE_MIDI;
	devc->synthno = 0;

	mpu401_input_loop(devc);

	devc->inputintr = input;
	devc->opened = mode;

	return 0;
}

static void mpu401_close(int dev)
{
	struct mpu_config *devc;
	struct coproc_operations *coprocessor;

	devc = &dev_conf[dev];
	if (devc->uart_mode)
		reset_mpu401(devc);	/*
					 * This disables the UART mode
					 */
	devc->mode = 0;
	devc->inputintr = NULL;

	coprocessor = midi_devs[dev]->coproc;
	if (coprocessor) {
		coprocessor->close(coprocessor->devc, COPR_MIDI);
		module_put(coprocessor->owner);
	}
	devc->opened = 0;
}

static int mpu401_out(int dev, unsigned char midi_byte)
{
	int timeout;
	unsigned long flags;

	struct mpu_config *devc;

	devc = &dev_conf[dev];

	/*
	 * Sometimes it takes about 30000 loops before the output becomes ready
	 * (After reset). Normally it takes just about 10 loops.
	 */

	for (timeout = 30000; timeout > 0 && !output_ready(devc); timeout--);

	spin_lock_irqsave(&devc->lock,flags);
	if (!output_ready(devc))
	{
		printk(KERN_WARNING "mpu401: Send data timeout\n");
		spin_unlock_irqrestore(&devc->lock,flags);
		return 0;
	}
	write_data(devc, midi_byte);
	spin_unlock_irqrestore(&devc->lock,flags);
	return 1;
}

static int mpu401_command(int dev, mpu_command_rec * cmd)
{
	int i, timeout, ok;
	int ret = 0;
	unsigned long   flags;
	struct mpu_config *devc;

	devc = &dev_conf[dev];

	if (devc->uart_mode)	/*
				 * Not possible in UART mode
				 */
	{
		printk(KERN_WARNING "mpu401: commands not possible in the UART mode\n");
		return -EINVAL;
	}
	/*
	 * Test for input since pending input seems to block the output.
	 */
	if (input_avail(devc))
		mpu401_input_loop(devc);

	/*
	 * Sometimes it takes about 50000 loops before the output becomes ready
	 * (After reset). Normally it takes just about 10 loops.
	 */

	timeout = 50000;
retry:
	if (timeout-- <= 0)
	{
		printk(KERN_WARNING "mpu401: Command (0x%x) timeout\n", (int) cmd->cmd);
		return -EIO;
	}
	spin_lock_irqsave(&devc->lock,flags);

	if (!output_ready(devc))
	{
		spin_unlock_irqrestore(&devc->lock,flags);
		goto retry;
	}
	write_command(devc, cmd->cmd);

	ok = 0;
	for (timeout = 50000; timeout > 0 && !ok; timeout--)
	{
		if (input_avail(devc))
		{
			if (devc->opened && devc->mode == MODE_SYNTH)
			{
				if (mpu_input_scanner(devc, read_data(devc)) == MPU_ACK)
					ok = 1;
			}
			else
			{
				/* Device is not currently open. Use simpler method */
				if (read_data(devc) == MPU_ACK)
					ok = 1;
			}
		}
	}
	if (!ok)
	{
		spin_unlock_irqrestore(&devc->lock,flags);
		return -EIO;
	}
	if (cmd->nr_args)
	{
		for (i = 0; i < cmd->nr_args; i++)
		{
			for (timeout = 3000; timeout > 0 && !output_ready(devc); timeout--);

			if (!mpu401_out(dev, cmd->data[i]))
			{
				spin_unlock_irqrestore(&devc->lock,flags);
				printk(KERN_WARNING "mpu401: Command (0x%x), parm send failed.\n", (int) cmd->cmd);
				return -EIO;
			}
		}
	}
	ret = 0;
	cmd->data[0] = 0;

	if (cmd->nr_returns)
	{
		for (i = 0; i < cmd->nr_returns; i++)
		{
			ok = 0;
			for (timeout = 5000; timeout > 0 && !ok; timeout--)
				if (input_avail(devc))
				{
					cmd->data[i] = read_data(devc);
					ok = 1;
				}
			if (!ok)
			{
				spin_unlock_irqrestore(&devc->lock,flags);
				return -EIO;
			}
		}
	}
	spin_unlock_irqrestore(&devc->lock,flags);
	return ret;
}

static int mpu_cmd(int dev, int cmd, int data)
{
	int ret;

	static mpu_command_rec rec;

	rec.cmd = cmd & 0xff;
	rec.nr_args = ((cmd & 0xf0) == 0xE0);
	rec.nr_returns = ((cmd & 0xf0) == 0xA0);
	rec.data[0] = data & 0xff;

	if ((ret = mpu401_command(dev, &rec)) < 0)
		return ret;
	return (unsigned char) rec.data[0];
}

static int mpu401_prefix_cmd(int dev, unsigned char status)
{
	struct mpu_config *devc = &dev_conf[dev];

	if (devc->uart_mode)
		return 1;

	if (status < 0xf0)
	{
		if (mpu_cmd(dev, 0xD0, 0) < 0)
			return 0;
		return 1;
	}
	switch (status)
	{
		case 0xF0:
			if (mpu_cmd(dev, 0xDF, 0) < 0)
				return 0;
			return 1;

		default:
			return 0;
	}
}

static int mpu401_start_read(int dev)
{
	return 0;
}

static int mpu401_end_read(int dev)
{
	return 0;
}

static int mpu401_ioctl(int dev, unsigned cmd, void __user *arg)
{
	struct mpu_config *devc;
	mpu_command_rec rec;
	int val, ret;

	devc = &dev_conf[dev];
	switch (cmd) 
	{
		case SNDCTL_MIDI_MPUMODE:
			if (!(devc->capabilities & MPU_CAP_INTLG)) { /* No intelligent mode */
				printk(KERN_WARNING "mpu401: Intelligent mode not supported by the HW\n");
				return -EINVAL;
			}
			if (get_user(val, (int __user *)arg))
				return -EFAULT;
			set_uart_mode(dev, devc, !val);
			return 0;

		case SNDCTL_MIDI_MPUCMD:
			if (copy_from_user(&rec, arg, sizeof(rec)))
				return -EFAULT;
			if ((ret = mpu401_command(dev, &rec)) < 0)
				return ret;
			if (copy_to_user(arg, &rec, sizeof(rec)))
				return -EFAULT;
			return 0;

		default:
			return -EINVAL;
	}
}

static void mpu401_kick(int dev)
{
}

static int mpu401_buffer_status(int dev)
{
	return 0;		/*
				 * No data in buffers
				 */
}

static int mpu_synth_ioctl(int dev, unsigned int cmd, void __user *arg)
{
	int midi_dev;
	struct mpu_config *devc;

	midi_dev = synth_devs[dev]->midi_dev;

	if (midi_dev < 0 || midi_dev > num_midis || midi_devs[midi_dev] == NULL)
		return -ENXIO;

	devc = &dev_conf[midi_dev];

	switch (cmd)
	{

		case SNDCTL_SYNTH_INFO:
			if (copy_to_user(arg, &mpu_synth_info[midi_dev],
					sizeof(struct synth_info)))
				return -EFAULT;
			return 0;

		case SNDCTL_SYNTH_MEMAVL:
			return 0x7fffffff;

		default:
			return -EINVAL;
	}
}

static int mpu_synth_open(int dev, int mode)
{
	int midi_dev, err;
	struct mpu_config *devc;
	struct coproc_operations *coprocessor;

	midi_dev = synth_devs[dev]->midi_dev;

	if (midi_dev < 0 || midi_dev > num_midis || midi_devs[midi_dev] == NULL)
		return -ENXIO;

	devc = &dev_conf[midi_dev];

	/*
	 *  Verify that the device is really running.
	 *  Some devices (such as Ensoniq SoundScape don't
	 *  work before the on board processor (OBP) is initialized
	 *  by downloading its microcode.
	 */

	if (!devc->initialized)
	{
		if (mpu401_status(devc) == 0xff)	/* Bus float */
		{
			printk(KERN_ERR "mpu401: Device not initialized properly\n");
			return -EIO;
		}
		reset_mpu401(devc);
	}
	if (devc->opened)
		return -EBUSY;
	devc->mode = MODE_SYNTH;
	devc->synthno = dev;

	devc->inputintr = NULL;

	coprocessor = midi_devs[midi_dev]->coproc;
	if (coprocessor) {
		if (!try_module_get(coprocessor->owner))
			return -ENODEV;

		if ((err = coprocessor->open(coprocessor->devc, COPR_MIDI)) < 0)
		{
			printk(KERN_WARNING "mpu401: Can't access coprocessor device\n");
			return err;
		}
	}
	devc->opened = mode;
	reset_mpu401(devc);

	if (mode & OPEN_READ)
	{
		mpu_cmd(midi_dev, 0x8B, 0);	/* Enable data in stop mode */
		mpu_cmd(midi_dev, 0x34, 0);	/* Return timing bytes in stop mode */
		mpu_cmd(midi_dev, 0x87, 0);	/* Enable pitch & controller */
	}
	return 0;
}

static void mpu_synth_close(int dev)
{ 
	int midi_dev;
	struct mpu_config *devc;
	struct coproc_operations *coprocessor;

	midi_dev = synth_devs[dev]->midi_dev;

	devc = &dev_conf[midi_dev];
	mpu_cmd(midi_dev, 0x15, 0);	/* Stop recording, playback and MIDI */
	mpu_cmd(midi_dev, 0x8a, 0);	/* Disable data in stopped mode */

	devc->inputintr = NULL;

	coprocessor = midi_devs[midi_dev]->coproc;
	if (coprocessor) {
		coprocessor->close(coprocessor->devc, COPR_MIDI);
		module_put(coprocessor->owner);
	}
	devc->opened = 0;
	devc->mode = 0;
}

#define MIDI_SYNTH_NAME	"MPU-401 UART Midi"
#define MIDI_SYNTH_CAPS	SYNTH_CAP_INPUT
#include "midi_synth.h"

static struct synth_operations mpu401_synth_proto =
{
	.owner		= THIS_MODULE,
	.id		= "MPU401",
	.info		= NULL,
	.midi_dev	= 0,
	.synth_type	= SYNTH_TYPE_MIDI,
	.synth_subtype	= 0,
	.open		= mpu_synth_open,
	.close		= mpu_synth_close,
	.ioctl		= mpu_synth_ioctl,
	.kill_note	= midi_synth_kill_note,
	.start_note	= midi_synth_start_note,
	.set_instr	= midi_synth_set_instr,
	.reset		= midi_synth_reset,
	.hw_control	= midi_synth_hw_control,
	.load_patch	= midi_synth_load_patch,
	.aftertouch	= midi_synth_aftertouch,
	.controller	= midi_synth_controller,
	.panning	= midi_synth_panning,
	.bender		= midi_synth_bender,
	.setup_voice	= midi_synth_setup_voice,
	.send_sysex	= midi_synth_send_sysex
};

static struct synth_operations *mpu401_synth_operations[MAX_MIDI_DEV];

static struct midi_operations mpu401_midi_proto =
{
	.owner		= THIS_MODULE,
	.info		= {"MPU-401 Midi", 0, MIDI_CAP_MPU401, SNDCARD_MPU401},
	.in_info	= {0},
	.open		= mpu401_open,
	.close		= mpu401_close,
	.ioctl		= mpu401_ioctl,
	.outputc	= mpu401_out,
	.start_read	= mpu401_start_read,
	.end_read	= mpu401_end_read,
	.kick		= mpu401_kick,
	.buffer_status	= mpu401_buffer_status,
	.prefix_cmd	= mpu401_prefix_cmd
};

static struct midi_operations mpu401_midi_operations[MAX_MIDI_DEV];

static void mpu401_chk_version(int n, struct mpu_config *devc)
{
	int tmp;
	unsigned long flags;

	devc->version = devc->revision = 0;

	spin_lock_irqsave(&devc->lock,flags);
	if ((tmp = mpu_cmd(n, 0xAC, 0)) < 0)
	{
		spin_unlock_irqrestore(&devc->lock,flags);
		return;
	}
	if ((tmp & 0xf0) > 0x20)	/* Why it's larger than 2.x ??? */
	{
		spin_unlock_irqrestore(&devc->lock,flags);
		return;
	}
	devc->version = tmp;

	if ((tmp = mpu_cmd(n, 0xAD, 0)) < 0)
	{
		devc->version = 0;
		spin_unlock_irqrestore(&devc->lock,flags);
		return;
	}
	devc->revision = tmp;
	spin_unlock_irqrestore(&devc->lock,flags);
}

int attach_mpu401(struct address_info *hw_config, struct module *owner)
{
	unsigned long flags;
	char revision_char;

	int m, ret;
	struct mpu_config *devc;

	hw_config->slots[1] = -1;
	m = sound_alloc_mididev();
	if (m == -1)
	{
		printk(KERN_WARNING "MPU-401: Too many midi devices detected\n");
		ret = -ENOMEM;
		goto out_err;
	}
	devc = &dev_conf[m];
	devc->base = hw_config->io_base;
	devc->osp = hw_config->osp;
	devc->irq = hw_config->irq;
	devc->opened = 0;
	devc->uart_mode = 0;
	devc->initialized = 0;
	devc->version = 0;
	devc->revision = 0;
	devc->capabilities = 0;
	devc->timer_flag = 0;
	devc->m_busy = 0;
	devc->m_state = ST_INIT;
	devc->shared_irq = hw_config->always_detect;
	devc->irq = hw_config->irq;
	spin_lock_init(&devc->lock);

	if (devc->irq < 0)
	{
		devc->irq *= -1;
		devc->shared_irq = 1;
	}

	if (!hw_config->always_detect)
	{
		/* Verify the hardware again */
		if (!reset_mpu401(devc))
		{
			printk(KERN_WARNING "mpu401: Device didn't respond\n");
			ret = -ENODEV;
			goto out_mididev;
		}
		if (!devc->shared_irq)
		{
			if (request_irq(devc->irq, mpuintr, 0, "mpu401", (void *)m) < 0)
			{
				printk(KERN_WARNING "mpu401: Failed to allocate IRQ%d\n", devc->irq);
				ret = -ENOMEM;
				goto out_mididev;
			}
		}
		spin_lock_irqsave(&devc->lock,flags);
		mpu401_chk_version(m, devc);
		if (devc->version == 0)
			mpu401_chk_version(m, devc);
			spin_unlock_irqrestore(&devc->lock,flags);
	}

	if (devc->version != 0)
		if (mpu_cmd(m, 0xC5, 0) >= 0)	/* Set timebase OK */
			if (mpu_cmd(m, 0xE0, 120) >= 0)		/* Set tempo OK */
				devc->capabilities |= MPU_CAP_INTLG;	/* Supports intelligent mode */


	mpu401_synth_operations[m] = (struct synth_operations *)kmalloc(sizeof(struct synth_operations), GFP_KERNEL);

	if (mpu401_synth_operations[m] == NULL)
	{
		printk(KERN_ERR "mpu401: Can't allocate memory\n");
		ret = -ENOMEM;
		goto out_irq;
	}
	if (!(devc->capabilities & MPU_CAP_INTLG))	/* No intelligent mode */
	{
		memcpy((char *) mpu401_synth_operations[m],
			(char *) &std_midi_synth,
			 sizeof(struct synth_operations));
	}
	else
	{
		memcpy((char *) mpu401_synth_operations[m],
			(char *) &mpu401_synth_proto,
			 sizeof(struct synth_operations));
	}
	if (owner)
		mpu401_synth_operations[m]->owner = owner;

	memcpy((char *) &mpu401_midi_operations[m],
	       (char *) &mpu401_midi_proto,
	       sizeof(struct midi_operations));

	mpu401_midi_operations[m].converter = mpu401_synth_operations[m];

	memcpy((char *) &mpu_synth_info[m],
	       (char *) &mpu_synth_info_proto,
	       sizeof(struct synth_info));

	n_mpu_devs++;

	if (devc->version == 0x20 && devc->revision >= 0x07)	/* MusicQuest interface */
	{
		int ports = (devc->revision & 0x08) ? 32 : 16;

		devc->capabilities |= MPU_CAP_SYNC | MPU_CAP_SMPTE |
				MPU_CAP_CLS | MPU_CAP_2PORT;

		revision_char = (devc->revision == 0x7f) ? 'M' : ' ';
		sprintf(mpu_synth_info[m].name, "MQX-%d%c MIDI Interface #%d",
				ports,
				revision_char,
				n_mpu_devs);
	}
	else
	{
		revision_char = devc->revision ? devc->revision + '@' : ' ';
		if ((int) devc->revision > ('Z' - '@'))
			revision_char = '+';

		devc->capabilities |= MPU_CAP_SYNC | MPU_CAP_FSK;

		if (hw_config->name)
			sprintf(mpu_synth_info[m].name, "%s (MPU401)", hw_config->name);
		else
			sprintf(mpu_synth_info[m].name,
				"MPU-401 %d.%d%c Midi interface #%d",
				(int) (devc->version & 0xf0) >> 4,
				devc->version & 0x0f,
				revision_char,
				n_mpu_devs);
	}

	strcpy(mpu401_midi_operations[m].info.name,
	       mpu_synth_info[m].name);

	conf_printf(mpu_synth_info[m].name, hw_config);

	mpu401_synth_operations[m]->midi_dev = devc->devno = m;
	mpu401_synth_operations[devc->devno]->info = &mpu_synth_info[devc->devno];

	if (devc->capabilities & MPU_CAP_INTLG)		/* Intelligent mode */
		hw_config->slots[2] = mpu_timer_init(m);

	midi_devs[m] = &mpu401_midi_operations[devc->devno];
	
	if (owner)
		midi_devs[m]->owner = owner;

	hw_config->slots[1] = m;
	sequencer_init();
	
	return 0;

out_irq:
	free_irq(devc->irq, (void *)m);
out_mididev:
	sound_unload_mididev(m);
out_err:
	release_region(hw_config->io_base, 2);
	return ret;
}

static int reset_mpu401(struct mpu_config *devc)
{
	unsigned long flags;
	int ok, timeout, n;
	int timeout_limit;

	/*
	 * Send the RESET command. Try again if no success at the first time.
	 * (If the device is in the UART mode, it will not ack the reset cmd).
	 */

	ok = 0;

	timeout_limit = devc->initialized ? 30000 : 100000;
	devc->initialized = 1;

	for (n = 0; n < 2 && !ok; n++)
	{
		for (timeout = timeout_limit; timeout > 0 && !ok; timeout--)
			  ok = output_ready(devc);

		write_command(devc, MPU_RESET);	/*
							   * Send MPU-401 RESET Command
							 */

		/*
		 * 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 = timeout_limit * 2; timeout > 0 && !ok; timeout--)
		{
			spin_lock_irqsave(&devc->lock,flags);
			if (input_avail(devc))
				if (read_data(devc) == MPU_ACK)
					ok = 1;
			spin_unlock_irqrestore(&devc->lock,flags);
		}

	}

	devc->m_state = ST_INIT;
	devc->m_ptr = 0;
	devc->m_left = 0;
	devc->last_status = 0;
	devc->uart_mode = 0;

	return ok;
}

static void set_uart_mode(int dev, struct mpu_config *devc, int arg)
{
	if (!arg && (devc->capabilities & MPU_CAP_INTLG))
		return;
	if ((devc->uart_mode == 0) == (arg == 0))
		return;		/* Already set */
	reset_mpu401(devc);	/* This exits the uart mode */

	if (arg)
	{
		if (mpu_cmd(dev, UART_MODE_ON, 0) < 0)
		{
			printk(KERN_ERR "mpu401: Can't enter UART mode\n");
			devc->uart_mode = 0;
			return;
		}
	}
	devc->uart_mode = arg;

}

int probe_mpu401(struct address_info *hw_config, struct resource *ports)
{
	int ok = 0;
	struct mpu_config tmp_devc;

	tmp_devc.base = hw_config->io_base;
	tmp_devc.irq = hw_config->irq;
	tmp_devc.initialized = 0;
	tmp_devc.opened = 0;
	tmp_devc.osp = hw_config->osp;

	if (hw_config->always_detect)
		return 1;

	if (inb(hw_config->io_base + 1) == 0xff)
	{
		DDB(printk("MPU401: Port %x looks dead.\n", hw_config->io_base));
		return 0;	/* Just bus float? */
	}
	ok = reset_mpu401(&tmp_devc);

	if (!ok)
	{
		DDB(printk("MPU401: Reset failed on port %x\n", hw_config->io_base));
	}
	return ok;
}

void unload_mpu401(struct address_info *hw_config)
{
	void *p;
	int n=hw_config->slots[1];
		
	if (n != -1) {
		release_region(hw_config->io_base, 2);
		if (hw_config->always_detect == 0 && hw_config->irq > 0)
			free_irq(hw_config->irq, (void *)n);
		p=mpu401_synth_operations[n];
		sound_unload_mididev(n);
		sound_unload_timerdev(hw_config->slots[2]);
		kfree(p);
	}
}

/*****************************************************
 *      Timer stuff
 ****************************************************/

static volatile int timer_initialized = 0, timer_open = 0, tmr_running = 0;
static volatile int curr_tempo, curr_timebase, hw_timebase;
static int      max_timebase = 8;	/* 8*24=192 ppqn */
static volatile unsigned long next_event_time;
static volatile unsigned long curr_ticks, curr_clocks;
static unsigned long prev_event_time;
static int      metronome_mode;

static unsigned long clocks2ticks(unsigned long clocks)
{
	/*
	 * The MPU-401 supports just a limited set of possible timebase values.
	 * Since the applications require more choices, the driver has to
	 * program the HW to do its best and to convert between the HW and
	 * actual timebases.
	 */
	return ((clocks * curr_timebase) + (hw_timebase / 2)) / hw_timebase;
}

static void set_timebase(int midi_dev, int val)
{
	int hw_val;

	if (val < 48)
		val = 48;
	if (val > 1000)
		val = 1000;

	hw_val = val;
	hw_val = (hw_val + 12) / 24;
	if (hw_val > max_timebase)
		hw_val = max_timebase;

	if (mpu_cmd(midi_dev, 0xC0 | (hw_val & 0x0f), 0) < 0)
	{
		printk(KERN_WARNING "mpu401: Can't set HW timebase to %d\n", hw_val * 24);
		return;
	}
	hw_timebase = hw_val * 24;
	curr_timebase = val;

}

static void tmr_reset(struct mpu_config *devc)
{
	unsigned long flags;

	spin_lock_irqsave(&devc->lock,flags);
	next_event_time = (unsigned long) -1;
	prev_event_time = 0;
	curr_ticks = curr_clocks = 0;
	spin_unlock_irqrestore(&devc->lock,flags);
}

static void set_timer_mode(int midi_dev)
{
	if (timer_mode & TMR_MODE_CLS)
		mpu_cmd(midi_dev, 0x3c, 0);	/* Use CLS sync */
	else if (timer_mode & TMR_MODE_SMPTE)
		mpu_cmd(midi_dev, 0x3d, 0);	/* Use SMPTE sync */

	if (timer_mode & TMR_INTERNAL)
	{
		  mpu_cmd(midi_dev, 0x80, 0);	/* Use MIDI sync */
	}
	else
	{
		if (timer_mode & (TMR_MODE_MIDI | TMR_MODE_CLS))
		{
			mpu_cmd(midi_dev, 0x82, 0);		/* Use MIDI sync */
			mpu_cmd(midi_dev, 0x91, 0);		/* Enable ext MIDI ctrl */
		}
		else if (timer_mode & TMR_MODE_FSK)
			mpu_cmd(midi_dev, 0x81, 0);	/* Use FSK sync */
	}
}

static void stop_metronome(int midi_dev)
{
	mpu_cmd(midi_dev, 0x84, 0);	/* Disable metronome */
}

static void setup_metronome(int midi_dev)
{
	int numerator, denominator;
	int clks_per_click, num_32nds_per_beat;
	int beats_per_measure;

	numerator = ((unsigned) metronome_mode >> 24) & 0xff;
	denominator = ((unsigned) metronome_mode >> 16) & 0xff;
	clks_per_click = ((unsigned) metronome_mode >> 8) & 0xff;
	num_32nds_per_beat = (unsigned) metronome_mode & 0xff;
	beats_per_measure = (numerator * 4) >> denominator;

	if (!metronome_mode)
		mpu_cmd(midi_dev, 0x84, 0);	/* Disable metronome */
	else
	{
		mpu_cmd(midi_dev, 0xE4, clks_per_click);
		mpu_cmd(midi_dev, 0xE6, beats_per_measure);
		mpu_cmd(midi_dev, 0x83, 0);	/* Enable metronome without accents */
	}
}

static int mpu_start_timer(int midi_dev)
{
	struct mpu_config *devc= &dev_conf[midi_dev];

	tmr_reset(devc);
	set_timer_mode(midi_dev);

	if (tmr_running)
		return TIMER_NOT_ARMED;		/* Already running */

	if (timer_mode & TMR_INTERNAL)
	{
		mpu_cmd(midi_dev, 0x02, 0);	/* Send MIDI start */
		tmr_running = 1;
		return TIMER_NOT_ARMED;
	}
	else
	{
		mpu_cmd(midi_dev, 0x35, 0);	/* Enable mode messages to PC */
		mpu_cmd(midi_dev, 0x38, 0);	/* Enable sys common messages to PC */
		mpu_cmd(midi_dev, 0x39, 0);	/* Enable real time messages to PC */
		mpu_cmd(midi_dev, 0x97, 0);	/* Enable system exclusive messages to PC */
	}
	return TIMER_ARMED;
}

static int mpu_timer_open(int dev, int mode)
{
	int midi_dev = sound_timer_devs[dev]->devlink;
	struct mpu_config *devc= &dev_conf[midi_dev];

	if (timer_open)
		return -EBUSY;

	tmr_reset(devc);
	curr_tempo = 50;
	mpu_cmd(midi_dev, 0xE0, 50);
	curr_timebase = hw_timebase = 120;
	set_timebase(midi_dev, 120);
	timer_open = 1;
	metronome_mode = 0;
	set_timer_mode(midi_dev);

	mpu_cmd(midi_dev, 0xe7, 0x04);	/* Send all clocks to host */
	mpu_cmd(midi_dev, 0x95, 0);	/* Enable clock to host */

	return 0;
}

static void mpu_timer_close(int dev)
{
	int midi_dev = sound_timer_devs[dev]->devlink;

	timer_open = tmr_running = 0;
	mpu_cmd(midi_dev, 0x15, 0);	/* Stop all */
	mpu_cmd(midi_dev, 0x94, 0);	/* Disable clock to host */
	mpu_cmd(midi_dev, 0x8c, 0);	/* Disable measure end messages to host */
	stop_metronome(midi_dev);
}

static int mpu_timer_event(int dev, unsigned char *event)
{
	unsigned char command = event[1];
	unsigned long parm = *(unsigned int *) &event[4];
	int midi_dev = sound_timer_devs[dev]->devlink;

	switch (command)
	{
		case TMR_WAIT_REL:
			parm += prev_event_time;
		case TMR_WAIT_ABS:
			if (parm > 0)
			{
				long time;

				if (parm <= curr_ticks)	/* It's the time */
					return TIMER_NOT_ARMED;
				time = parm;
				next_event_time = prev_event_time = time;

				return TIMER_ARMED;
			}
			break;

		case TMR_START:
			if (tmr_running)
				break;
			return mpu_start_timer(midi_dev);

		case TMR_STOP:
			mpu_cmd(midi_dev, 0x01, 0);	/* Send MIDI stop */
			stop_metronome(midi_dev);
			tmr_running = 0;
			break;

		case TMR_CONTINUE:
			if (tmr_running)
				break;
			mpu_cmd(midi_dev, 0x03, 0);	/* Send MIDI continue */
			setup_metronome(midi_dev);
			tmr_running = 1;
			break;

		case TMR_TEMPO:
			if (parm)
			{
				if (parm < 8)
					parm = 8;
			 	if (parm > 250)
					parm = 250;
				if (mpu_cmd(midi_dev, 0xE0, parm) < 0)
					printk(KERN_WARNING "mpu401: Can't set tempo to %d\n", (int) parm);
				curr_tempo = parm;
			}
			break;

		case TMR_ECHO:
			seq_copy_to_input(event, 8);
			break;

		case TMR_TIMESIG:
			if (metronome_mode)	/* Metronome enabled */
			{
				metronome_mode = parm;
				setup_metronome(midi_dev);
			}
			break;

		default:;
	}
	return TIMER_NOT_ARMED;
}

static unsigned long mpu_timer_get_time(int dev)
{
	if (!timer_open)
		return 0;

	return curr_ticks;
}

static int mpu_timer_ioctl(int dev, unsigned int command, void __user *arg)
{
	int midi_dev = sound_timer_devs[dev]->devlink;
	int __user *p = (int __user *)arg;

	switch (command)
	{
		case SNDCTL_TMR_SOURCE:
			{
				int parm;

				if (get_user(parm, p))
					return -EFAULT;
				parm &= timer_caps;

				if (parm != 0)
				{
					timer_mode = parm;
	
					if (timer_mode & TMR_MODE_CLS)
						mpu_cmd(midi_dev, 0x3c, 0);		/* Use CLS sync */
					else if (timer_mode & TMR_MODE_SMPTE)
						mpu_cmd(midi_dev, 0x3d, 0);		/* Use SMPTE sync */
				}
				if (put_user(timer_mode, p))
					return -EFAULT;
				return timer_mode;
			}
			break;

		case SNDCTL_TMR_START:
			mpu_start_timer(midi_dev);
			return 0;

		case SNDCTL_TMR_STOP:
			tmr_running = 0;
			mpu_cmd(midi_dev, 0x01, 0);	/* Send MIDI stop */
			stop_metronome(midi_dev);
			return 0;

		case SNDCTL_TMR_CONTINUE:
			if (tmr_running)
				return 0;
			tmr_running = 1;
			mpu_cmd(midi_dev, 0x03, 0);	/* Send MIDI continue */
			return 0;

		case SNDCTL_TMR_TIMEBASE:
			{
				int val;
				if (get_user(val, p))
					return -EFAULT;
				if (val)
					set_timebase(midi_dev, val);
				if (put_user(curr_timebase, p))
					return -EFAULT;
				return curr_timebase;
			}
			break;

		case SNDCTL_TMR_TEMPO:
			{
				int val;
				int ret;

				if (get_user(val, p))
					return -EFAULT;

				if (val)
				{
					if (val < 8)
						val = 8;
					if (val > 250)
						val = 250;
					if ((ret = mpu_cmd(midi_dev, 0xE0, val)) < 0)
					{
						printk(KERN_WARNING "mpu401: Can't set tempo to %d\n", (int) val);
						return ret;
					}
					curr_tempo = val;
				}
				if (put_user(curr_tempo, p))
					return -EFAULT;
				return curr_tempo;
			}
			break;

		case SNDCTL_SEQ_CTRLRATE:
			{
				int val;
				if (get_user(val, p))
					return -EFAULT;

				if (val != 0)		/* Can't change */
					return -EINVAL;
				val = ((curr_tempo * curr_timebase) + 30)/60;
				if (put_user(val, p))
					return -EFAULT;
				return val;
			}
			break;

		case SNDCTL_SEQ_GETTIME:
			if (put_user(curr_ticks, p))
				return -EFAULT;
			return curr_ticks;

		case SNDCTL_TMR_METRONOME:
			if (get_user(metronome_mode, p))
				return -EFAULT;
			setup_metronome(midi_dev);
			return 0;

		default:;
	}
	return -EINVAL;
}

static void mpu_timer_arm(int dev, long time)
{
	if (time < 0)
		time = curr_ticks + 1;
	else if (time <= curr_ticks)	/* It's the time */
		return;
	next_event_time = prev_event_time = time;
	return;
}

static struct sound_timer_operations mpu_timer =
{
	.owner		= THIS_MODULE,
	.info		= {"MPU-401 Timer", 0},
	.priority	= 10,	/* Priority */
	.devlink	= 0,	/* Local device link */
	.open		= mpu_timer_open,
	.close		= mpu_timer_close,
	.event		= mpu_timer_event,
	.get_time	= mpu_timer_get_time,
	.ioctl		= mpu_timer_ioctl,
	.arm_timer	= mpu_timer_arm
};

static void mpu_timer_interrupt(void)
{
	if (!timer_open)
		return;

	if (!tmr_running)
		return;

	curr_clocks++;
	curr_ticks = clocks2ticks(curr_clocks);

	if (curr_ticks >= next_event_time)
	{
		next_event_time = (unsigned long) -1;
		sequencer_timer(0);
	}
}

static void timer_ext_event(struct mpu_config *devc, int event, int parm)
{
	int midi_dev = devc->devno;

	if (!devc->timer_flag)
		return;

	switch (event)
	{
		case TMR_CLOCK:
			printk("<MIDI clk>");
			break;

		case TMR_START:
			printk("Ext MIDI start\n");
			if (!tmr_running)
			{
				if (timer_mode & TMR_EXTERNAL)
				{
					tmr_running = 1;
					setup_metronome(midi_dev);
					next_event_time = 0;
					STORE(SEQ_START_TIMER());
				}
			}
			break;

		case TMR_STOP:
			printk("Ext MIDI stop\n");
			if (timer_mode & TMR_EXTERNAL)
			{
				tmr_running = 0;
				stop_metronome(midi_dev);
				STORE(SEQ_STOP_TIMER());
			}
			break;

		case TMR_CONTINUE:
			printk("Ext MIDI continue\n");
			if (timer_mode & TMR_EXTERNAL)
			{
				tmr_running = 1;
				setup_metronome(midi_dev);
				STORE(SEQ_CONTINUE_TIMER());
		  	}
		  	break;

		case TMR_SPP:
			printk("Songpos: %d\n", parm);
			if (timer_mode & TMR_EXTERNAL)
			{
				STORE(SEQ_SONGPOS(parm));
			}
			break;
	}
}

static int mpu_timer_init(int midi_dev)
{
	struct mpu_config *devc;
	int n;

	devc = &dev_conf[midi_dev];

	if (timer_initialized)
		return -1;	/* There is already a similar timer */

	timer_initialized = 1;

	mpu_timer.devlink = midi_dev;
	dev_conf[midi_dev].timer_flag = 1;

	n = sound_alloc_timerdev();
	if (n == -1)
		n = 0;
	sound_timer_devs[n] = &mpu_timer;

	if (devc->version < 0x20)	/* Original MPU-401 */
		timer_caps = TMR_INTERNAL | TMR_EXTERNAL | TMR_MODE_FSK | TMR_MODE_MIDI;
	else
	{
		/*
		 * The version number 2.0 is used (at least) by the
		 * MusicQuest cards and the Roland Super-MPU.
		 *
		 * MusicQuest has given a special meaning to the bits of the
		 * revision number. The Super-MPU returns 0.
		 */

		if (devc->revision)
			timer_caps |= TMR_EXTERNAL | TMR_MODE_MIDI;

		if (devc->revision & 0x02)
			timer_caps |= TMR_MODE_CLS;


		if (devc->revision & 0x40)
			max_timebase = 10;	/* Has the 216 and 240 ppqn modes */
	}

	timer_mode = (TMR_INTERNAL | TMR_MODE_MIDI) & timer_caps;
	return n;

}

EXPORT_SYMBOL(probe_mpu401);
EXPORT_SYMBOL(attach_mpu401);
EXPORT_SYMBOL(unload_mpu401);

static struct address_info cfg;

static int io = -1;
static int irq = -1;

module_param(irq, int, 0);
module_param(io, int, 0);

static int __init init_mpu401(void)
{
	int ret;
	/* Can be loaded either for module use or to provide functions
	   to others */
	if (io != -1 && irq != -1) {
		struct resource *ports;
	        cfg.irq = irq;
		cfg.io_base = io;
		ports = request_region(io, 2, "mpu401");
		if (!ports)
			return -EBUSY;
		if (probe_mpu401(&cfg, ports) == 0) {
			release_region(io, 2);
			return -ENODEV;
		}
		if ((ret = attach_mpu401(&cfg, THIS_MODULE)))
			return ret;
	}
	
	return 0;
}

static void __exit cleanup_mpu401(void)
{
	if (io != -1 && irq != -1) {
		/* Check for use by, for example, sscape driver */
		unload_mpu401(&cfg);
	}
}

module_init(init_mpu401);
module_exit(cleanup_mpu401);

#ifndef MODULE
static int __init setup_mpu401(char *str)
{
        /* io, irq */
	int ints[3];
	
	str = get_options(str, ARRAY_SIZE(ints), ints);
	
	io = ints[1];
	irq = ints[2];

	return 1;
}

__setup("mpu401=", setup_mpu401);
#endif
MODULE_LICENSE("GPL");
