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

#include "motu.h"

#define	READY_TIMEOUT_MS	200

#define ISOC_COMM_CONTROL_OFFSET		0x0b00
#define  ISOC_COMM_CONTROL_MASK			0xffff0000
#define  CHANGE_RX_ISOC_COMM_STATE		0x80000000
#define  RX_ISOC_COMM_IS_ACTIVATED		0x40000000
#define  RX_ISOC_COMM_CHANNEL_MASK		0x3f000000
#define  RX_ISOC_COMM_CHANNEL_SHIFT		24
#define  CHANGE_TX_ISOC_COMM_STATE		0x00800000
#define  TX_ISOC_COMM_IS_ACTIVATED		0x00400000
#define  TX_ISOC_COMM_CHANNEL_MASK		0x003f0000
#define  TX_ISOC_COMM_CHANNEL_SHIFT		16

#define PACKET_FORMAT_OFFSET			0x0b10
#define  TX_PACKET_EXCLUDE_DIFFERED_DATA_CHUNKS	0x00000080
#define  RX_PACKET_EXCLUDE_DIFFERED_DATA_CHUNKS	0x00000040
#define  TX_PACKET_TRANSMISSION_SPEED_MASK	0x0000000f

static int keep_resources(struct snd_motu *motu, unsigned int rate,
			  struct amdtp_stream *stream)
{
	struct fw_iso_resources *resources;
	struct snd_motu_packet_format *packet_format;
	unsigned int midi_ports = 0;
	int err;

	if (stream == &motu->rx_stream) {
		resources = &motu->rx_resources;
		packet_format = &motu->rx_packet_formats;

		if ((motu->spec->flags & SND_MOTU_SPEC_RX_MIDI_2ND_Q) ||
		    (motu->spec->flags & SND_MOTU_SPEC_RX_MIDI_3RD_Q))
			midi_ports = 1;
	} else {
		resources = &motu->tx_resources;
		packet_format = &motu->tx_packet_formats;

		if ((motu->spec->flags & SND_MOTU_SPEC_TX_MIDI_2ND_Q) ||
		    (motu->spec->flags & SND_MOTU_SPEC_TX_MIDI_3RD_Q))
			midi_ports = 1;
	}

	err = amdtp_motu_set_parameters(stream, rate, midi_ports,
					packet_format);
	if (err < 0)
		return err;

	return fw_iso_resources_allocate(resources,
				amdtp_stream_get_max_payload(stream),
				fw_parent_device(motu->unit)->max_speed);
}

static int begin_session(struct snd_motu *motu)
{
	__be32 reg;
	u32 data;
	int err;

	// Configure the unit to start isochronous communication.
	err = snd_motu_transaction_read(motu, ISOC_COMM_CONTROL_OFFSET, &reg,
					sizeof(reg));
	if (err < 0)
		return err;
	data = be32_to_cpu(reg) & ~ISOC_COMM_CONTROL_MASK;

	data |= CHANGE_RX_ISOC_COMM_STATE | RX_ISOC_COMM_IS_ACTIVATED |
		(motu->rx_resources.channel << RX_ISOC_COMM_CHANNEL_SHIFT) |
		CHANGE_TX_ISOC_COMM_STATE | TX_ISOC_COMM_IS_ACTIVATED |
		(motu->tx_resources.channel << TX_ISOC_COMM_CHANNEL_SHIFT);

	reg = cpu_to_be32(data);
	return snd_motu_transaction_write(motu, ISOC_COMM_CONTROL_OFFSET, &reg,
					  sizeof(reg));
}

static void finish_session(struct snd_motu *motu)
{
	__be32 reg;
	u32 data;
	int err;

	err = snd_motu_protocol_switch_fetching_mode(motu, false);
	if (err < 0)
		return;

	err = snd_motu_transaction_read(motu, ISOC_COMM_CONTROL_OFFSET, &reg,
					sizeof(reg));
	if (err < 0)
		return;
	data = be32_to_cpu(reg);

	data &= ~(RX_ISOC_COMM_IS_ACTIVATED | TX_ISOC_COMM_IS_ACTIVATED);
	data |= CHANGE_RX_ISOC_COMM_STATE | CHANGE_TX_ISOC_COMM_STATE;

	reg = cpu_to_be32(data);
	snd_motu_transaction_write(motu, ISOC_COMM_CONTROL_OFFSET, &reg,
				   sizeof(reg));
}

int snd_motu_stream_cache_packet_formats(struct snd_motu *motu)
{
	int err;

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

	if (motu->spec->flags & SND_MOTU_SPEC_TX_MIDI_2ND_Q) {
		motu->tx_packet_formats.midi_flag_offset = 4;
		motu->tx_packet_formats.midi_byte_offset = 6;
	} else if (motu->spec->flags & SND_MOTU_SPEC_TX_MIDI_3RD_Q) {
		motu->tx_packet_formats.midi_flag_offset = 8;
		motu->tx_packet_formats.midi_byte_offset = 7;
	}

	if (motu->spec->flags & SND_MOTU_SPEC_RX_MIDI_2ND_Q) {
		motu->rx_packet_formats.midi_flag_offset = 4;
		motu->rx_packet_formats.midi_byte_offset = 6;
	} else if (motu->spec->flags & SND_MOTU_SPEC_RX_MIDI_3RD_Q) {
		motu->rx_packet_formats.midi_flag_offset = 8;
		motu->rx_packet_formats.midi_byte_offset = 7;
	}

	return 0;
}

int snd_motu_stream_reserve_duplex(struct snd_motu *motu, unsigned int rate,
				   unsigned int frames_per_period,
				   unsigned int frames_per_buffer)
{
	unsigned int curr_rate;
	int err;

	err = snd_motu_protocol_get_clock_rate(motu, &curr_rate);
	if (err < 0)
		return err;
	if (rate == 0)
		rate = curr_rate;

	if (motu->substreams_counter == 0 || curr_rate != rate) {
		amdtp_domain_stop(&motu->domain);
		finish_session(motu);

		fw_iso_resources_free(&motu->tx_resources);
		fw_iso_resources_free(&motu->rx_resources);

		kfree(motu->cache.event_offsets);
		motu->cache.event_offsets = NULL;

		err = snd_motu_protocol_set_clock_rate(motu, rate);
		if (err < 0) {
			dev_err(&motu->unit->device,
				"fail to set sampling rate: %d\n", err);
			return err;
		}

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

		err = keep_resources(motu, rate, &motu->tx_stream);
		if (err < 0)
			return err;

		err = keep_resources(motu, rate, &motu->rx_stream);
		if (err < 0) {
			fw_iso_resources_free(&motu->tx_resources);
			return err;
		}

		err = amdtp_domain_set_events_per_period(&motu->domain,
					frames_per_period, frames_per_buffer);
		if (err < 0) {
			fw_iso_resources_free(&motu->tx_resources);
			fw_iso_resources_free(&motu->rx_resources);
			return err;
		}

		motu->cache.size = motu->tx_stream.syt_interval * frames_per_buffer;
		motu->cache.event_offsets = kcalloc(motu->cache.size, sizeof(*motu->cache.event_offsets),
						  GFP_KERNEL);
		if (!motu->cache.event_offsets) {
			fw_iso_resources_free(&motu->tx_resources);
			fw_iso_resources_free(&motu->rx_resources);
			return -ENOMEM;
		}
	}

	return 0;
}

static int ensure_packet_formats(struct snd_motu *motu)
{
	__be32 reg;
	u32 data;
	int err;

	err = snd_motu_transaction_read(motu, PACKET_FORMAT_OFFSET, &reg,
					sizeof(reg));
	if (err < 0)
		return err;
	data = be32_to_cpu(reg);

	data &= ~(TX_PACKET_EXCLUDE_DIFFERED_DATA_CHUNKS |
		  RX_PACKET_EXCLUDE_DIFFERED_DATA_CHUNKS|
		  TX_PACKET_TRANSMISSION_SPEED_MASK);
	if (motu->spec->tx_fixed_pcm_chunks[0] == motu->tx_packet_formats.pcm_chunks[0])
		data |= TX_PACKET_EXCLUDE_DIFFERED_DATA_CHUNKS;
	if (motu->spec->rx_fixed_pcm_chunks[0] == motu->rx_packet_formats.pcm_chunks[0])
		data |= RX_PACKET_EXCLUDE_DIFFERED_DATA_CHUNKS;
	data |= fw_parent_device(motu->unit)->max_speed;

	reg = cpu_to_be32(data);
	return snd_motu_transaction_write(motu, PACKET_FORMAT_OFFSET, &reg,
					  sizeof(reg));
}

int snd_motu_stream_start_duplex(struct snd_motu *motu)
{
	unsigned int generation = motu->rx_resources.generation;
	int err = 0;

	if (motu->substreams_counter == 0)
		return 0;

	if (amdtp_streaming_error(&motu->rx_stream) ||
	    amdtp_streaming_error(&motu->tx_stream)) {
		amdtp_domain_stop(&motu->domain);
		finish_session(motu);
	}

	if (generation != fw_parent_device(motu->unit)->card->generation) {
		err = fw_iso_resources_update(&motu->rx_resources);
		if (err < 0)
			return err;

		err = fw_iso_resources_update(&motu->tx_resources);
		if (err < 0)
			return err;
	}

	if (!amdtp_stream_running(&motu->rx_stream)) {
		int spd = fw_parent_device(motu->unit)->max_speed;

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

		if (motu->spec->flags & SND_MOTU_SPEC_REGISTER_DSP) {
			err = snd_motu_register_dsp_message_parser_init(motu);
			if (err < 0)
				return err;
		} else if (motu->spec->flags & SND_MOTU_SPEC_COMMAND_DSP) {
			err = snd_motu_command_dsp_message_parser_init(motu, motu->tx_stream.sfc);
			if (err < 0)
				return err;
		}

		err = begin_session(motu);
		if (err < 0) {
			dev_err(&motu->unit->device,
				"fail to start isochronous comm: %d\n", err);
			goto stop_streams;
		}

		err = amdtp_domain_add_stream(&motu->domain, &motu->tx_stream,
					      motu->tx_resources.channel, spd);
		if (err < 0)
			goto stop_streams;

		err = amdtp_domain_add_stream(&motu->domain, &motu->rx_stream,
					      motu->rx_resources.channel, spd);
		if (err < 0)
			goto stop_streams;

		motu->cache.tail = 0;
		motu->cache.tx_cycle_count = UINT_MAX;
		motu->cache.head = 0;
		motu->cache.rx_cycle_count = UINT_MAX;

		// NOTE: The device requires both of replay; the sequence of the number of data
		// blocks per packet, and the sequence of source packet header per data block as
		// presentation time.
		err = amdtp_domain_start(&motu->domain, 0, true, false);
		if (err < 0)
			goto stop_streams;

		if (!amdtp_domain_wait_ready(&motu->domain, READY_TIMEOUT_MS)) {
			err = -ETIMEDOUT;
			goto stop_streams;
		}

		err = snd_motu_protocol_switch_fetching_mode(motu, true);
		if (err < 0) {
			dev_err(&motu->unit->device,
				"fail to enable frame fetching: %d\n", err);
			goto stop_streams;
		}
	}

	return 0;

stop_streams:
	amdtp_domain_stop(&motu->domain);
	finish_session(motu);
	return err;
}

void snd_motu_stream_stop_duplex(struct snd_motu *motu)
{
	if (motu->substreams_counter == 0) {
		amdtp_domain_stop(&motu->domain);
		finish_session(motu);

		fw_iso_resources_free(&motu->tx_resources);
		fw_iso_resources_free(&motu->rx_resources);

		kfree(motu->cache.event_offsets);
		motu->cache.event_offsets = NULL;
	}
}

static int init_stream(struct snd_motu *motu, struct amdtp_stream *s)
{
	struct fw_iso_resources *resources;
	enum amdtp_stream_direction dir;
	int err;

	if (s == &motu->tx_stream) {
		resources = &motu->tx_resources;
		dir = AMDTP_IN_STREAM;
	} else {
		resources = &motu->rx_resources;
		dir = AMDTP_OUT_STREAM;
	}

	err = fw_iso_resources_init(resources, motu->unit);
	if (err < 0)
		return err;

	err = amdtp_motu_init(s, motu->unit, dir, motu->spec, &motu->cache);
	if (err < 0)
		fw_iso_resources_destroy(resources);

	return err;
}

static void destroy_stream(struct snd_motu *motu, struct amdtp_stream *s)
{
	amdtp_stream_destroy(s);

	if (s == &motu->tx_stream)
		fw_iso_resources_destroy(&motu->tx_resources);
	else
		fw_iso_resources_destroy(&motu->rx_resources);
}

int snd_motu_stream_init_duplex(struct snd_motu *motu)
{
	int err;

	err = init_stream(motu, &motu->tx_stream);
	if (err < 0)
		return err;

	err = init_stream(motu, &motu->rx_stream);
	if (err < 0) {
		destroy_stream(motu, &motu->tx_stream);
		return err;
	}

	err = amdtp_domain_init(&motu->domain);
	if (err < 0) {
		destroy_stream(motu, &motu->tx_stream);
		destroy_stream(motu, &motu->rx_stream);
	}

	return err;
}

// This function should be called before starting streams or after stopping
// streams.
void snd_motu_stream_destroy_duplex(struct snd_motu *motu)
{
	amdtp_domain_destroy(&motu->domain);

	destroy_stream(motu, &motu->rx_stream);
	destroy_stream(motu, &motu->tx_stream);

	motu->substreams_counter = 0;
}

static void motu_lock_changed(struct snd_motu *motu)
{
	motu->dev_lock_changed = true;
	wake_up(&motu->hwdep_wait);
}

int snd_motu_stream_lock_try(struct snd_motu *motu)
{
	int err;

	spin_lock_irq(&motu->lock);

	if (motu->dev_lock_count < 0) {
		err = -EBUSY;
		goto out;
	}

	if (motu->dev_lock_count++ == 0)
		motu_lock_changed(motu);
	err = 0;
out:
	spin_unlock_irq(&motu->lock);
	return err;
}

void snd_motu_stream_lock_release(struct snd_motu *motu)
{
	spin_lock_irq(&motu->lock);

	if (WARN_ON(motu->dev_lock_count <= 0))
		goto out;

	if (--motu->dev_lock_count == 0)
		motu_lock_changed(motu);
out:
	spin_unlock_irq(&motu->lock);
}
