/*
 * Linux driver for TerraTec DMX 6Fire USB
 *
 * Rawmidi driver
 *
 * Author:	Torsten Schenk <torsten.schenk@zoho.com>
 * Created:	Jan 01, 2011
 * Version:	0.3.0
 * Copyright:	(C) Torsten Schenk
 *
 * 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.
 */

#include <sound/rawmidi.h>

#include "midi.h"
#include "chip.h"
#include "comm.h"

static void usb6fire_midi_out_handler(struct urb *urb)
{
	struct midi_runtime *rt = urb->context;
	int ret;
	unsigned long flags;

	spin_lock_irqsave(&rt->out_lock, flags);

	if (rt->out) {
		ret = snd_rawmidi_transmit(rt->out, rt->out_buffer + 4,
				MIDI_BUFSIZE - 4);
		if (ret > 0) { /* more data available, send next packet */
			rt->out_buffer[1] = ret + 2;
			rt->out_buffer[3] = rt->out_serial++;
			urb->transfer_buffer_length = ret + 4;

			ret = usb_submit_urb(urb, GFP_ATOMIC);
			if (ret < 0)
				snd_printk(KERN_ERR PREFIX "midi out urb "
						"submit failed: %d\n", ret);
		} else /* no more data to transmit */
			rt->out = NULL;
	}
	spin_unlock_irqrestore(&rt->out_lock, flags);
}

static void usb6fire_midi_in_received(
		struct midi_runtime *rt, u8 *data, int length)
{
	unsigned long flags;

	spin_lock_irqsave(&rt->in_lock, flags);
	if (rt->in)
		snd_rawmidi_receive(rt->in, data, length);
	spin_unlock_irqrestore(&rt->in_lock, flags);
}

static int usb6fire_midi_out_open(struct snd_rawmidi_substream *alsa_sub)
{
	return 0;
}

static int usb6fire_midi_out_close(struct snd_rawmidi_substream *alsa_sub)
{
	return 0;
}

static void usb6fire_midi_out_trigger(
		struct snd_rawmidi_substream *alsa_sub, int up)
{
	struct midi_runtime *rt = alsa_sub->rmidi->private_data;
	struct urb *urb = &rt->out_urb;
	__s8 ret;
	unsigned long flags;

	spin_lock_irqsave(&rt->out_lock, flags);
	if (up) { /* start transfer */
		if (rt->out) { /* we are already transmitting so just return */
			spin_unlock_irqrestore(&rt->out_lock, flags);
			return;
		}

		ret = snd_rawmidi_transmit(alsa_sub, rt->out_buffer + 4,
				MIDI_BUFSIZE - 4);
		if (ret > 0) {
			rt->out_buffer[1] = ret + 2;
			rt->out_buffer[3] = rt->out_serial++;
			urb->transfer_buffer_length = ret + 4;

			ret = usb_submit_urb(urb, GFP_ATOMIC);
			if (ret < 0)
				snd_printk(KERN_ERR PREFIX "midi out urb "
						"submit failed: %d\n", ret);
			else
				rt->out = alsa_sub;
		}
	} else if (rt->out == alsa_sub)
		rt->out = NULL;
	spin_unlock_irqrestore(&rt->out_lock, flags);
}

static void usb6fire_midi_out_drain(struct snd_rawmidi_substream *alsa_sub)
{
	struct midi_runtime *rt = alsa_sub->rmidi->private_data;
	int retry = 0;

	while (rt->out && retry++ < 100)
		msleep(10);
}

static int usb6fire_midi_in_open(struct snd_rawmidi_substream *alsa_sub)
{
	return 0;
}

static int usb6fire_midi_in_close(struct snd_rawmidi_substream *alsa_sub)
{
	return 0;
}

static void usb6fire_midi_in_trigger(
		struct snd_rawmidi_substream *alsa_sub, int up)
{
	struct midi_runtime *rt = alsa_sub->rmidi->private_data;
	unsigned long flags;

	spin_lock_irqsave(&rt->in_lock, flags);
	if (up)
		rt->in = alsa_sub;
	else
		rt->in = NULL;
	spin_unlock_irqrestore(&rt->in_lock, flags);
}

static struct snd_rawmidi_ops out_ops = {
	.open = usb6fire_midi_out_open,
	.close = usb6fire_midi_out_close,
	.trigger = usb6fire_midi_out_trigger,
	.drain = usb6fire_midi_out_drain
};

static struct snd_rawmidi_ops in_ops = {
	.open = usb6fire_midi_in_open,
	.close = usb6fire_midi_in_close,
	.trigger = usb6fire_midi_in_trigger
};

int __devinit usb6fire_midi_init(struct sfire_chip *chip)
{
	int ret;
	struct midi_runtime *rt = kzalloc(sizeof(struct midi_runtime),
			GFP_KERNEL);
	struct comm_runtime *comm_rt = chip->comm;

	if (!rt)
		return -ENOMEM;

	rt->chip = chip;
	rt->in_received = usb6fire_midi_in_received;
	rt->out_buffer[0] = 0x80; /* 'send midi' command */
	rt->out_buffer[1] = 0x00; /* size of data */
	rt->out_buffer[2] = 0x00; /* always 0 */
	spin_lock_init(&rt->in_lock);
	spin_lock_init(&rt->out_lock);

	comm_rt->init_urb(comm_rt, &rt->out_urb, rt->out_buffer, rt,
			usb6fire_midi_out_handler);

	ret = snd_rawmidi_new(chip->card, "6FireUSB", 0, 1, 1, &rt->instance);
	if (ret < 0) {
		kfree(rt);
		snd_printk(KERN_ERR PREFIX "unable to create midi.\n");
		return ret;
	}
	rt->instance->private_data = rt;
	strcpy(rt->instance->name, "DMX6FireUSB MIDI");
	rt->instance->info_flags = SNDRV_RAWMIDI_INFO_OUTPUT |
			SNDRV_RAWMIDI_INFO_INPUT |
			SNDRV_RAWMIDI_INFO_DUPLEX;
	snd_rawmidi_set_ops(rt->instance, SNDRV_RAWMIDI_STREAM_OUTPUT,
			&out_ops);
	snd_rawmidi_set_ops(rt->instance, SNDRV_RAWMIDI_STREAM_INPUT,
			&in_ops);

	chip->midi = rt;
	return 0;
}

void usb6fire_midi_abort(struct sfire_chip *chip)
{
	struct midi_runtime *rt = chip->midi;

	if (rt)
		usb_poison_urb(&rt->out_urb);
}

void usb6fire_midi_destroy(struct sfire_chip *chip)
{
	kfree(chip->midi);
	chip->midi = NULL;
}
