// SPDX-License-Identifier: GPL-2.0-only
/*
 * motu-midi.h - a part of driver for MOTU FireWire series
 *
 * Copyright (c) 2015-2017 Takashi Sakamoto <o-takashi@sakamocchi.jp>
 */
#include "motu.h"

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

	err = snd_motu_stream_lock_try(motu);
	if (err < 0)
		return err;

	mutex_lock(&motu->mutex);

	err = snd_motu_stream_reserve_duplex(motu, 0, 0, 0);
	if (err >= 0) {
		++motu->substreams_counter;
		err = snd_motu_stream_start_duplex(motu);
		if (err < 0)
			--motu->substreams_counter;
	}

	mutex_unlock(&motu->mutex);

	if (err < 0)
		snd_motu_stream_lock_release(motu);

	return err;
}

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

	mutex_lock(&motu->mutex);

	--motu->substreams_counter;
	snd_motu_stream_stop_duplex(motu);

	mutex_unlock(&motu->mutex);

	snd_motu_stream_lock_release(motu);
	return 0;
}

static void midi_capture_trigger(struct snd_rawmidi_substream *substrm, int up)
{
	struct snd_motu *motu = substrm->rmidi->private_data;
	unsigned long flags;

	spin_lock_irqsave(&motu->lock, flags);

	if (up)
		amdtp_motu_midi_trigger(&motu->tx_stream, substrm->number,
					substrm);
	else
		amdtp_motu_midi_trigger(&motu->tx_stream, substrm->number,
					NULL);

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

static void midi_playback_trigger(struct snd_rawmidi_substream *substrm, int up)
{
	struct snd_motu *motu = substrm->rmidi->private_data;
	unsigned long flags;

	spin_lock_irqsave(&motu->lock, flags);

	if (up)
		amdtp_motu_midi_trigger(&motu->rx_stream, substrm->number,
					substrm);
	else
		amdtp_motu_midi_trigger(&motu->rx_stream, substrm->number,
					NULL);

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

static void set_midi_substream_names(struct snd_motu *motu,
				     struct snd_rawmidi_str *str)
{
	struct snd_rawmidi_substream *subs;

	list_for_each_entry(subs, &str->substreams, list) {
		scnprintf(subs->name, sizeof(subs->name),
			  "%s MIDI %d", motu->card->shortname, subs->number + 1);
	}
}

int snd_motu_create_midi_devices(struct snd_motu *motu)
{
	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,
	};
	struct snd_rawmidi *rmidi;
	struct snd_rawmidi_str *str;
	int err;

	/* create midi ports */
	err = snd_rawmidi_new(motu->card, motu->card->driver, 0, 1, 1, &rmidi);
	if (err < 0)
		return err;

	snprintf(rmidi->name, sizeof(rmidi->name),
		 "%s MIDI", motu->card->shortname);
	rmidi->private_data = motu;

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

	snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT,
			    &capture_ops);
	str = &rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT];
	set_midi_substream_names(motu, str);

	snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
			    &playback_ops);
	str = &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT];
	set_midi_substream_names(motu, str);

	return 0;
}
