/*
 * dice_stream.c - a part of driver for DICE based devices
 *
 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
 * Copyright (c) 2014 Takashi Sakamoto <o-takashi@sakamocchi.jp>
 *
 * Licensed under the terms of the GNU General Public License, version 2.
 */

#include "dice.h"

#define	CALLBACK_TIMEOUT	200

const unsigned int snd_dice_rates[SND_DICE_RATES_COUNT] = {
	/* mode 0 */
	[0] =  32000,
	[1] =  44100,
	[2] =  48000,
	/* mode 1 */
	[3] =  88200,
	[4] =  96000,
	/* mode 2 */
	[5] = 176400,
	[6] = 192000,
};

int snd_dice_stream_get_rate_mode(struct snd_dice *dice, unsigned int rate,
				  unsigned int *mode)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(snd_dice_rates); i++) {
		if (!(dice->clock_caps & BIT(i)))
			continue;
		if (snd_dice_rates[i] != rate)
			continue;

		*mode = (i - 1) / 2;
		return 0;
	}
	return -EINVAL;
}

static void release_resources(struct snd_dice *dice,
			      struct fw_iso_resources *resources)
{
	unsigned int channel;

	/* Reset channel number */
	channel = cpu_to_be32((u32)-1);
	if (resources == &dice->tx_resources)
		snd_dice_transaction_write_tx(dice, TX_ISOCHRONOUS,
					      &channel, 4);
	else
		snd_dice_transaction_write_rx(dice, RX_ISOCHRONOUS,
					      &channel, 4);

	fw_iso_resources_free(resources);
}

static int keep_resources(struct snd_dice *dice,
			  struct fw_iso_resources *resources,
			  unsigned int max_payload_bytes)
{
	unsigned int channel;
	int err;

	err = fw_iso_resources_allocate(resources, max_payload_bytes,
				fw_parent_device(dice->unit)->max_speed);
	if (err < 0)
		goto end;

	/* Set channel number */
	channel = cpu_to_be32(resources->channel);
	if (resources == &dice->tx_resources)
		err = snd_dice_transaction_write_tx(dice, TX_ISOCHRONOUS,
						    &channel, 4);
	else
		err = snd_dice_transaction_write_rx(dice, RX_ISOCHRONOUS,
						    &channel, 4);
	if (err < 0)
		release_resources(dice, resources);
end:
	return err;
}

static void stop_stream(struct snd_dice *dice, struct amdtp_stream *stream)
{
	amdtp_stream_pcm_abort(stream);
	amdtp_stream_stop(stream);

	if (stream == &dice->tx_stream)
		release_resources(dice, &dice->tx_resources);
	else
		release_resources(dice, &dice->rx_resources);
}

static int start_stream(struct snd_dice *dice, struct amdtp_stream *stream,
			unsigned int rate)
{
	struct fw_iso_resources *resources;
	unsigned int i, mode, pcm_chs, midi_ports;
	int err;

	err = snd_dice_stream_get_rate_mode(dice, rate, &mode);
	if (err < 0)
		goto end;
	if (stream == &dice->tx_stream) {
		resources = &dice->tx_resources;
		pcm_chs = dice->tx_channels[mode];
		midi_ports = dice->tx_midi_ports[mode];
	} else {
		resources = &dice->rx_resources;
		pcm_chs = dice->rx_channels[mode];
		midi_ports = dice->rx_midi_ports[mode];
	}

	/*
	 * At 176.4/192.0 kHz, Dice has a quirk to transfer two PCM frames in
	 * one data block of AMDTP packet. Thus sampling transfer frequency is
	 * a half of PCM sampling frequency, i.e. PCM frames at 192.0 kHz are
	 * transferred on AMDTP packets at 96 kHz. Two successive samples of a
	 * channel are stored consecutively in the packet. This quirk is called
	 * as 'Dual Wire'.
	 * For this quirk, blocking mode is required and PCM buffer size should
	 * be aligned to SYT_INTERVAL.
	 */
	if (mode > 1) {
		rate /= 2;
		pcm_chs *= 2;
		stream->double_pcm_frames = true;
	} else {
		stream->double_pcm_frames = false;
	}

	amdtp_stream_set_parameters(stream, rate, pcm_chs, midi_ports);
	if (mode > 1) {
		pcm_chs /= 2;

		for (i = 0; i < pcm_chs; i++) {
			stream->pcm_positions[i] = i * 2;
			stream->pcm_positions[i + pcm_chs] = i * 2 + 1;
		}
	}

	err = keep_resources(dice, resources,
			     amdtp_stream_get_max_payload(stream));
	if (err < 0) {
		dev_err(&dice->unit->device,
			"fail to keep isochronous resources\n");
		goto end;
	}

	err = amdtp_stream_start(stream, resources->channel,
				 fw_parent_device(dice->unit)->max_speed);
	if (err < 0)
		release_resources(dice, resources);
end:
	return err;
}

static int get_sync_mode(struct snd_dice *dice, enum cip_flags *sync_mode)
{
	u32 source;
	int err;

	err = snd_dice_transaction_get_clock_source(dice, &source);
	if (err < 0)
		goto end;

	switch (source) {
	/* So-called 'SYT Match' modes, sync_to_syt value of packets received */
	case CLOCK_SOURCE_ARX4:	/* in 4th stream */
	case CLOCK_SOURCE_ARX3:	/* in 3rd stream */
	case CLOCK_SOURCE_ARX2:	/* in 2nd stream */
		err = -ENOSYS;
		break;
	case CLOCK_SOURCE_ARX1:	/* in 1st stream, which this driver uses */
		*sync_mode = 0;
		break;
	default:
		*sync_mode = CIP_SYNC_TO_DEVICE;
		break;
	}
end:
	return err;
}

int snd_dice_stream_start_duplex(struct snd_dice *dice, unsigned int rate)
{
	struct amdtp_stream *master, *slave;
	unsigned int curr_rate;
	enum cip_flags sync_mode;
	int err = 0;

	if (dice->substreams_counter == 0)
		goto end;

	err = get_sync_mode(dice, &sync_mode);
	if (err < 0)
		goto end;
	if (sync_mode == CIP_SYNC_TO_DEVICE) {
		master = &dice->tx_stream;
		slave  = &dice->rx_stream;
	} else {
		master = &dice->rx_stream;
		slave  = &dice->tx_stream;
	}

	/* Some packet queueing errors. */
	if (amdtp_streaming_error(master) || amdtp_streaming_error(slave))
		stop_stream(dice, master);

	/* Stop stream if rate is different. */
	err = snd_dice_transaction_get_rate(dice, &curr_rate);
	if (err < 0) {
		dev_err(&dice->unit->device,
			"fail to get sampling rate\n");
		goto end;
	}
	if (rate == 0)
		rate = curr_rate;
	if (rate != curr_rate)
		stop_stream(dice, master);

	if (!amdtp_stream_running(master)) {
		stop_stream(dice, slave);
		snd_dice_transaction_clear_enable(dice);

		amdtp_stream_set_sync(sync_mode, master, slave);

		err = snd_dice_transaction_set_rate(dice, rate);
		if (err < 0) {
			dev_err(&dice->unit->device,
				"fail to set sampling rate\n");
			goto end;
		}

		/* Start both streams. */
		err = start_stream(dice, master, rate);
		if (err < 0) {
			dev_err(&dice->unit->device,
				"fail to start AMDTP master stream\n");
			goto end;
		}
		err = start_stream(dice, slave, rate);
		if (err < 0) {
			dev_err(&dice->unit->device,
				"fail to start AMDTP slave stream\n");
			stop_stream(dice, master);
			goto end;
		}
		err = snd_dice_transaction_set_enable(dice);
		if (err < 0) {
			dev_err(&dice->unit->device,
				"fail to enable interface\n");
			stop_stream(dice, master);
			stop_stream(dice, slave);
			goto end;
		}

		/* Wait first callbacks */
		if (!amdtp_stream_wait_callback(master, CALLBACK_TIMEOUT) ||
		    !amdtp_stream_wait_callback(slave, CALLBACK_TIMEOUT)) {
			snd_dice_transaction_clear_enable(dice);
			stop_stream(dice, master);
			stop_stream(dice, slave);
			err = -ETIMEDOUT;
		}
	}
end:
	return err;
}

void snd_dice_stream_stop_duplex(struct snd_dice *dice)
{
	if (dice->substreams_counter > 0)
		return;

	snd_dice_transaction_clear_enable(dice);

	stop_stream(dice, &dice->tx_stream);
	stop_stream(dice, &dice->rx_stream);
}

static int init_stream(struct snd_dice *dice, struct amdtp_stream *stream)
{
	int err;
	struct fw_iso_resources *resources;
	enum amdtp_stream_direction dir;

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

	err = fw_iso_resources_init(resources, dice->unit);
	if (err < 0)
		goto end;
	resources->channels_mask = 0x00000000ffffffffuLL;

	err = amdtp_stream_init(stream, dice->unit, dir, CIP_BLOCKING);
	if (err < 0) {
		amdtp_stream_destroy(stream);
		fw_iso_resources_destroy(resources);
	}
end:
	return err;
}

/*
 * This function should be called before starting streams or after stopping
 * streams.
 */
static void destroy_stream(struct snd_dice *dice, struct amdtp_stream *stream)
{
	struct fw_iso_resources *resources;

	if (stream == &dice->tx_stream)
		resources = &dice->tx_resources;
	else
		resources = &dice->rx_resources;

	amdtp_stream_destroy(stream);
	fw_iso_resources_destroy(resources);
}

int snd_dice_stream_init_duplex(struct snd_dice *dice)
{
	int err;

	dice->substreams_counter = 0;

	err = init_stream(dice, &dice->tx_stream);
	if (err < 0)
		goto end;

	err = init_stream(dice, &dice->rx_stream);
	if (err < 0)
		destroy_stream(dice, &dice->tx_stream);
end:
	return err;
}

void snd_dice_stream_destroy_duplex(struct snd_dice *dice)
{
	snd_dice_transaction_clear_enable(dice);

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

	dice->substreams_counter = 0;
}

void snd_dice_stream_update_duplex(struct snd_dice *dice)
{
	/*
	 * On a bus reset, the DICE firmware disables streaming and then goes
	 * off contemplating its own navel for hundreds of milliseconds before
	 * it can react to any of our attempts to reenable streaming.  This
	 * means that we lose synchronization anyway, so we force our streams
	 * to stop so that the application can restart them in an orderly
	 * manner.
	 */
	dice->global_enabled = false;

	stop_stream(dice, &dice->rx_stream);
	stop_stream(dice, &dice->tx_stream);

	fw_iso_resources_update(&dice->rx_resources);
	fw_iso_resources_update(&dice->tx_resources);
}

static void dice_lock_changed(struct snd_dice *dice)
{
	dice->dev_lock_changed = true;
	wake_up(&dice->hwdep_wait);
}

int snd_dice_stream_lock_try(struct snd_dice *dice)
{
	int err;

	spin_lock_irq(&dice->lock);

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

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

void snd_dice_stream_lock_release(struct snd_dice *dice)
{
	spin_lock_irq(&dice->lock);

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

	if (--dice->dev_lock_count == 0)
		dice_lock_changed(dice);
out:
	spin_unlock_irq(&dice->lock);
}
