/*
 * sound/oss/pas2_midi.c
 *
 * The low level driver for the PAS Midi Interface.
 */
/*
 * 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.
 *
 * Bartlomiej Zolnierkiewicz	: Added __init to pas_init_mixer()
 */

#include <linux/init.h>
#include <linux/spinlock.h>
#include "sound_config.h"

#include "pas2.h"

extern spinlock_t pas_lock;

static int      midi_busy, input_opened;
static int      my_dev;

int pas2_mididev=-1;

static unsigned char tmp_queue[256];
static volatile int qlen;
static volatile unsigned char qhead, qtail;

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

static int pas_midi_open(int dev, int mode,
	      void            (*input) (int dev, unsigned char data),
	      void            (*output) (int dev)
)
{
	int             err;
	unsigned long   flags;
	unsigned char   ctrl;


	if (midi_busy)
		return -EBUSY;

	/*
	 * Reset input and output FIFO pointers
	 */
	pas_write(0x20 | 0x40,
		  0x178b);

	spin_lock_irqsave(&pas_lock, flags);

	if ((err = pas_set_intr(0x10)) < 0)
	{
		spin_unlock_irqrestore(&pas_lock, flags);
		return err;
	}
	/*
	 * Enable input available and output FIFO empty interrupts
	 */

	ctrl = 0;
	input_opened = 0;
	midi_input_intr = input;

	if (mode == OPEN_READ || mode == OPEN_READWRITE)
	{
		ctrl |= 0x04;	/* Enable input */
		input_opened = 1;
	}
	if (mode == OPEN_WRITE || mode == OPEN_READWRITE)
	{
		ctrl |= 0x08 | 0x10;	/* Enable output */
	}
	pas_write(ctrl, 0x178b);

	/*
	 * Acknowledge any pending interrupts
	 */

	pas_write(0xff, 0x1B88);

	spin_unlock_irqrestore(&pas_lock, flags);

	midi_busy = 1;
	qlen = qhead = qtail = 0;
	return 0;
}

static void pas_midi_close(int dev)
{

	/*
	 * Reset FIFO pointers, disable intrs
	 */
	pas_write(0x20 | 0x40, 0x178b);

	pas_remove_intr(0x10);
	midi_busy = 0;
}

static int dump_to_midi(unsigned char midi_byte)
{
	int fifo_space, x;

	fifo_space = ((x = pas_read(0x1B89)) >> 4) & 0x0f;

	/*
	 * The MIDI FIFO space register and it's documentation is nonunderstandable.
	 * There seem to be no way to differentiate between buffer full and buffer
	 * empty situations. For this reason we don't never write the buffer
	 * completely full. In this way we can assume that 0 (or is it 15)
	 * means that the buffer is empty.
	 */

	if (fifo_space < 2 && fifo_space != 0)	/* Full (almost) */
		return 0;	/* Ask upper layers to retry after some time */

	pas_write(midi_byte, 0x178A);

	return 1;
}

static int pas_midi_out(int dev, unsigned char midi_byte)
{

	unsigned long flags;

	/*
	 * Drain the local queue first
	 */

	spin_lock_irqsave(&pas_lock, flags);

	while (qlen && dump_to_midi(tmp_queue[qhead]))
	{
		qlen--;
		qhead++;
	}

	spin_unlock_irqrestore(&pas_lock, flags);

	/*
	 *	Output the byte if the local queue is empty.
	 */

	if (!qlen)
		if (dump_to_midi(midi_byte))
			return 1;

	/*
	 *	Put to the local queue
	 */

	if (qlen >= 256)
		return 0;	/* Local queue full */

	spin_lock_irqsave(&pas_lock, flags);

	tmp_queue[qtail] = midi_byte;
	qlen++;
	qtail++;

	spin_unlock_irqrestore(&pas_lock, flags);

	return 1;
}

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

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

static void pas_midi_kick(int dev)
{
}

static int pas_buffer_status(int dev)
{
	return qlen;
}

#define MIDI_SYNTH_NAME	"Pro Audio Spectrum Midi"
#define MIDI_SYNTH_CAPS	SYNTH_CAP_INPUT
#include "midi_synth.h"

static struct midi_operations pas_midi_operations =
{
	.owner		= THIS_MODULE,
	.info		= {"Pro Audio Spectrum", 0, 0, SNDCARD_PAS},
	.converter	= &std_midi_synth,
	.in_info	= {0},
	.open		= pas_midi_open,
	.close		= pas_midi_close,
	.outputc	= pas_midi_out,
	.start_read	= pas_midi_start_read,
	.end_read	= pas_midi_end_read,
	.kick		= pas_midi_kick,
	.buffer_status	= pas_buffer_status,
};

void __init pas_midi_init(void)
{
	int dev = sound_alloc_mididev();

	if (dev == -1)
	{
		printk(KERN_WARNING "pas_midi_init: Too many midi devices detected\n");
		return;
	}
	std_midi_synth.midi_dev = my_dev = dev;
	midi_devs[dev] = &pas_midi_operations;
	pas2_mididev = dev;
	sequencer_init();
}

void pas_midi_interrupt(void)
{
	unsigned char   stat;
	int             i, incount;

	stat = pas_read(0x1B88);

	if (stat & 0x04)	/* Input data available */
	{
		incount = pas_read(0x1B89) & 0x0f;	/* Input FIFO size */
		if (!incount)
			incount = 16;

		for (i = 0; i < incount; i++)
			if (input_opened)
			{
				midi_input_intr(my_dev, pas_read(0x178A));
			} else
				pas_read(0x178A);	/* Flush */
	}
	if (stat & (0x08 | 0x10))
	{
		spin_lock(&pas_lock);/* called in irq context */

		while (qlen && dump_to_midi(tmp_queue[qhead]))
		{
			qlen--;
			qhead++;
		}

		spin_unlock(&pas_lock);
	}
	if (stat & 0x40)
	{
		printk(KERN_WARNING "MIDI output overrun %x,%x\n", pas_read(0x1B89), stat);
	}
	pas_write(stat, 0x1B88);	/* Acknowledge interrupts */
}
