/*
 * Copyright (c) 2017 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @file
 * @brief Private API for SPI drivers
 */

#ifndef __SPI_DRIVER_COMMON_H__
#define __SPI_DRIVER_COMMON_H__

#include <gpio.h>
#include <spi.h>

#ifdef __cplusplus
extern "C" {
#endif

struct spi_context {
	struct spi_config *config;

	struct k_sem lock;
	struct k_sem sync;
	int sync_status;

#ifdef CONFIG_POLL
	struct k_poll_signal *signal;
	bool asynchronous;
#endif
	const struct spi_buf *current_tx;
	size_t tx_count;
	struct spi_buf *current_rx;
	size_t rx_count;

	u8_t *tx_buf;
	size_t tx_len;
	u8_t *rx_buf;
	size_t rx_len;
};

#define SPI_CONTEXT_INIT_LOCK(_data, _ctx_name)				\
	._ctx_name.lock = _K_SEM_INITIALIZER(_data._ctx_name.lock, 0, 1)

#define SPI_CONTEXT_INIT_SYNC(_data, _ctx_name)				\
	._ctx_name.sync = _K_SEM_INITIALIZER(_data._ctx_name.sync, 0, 1)

static inline bool spi_context_configured(struct spi_context *ctx,
					  struct spi_config *config)
{
	return !!(ctx->config == config);
}

static inline void spi_context_lock(struct spi_context *ctx,
				    bool asynchronous,
				    struct k_poll_signal *signal)
{
	k_sem_take(&ctx->lock, K_FOREVER);

#ifdef CONFIG_POLL
	ctx->asynchronous = asynchronous;
	ctx->signal = signal;
#endif
}

static inline void spi_context_release(struct spi_context *ctx, int status)
{
	if (!status && (ctx->config->operation & SPI_LOCK_ON)) {
		return;
	}

#ifdef CONFIG_POLL
	if (!ctx->asynchronous || status) {
		k_sem_give(&ctx->lock);
	}
#else
	k_sem_give(&ctx->lock);
#endif
}

static inline void spi_context_unlock_unconditionally(struct spi_context *ctx)
{
	if (!k_sem_count_get(&ctx->lock)) {
		k_sem_give(&ctx->lock);
	}
}

static inline int spi_context_wait_for_completion(struct spi_context *ctx)
{
	int status = 0;
#ifdef CONFIG_POLL
	if (!ctx->asynchronous) {
		k_sem_take(&ctx->sync, K_FOREVER);
		status = ctx->sync_status;
	}
#else
	k_sem_take(&ctx->sync, K_FOREVER);
	status = ctx->sync_status;
#endif
	return status;
}

static inline void spi_context_complete(struct spi_context *ctx, int status)
{
#ifdef CONFIG_POLL
	if (!ctx->asynchronous) {
		ctx->sync_status = status;
		k_sem_give(&ctx->sync);
	} else {
		if (ctx->signal) {
			k_poll_signal(ctx->signal, status);
		}

		if (!(ctx->config->operation & SPI_LOCK_ON)) {
			k_sem_give(&ctx->lock);
		}
	}
#else
	ctx->sync_status = status;
	k_sem_give(&ctx->sync);
#endif
}

static inline void spi_context_cs_configure(struct spi_context *ctx)
{
	if (ctx->config->cs && ctx->config->cs->gpio_dev) {
		gpio_pin_configure(ctx->config->cs->gpio_dev,
				   ctx->config->cs->gpio_pin, GPIO_DIR_OUT);
		gpio_pin_write(ctx->config->cs->gpio_dev,
			       ctx->config->cs->gpio_pin, 1);
	} else {
		SYS_LOG_INF("CS control inhibited (no GPIO device)");
	}
}

static inline void spi_context_cs_control(struct spi_context *ctx, bool on)
{
	if (ctx->config->cs && ctx->config->cs->gpio_dev) {
		if (on) {
			gpio_pin_write(ctx->config->cs->gpio_dev,
				       ctx->config->cs->gpio_pin, 0);
			k_busy_wait(ctx->config->cs->delay);
		} else {
			if (ctx->config->operation & SPI_HOLD_ON_CS) {
				return;
			}

			k_busy_wait(ctx->config->cs->delay);
			gpio_pin_write(ctx->config->cs->gpio_dev,
				       ctx->config->cs->gpio_pin, 1);
		}
	}
}

static inline void spi_context_buffers_setup(struct spi_context *ctx,
					     const struct spi_buf *tx_bufs,
					     size_t tx_count,
					     struct spi_buf *rx_bufs,
					     size_t rx_count,
					     u8_t dfs)
{
	SYS_LOG_DBG("tx_bufs %p (%zu) - rx_bufs %p (%zu) - %u",
		    tx_bufs, tx_count, rx_bufs, rx_count, dfs);

	ctx->current_tx = tx_bufs;
	ctx->tx_count = tx_count;
	ctx->current_rx = rx_bufs;
	ctx->rx_count = rx_count;

	if (tx_bufs) {
		ctx->tx_buf = tx_bufs->buf;
		ctx->tx_len = tx_bufs->len / dfs;
	} else {
		ctx->tx_buf = NULL;
		ctx->tx_len = 0;
	}

	if (rx_bufs) {
		ctx->rx_buf = rx_bufs->buf;
		ctx->rx_len = rx_bufs->len / dfs;
	} else {
		ctx->rx_buf = NULL;
		ctx->rx_len = 0;
	}

	ctx->sync_status = 0;

	SYS_LOG_DBG("current_tx %p (%zu), current_rx %p (%zu),"
		    " tx buf/len %p/%zu, rx buf/len %p/%zu",
		    ctx->current_tx, ctx->tx_count,
		    ctx->current_rx, ctx->rx_count,
		    ctx->tx_buf, ctx->tx_len, ctx->rx_buf, ctx->rx_len);
}

static ALWAYS_INLINE
void spi_context_update_tx(struct spi_context *ctx, u8_t dfs, u32_t len)
{
	if (!ctx->tx_len) {
		return;
	}

	if (len > ctx->tx_len) {
		SYS_LOG_ERR("Update exceeds current buffer");
		return;
	}

	ctx->tx_len -= len;
	if (!ctx->tx_len) {
		ctx->current_tx++;
		ctx->tx_count--;

		if (ctx->tx_count) {
			ctx->tx_buf = ctx->current_tx->buf;
			ctx->tx_len = ctx->current_tx->len / dfs;
		} else {
			ctx->tx_buf = NULL;
		}
	} else if (ctx->tx_buf) {
		ctx->tx_buf += dfs * len;
	}

	SYS_LOG_DBG("tx buf/len %p/%zu", ctx->tx_buf, ctx->tx_len);
}

static ALWAYS_INLINE
bool spi_context_tx_on(struct spi_context *ctx)
{
	return !!(ctx->tx_buf || ctx->tx_len);
}

static ALWAYS_INLINE
void spi_context_update_rx(struct spi_context *ctx, u8_t dfs, u32_t len)
{
	if (!ctx->rx_len) {
		return;
	}

	if (len > ctx->rx_len) {
		SYS_LOG_ERR("Update exceeds current buffer");
		return;
	}

	ctx->rx_len -= len;
	if (!ctx->rx_len) {
		ctx->current_rx++;
		ctx->rx_count--;

		if (ctx->rx_count) {
			ctx->rx_buf = ctx->current_rx->buf;
			ctx->rx_len = ctx->current_rx->len / dfs;
		} else {
			ctx->rx_buf = NULL;
		}
	} else if (ctx->rx_buf) {
		ctx->rx_buf += dfs * len;
	}

	SYS_LOG_DBG("rx buf/len %p/%zu", ctx->rx_buf, ctx->rx_len);
}

static ALWAYS_INLINE
bool spi_context_rx_on(struct spi_context *ctx)
{
	return !!(ctx->rx_buf || ctx->rx_len);
}

static inline size_t spi_context_longest_current_buf(struct spi_context *ctx)
{
	if (!ctx->tx_len) {
		return ctx->rx_len;
	} else if (!ctx->rx_len) {
		return ctx->tx_len;
	} else if (ctx->tx_len < ctx->rx_len) {
		return ctx->tx_len;
	}

	return ctx->rx_len;
}

#ifdef __cplusplus
}
#endif

#endif /* __SPI_DRIVER_COMMON_H__ */
