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

#include <errno.h>

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

#include "qm_ss_spi.h"
#include "qm_ss_isr.h"
#include "ss_clk.h"

struct ss_pending_transfer {
	struct device *dev;
	qm_ss_spi_async_transfer_t xfer;
};

static struct ss_pending_transfer pending_transfers[2];

struct ss_spi_qmsi_config {
	qm_ss_spi_t spi;
#ifdef CONFIG_SPI_SS_CS_GPIO
	char *cs_port;
	u32_t cs_pin;
#endif
};

struct ss_spi_qmsi_runtime {
#ifdef CONFIG_SPI_SS_CS_GPIO
	struct device *gpio_cs;
#endif
	struct k_sem device_sync_sem;
	struct k_sem sem;
	qm_ss_spi_config_t cfg;
	int rc;
	bool loopback;
#ifdef CONFIG_DEVICE_POWER_MANAGEMENT
	u32_t device_power_state;
	qm_ss_spi_context_t spi_ctx;
#endif
};

static inline qm_ss_spi_bmode_t config_to_bmode(u8_t mode)
{
	switch (mode) {
	case SPI_MODE_CPHA:
		return QM_SS_SPI_BMODE_1;
	case SPI_MODE_CPOL:
		return QM_SS_SPI_BMODE_2;
	case SPI_MODE_CPOL | SPI_MODE_CPHA:
		return QM_SS_SPI_BMODE_3;
	default:
		return QM_SS_SPI_BMODE_0;
	}
}

#ifdef CONFIG_SPI_SS_CS_GPIO
static void spi_control_cs(struct device *dev, bool active)
{
	struct ss_spi_qmsi_runtime *context = dev->driver_data;
	const struct ss_spi_qmsi_config *config = dev->config->config_info;
	struct device *gpio = context->gpio_cs;

	if (!gpio)
		return;

	gpio_pin_write(gpio, config->cs_pin, !active);
}
#endif

static int ss_spi_qmsi_configure(struct device *dev,
				 struct spi_config *config)
{
	struct ss_spi_qmsi_runtime *context = dev->driver_data;
	qm_ss_spi_config_t *cfg = &context->cfg;

	cfg->frame_size = SPI_WORD_SIZE_GET(config->config) - 1;
	cfg->bus_mode = config_to_bmode(SPI_MODE(config->config));
	/* As loopback is implemented inside the controller,
	 * the bus mode doesn't matter.
	 */
	context->loopback = SPI_MODE(config->config) & SPI_MODE_LOOP;
	cfg->clk_divider = config->max_sys_freq;

	/* Will set the configuration before the transfer starts */
	return 0;
}

static void spi_qmsi_callback(void *data, int error, qm_ss_spi_status_t status,
			      u16_t len)
{
	const struct ss_spi_qmsi_config *spi_config =
			       ((struct device *)data)->config->config_info;
	qm_ss_spi_t spi_id = spi_config->spi;
	struct ss_pending_transfer *pending = &pending_transfers[spi_id];
	struct device *dev = pending->dev;
	struct ss_spi_qmsi_runtime *context;

	if (!dev)
		return;

	context = dev->driver_data;

#ifdef CONFIG_SPI_SS_CS_GPIO
	spi_control_cs(dev, false);
#endif

	pending->dev = NULL;
	context->rc = error;
	k_sem_give(&context->device_sync_sem);
}

static int ss_spi_qmsi_slave_select(struct device *dev, u32_t slave)
{
	const struct ss_spi_qmsi_config *spi_config = dev->config->config_info;
	qm_ss_spi_t spi_id = spi_config->spi;

	return qm_ss_spi_slave_select(spi_id, 1 << (slave - 1)) ? -EIO : 0;
}

static inline u8_t frame_size_to_dfs(qm_ss_spi_frame_size_t frame_size)
{
	if (frame_size <= QM_SS_SPI_FRAME_SIZE_8_BIT) {
		return 1;
	}

	if (frame_size <= QM_SS_SPI_FRAME_SIZE_16_BIT) {
		return 2;
	}

	/* This should never happen, it will crash later on. */
	return 0;
}

static int ss_spi_qmsi_transceive(struct device *dev,
				  const void *tx_buf, u32_t tx_buf_len,
				  void *rx_buf, u32_t rx_buf_len)
{
	const struct ss_spi_qmsi_config *spi_config = dev->config->config_info;
	qm_ss_spi_t spi_id = spi_config->spi;
	struct ss_spi_qmsi_runtime *context = dev->driver_data;
	qm_ss_spi_config_t *cfg = &context->cfg;
	u8_t dfs = frame_size_to_dfs(cfg->frame_size);
	qm_ss_spi_async_transfer_t *xfer;
	int rc;

	k_sem_take(&context->sem, K_FOREVER);
	if (pending_transfers[spi_id].dev) {
		k_sem_give(&context->sem);
		return -EBUSY;
	}
	pending_transfers[spi_id].dev = dev;
	k_sem_give(&context->sem);

	device_busy_set(dev);

	xfer = &pending_transfers[spi_id].xfer;

	xfer->rx = rx_buf;
	xfer->rx_len = rx_buf_len / dfs;
	xfer->tx = (u8_t *)tx_buf;
	xfer->tx_len = tx_buf_len / dfs;
	xfer->callback_data = dev;
	xfer->callback = spi_qmsi_callback;

	if (tx_buf_len == 0) {
		cfg->transfer_mode = QM_SS_SPI_TMOD_RX;
	} else if (rx_buf_len == 0) {
		cfg->transfer_mode = QM_SS_SPI_TMOD_TX;
	} else {
		cfg->transfer_mode = QM_SS_SPI_TMOD_TX_RX;
	}

	if (context->loopback) {
		u32_t ctrl;

		if (spi_id == 0) {
			ctrl = __builtin_arc_lr(QM_SS_SPI_0_BASE +
						QM_SS_SPI_CTRL);
			ctrl |= BIT(11);
			__builtin_arc_sr(ctrl, QM_SS_SPI_0_BASE +
					 QM_SS_SPI_CTRL);
		} else {
			ctrl = __builtin_arc_lr(QM_SS_SPI_1_BASE +
						QM_SS_SPI_CTRL);
			ctrl |= BIT(11);
			__builtin_arc_sr(ctrl, QM_SS_SPI_1_BASE +
					 QM_SS_SPI_CTRL);
		}
	}

	rc = qm_ss_spi_set_config(spi_id, cfg);
	if (rc != 0) {
		device_busy_clear(dev);
		return -EINVAL;
	}

#ifdef CONFIG_SPI_SS_CS_GPIO
	spi_control_cs(dev, true);
#endif

	rc = qm_ss_spi_irq_transfer(spi_id, xfer);
	if (rc != 0) {
#ifdef CONFIG_SPI_SS_CS_GPIO
		spi_control_cs(dev, false);
#endif
		device_busy_clear(dev);
		return -EIO;
	}

	k_sem_take(&context->device_sync_sem, K_FOREVER);

	device_busy_clear(dev);
	return context->rc ? -EIO : 0;
}

static const struct spi_driver_api ss_spi_qmsi_api = {
	.configure = ss_spi_qmsi_configure,
	.slave_select = ss_spi_qmsi_slave_select,
	.transceive = ss_spi_qmsi_transceive,
};

#ifdef CONFIG_SPI_SS_CS_GPIO
static struct device *gpio_cs_init(const struct ss_spi_qmsi_config *config)
{
	struct device *gpio;

	if (!config->cs_port)
		return NULL;

	gpio = device_get_binding(config->cs_port);
	if (!gpio)
		return NULL;

	gpio_pin_configure(gpio, config->cs_pin, GPIO_DIR_OUT);
	gpio_pin_write(gpio, config->cs_pin, 1);

	return gpio;
}
#endif

static int ss_spi_qmsi_init(struct device *dev);


#ifdef CONFIG_DEVICE_POWER_MANAGEMENT
static void ss_spi_master_set_power_state(struct device *dev,
					  u32_t power_state)
{
	struct ss_spi_qmsi_runtime *context = dev->driver_data;

	context->device_power_state = power_state;
}

static u32_t ss_spi_master_get_power_state(struct device *dev)
{
	struct ss_spi_qmsi_runtime *context = dev->driver_data;

	return context->device_power_state;
}

static int ss_spi_master_suspend_device(struct device *dev)
{
	if (device_busy_check(dev)) {
		return -EBUSY;
	}

	const struct ss_spi_qmsi_config *config = dev->config->config_info;
	struct ss_spi_qmsi_runtime *drv_data = dev->driver_data;

	qm_ss_spi_save_context(config->spi, &drv_data->spi_ctx);

	ss_spi_master_set_power_state(dev, DEVICE_PM_SUSPEND_STATE);

	return 0;
}

static int ss_spi_master_resume_device_from_suspend(struct device *dev)
{
	const struct ss_spi_qmsi_config *config = dev->config->config_info;
	struct ss_spi_qmsi_runtime *drv_data = dev->driver_data;

	qm_ss_spi_restore_context(config->spi, &drv_data->spi_ctx);

	ss_spi_master_set_power_state(dev, DEVICE_PM_ACTIVE_STATE);

	return 0;
}

/*
* Implements the driver control management functionality
* the *context may include IN data or/and OUT data
*/
static int ss_spi_master_qmsi_device_ctrl(struct device *port,
				       u32_t ctrl_command, void *context)
{
	if (ctrl_command == DEVICE_PM_SET_POWER_STATE) {
		if (*((u32_t *)context) == DEVICE_PM_SUSPEND_STATE) {
			return ss_spi_master_suspend_device(port);
		} else if (*((u32_t *)context) == DEVICE_PM_ACTIVE_STATE) {
			return ss_spi_master_resume_device_from_suspend(port);
		}
	} else if (ctrl_command == DEVICE_PM_GET_POWER_STATE) {
		*((u32_t *)context) = ss_spi_master_get_power_state(port);
	}
	return 0;
}
#else
#define ss_spi_master_set_power_state(...)
#endif /* CONFIG_DEVICE_POWER_MANAGEMENT */

#ifdef CONFIG_SPI_SS_0
static const struct ss_spi_qmsi_config spi_qmsi_mst_0_config = {
	.spi = QM_SS_SPI_0,
#ifdef CONFIG_SPI_SS_CS_GPIO
	.cs_port = CONFIG_SPI_SS_0_CS_GPIO_PORT,
	.cs_pin = CONFIG_SPI_SS_0_CS_GPIO_PIN,
#endif
};

static struct ss_spi_qmsi_runtime spi_qmsi_mst_0_runtime;

DEVICE_DEFINE(ss_spi_master_0, CONFIG_SPI_SS_0_NAME, ss_spi_qmsi_init,
	      ss_spi_master_qmsi_device_ctrl, &spi_qmsi_mst_0_runtime,
	      &spi_qmsi_mst_0_config, POST_KERNEL, CONFIG_SPI_SS_INIT_PRIORITY,
	      NULL);
#endif /* CONFIG_SPI_SS_0 */

#ifdef CONFIG_SPI_SS_1
static const struct ss_spi_qmsi_config spi_qmsi_mst_1_config = {
	.spi = QM_SS_SPI_1,
#ifdef CONFIG_SPI_SS_CS_GPIO
	.cs_port = CONFIG_SPI_SS_1_CS_GPIO_PORT,
	.cs_pin = CONFIG_SPI_SS_1_CS_GPIO_PIN,
#endif
};

static struct ss_spi_qmsi_runtime spi_qmsi_mst_1_runtime;

DEVICE_DEFINE(ss_spi_master_1, CONFIG_SPI_SS_1_NAME, ss_spi_qmsi_init,
	      ss_spi_master_qmsi_device_ctrl, &spi_qmsi_mst_1_runtime,
	      &spi_qmsi_mst_1_config, POST_KERNEL, CONFIG_SPI_SS_INIT_PRIORITY,
	      NULL);
#endif /* CONFIG_SPI_SS_1 */

static void ss_spi_err_isr(void *arg)
{
	struct device *dev = arg;
	const struct ss_spi_qmsi_config *spi_config = dev->config->config_info;

	if (spi_config->spi == QM_SS_SPI_0) {
		qm_ss_spi_0_error_isr(NULL);
	} else {
		qm_ss_spi_1_error_isr(NULL);
	}
}

static void ss_spi_rx_isr(void *arg)
{
	struct device *dev = arg;
	const struct ss_spi_qmsi_config *spi_config = dev->config->config_info;

	if (spi_config->spi == QM_SS_SPI_0) {
		qm_ss_spi_0_rx_avail_isr(NULL);
	} else {
		qm_ss_spi_1_rx_avail_isr(NULL);
	}
}

static void ss_spi_tx_isr(void *arg)
{
	struct device *dev = arg;
	const struct ss_spi_qmsi_config *spi_config = dev->config->config_info;

	if (spi_config->spi == QM_SS_SPI_0) {
		qm_ss_spi_0_tx_req_isr(NULL);
	} else {
		qm_ss_spi_1_tx_req_isr(NULL);
	}
}

static int ss_spi_qmsi_init(struct device *dev)
{
	const struct ss_spi_qmsi_config *spi_config = dev->config->config_info;
	struct ss_spi_qmsi_runtime *context = dev->driver_data;
	u32_t *scss_intmask = NULL;

	switch (spi_config->spi) {
#ifdef CONFIG_SPI_SS_0
	case QM_SS_SPI_0:
		IRQ_CONNECT(IRQ_SPI0_ERR_INT, CONFIG_SPI_SS_0_IRQ_PRI,
			    ss_spi_err_isr, DEVICE_GET(ss_spi_master_0), 0);
		irq_enable(IRQ_SPI0_ERR_INT);

		IRQ_CONNECT(IRQ_SPI0_RX_AVAIL, CONFIG_SPI_SS_0_IRQ_PRI,
			    ss_spi_rx_isr, DEVICE_GET(ss_spi_master_0), 0);
		irq_enable(IRQ_SPI0_RX_AVAIL);

		IRQ_CONNECT(IRQ_SPI0_TX_REQ, CONFIG_SPI_SS_0_IRQ_PRI,
			    ss_spi_tx_isr, DEVICE_GET(ss_spi_master_0), 0);
		irq_enable(IRQ_SPI0_TX_REQ);

		ss_clk_spi_enable(0);

		/* Route SPI interrupts to Sensor Subsystem */
		scss_intmask = (u32_t *)&QM_INTERRUPT_ROUTER->ss_spi_0_int;
		*scss_intmask &= ~BIT(8);
		scss_intmask++;
		*scss_intmask &= ~BIT(8);
		scss_intmask++;
		*scss_intmask &= ~BIT(8);
		break;
#endif /* CONFIG_SPI_SS_0 */

#ifdef CONFIG_SPI_SS_1
	case QM_SS_SPI_1:
		IRQ_CONNECT(IRQ_SPI1_ERR_INT, CONFIG_SPI_SS_1_IRQ_PRI,
			    ss_spi_err_isr, DEVICE_GET(ss_spi_master_1), 0);
		irq_enable(IRQ_SPI1_ERR_INT);

		IRQ_CONNECT(IRQ_SPI1_RX_AVAIL, CONFIG_SPI_SS_1_IRQ_PRI,
			    ss_spi_rx_isr, DEVICE_GET(ss_spi_master_1), 0);
		irq_enable(IRQ_SPI1_RX_AVAIL);

		IRQ_CONNECT(IRQ_SPI1_TX_REQ, CONFIG_SPI_SS_1_IRQ_PRI,
			    ss_spi_tx_isr, DEVICE_GET(ss_spi_master_1), 0);
		irq_enable(IRQ_SPI1_TX_REQ);

		ss_clk_spi_enable(1);

		/* Route SPI interrupts to Sensor Subsystem */
		scss_intmask = (u32_t *)&QM_INTERRUPT_ROUTER->ss_spi_1_int;
		*scss_intmask &= ~BIT(8);
		scss_intmask++;
		*scss_intmask &= ~BIT(8);
		scss_intmask++;
		*scss_intmask &= ~BIT(8);
		break;
#endif /* CONFIG_SPI_SS_1 */

	default:
		return -EIO;
	}

#ifdef CONFIG_SPI_SS_CS_GPIO
	context->gpio_cs = gpio_cs_init(spi_config);
#endif
	k_sem_init(&context->device_sync_sem, 0, UINT_MAX);
	k_sem_init(&context->sem, 0, UINT_MAX);
	k_sem_give(&context->sem);

	ss_spi_master_set_power_state(dev, DEVICE_PM_ACTIVE_STATE);

	dev->driver_api = &ss_spi_qmsi_api;

	return 0;
}
