/*
 * digi00x-midi.h - a part of driver for Digidesign Digi 002/003 family
 *
 * Copyright (c) 2014-2015 Takashi Sakamoto
 *
 * Licensed under the terms of the GNU General Public License, version 2.
 */

#include "digi00x.h"

static int midi_open(struct snd_rawmidi_substream *substream)
{
	struct snd_dg00x *dg00x = substream->rmidi->private_data;
	int err;

	err = snd_dg00x_stream_lock_try(dg00x);
	if (err < 0)
		return err;

	mutex_lock(&dg00x->mutex);
	dg00x->substreams_counter++;
	err = snd_dg00x_stream_start_duplex(dg00x, 0);
	mutex_unlock(&dg00x->mutex);
	if (err < 0)
		snd_dg00x_stream_lock_release(dg00x);

	return err;
}

static int midi_close(struct snd_rawmidi_substream *substream)
{
	struct snd_dg00x *dg00x = substream->rmidi->private_data;

	mutex_lock(&dg00x->mutex);
	dg00x->substreams_counter--;
	snd_dg00x_stream_stop_duplex(dg00x);
	mutex_unlock(&dg00x->mutex);

	snd_dg00x_stream_lock_release(dg00x);
	return 0;
}

static void midi_capture_trigger(struct snd_rawmidi_substream *substream,
				 int up)
{
	struct snd_dg00x *dg00x = substream->rmidi->private_data;
	unsigned int port;
	unsigned long flags;

	if (substream->rmidi->device == 0)
		port = substream->number;
	else
		port = 2;

	spin_lock_irqsave(&dg00x->lock, flags);

	if (up)
		amdtp_dot_midi_trigger(&dg00x->tx_stream, port, substream);
	else
		amdtp_dot_midi_trigger(&dg00x->tx_stream, port, NULL);

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

static void midi_playback_trigger(struct snd_rawmidi_substream *substream,
				  int up)
{
	struct snd_dg00x *dg00x = substream->rmidi->private_data;
	unsigned int port;
	unsigned long flags;

	if (substream->rmidi->device == 0)
		port = substream->number;
	else
		port = 2;

	spin_lock_irqsave(&dg00x->lock, flags);

	if (up)
		amdtp_dot_midi_trigger(&dg00x->rx_stream, port, substream);
	else
		amdtp_dot_midi_trigger(&dg00x->rx_stream, port, NULL);

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

static void set_substream_names(struct snd_dg00x *dg00x,
				struct snd_rawmidi *rmidi, bool is_console)
{
	struct snd_rawmidi_substream *subs;
	struct snd_rawmidi_str *str;
	int i;

	for (i = 0; i < 2; ++i) {
		str = &rmidi->streams[i];

		list_for_each_entry(subs, &str->substreams, list) {
			if (!is_console) {
				snprintf(subs->name, sizeof(subs->name),
					 "%s MIDI %d",
					 dg00x->card->shortname,
					 subs->number + 1);
			} else {
				snprintf(subs->name, sizeof(subs->name),
					 "%s control",
					 dg00x->card->shortname);
			}
		}
	}
}

static int add_substream_pair(struct snd_dg00x *dg00x, unsigned int out_ports,
			      unsigned int in_ports, bool is_console)
{
	static const struct snd_rawmidi_ops capture_ops = {
		.open = midi_open,
		.close = midi_close,
		.trigger = midi_capture_trigger,
	};
	static const struct snd_rawmidi_ops playback_ops = {
		.open = midi_open,
		.close = midi_close,
		.trigger = midi_playback_trigger,
	};
	const char *label;
	struct snd_rawmidi *rmidi;
	int err;

	/* Add physical midi ports. */
	err = snd_rawmidi_new(dg00x->card, dg00x->card->driver, is_console,
			      out_ports, in_ports, &rmidi);
	if (err < 0)
		return err;
	rmidi->private_data = dg00x;

	if (!is_console)
		label = "%s control";
	else
		label = "%s MIDI";
	snprintf(rmidi->name, sizeof(rmidi->name), label,
		 dg00x->card->shortname);

	snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &playback_ops);
	snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &capture_ops);

	rmidi->info_flags |= SNDRV_RAWMIDI_INFO_INPUT |
			     SNDRV_RAWMIDI_INFO_OUTPUT |
			     SNDRV_RAWMIDI_INFO_DUPLEX;

	set_substream_names(dg00x, rmidi, is_console);

	return 0;
}

int snd_dg00x_create_midi_devices(struct snd_dg00x *dg00x)
{
	int err;

	/* Add physical midi ports. */
	err = add_substream_pair(dg00x, DOT_MIDI_OUT_PORTS, DOT_MIDI_IN_PORTS,
				 false);
	if (err < 0)
		return err;

	if (dg00x->is_console)
		err = add_substream_pair(dg00x, 1, 1, true);

	return err;
}
