/*
 * Copyright (c) 2016 Intel Corporation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#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_CS_GPIO
	char *cs_port;
	uint32_t cs_pin;
#endif
};

struct ss_spi_qmsi_runtime {
#ifdef CONFIG_SPI_CS_GPIO
	struct device *gpio_cs;
#endif
	device_sync_call_t sync;
	struct k_sem sem;
	qm_ss_spi_config_t cfg;
	int rc;
	bool loopback;
#ifdef CONFIG_DEVICE_POWER_MANAGEMENT
	uint32_t device_power_state;
#ifdef CONFIG_SYS_POWER_DEEP_SLEEP
	qm_ss_spi_context_t spi_ctx;
#endif
#endif
};

static inline qm_ss_spi_bmode_t config_to_bmode(uint8_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_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,
			      uint16_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_CS_GPIO
	spi_control_cs(dev, false);
#endif

	pending->dev = NULL;
	context->rc = error;
	device_sync_call_complete(&context->sync);
}

static int ss_spi_qmsi_slave_select(struct device *dev, uint32_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 uint8_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, uint32_t tx_buf_len,
				  void *rx_buf, uint32_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;
	uint8_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);

	xfer = &pending_transfers[spi_id].xfer;

	xfer->rx = rx_buf;
	xfer->rx_len = rx_buf_len / dfs;
	xfer->tx = (uint8_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) {
		uint32_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) {
		return -EINVAL;
	}

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

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

	device_sync_call_wait(&context->sync);

	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_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,
					  uint32_t power_state)
{
	struct ss_spi_qmsi_runtime *context = dev->driver_data;

	context->device_power_state = power_state;
}

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

	return context->device_power_state;
}

#ifdef CONFIG_SYS_POWER_DEEP_SLEEP
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;
}
#endif /* CONFIG_SYS_POWER_DEEP_SLEEP */

/*
* 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,
				       uint32_t ctrl_command, void *context)
{
	if (ctrl_command == DEVICE_PM_SET_POWER_STATE) {
#ifdef CONFIG_SYS_POWER_DEEP_SLEEP
		if (*((uint32_t *)context) == DEVICE_PM_SUSPEND_STATE) {
			return ss_spi_master_suspend_device(port);
		} else if (*((uint32_t *)context) == DEVICE_PM_ACTIVE_STATE) {
			return ss_spi_master_resume_device_from_suspend(port);
		}
#endif /* CONFIG_SYS_POWER_DEEP_SLEEP */
	} else if (ctrl_command == DEVICE_PM_GET_POWER_STATE) {
		*((uint32_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_0
static const struct ss_spi_qmsi_config spi_qmsi_mst_0_config = {
	.spi = QM_SS_SPI_0,
#ifdef CONFIG_SPI_CS_GPIO
	.cs_port = CONFIG_SPI_0_CS_GPIO_PORT,
	.cs_pin = CONFIG_SPI_0_CS_GPIO_PIN,
#endif
};

static struct ss_spi_qmsi_runtime spi_qmsi_mst_0_runtime;

DEVICE_DEFINE(ss_spi_master_0, CONFIG_SPI_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_INIT_PRIORITY,
	      NULL);
#endif /* CONFIG_SPI_0 */

#ifdef CONFIG_SPI_1
static const struct ss_spi_qmsi_config spi_qmsi_mst_1_config = {
	.spi = QM_SS_SPI_1,
#ifdef CONFIG_SPI_CS_GPIO
	.cs_port = CONFIG_SPI_1_CS_GPIO_PORT,
	.cs_pin = CONFIG_SPI_1_CS_GPIO_PIN,
#endif
};

static struct ss_spi_qmsi_runtime spi_qmsi_mst_1_runtime;

DEVICE_DEFINE(ss_spi_master_1, CONFIG_SPI_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_INIT_PRIORITY,
	      NULL);
#endif /* CONFIG_SPI_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;
	uint32_t *scss_intmask = NULL;

	switch (spi_config->spi) {
#ifdef CONFIG_SPI_0
	case QM_SS_SPI_0:
		IRQ_CONNECT(IRQ_SPI0_ERR_INT, CONFIG_SPI_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_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_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 = (uint32_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_0 */

#ifdef CONFIG_SPI_1
	case QM_SS_SPI_1:
		IRQ_CONNECT(IRQ_SPI1_ERR_INT, CONFIG_SPI_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_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_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 = (uint32_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_1 */

	default:
		return -EIO;
	}

#ifdef CONFIG_SPI_CS_GPIO
	context->gpio_cs = gpio_cs_init(spi_config);
#endif
	device_sync_call_init(&context->sync);
	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;
}
