/*
 * sound/sb_dsp.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 "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] = (struct midi_operations *)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 = (struct synth_operations *)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();
}
