/*
 * sound/oss/sb_midi.c
 *
 * The low level driver for the Sound Blaster DS chips.
 *
 *
 * 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.
 */

#include <linux/spinlock.h>
#include <linux/slab.h>

#include "sound_config.h"

#include "sb.h"
#undef SB_TEST_IRQ

/*
 * 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 sb_midi_open(int dev, int mode,
	     void            (*input) (int dev, unsigned char data),
	     void            (*output) (int dev)
)
{
	sb_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->irq_mode = IMODE_MIDI;
	devc->midi_broken = 0;

	sb_dsp_reset(devc);

	if (!sb_dsp_command(devc, 0x35))	/* Start MIDI UART mode */
	{
		  devc->opened = 0;
		  return -EIO;
	}
	devc->intr_active = 1;

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

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

	if (devc == NULL)
		return;

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

static int sb_midi_out(int dev, unsigned char midi_byte)
{
	sb_devc *devc = midi_devs[dev]->devc;

	if (devc == NULL)
		return 1;

	if (devc->midi_broken)
		return 1;

	if (!sb_dsp_command(devc, midi_byte))
	{
		devc->midi_broken = 1;
		return 1;
	}
	return 1;
}

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

static int sb_midi_end_read(int dev)
{
	sb_devc *devc = midi_devs[dev]->devc;

	if (devc == NULL)
		return -ENXIO;

	sb_dsp_reset(devc);
	devc->intr_active = 0;
	return 0;
}

static int sb_midi_ioctl(int dev, unsigned cmd, void __user *arg)
{
        return -EINVAL;
}

void sb_midi_interrupt(sb_devc * devc)
{
	unsigned long   flags;
	unsigned char   data;

	if (devc == NULL)
		return;

	spin_lock_irqsave(&devc->lock, flags);

	data = inb(DSP_READ);
	if (devc->input_opened)
		devc->midi_input_intr(devc->my_mididev, data);

	spin_unlock_irqrestore(&devc->lock, flags);
}

#define MIDI_SYNTH_NAME	"Sound Blaster Midi"
#define MIDI_SYNTH_CAPS	0
#include "midi_synth.h"

static struct midi_operations sb_midi_operations =
{
	.owner		= THIS_MODULE,
	.info		= {"Sound Blaster", 0, 0, SNDCARD_SB},
	.converter	= &std_midi_synth,
	.in_info	= {0},
	.open		= sb_midi_open,
	.close		= sb_midi_close,
	.ioctl		= sb_midi_ioctl,
	.outputc	= sb_midi_out,
	.start_read	= sb_midi_start_read,
	.end_read	= sb_midi_end_read,
};

void sb_dsp_midi_init(sb_devc * devc, struct module *owner)
{
	int dev;

	if (devc->model < 2)	/* No MIDI support for SB 1.x */
		return;

	dev = sound_alloc_mididev();

	if (dev == -1)
	{
		printk(KERN_ERR "sb_midi: too many MIDI devices detected\n");
		return;
	}
	std_midi_synth.midi_dev = devc->my_mididev = dev;
	midi_devs[dev] = kmalloc(sizeof(struct midi_operations), GFP_KERNEL);
	if (midi_devs[dev] == NULL)
	{
		printk(KERN_WARNING "Sound Blaster:  failed to allocate MIDI memory.\n");
		sound_unload_mididev(dev);
		  return;
	}
	memcpy((char *) midi_devs[dev], (char *) &sb_midi_operations,
	       sizeof(struct midi_operations));

	if (owner)
			midi_devs[dev]->owner = owner;
	
	midi_devs[dev]->devc = devc;


	midi_devs[dev]->converter = kmalloc(sizeof(struct synth_operations), GFP_KERNEL);
	if (midi_devs[dev]->converter == NULL)
	{
		  printk(KERN_WARNING "Sound Blaster:  failed to allocate MIDI memory.\n");
		  kfree(midi_devs[dev]);
		  sound_unload_mididev(dev);
		  return;
	}
	memcpy((char *) midi_devs[dev]->converter, (char *) &std_midi_synth,
	       sizeof(struct synth_operations));

	midi_devs[dev]->converter->id = "SBMIDI";
	sequencer_init();
}
