/*
 * sound/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;
}

int intchk_mpu401(void *dev_id)
{
	struct mpu_config *devc;
	int dev = (int) dev_id;

	devc = &dev_conf[dev];
	return input_avail(devc);
}

irqreturn_t mpuintr(int irq, void *dev_id, struct pt_regs *dummy)
{
	struct mpu_config *devc;
	int dev = (int) 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);
EXPORT_SYMBOL(intchk_mpu401);
EXPORT_SYMBOL(mpuintr);

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");
