/*
 **********************************************************************
 *     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 = 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 = 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 = 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 */
const 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 = 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 = 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

