/*
 * dice_transaction.c - a part of driver for Dice based devices
 *
 * Copyright (c) Clemens Ladisch
 * Copyright (c) 2014 Takashi Sakamoto
 *
 * Licensed under the terms of the GNU General Public License, version 2.
 */

#include "dice.h"

#define NOTIFICATION_TIMEOUT_MS	(2 * MSEC_PER_SEC)

static u64 get_subaddr(struct snd_dice *dice, enum snd_dice_addr_type type,
		       u64 offset)
{
	switch (type) {
	case SND_DICE_ADDR_TYPE_TX:
		offset += dice->tx_offset;
		break;
	case SND_DICE_ADDR_TYPE_RX:
		offset += dice->rx_offset;
		break;
	case SND_DICE_ADDR_TYPE_SYNC:
		offset += dice->sync_offset;
		break;
	case SND_DICE_ADDR_TYPE_RSRV:
		offset += dice->rsrv_offset;
		break;
	case SND_DICE_ADDR_TYPE_GLOBAL:
	default:
		offset += dice->global_offset;
		break;
	}
	offset += DICE_PRIVATE_SPACE;
	return offset;
}

int snd_dice_transaction_write(struct snd_dice *dice,
			       enum snd_dice_addr_type type,
			       unsigned int offset, void *buf, unsigned int len)
{
	return snd_fw_transaction(dice->unit,
				  (len == 4) ? TCODE_WRITE_QUADLET_REQUEST :
					       TCODE_WRITE_BLOCK_REQUEST,
				  get_subaddr(dice, type, offset), buf, len, 0);
}

int snd_dice_transaction_read(struct snd_dice *dice,
			      enum snd_dice_addr_type type, unsigned int offset,
			      void *buf, unsigned int len)
{
	return snd_fw_transaction(dice->unit,
				  (len == 4) ? TCODE_READ_QUADLET_REQUEST :
					       TCODE_READ_BLOCK_REQUEST,
				  get_subaddr(dice, type, offset), buf, len, 0);
}

static unsigned int get_clock_info(struct snd_dice *dice, __be32 *info)
{
	return snd_dice_transaction_read_global(dice, GLOBAL_CLOCK_SELECT,
						info, 4);
}

static int set_clock_info(struct snd_dice *dice,
			  unsigned int rate, unsigned int source)
{
	unsigned int i;
	__be32 info;
	u32 mask;
	u32 clock;
	int err;

	err = get_clock_info(dice, &info);
	if (err < 0)
		return err;

	clock = be32_to_cpu(info);
	if (source != UINT_MAX) {
		mask = CLOCK_SOURCE_MASK;
		clock &= ~mask;
		clock |= source;
	}
	if (rate != UINT_MAX) {
		for (i = 0; i < ARRAY_SIZE(snd_dice_rates); i++) {
			if (snd_dice_rates[i] == rate)
				break;
		}
		if (i == ARRAY_SIZE(snd_dice_rates))
			return -EINVAL;

		mask = CLOCK_RATE_MASK;
		clock &= ~mask;
		clock |= i << CLOCK_RATE_SHIFT;
	}
	info = cpu_to_be32(clock);

	if (completion_done(&dice->clock_accepted))
		reinit_completion(&dice->clock_accepted);

	err = snd_dice_transaction_write_global(dice, GLOBAL_CLOCK_SELECT,
						&info, 4);
	if (err < 0)
		return err;

	if (wait_for_completion_timeout(&dice->clock_accepted,
			msecs_to_jiffies(NOTIFICATION_TIMEOUT_MS)) == 0)
		return -ETIMEDOUT;

	return 0;
}

int snd_dice_transaction_get_clock_source(struct snd_dice *dice,
					  unsigned int *source)
{
	__be32 info;
	int err;

	err = get_clock_info(dice, &info);
	if (err >= 0)
		*source = be32_to_cpu(info) & CLOCK_SOURCE_MASK;

	return err;
}

int snd_dice_transaction_get_rate(struct snd_dice *dice, unsigned int *rate)
{
	__be32 info;
	unsigned int index;
	int err;

	err = get_clock_info(dice, &info);
	if (err < 0)
		goto end;

	index = (be32_to_cpu(info) & CLOCK_RATE_MASK) >> CLOCK_RATE_SHIFT;
	if (index >= SND_DICE_RATES_COUNT) {
		err = -ENOSYS;
		goto end;
	}

	*rate = snd_dice_rates[index];
end:
	return err;
}
int snd_dice_transaction_set_rate(struct snd_dice *dice, unsigned int rate)
{
	return set_clock_info(dice, rate, UINT_MAX);
}

int snd_dice_transaction_set_enable(struct snd_dice *dice)
{
	__be32 value;
	int err = 0;

	if (dice->global_enabled)
		goto end;

	value = cpu_to_be32(1);
	err = snd_fw_transaction(dice->unit, TCODE_WRITE_QUADLET_REQUEST,
				 get_subaddr(dice, SND_DICE_ADDR_TYPE_GLOBAL,
					     GLOBAL_ENABLE),
				 &value, 4,
				 FW_FIXED_GENERATION | dice->owner_generation);
	if (err < 0)
		goto end;

	dice->global_enabled = true;
end:
	return err;
}

void snd_dice_transaction_clear_enable(struct snd_dice *dice)
{
	__be32 value;

	value = 0;
	snd_fw_transaction(dice->unit, TCODE_WRITE_QUADLET_REQUEST,
			   get_subaddr(dice, SND_DICE_ADDR_TYPE_GLOBAL,
				       GLOBAL_ENABLE),
			   &value, 4, FW_QUIET |
			   FW_FIXED_GENERATION | dice->owner_generation);

	dice->global_enabled = false;
}

static void dice_notification(struct fw_card *card, struct fw_request *request,
			      int tcode, int destination, int source,
			      int generation, unsigned long long offset,
			      void *data, size_t length, void *callback_data)
{
	struct snd_dice *dice = callback_data;
	u32 bits;
	unsigned long flags;

	if (tcode != TCODE_WRITE_QUADLET_REQUEST) {
		fw_send_response(card, request, RCODE_TYPE_ERROR);
		return;
	}
	if ((offset & 3) != 0) {
		fw_send_response(card, request, RCODE_ADDRESS_ERROR);
		return;
	}

	bits = be32_to_cpup(data);

	spin_lock_irqsave(&dice->lock, flags);
	dice->notification_bits |= bits;
	spin_unlock_irqrestore(&dice->lock, flags);

	fw_send_response(card, request, RCODE_COMPLETE);

	if (bits & NOTIFY_CLOCK_ACCEPTED)
		complete(&dice->clock_accepted);
	wake_up(&dice->hwdep_wait);
}

static int register_notification_address(struct snd_dice *dice, bool retry)
{
	struct fw_device *device = fw_parent_device(dice->unit);
	__be64 *buffer;
	unsigned int retries;
	int err;

	retries = (retry) ? 3 : 0;

	buffer = kmalloc(2 * 8, GFP_KERNEL);
	if (!buffer)
		return -ENOMEM;

	for (;;) {
		buffer[0] = cpu_to_be64(OWNER_NO_OWNER);
		buffer[1] = cpu_to_be64(
			((u64)device->card->node_id << OWNER_NODE_SHIFT) |
			dice->notification_handler.offset);

		dice->owner_generation = device->generation;
		smp_rmb(); /* node_id vs. generation */
		err = snd_fw_transaction(dice->unit, TCODE_LOCK_COMPARE_SWAP,
					 get_subaddr(dice,
						     SND_DICE_ADDR_TYPE_GLOBAL,
						     GLOBAL_OWNER),
					 buffer, 2 * 8,
					 FW_FIXED_GENERATION |
							dice->owner_generation);
		if (err == 0) {
			/* success */
			if (buffer[0] == cpu_to_be64(OWNER_NO_OWNER))
				break;
			/* The address seems to be already registered. */
			if (buffer[0] == buffer[1])
				break;

			dev_err(&dice->unit->device,
				"device is already in use\n");
			err = -EBUSY;
		}
		if (err != -EAGAIN || retries-- > 0)
			break;

		msleep(20);
	}

	kfree(buffer);

	if (err < 0)
		dice->owner_generation = -1;

	return err;
}

static void unregister_notification_address(struct snd_dice *dice)
{
	struct fw_device *device = fw_parent_device(dice->unit);
	__be64 *buffer;

	buffer = kmalloc(2 * 8, GFP_KERNEL);
	if (buffer == NULL)
		return;

	buffer[0] = cpu_to_be64(
		((u64)device->card->node_id << OWNER_NODE_SHIFT) |
		dice->notification_handler.offset);
	buffer[1] = cpu_to_be64(OWNER_NO_OWNER);
	snd_fw_transaction(dice->unit, TCODE_LOCK_COMPARE_SWAP,
			   get_subaddr(dice, SND_DICE_ADDR_TYPE_GLOBAL,
				       GLOBAL_OWNER),
			   buffer, 2 * 8, FW_QUIET |
			   FW_FIXED_GENERATION | dice->owner_generation);

	kfree(buffer);

	dice->owner_generation = -1;
}

void snd_dice_transaction_destroy(struct snd_dice *dice)
{
	struct fw_address_handler *handler = &dice->notification_handler;

	if (handler->callback_data == NULL)
		return;

	unregister_notification_address(dice);

	fw_core_remove_address_handler(handler);
	handler->callback_data = NULL;
}

int snd_dice_transaction_reinit(struct snd_dice *dice)
{
	struct fw_address_handler *handler = &dice->notification_handler;

	if (handler->callback_data == NULL)
		return -EINVAL;

	return register_notification_address(dice, false);
}

static int get_subaddrs(struct snd_dice *dice)
{
	static const int min_values[10] = {
		10, 0x64 / 4,
		10, 0x18 / 4,
		10, 0x18 / 4,
		0, 0,
		0, 0,
	};
	__be32 *pointers;
	__be32 version;
	u32 data;
	unsigned int i;
	int err;

	pointers = kmalloc_array(ARRAY_SIZE(min_values), sizeof(__be32),
				 GFP_KERNEL);
	if (pointers == NULL)
		return -ENOMEM;

	/*
	 * Check that the sub address spaces exist and are located inside the
	 * private address space.  The minimum values are chosen so that all
	 * minimally required registers are included.
	 */
	err = snd_fw_transaction(dice->unit, TCODE_READ_BLOCK_REQUEST,
				 DICE_PRIVATE_SPACE, pointers,
				 sizeof(__be32) * ARRAY_SIZE(min_values), 0);
	if (err < 0)
		goto end;

	for (i = 0; i < ARRAY_SIZE(min_values); ++i) {
		data = be32_to_cpu(pointers[i]);
		if (data < min_values[i] || data >= 0x40000) {
			err = -ENODEV;
			goto end;
		}
	}

	/*
	 * Check that the implemented DICE driver specification major version
	 * number matches.
	 */
	err = snd_fw_transaction(dice->unit, TCODE_READ_QUADLET_REQUEST,
				 DICE_PRIVATE_SPACE +
				 be32_to_cpu(pointers[0]) * 4 + GLOBAL_VERSION,
				 &version, sizeof(version), 0);
	if (err < 0)
		goto end;

	if ((version & cpu_to_be32(0xff000000)) != cpu_to_be32(0x01000000)) {
		dev_err(&dice->unit->device,
			"unknown DICE version: 0x%08x\n", be32_to_cpu(version));
		err = -ENODEV;
		goto end;
	}

	dice->global_offset = be32_to_cpu(pointers[0]) * 4;
	dice->tx_offset = be32_to_cpu(pointers[2]) * 4;
	dice->rx_offset = be32_to_cpu(pointers[4]) * 4;
	dice->sync_offset = be32_to_cpu(pointers[6]) * 4;
	dice->rsrv_offset = be32_to_cpu(pointers[8]) * 4;

	/* Set up later. */
	if (be32_to_cpu(pointers[1]) * 4 >= GLOBAL_CLOCK_CAPABILITIES + 4)
		dice->clock_caps = 1;
end:
	kfree(pointers);
	return err;
}

int snd_dice_transaction_init(struct snd_dice *dice)
{
	struct fw_address_handler *handler = &dice->notification_handler;
	int err;

	err = get_subaddrs(dice);
	if (err < 0)
		return err;

	/* Allocation callback in address space over host controller */
	handler->length = 4;
	handler->address_callback = dice_notification;
	handler->callback_data = dice;
	err = fw_core_add_address_handler(handler, &fw_high_memory_region);
	if (err < 0) {
		handler->callback_data = NULL;
		return err;
	}

	/* Register the address space */
	err = register_notification_address(dice, true);
	if (err < 0) {
		fw_core_remove_address_handler(handler);
		handler->callback_data = NULL;
	}

	return err;
}
