/*
 **********************************************************************
 *     midi.c - /dev/midi interface for emu10k1 driver
 *     Copyright 1999, 2000 Creative Labs, Inc.
 *
 **********************************************************************
 *
 *     Date                 Author          Summary of changes
 *     ----                 ------          ------------------
 *     October 20, 1999     Bertrand Lee    base code release
 *
 **********************************************************************
 *
 *     This program is free software; you can redistribute it and/or
 *     modify it under the terms of the GNU General Public License as
 *     published by the Free Software Foundation; either version 2 of
 *     the License, or (at your option) any later version.
 *
 *     This program is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *     GNU General Public License for more details.
 *
 *     You should have received a copy of the GNU General Public
 *     License along with this program; if not, write to the Free
 *     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
 *     USA.
 *
 **********************************************************************
 */

#include <linux/module.h>
#include <linux/poll.h>
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/smp_lock.h>
#include <asm/uaccess.h>

#include "hwaccess.h"
#include "cardmo.h"
#include "cardmi.h"
#include "midi.h"

#ifdef EMU10K1_SEQUENCER
#include "../sound_config.h"
#endif

static DEFINE_SPINLOCK(midi_spinlock);

static void init_midi_hdr(struct midi_hdr *midihdr)
{
	midihdr->bufferlength = MIDIIN_BUFLEN;
	midihdr->bytesrecorded = 0;
	midihdr->flags = 0;
}

static int midiin_add_buffer(struct emu10k1_mididevice *midi_dev, struct midi_hdr **midihdrptr)
{
	struct midi_hdr *midihdr;

	if ((midihdr = (struct midi_hdr *) kmalloc(sizeof(struct midi_hdr), GFP_KERNEL)) == NULL) {
		ERROR();
		return -EINVAL;
	}

	init_midi_hdr(midihdr);

	midihdr->data = kmalloc(MIDIIN_BUFLEN, GFP_KERNEL);
	if (!midihdr->data) {
		ERROR();
		kfree(midihdr);
		return -1;
	}

	if (emu10k1_mpuin_add_buffer(midi_dev->card->mpuin, midihdr) < 0) {
		ERROR();
		kfree(midihdr->data);
		kfree(midihdr);
		return -1;
	}

	*midihdrptr = midihdr;
	list_add_tail(&midihdr->list, &midi_dev->mid_hdrs);

	return 0;
}

static int emu10k1_midi_open(struct inode *inode, struct file *file)
{
	int minor = iminor(inode);
	struct emu10k1_card *card = NULL;
	struct emu10k1_mididevice *midi_dev;
	struct list_head *entry;

	DPF(2, "emu10k1_midi_open()\n");

	/* Check for correct device to open */
	list_for_each(entry, &emu10k1_devs) {
		card = list_entry(entry, struct emu10k1_card, list);

		if (card->midi_dev == minor)
			goto match;
	}

	return -ENODEV;

match:
#ifdef EMU10K1_SEQUENCER
	if (card->seq_mididev)	/* card is opened by sequencer */
		return -EBUSY;
#endif

	/* Wait for device to become free */
	mutex_lock(&card->open_sem);
	while (card->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) {
		if (file->f_flags & O_NONBLOCK) {
			mutex_unlock(&card->open_sem);
			return -EBUSY;
		}

		mutex_unlock(&card->open_sem);
		interruptible_sleep_on(&card->open_wait);

		if (signal_pending(current)) {
			return -ERESTARTSYS;
		}

		mutex_lock(&card->open_sem);
	}

	if ((midi_dev = (struct emu10k1_mididevice *) kmalloc(sizeof(*midi_dev), GFP_KERNEL)) == NULL)
		return -EINVAL;

	midi_dev->card = card;
	midi_dev->mistate = MIDIIN_STATE_STOPPED;
	init_waitqueue_head(&midi_dev->oWait);
	init_waitqueue_head(&midi_dev->iWait);
	midi_dev->ird = 0;
	midi_dev->iwr = 0;
	midi_dev->icnt = 0;
	INIT_LIST_HEAD(&midi_dev->mid_hdrs);

	if (file->f_mode & FMODE_READ) {
		struct midi_openinfo dsCardMidiOpenInfo;
		struct midi_hdr *midihdr1;
		struct midi_hdr *midihdr2;

		dsCardMidiOpenInfo.refdata = (unsigned long) midi_dev;

		if (emu10k1_mpuin_open(card, &dsCardMidiOpenInfo) < 0) {
			ERROR();
			kfree(midi_dev);
			return -ENODEV;
		}

		/* Add two buffers to receive sysex buffer */
		if (midiin_add_buffer(midi_dev, &midihdr1) < 0) {
			kfree(midi_dev);
			return -ENODEV;
		}

		if (midiin_add_buffer(midi_dev, &midihdr2) < 0) {
			list_del(&midihdr1->list);
			kfree(midihdr1->data);
			kfree(midihdr1);
			kfree(midi_dev);
			return -ENODEV;
		}
	}

	if (file->f_mode & FMODE_WRITE) {
		struct midi_openinfo dsCardMidiOpenInfo;

		dsCardMidiOpenInfo.refdata = (unsigned long) midi_dev;

		if (emu10k1_mpuout_open(card, &dsCardMidiOpenInfo) < 0) {
			ERROR();
			kfree(midi_dev);
			return -ENODEV;
		}
	}

	file->private_data = (void *) midi_dev;

	card->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE);

	mutex_unlock(&card->open_sem);

	return nonseekable_open(inode, file);
}

static int emu10k1_midi_release(struct inode *inode, struct file *file)
{
	struct emu10k1_mididevice *midi_dev = (struct emu10k1_mididevice *) file->private_data;
	struct emu10k1_card *card;

	lock_kernel();

	card = midi_dev->card;
	DPF(2, "emu10k1_midi_release()\n");

	if (file->f_mode & FMODE_WRITE) {
		if (!(file->f_flags & O_NONBLOCK)) {

			while (!signal_pending(current) && (card->mpuout->firstmidiq != NULL)) {
				DPF(4, "Cannot close - buffers not empty\n");

				interruptible_sleep_on(&midi_dev->oWait);

			}
		}

		emu10k1_mpuout_close(card);
	}

	if (file->f_mode & FMODE_READ) {
		struct midi_hdr *midihdr;

		if (midi_dev->mistate == MIDIIN_STATE_STARTED) {
			emu10k1_mpuin_stop(card);
			midi_dev->mistate = MIDIIN_STATE_STOPPED;
		}

		emu10k1_mpuin_reset(card);
		emu10k1_mpuin_close(card);

		while (!list_empty(&midi_dev->mid_hdrs)) {
			midihdr = list_entry(midi_dev->mid_hdrs.next, struct midi_hdr, list);

			list_del(midi_dev->mid_hdrs.next);
			kfree(midihdr->data);
			kfree(midihdr);
		}
	}

	kfree(midi_dev);

	mutex_lock(&card->open_sem);
	card->open_mode &= ~((file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE));
	mutex_unlock(&card->open_sem);
	wake_up_interruptible(&card->open_wait);

	unlock_kernel();

	return 0;
}

static ssize_t emu10k1_midi_read(struct file *file, char __user *buffer, size_t count, loff_t * pos)
{
	struct emu10k1_mididevice *midi_dev = (struct emu10k1_mididevice *) file->private_data;
	ssize_t ret = 0;
	u16 cnt;
	unsigned long flags;

	DPD(4, "emu10k1_midi_read(), count %#x\n", (u32) count);

	if (!access_ok(VERIFY_WRITE, buffer, count))
		return -EFAULT;

	if (midi_dev->mistate == MIDIIN_STATE_STOPPED) {
		if (emu10k1_mpuin_start(midi_dev->card) < 0) {
			ERROR();
			return -EINVAL;
		}

		midi_dev->mistate = MIDIIN_STATE_STARTED;
	}

	while (count > 0) {
		cnt = MIDIIN_BUFLEN - midi_dev->ird;

		spin_lock_irqsave(&midi_spinlock, flags);

		if (midi_dev->icnt < cnt)
			cnt = midi_dev->icnt;

		spin_unlock_irqrestore(&midi_spinlock, flags);

		if (cnt > count)
			cnt = count;

		if (cnt <= 0) {
			if (file->f_flags & O_NONBLOCK)
				return ret ? ret : -EAGAIN;
			DPF(2, " Go to sleep...\n");

			interruptible_sleep_on(&midi_dev->iWait);

			if (signal_pending(current))
				return ret ? ret : -ERESTARTSYS;

			continue;
		}

		if (copy_to_user(buffer, midi_dev->iBuf + midi_dev->ird, cnt)) {
			ERROR();
			return ret ? ret : -EFAULT;
		}

		midi_dev->ird += cnt;
		midi_dev->ird %= MIDIIN_BUFLEN;

		spin_lock_irqsave(&midi_spinlock, flags);

		midi_dev->icnt -= cnt;

		spin_unlock_irqrestore(&midi_spinlock, flags);

		count -= cnt;
		buffer += cnt;
		ret += cnt;

		if (midi_dev->icnt == 0)
			break;
	}

	return ret;
}

static ssize_t emu10k1_midi_write(struct file *file, const char __user *buffer, size_t count, loff_t * pos)
{
	struct emu10k1_mididevice *midi_dev = (struct emu10k1_mididevice *) file->private_data;
	struct midi_hdr *midihdr;
	unsigned long flags;

	DPD(4, "emu10k1_midi_write(), count=%#x\n", (u32) count);

	if (!access_ok(VERIFY_READ, buffer, count))
		return -EFAULT;

	if ((midihdr = (struct midi_hdr *) kmalloc(sizeof(struct midi_hdr), GFP_KERNEL)) == NULL)
		return -EINVAL;

	midihdr->bufferlength = count;
	midihdr->bytesrecorded = 0;
	midihdr->flags = 0;

	midihdr->data = kmalloc(count, GFP_KERNEL);
	if (!midihdr->data) {
		ERROR();
		kfree(midihdr);
		return -EINVAL;
	}

	if (copy_from_user(midihdr->data, buffer, count)) {
		kfree(midihdr->data);
		kfree(midihdr);
		return -EFAULT;
	}

	spin_lock_irqsave(&midi_spinlock, flags);

	if (emu10k1_mpuout_add_buffer(midi_dev->card, midihdr) < 0) {
		ERROR();
		kfree(midihdr->data);
		kfree(midihdr);
		spin_unlock_irqrestore(&midi_spinlock, flags);
		return -EINVAL;
	}

	spin_unlock_irqrestore(&midi_spinlock, flags);

	return count;
}

static unsigned int emu10k1_midi_poll(struct file *file, struct poll_table_struct *wait)
{
	struct emu10k1_mididevice *midi_dev = (struct emu10k1_mididevice *) file->private_data;
	unsigned long flags;
	unsigned int mask = 0;

	DPF(4, "emu10k1_midi_poll() called\n");

	if (file->f_mode & FMODE_WRITE)
		poll_wait(file, &midi_dev->oWait, wait);

	if (file->f_mode & FMODE_READ)
		poll_wait(file, &midi_dev->iWait, wait);

	spin_lock_irqsave(&midi_spinlock, flags);

	if (file->f_mode & FMODE_WRITE)
		mask |= POLLOUT | POLLWRNORM;

	if (file->f_mode & FMODE_READ) {
		if (midi_dev->mistate == MIDIIN_STATE_STARTED)
			if (midi_dev->icnt > 0)
				mask |= POLLIN | POLLRDNORM;
	}

	spin_unlock_irqrestore(&midi_spinlock, flags);

	return mask;
}

int emu10k1_midi_callback(unsigned long msg, unsigned long refdata, unsigned long *pmsg)
{
	struct emu10k1_mididevice *midi_dev = (struct emu10k1_mididevice *) refdata;
	struct midi_hdr *midihdr = NULL;
	unsigned long flags;
	int i;

	DPF(4, "emu10k1_midi_callback()\n");

	spin_lock_irqsave(&midi_spinlock, flags);

	switch (msg) {
	case ICARDMIDI_OUTLONGDATA:
		midihdr = (struct midi_hdr *) pmsg[2];

		kfree(midihdr->data);
		kfree(midihdr);
		wake_up_interruptible(&midi_dev->oWait);

		break;

	case ICARDMIDI_INLONGDATA:
		midihdr = (struct midi_hdr *) pmsg[2];

		for (i = 0; i < midihdr->bytesrecorded; i++) {
			midi_dev->iBuf[midi_dev->iwr++] = midihdr->data[i];
			midi_dev->iwr %= MIDIIN_BUFLEN;
		}

		midi_dev->icnt += midihdr->bytesrecorded;

		if (midi_dev->mistate == MIDIIN_STATE_STARTED) {
			init_midi_hdr(midihdr);
			emu10k1_mpuin_add_buffer(midi_dev->card->mpuin, midihdr);
			wake_up_interruptible(&midi_dev->iWait);
		}
		break;

	case ICARDMIDI_INDATA:
		{
			u8 *pBuf = (u8 *) & pmsg[1];
			u16 bytesvalid = pmsg[2];

			for (i = 0; i < bytesvalid; i++) {
				midi_dev->iBuf[midi_dev->iwr++] = pBuf[i];
				midi_dev->iwr %= MIDIIN_BUFLEN;
			}

			midi_dev->icnt += bytesvalid;
		}

		wake_up_interruptible(&midi_dev->iWait);
		break;

	default:		/* Unknown message */
		spin_unlock_irqrestore(&midi_spinlock, flags);
		return -1;
	}

	spin_unlock_irqrestore(&midi_spinlock, flags);

	return 0;
}

/* MIDI file operations */
struct file_operations emu10k1_midi_fops = {
	.owner		= THIS_MODULE,
	.read		= emu10k1_midi_read,
	.write		= emu10k1_midi_write,
	.poll		= emu10k1_midi_poll,
	.open		= emu10k1_midi_open,
	.release	= emu10k1_midi_release,
};


#ifdef EMU10K1_SEQUENCER

/* functions used for sequencer access */

int emu10k1_seq_midi_open(int dev, int mode,
				void (*input) (int dev, unsigned char data),
				void (*output) (int dev))
{
	struct emu10k1_card *card;
	struct midi_openinfo dsCardMidiOpenInfo;
	struct emu10k1_mididevice *midi_dev;

	if (midi_devs[dev] == NULL || midi_devs[dev]->devc == NULL)
		return -EINVAL;

	card = midi_devs[dev]->devc;

	if (card->open_mode)		/* card is opened native */
		return -EBUSY;
			
	DPF(2, "emu10k1_seq_midi_open()\n");
	
	if ((midi_dev = (struct emu10k1_mididevice *) kmalloc(sizeof(*midi_dev), GFP_KERNEL)) == NULL)
		return -EINVAL;

	midi_dev->card = card;
	midi_dev->mistate = MIDIIN_STATE_STOPPED;
	init_waitqueue_head(&midi_dev->oWait);
	init_waitqueue_head(&midi_dev->iWait);
	midi_dev->ird = 0;
	midi_dev->iwr = 0;
	midi_dev->icnt = 0;
	INIT_LIST_HEAD(&midi_dev->mid_hdrs);

	dsCardMidiOpenInfo.refdata = (unsigned long) midi_dev;

	if (emu10k1_mpuout_open(card, &dsCardMidiOpenInfo) < 0) {
		ERROR();
		return -ENODEV;
	}

	card->seq_mididev = midi_dev;
		
	return 0;
}

void emu10k1_seq_midi_close(int dev)
{
	struct emu10k1_card *card;

	DPF(2, "emu10k1_seq_midi_close()\n");
	if (midi_devs[dev] == NULL || midi_devs[dev]->devc == NULL)
		return;

	card = midi_devs[dev]->devc;
	emu10k1_mpuout_close(card);

	kfree(card->seq_mididev);
	card->seq_mididev = NULL;
}

int emu10k1_seq_midi_out(int dev, unsigned char midi_byte)
{
	struct emu10k1_card *card;
	struct midi_hdr *midihdr;
	unsigned long flags;

	if (midi_devs[dev] == NULL || midi_devs[dev]->devc == NULL)
		return -EINVAL;

	card = midi_devs[dev]->devc;

	if ((midihdr = (struct midi_hdr *) kmalloc(sizeof(struct midi_hdr), GFP_KERNEL)) == NULL)
		return -EINVAL;

	midihdr->bufferlength = 1;
	midihdr->bytesrecorded = 0;
	midihdr->flags = 0;

	midihdr->data = kmalloc(1, GFP_KERNEL);
	if (!midihdr->data) {
		ERROR();
		kfree(midihdr);
		return -EINVAL;
	}

	*(midihdr->data) = midi_byte;
	
	spin_lock_irqsave(&midi_spinlock, flags);

	if (emu10k1_mpuout_add_buffer(card, midihdr) < 0) {
		ERROR();
		kfree(midihdr->data);
		kfree(midihdr);
		spin_unlock_irqrestore(&midi_spinlock, flags);
		return -EINVAL;
	}

	spin_unlock_irqrestore(&midi_spinlock, flags);

	return 1;
}

int emu10k1_seq_midi_start_read(int dev)
{
	return 0;
}

int emu10k1_seq_midi_end_read(int dev)
{
	return 0;
}

void emu10k1_seq_midi_kick(int dev)
{
}

int emu10k1_seq_midi_buffer_status(int dev)
{
	int count;
	struct midi_queue *queue;
	struct emu10k1_card *card;

	if (midi_devs[dev] == NULL || midi_devs[dev]->devc == NULL)
		return -EINVAL;

	count = 0;

	card = midi_devs[dev]->devc;
	queue = card->mpuout->firstmidiq;

	while (queue != NULL) {
		count++;
		if (queue == card->mpuout->lastmidiq)
			break;

		queue = queue->next;
	}

	return count;
}

#endif

