/*
 * sound/oss/v_midi.c
 *
 * The low level driver for the Sound Blaster DS chips.
 *
 *
 * Copyright (C) by Hannu Savolainen 1993-1996
 *
 * USS/Lite 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.
 * ??
 *
 * Changes
 *	Alan Cox		Modularisation, changed memory allocations
 *	Christoph Hellwig	Adapted to module_init/module_exit
 *
 * Status
 *	Untested
 */

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

#include "v_midi.h"

static vmidi_devc *v_devc[2] = { NULL, NULL};
static int midi1,midi2;
static void *midi_mem = NULL;

/*
 * The DSP channel can be used either for input or output. Variable
 * 'sb_irq_mode' will be set when the program calls read or write first time
 * after open. Current version doesn't support mode changes without closing
 * and reopening the device. Support for this feature may be implemented in a
 * future version of this driver.
 */


static int v_midi_open (int dev, int mode,
	      void            (*input) (int dev, unsigned char data),
	      void            (*output) (int dev)
)
{
	vmidi_devc *devc = midi_devs[dev]->devc;
	unsigned long flags;

	if (devc == NULL)
		return -(ENXIO);

	spin_lock_irqsave(&devc->lock,flags);
	if (devc->opened)
	{
		spin_unlock_irqrestore(&devc->lock,flags);
		return -(EBUSY);
	}
	devc->opened = 1;
	spin_unlock_irqrestore(&devc->lock,flags);

	devc->intr_active = 1;

	if (mode & OPEN_READ)
	{
		devc->input_opened = 1;
		devc->midi_input_intr = input;
	}

	return 0;
}

static void v_midi_close (int dev)
{
	vmidi_devc *devc = midi_devs[dev]->devc;
	unsigned long flags;

	if (devc == NULL)
		return;

	spin_lock_irqsave(&devc->lock,flags);
	devc->intr_active = 0;
	devc->input_opened = 0;
	devc->opened = 0;
	spin_unlock_irqrestore(&devc->lock,flags);
}

static int v_midi_out (int dev, unsigned char midi_byte)
{
	vmidi_devc *devc = midi_devs[dev]->devc;
	vmidi_devc *pdevc;

	if (devc == NULL)
		return -ENXIO;

	pdevc = midi_devs[devc->pair_mididev]->devc;
	if (pdevc->input_opened > 0){
		if (MIDIbuf_avail(pdevc->my_mididev) > 500)
			return 0;
		pdevc->midi_input_intr (pdevc->my_mididev, midi_byte);
	}
	return 1;
}

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

static int v_midi_end_read (int dev)
{
	vmidi_devc *devc = midi_devs[dev]->devc;
	if (devc == NULL)
		return -ENXIO;

	devc->intr_active = 0;
	return 0;
}

/* why -EPERM and not -EINVAL?? */

static inline int v_midi_ioctl (int dev, unsigned cmd, void __user *arg)
{
	return -EPERM;
}


#define MIDI_SYNTH_NAME	"Loopback MIDI"
#define MIDI_SYNTH_CAPS	SYNTH_CAP_INPUT

#include "midi_synth.h"

static struct midi_operations v_midi_operations =
{
	.owner		= THIS_MODULE,
	.info		= {"Loopback MIDI Port 1", 0, 0, SNDCARD_VMIDI},
	.converter	= &std_midi_synth,
	.in_info	= {0},
	.open		= v_midi_open,
	.close		= v_midi_close,
	.ioctl		= v_midi_ioctl,
	.outputc	= v_midi_out,
	.start_read	= v_midi_start_read,
	.end_read	= v_midi_end_read,
};

static struct midi_operations v_midi_operations2 =
{
	.owner		= THIS_MODULE,
	.info		= {"Loopback MIDI Port 2", 0, 0, SNDCARD_VMIDI},
	.converter	= &std_midi_synth,
	.in_info	= {0},
	.open		= v_midi_open,
	.close		= v_midi_close,
	.ioctl		= v_midi_ioctl,
	.outputc	= v_midi_out,
	.start_read	= v_midi_start_read,
	.end_read	= v_midi_end_read,
};

/*
 *	We kmalloc just one of these - it makes life simpler and the code
 *	cleaner and the memory handling far more efficient
 */
 
struct vmidi_memory
{
	/* Must be first */
	struct midi_operations m_ops[2];
	struct synth_operations s_ops[2];
	struct vmidi_devc v_ops[2];
};

static void __init attach_v_midi (struct address_info *hw_config)
{
	struct vmidi_memory *m;
	/* printk("Attaching v_midi device.....\n"); */

	midi1 = sound_alloc_mididev();
	if (midi1 == -1)
	{
		printk(KERN_ERR "v_midi: Too many midi devices detected\n");
		return;
	}
	
	m = kmalloc(sizeof(struct vmidi_memory), GFP_KERNEL);
	if (m == NULL)
	{
		printk(KERN_WARNING "Loopback MIDI: Failed to allocate memory\n");
		sound_unload_mididev(midi1);
		return;
	}
	
	midi_mem = m;
	
	midi_devs[midi1] = &m->m_ops[0];
	

	midi2 = sound_alloc_mididev();
	if (midi2 == -1)
	{
		printk (KERN_ERR "v_midi: Too many midi devices detected\n");
		kfree(m);
		sound_unload_mididev(midi1);
		return;
	}

	midi_devs[midi2] = &m->m_ops[1];

	/* printk("VMIDI1: %d   VMIDI2: %d\n",midi1,midi2); */

	/* for MIDI-1 */
	v_devc[0] = &m->v_ops[0];
	memcpy ((char *) midi_devs[midi1], (char *) &v_midi_operations,
		sizeof (struct midi_operations));

	v_devc[0]->my_mididev = midi1;
	v_devc[0]->pair_mididev = midi2;
	v_devc[0]->opened = v_devc[0]->input_opened = 0;
	v_devc[0]->intr_active = 0;
	v_devc[0]->midi_input_intr = NULL;
	spin_lock_init(&v_devc[0]->lock);

	midi_devs[midi1]->devc = v_devc[0];

	midi_devs[midi1]->converter = &m->s_ops[0];
	std_midi_synth.midi_dev = midi1;
	memcpy ((char *) midi_devs[midi1]->converter, (char *) &std_midi_synth,
		sizeof (struct synth_operations));
	midi_devs[midi1]->converter->id = "V_MIDI 1";

	/* for MIDI-2 */
	v_devc[1] = &m->v_ops[1];

	memcpy ((char *) midi_devs[midi2], (char *) &v_midi_operations2,
		sizeof (struct midi_operations));

	v_devc[1]->my_mididev = midi2;
	v_devc[1]->pair_mididev = midi1;
	v_devc[1]->opened = v_devc[1]->input_opened = 0;
	v_devc[1]->intr_active = 0;
	v_devc[1]->midi_input_intr = NULL;
	spin_lock_init(&v_devc[1]->lock);

	midi_devs[midi2]->devc = v_devc[1];
	midi_devs[midi2]->converter = &m->s_ops[1];

	std_midi_synth.midi_dev = midi2;
	memcpy ((char *) midi_devs[midi2]->converter, (char *) &std_midi_synth,
		sizeof (struct synth_operations));
	midi_devs[midi2]->converter->id = "V_MIDI 2";

	sequencer_init();
	/* printk("Attached v_midi device\n"); */
}

static inline int __init probe_v_midi(struct address_info *hw_config)
{
	return(1);	/* always OK */
}


static void __exit unload_v_midi(struct address_info *hw_config)
{
	sound_unload_mididev(midi1);
	sound_unload_mididev(midi2);
	kfree(midi_mem);
}

static struct address_info cfg; /* dummy */

static int __init init_vmidi(void)
{
	printk("MIDI Loopback device driver\n");
	if (!probe_v_midi(&cfg))
		return -ENODEV;
	attach_v_midi(&cfg);

	return 0;
}

static void __exit cleanup_vmidi(void)
{
	unload_v_midi(&cfg);
}

module_init(init_vmidi);
module_exit(cleanup_vmidi);
MODULE_LICENSE("GPL");
