/*
 * sound/uart6850.c
 *
 *
 * 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.
 * Extended by Alan Cox for Red Hat Software. Now a loadable MIDI driver.
 * 28/4/97 - (C) Copyright Alan Cox. Released under the GPL version 2.
 *
 * Alan Cox:		Updated for new modular code. Removed snd_* irq handling. Now
 *			uses native linux resources
 * Christoph Hellwig:	Adapted to module_init/module_exit
 * Jeff Garzik:		Made it work again, in theory
 *			FIXME: If the request_irq() succeeds, the probe succeeds. Ug.
 *
 *	Status: Testing required (no shit -jgarzik)
 *
 *
 */

#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/spinlock.h>
/* Mon Nov 22 22:38:35 MET 1993 marco@driq.home.usn.nl:
 *      added 6850 support, used with COVOX SoundMaster II and custom cards.
 */

#include "sound_config.h"

static int uart6850_base = 0x330;

static int *uart6850_osp;

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

static int uart6850_status(void)
{
	return inb(STATPORT);
}

#define input_avail()		(uart6850_status()&INPUT_AVAIL)
#define output_ready()		(uart6850_status()&OUTPUT_READY)

static void uart6850_cmd(unsigned char cmd)
{
	outb(cmd, COMDPORT);
}

static int uart6850_read(void)
{
	return inb(DATAPORT);
}

static void uart6850_write(unsigned char byte)
{
	outb(byte, DATAPORT);
}

#define	OUTPUT_READY	0x02	/* Mask for data ready Bit */
#define	INPUT_AVAIL	0x01	/* Mask for Data Send Ready Bit */

#define	UART_RESET	0x95
#define	UART_MODE_ON	0x03

static int uart6850_opened;
static int uart6850_irq;
static int uart6850_detected;
static int my_dev;
static DEFINE_SPINLOCK(lock);

static void (*midi_input_intr) (int dev, unsigned char data);
static void poll_uart6850(unsigned long dummy);


static DEFINE_TIMER(uart6850_timer, poll_uart6850, 0, 0);

static void uart6850_input_loop(void)
{
	int count = 10;

	while (count)
	{
		/*
		 * Not timed out
		 */
		if (input_avail())
		{
			unsigned char c = uart6850_read();
			count = 100;
			if (uart6850_opened & OPEN_READ)
				midi_input_intr(my_dev, c);
		}
		else
		{
			while (!input_avail() && count)
				count--;
		}
	}
}

static irqreturn_t m6850intr(int irq, void *dev_id, struct pt_regs *dummy)
{
	if (input_avail())
		uart6850_input_loop();
	return IRQ_HANDLED;
}

/*
 *	It looks like there is no input interrupts in the UART mode. Let's try
 *	polling.
 */

static void poll_uart6850(unsigned long dummy)
{
	unsigned long flags;

	if (!(uart6850_opened & OPEN_READ))
		return;		/* Device has been closed */

	spin_lock_irqsave(&lock,flags);
	if (input_avail())
		uart6850_input_loop();

	uart6850_timer.expires = 1 + jiffies;
	add_timer(&uart6850_timer);
	
	/*
	 *	Come back later
	 */

	spin_unlock_irqrestore(&lock,flags);
}

static int uart6850_open(int dev, int mode,
	      void            (*input) (int dev, unsigned char data),
	      void            (*output) (int dev)
)
{
	if (uart6850_opened)
	{
/*		  printk("Midi6850: Midi busy\n");*/
		  return -EBUSY;
	};

	uart6850_cmd(UART_RESET);
	uart6850_input_loop();
	midi_input_intr = input;
	uart6850_opened = mode;
	poll_uart6850(0);	/*
				 * Enable input polling
				 */

	return 0;
}

static void uart6850_close(int dev)
{
	uart6850_cmd(UART_MODE_ON);
	del_timer(&uart6850_timer);
	uart6850_opened = 0;
}

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

	/*
	 * Test for input since pending input seems to block the output.
	 */

	spin_lock_irqsave(&lock,flags);

	if (input_avail())
		uart6850_input_loop();

	spin_unlock_irqrestore(&lock,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(); timeout--);	/*
										 * Wait
										 */
	if (!output_ready())
	{
		printk(KERN_WARNING "Midi6850: Timeout\n");
		return 0;
	}
	uart6850_write(midi_byte);
	return 1;
}

static inline int uart6850_command(int dev, unsigned char *midi_byte)
{
	return 1;
}

static inline int uart6850_start_read(int dev)
{
	return 0;
}

static inline int uart6850_end_read(int dev)
{
	return 0;
}

static inline void uart6850_kick(int dev)
{
}

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

#define MIDI_SYNTH_NAME	"6850 UART Midi"
#define MIDI_SYNTH_CAPS	SYNTH_CAP_INPUT
#include "midi_synth.h"

static struct midi_operations uart6850_operations =
{
	.owner		= THIS_MODULE,
	.info		= {"6850 UART", 0, 0, SNDCARD_UART6850},
	.converter	= &std_midi_synth,
	.in_info	= {0},
	.open		= uart6850_open,
	.close		= uart6850_close,
	.outputc	= uart6850_out,
	.start_read	= uart6850_start_read,
	.end_read	= uart6850_end_read,
	.kick		= uart6850_kick,
	.command	= uart6850_command,
	.buffer_status	= uart6850_buffer_status
};


static void __init attach_uart6850(struct address_info *hw_config)
{
	int ok, timeout;
	unsigned long   flags;

	if (!uart6850_detected)
		return;

	if ((my_dev = sound_alloc_mididev()) == -1)
	{
		printk(KERN_INFO "uart6850: Too many midi devices detected\n");
		return;
	}
	uart6850_base = hw_config->io_base;
	uart6850_osp = hw_config->osp;
	uart6850_irq = hw_config->irq;

	spin_lock_irqsave(&lock,flags);

	for (timeout = 30000; timeout > 0 && !output_ready(); timeout--);	/*
										 * Wait
										 */
	uart6850_cmd(UART_MODE_ON);
	ok = 1;
	spin_unlock_irqrestore(&lock,flags);

	conf_printf("6850 Midi Interface", hw_config);

	std_midi_synth.midi_dev = my_dev;
	hw_config->slots[4] = my_dev;
	midi_devs[my_dev] = &uart6850_operations;
	sequencer_init();
}

static inline int reset_uart6850(void)
{
	uart6850_read();
	return 1;		/*
				 * OK
				 */
}

static int __init probe_uart6850(struct address_info *hw_config)
{
	int ok;

	uart6850_osp = hw_config->osp;
	uart6850_base = hw_config->io_base;
	uart6850_irq = hw_config->irq;

	if (request_irq(uart6850_irq, m6850intr, 0, "MIDI6850", NULL) < 0)
		return 0;

	ok = reset_uart6850();
	uart6850_detected = ok;
	return ok;
}

static void __exit unload_uart6850(struct address_info *hw_config)
{
	free_irq(hw_config->irq, NULL);
	sound_unload_mididev(hw_config->slots[4]);
}

static struct address_info cfg_mpu;

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

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

static int __init init_uart6850(void)
{
	cfg_mpu.io_base = io;
	cfg_mpu.irq = irq;

	if (cfg_mpu.io_base == -1 || cfg_mpu.irq == -1) {
		printk(KERN_INFO "uart6850: irq and io must be set.\n");
		return -EINVAL;
	}

	if (probe_uart6850(&cfg_mpu))
		return -ENODEV;
	attach_uart6850(&cfg_mpu);

	return 0;
}

static void __exit cleanup_uart6850(void)
{
	unload_uart6850(&cfg_mpu);
}

module_init(init_uart6850);
module_exit(cleanup_uart6850);

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

	return 1;
}
__setup("uart6850=", setup_uart6850);
#endif
MODULE_LICENSE("GPL");
