/*
 * Copyright (c) 2022 Google LLC
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT ite_it8xxx2_shi

#include "ec_host_cmd_periph_shi.h"

#include <zephyr/drivers/ec_host_cmd_periph/ec_host_cmd_periph.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/drivers/pinctrl.h>
#include <zephyr/dt-bindings/gpio/ite-it8xxx2-gpio.h>
#include <zephyr/logging/log.h>
#include <zephyr/mgmt/ec_host_cmd.h>
#include <zephyr/pm/device.h>
#include <zephyr/pm/device_runtime.h>
#include <zephyr/pm/policy.h>

BUILD_ASSERT(DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 1, "Invalid number of ITE SHI peripherals");

LOG_MODULE_REGISTER(host_cmd_shi_ite, CONFIG_EC_HC_LOG_LEVEL);

#define EC_SHI_PREAMBLE_LENGTH 4
#define EC_SHI_PAST_END_LENGTH 4
#define SPI_RX_MAX_FIFO_SIZE   DT_INST_PROP(0, buffer_rx_size)
#define SPI_TX_MAX_FIFO_SIZE   DT_INST_PROP(0, buffer_tx_size)

#define SHI_MAX_RESPONSE_SIZE                                                                      \
	(SPI_TX_MAX_FIFO_SIZE - EC_SHI_PREAMBLE_LENGTH - EC_SHI_PAST_END_LENGTH)

BUILD_ASSERT(CONFIG_EC_HOST_CMD_HANDLER_TX_BUFFER == SHI_MAX_RESPONSE_SIZE,
	     "EC HC TX has different size than SHI TX response size");
BUILD_ASSERT(CONFIG_EC_HOST_CMD_PERIPH_SHI_MAX_REQUEST <= SPI_RX_MAX_FIFO_SIZE,
	     "SHI max request size is too big");
BUILD_ASSERT(CONFIG_EC_HOST_CMD_PERIPH_SHI_MAX_RESPONSE <= SHI_MAX_RESPONSE_SIZE,
	     "SHI max response size is too big");

/* Parameters used by host protocols */
enum shi_state_machine {
	/* Interface is disabled */
	SHI_STATE_DISABLED,
	/* Ready to receive next request */
	SHI_STATE_READY_TO_RECV,
	/* Receiving request */
	SHI_STATE_RECEIVING,
	/* Processing request */
	SHI_STATE_PROCESSING,
	/* Received bad data */
	SHI_STATE_RX_BAD,

	SHI_STATE_COUNT,
};

/*
 * Structure shi_it8xxx2_cfg is about the setting of SHI,
 * this config will be used at initial time
 */
struct shi_it8xxx2_cfg {
	/* SHI alternate configuration */
	const struct pinctrl_dev_config *pcfg;
	/* Chip select pin */
	const struct gpio_dt_spec cs;
};

struct shi_it8xxx2_data {
	/* Peripheral data */
	struct k_sem handler_owns;
	struct k_sem dev_owns;
	struct gpio_callback cs_cb;
	/* Current state */
	enum shi_state_machine shi_state;
	/* Buffers */
	uint32_t in_msg_size;
	uint8_t in_msg[SPI_RX_MAX_FIFO_SIZE] __aligned(4);
	uint8_t out_msg[SPI_TX_MAX_FIFO_SIZE] __aligned(4);
};

static const uint8_t out_preamble[EC_SHI_PREAMBLE_LENGTH] = {
	EC_SHI_PROCESSING,
	EC_SHI_PROCESSING,
	EC_SHI_PROCESSING,
	/* This is the byte which matters */
	EC_SHI_FRAME_START,
};

static const int shi_ite_response_state[] = {
	[SHI_STATE_DISABLED] = EC_SHI_NOT_READY,  [SHI_STATE_READY_TO_RECV] = EC_SHI_RX_READY,
	[SHI_STATE_RECEIVING] = EC_SHI_RECEIVING, [SHI_STATE_PROCESSING] = EC_SHI_PROCESSING,
	[SHI_STATE_RX_BAD] = EC_SHI_RX_BAD_DATA,
};
BUILD_ASSERT(ARRAY_SIZE(shi_ite_response_state) == SHI_STATE_COUNT);

static void shi_ite_set_state(struct shi_it8xxx2_data *data, int state)
{
	/* SPI peripheral state machine */
	data->shi_state = state;

	/* Response spi peripheral state */
	IT83XX_SPI_SPISRDR = shi_ite_response_state[state];
}

static void shi_ite_reset_rx_fifo(void)
{
	/* End Rx FIFO access */
	IT83XX_SPI_TXRXFAR = 0x00;

	/* Rx FIFO reset and count monitor reset */
	IT83XX_SPI_FCR = IT83XX_SPI_RXFR | IT83XX_SPI_RXFCMR;
}

/* This routine handles spi received unexcepted data */
static void shi_ite_bad_received_data(const struct device *dev, int count)
{
	struct shi_it8xxx2_data *data = dev->data;

	/* State machine mismatch, timeout, or protocol we can't handle. */
	shi_ite_set_state(data, SHI_STATE_RX_BAD);

	/* End CPU access Rx FIFO, so it can clock in bytes from AP again. */
	IT83XX_SPI_TXRXFAR = 0;

	LOG_ERR("SPI rx bad data");
	LOG_HEXDUMP_DBG(data->in_msg, count, "in_msg=");
}

static void shi_ite_response_host_data(const struct device *dev, uint8_t *out_msg_addr, int tx_size)
{
	struct shi_it8xxx2_data *data = dev->data;

	/*
	 * Protect sequence of filling response packet for host.
	 * This will ensure CPU access FIFO is disabled at SPI end interrupt no
	 * matter the interrupt is triggered before or after the sequence.
	 */
	unsigned int key = irq_lock();

	if (data->shi_state == SHI_STATE_PROCESSING) {
		/* Tx FIFO reset and count monitor reset */
		IT83XX_SPI_TXFCR = IT83XX_SPI_TXFR | IT83XX_SPI_TXFCMR;

		/* CPU Tx FIFO1 and FIFO2 access */
		IT83XX_SPI_TXRXFAR = IT83XX_SPI_CPUTFA;

		for (int i = 0; i < tx_size; i += 4) {
			/* Write response data from out_msg buffer to Tx FIFO */
			IT83XX_SPI_CPUWTFDB0 = *(uint32_t *)(out_msg_addr + i);
		}

		/*
		 * After writing data to Tx FIFO is finished, this bit will
		 * be to indicate the SPI peripheral controller.
		 */
		IT83XX_SPI_TXFCR = IT83XX_SPI_TXFS;

		/* End Tx FIFO access */
		IT83XX_SPI_TXRXFAR = 0;

		/* SPI peripheral read Tx FIFO */
		IT83XX_SPI_FCR = IT83XX_SPI_SPISRTXF;
	}

	irq_unlock(key);
}

/*
 * Called to send a response back to the host.
 *
 * Some commands can continue for a while. This function is called by
 * host_command when it completes.
 */
static int shi_ite_periph_send(const struct device *dev,
			       const struct ec_host_cmd_periph_tx_buf *buf)
{
	struct shi_it8xxx2_data *data = dev->data;
	int tx_size;

	if (data->shi_state != SHI_STATE_PROCESSING) {
		LOG_ERR("The request data is not processing (state=%d)", data->shi_state);
		return -EBUSY;
	}

	/* Copy preamble */
	memcpy(data->out_msg, out_preamble, sizeof(out_preamble));

	/* Copy data */
	memcpy(data->out_msg + sizeof(out_preamble), buf->buf, buf->len);

	/* Append our past-end byte, which we reserved space for. */
	for (int i = 0; i < EC_SHI_PAST_END_LENGTH; i++) {
		data->out_msg[sizeof(out_preamble) + buf->len + i] = EC_SHI_PAST_END;
	}

	tx_size = buf->len + EC_SHI_PREAMBLE_LENGTH + EC_SHI_PAST_END_LENGTH;

	/* Transmit the reply */
	shi_ite_response_host_data(dev, data->out_msg, tx_size);

	return 0;
}

/* Store request data from Rx FIFO to in_msg buffer */
static void shi_ite_host_request_data(uint8_t *in_msg_addr, int count)
{
	/* CPU Rx FIFO1 access */
	IT83XX_SPI_TXRXFAR = IT83XX_SPI_CPURXF1A;

	/*
	 * In shi_ite_parse_header, the request data will separate to write in_msg buffer so we
	 * cannot set CPU to end accessing Rx FIFO in this function. We will set
	 * IT83XX_SPI_TXRXFAR = 0 in shi_ite_reset_rx_fifo.
	 */
	for (int i = 0; i < count; i += 4) {
		/* Get data from master to buffer */
		*(uint32_t *)(in_msg_addr + i) = IT83XX_SPI_RXFRDRB0;
	}
}

static int shi_ite_host_request_expected_size(const struct ec_host_cmd_request_header *r)
{
	/* Check host request version */
	if (r->prtcl_ver != EC_HOST_REQUEST_VERSION) {
		return 0;
	}

	/* Reserved byte should be 0 */
	if (r->reserved) {
		return 0;
	}

	return sizeof(*r) + r->data_len;
}

/* Parse header for version of spi-protocol */
static void shi_ite_parse_header(const struct device *dev)
{
	struct shi_it8xxx2_data *data = dev->data;
	struct ec_host_cmd_request_header *r = (struct ec_host_cmd_request_header *)data->in_msg;

	/* Store request data from Rx FIFO to in_msg buffer */
	shi_ite_host_request_data(data->in_msg, sizeof(*r));

	/* Protocol version 3 */
	if (data->in_msg[0] == EC_HOST_REQUEST_VERSION) {
		/* Check how big the packet should be */
		data->in_msg_size = shi_ite_host_request_expected_size(r);

		if (data->in_msg_size == 0 || data->in_msg_size > sizeof(data->in_msg)) {
			shi_ite_bad_received_data(dev, data->in_msg_size);
			return;
		}

		/* Store request data from Rx FIFO to in_msg buffer */
		shi_ite_host_request_data(data->in_msg + sizeof(*r),
					  data->in_msg_size - sizeof(*r));

		k_sem_give(&data->handler_owns);
	} else {
		/* Invalid version number */
		LOG_ERR("Invalid version number");
		shi_ite_bad_received_data(dev, 1);
	}
}

static void shi_ite_int_handler(const struct device *dev)
{
	struct shi_it8xxx2_data *data = dev->data;

	if (data->shi_state == SHI_STATE_DISABLED) {
		return;
	}

	/*
	 * The status of SPI end detection interrupt bit is set, it means that host command parse
	 * has been completed and AP has received the last byte which is EC_SHI_PAST_END from
	 * EC responded data, then AP ended the transaction.
	 */
	if (IT83XX_SPI_ISR & IT83XX_SPI_ENDDETECTINT) {
		/* Disable CPU access Rx FIFO to clock in data from AP again */
		IT83XX_SPI_TXRXFAR = 0;
		/* Ready to receive */
		shi_ite_set_state(data, SHI_STATE_READY_TO_RECV);
		/* CS# is deasserted, so write clear all slave status */
		IT83XX_SPI_ISR = 0xff;
		/* Allow the MCU to go into lower power mode */
		pm_policy_state_lock_put(PM_STATE_STANDBY, PM_ALL_SUBSTATES);
	}

	/*
	 * The status of Rx valid length interrupt bit is set that indicates reached target count
	 * (IT83XX_SPI_FTCB1R, IT83XX_SPI_FTCB0R) and the length field of the host requested data.
	 */
	if (IT83XX_SPI_RX_VLISR & IT83XX_SPI_RVLI) {
		/* write clear slave status */
		IT83XX_SPI_RX_VLISR = IT83XX_SPI_RVLI;
		/* Move to processing state */
		shi_ite_set_state(data, SHI_STATE_PROCESSING);
		/* Parse header for version of spi-protocol */
		shi_ite_parse_header(dev);
	}
}

void shi_ite_cs_callback(const struct device *port, struct gpio_callback *cb, gpio_port_pins_t pins)
{
	struct shi_it8xxx2_data *data = CONTAINER_OF(cb, struct shi_it8xxx2_data, cs_cb);

	if (data->shi_state == SHI_STATE_DISABLED) {
		return;
	}

	/* Prevent the MCU from sleeping during the transmission */
	pm_policy_state_lock_get(PM_STATE_STANDBY, PM_ALL_SUBSTATES);

	/* Move to processing state */
	shi_ite_set_state(data, SHI_STATE_PROCESSING);
}

static int shi_ite_init_registers(const struct device *dev)
{
	const struct shi_it8xxx2_cfg *const cfg = dev->config;
	/* Set FIFO data target count */
	struct ec_host_cmd_request_header cmd_head;
	int status;

	/*
	 * Target count means the size of host request.
	 * And plus extra 4 bytes because the CPU accesses FIFO base on word. If host requested
	 * data length is one byte, we need to align the data length to 4 bytes.
	 */
	int target_count = sizeof(cmd_head) + 4;
	/* Offset of data_len member of host request. */
	int offset = (char *)&cmd_head.data_len - (char *)&cmd_head;

	IT83XX_SPI_FTCB1R = (target_count >> 8) & 0xff;
	IT83XX_SPI_FTCB0R = target_count & 0xff;

	/*
	 * The register setting can capture the length field of host
	 * request.
	 */
	IT83XX_SPI_TCCB1 = (offset >> 8) & 0xff;
	IT83XX_SPI_TCCB0 = offset & 0xff;

	/*
	 * Memory controller configuration register 3.
	 * bit6 : SPI pin function select (0b:Enable, 1b:Mask)
	 */
	IT83XX_GCTRL_MCCR3 |= IT83XX_GCTRL_SPISLVPFE;

	/* Set unused blocked byte */
	IT83XX_SPI_HPR2 = 0x00;

	/* Rx valid length interrupt enabled */
	IT83XX_SPI_RX_VLISMR &= ~IT83XX_SPI_RVLIM;

	/*
	 * General control register2
	 * bit4 : Rx FIFO2 will not be overwrited once it's full.
	 * bit3 : Rx FIFO1 will not be overwrited once it's full.
	 * bit0 : Rx FIFO1/FIFO2 will reset after each CS_N goes high.
	 */
	IT83XX_SPI_GCR2 = IT83XX_SPI_RXF2OC | IT83XX_SPI_RXF1OC | IT83XX_SPI_RXFAR;

	/*
	 * Interrupt mask register (0b:Enable, 1b:Mask)
	 * bit5 : Rx byte reach interrupt mask
	 * bit2 : SPI end detection interrupt mask
	 */
	IT83XX_SPI_IMR &= ~IT83XX_SPI_EDIM;

	/* Reset fifo and prepare to for next transaction */
	shi_ite_reset_rx_fifo();

	/* Ready to receive */
	shi_ite_set_state(dev->data, SHI_STATE_READY_TO_RECV);

	/* Interrupt status register(write one to clear) */
	IT83XX_SPI_ISR = 0xff;

	/* SPI peripheral controller enable (after settings are ready) */
	IT83XX_SPI_SPISGCR = IT83XX_SPI_SPISCEN;

	/* Set the pin to SHI alternate function. */
	status = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT);
	if (status < 0) {
		LOG_ERR("Failed to configure SHI pins");
		return status;
	}

	/* Enable SPI peripheral interrupt */
	IRQ_CONNECT(DT_INST_IRQN(0), DT_INST_IRQ(0, priority), shi_ite_int_handler,
		    DEVICE_DT_INST_GET(0), 0);
	irq_enable(DT_INST_IRQN(0));

	return 0;
}

static int shi_ite_init_peripheral(const struct device *dev)
{
	struct shi_it8xxx2_data *data = dev->data;

	/* Allow writing to rx buff at startup and block on reading. */
	k_sem_init(&data->handler_owns, 0, 1);
	k_sem_init(&data->dev_owns, 1, 1);

	return 0;
}

static int shi_ite_init(const struct device *dev)
{
	const struct shi_it8xxx2_cfg *cfg = dev->config;
	struct shi_it8xxx2_data *data = dev->data;
	int ret;

	ret = shi_ite_init_registers(dev);
	if (ret) {
		return ret;
	}

	ret = shi_ite_init_peripheral(dev);
	if (ret) {
		return ret;
	}

	/* Configure the SPI chip select */
	ret = gpio_pin_configure(cfg->cs.port, cfg->cs.pin, GPIO_INPUT | cfg->cs.dt_flags);
	if (ret < 0) {
		LOG_ERR("Failed to configure SHI CS pin");
		return ret;
	}

	/* Enable SPI chip select pin interrupt */
	gpio_init_callback(&data->cs_cb, shi_ite_cs_callback, BIT(cfg->cs.pin));
	ret = gpio_add_callback(cfg->cs.port, &data->cs_cb);
	if (ret < 0) {
		return -EINVAL;
	}

	ret = gpio_pin_interrupt_configure(cfg->cs.port, cfg->cs.pin, GPIO_INT_EDGE_FALLING);
	if (ret < 0) {
		LOG_ERR("Failed to configure SHI CS interrupt");
		return -EINVAL;
	}

	pm_device_init_suspended(dev);
	return pm_device_runtime_enable(dev);
}

static int shi_ite_periph_init_context(const struct device *dev,
				       struct ec_host_cmd_periph_rx_ctx *rx_ctx)
{
	struct shi_it8xxx2_data *data = dev->data;

	rx_ctx->dev_owns = &data->dev_owns;
	rx_ctx->handler_owns = &data->handler_owns;
	rx_ctx->buf = data->in_msg;
	rx_ctx->len = &data->in_msg_size;

	return 0;
}

PINCTRL_DT_INST_DEFINE(0);

#ifdef CONFIG_PM_DEVICE
static int shi_ite_pm_cb(const struct device *dev, enum pm_device_action action)
{
	struct shi_it8xxx2_data *data = dev->data;
	int ret = 0;

	switch (action) {
	case PM_DEVICE_ACTION_SUSPEND:
		shi_ite_set_state(data, SHI_STATE_DISABLED);
		break;
	case PM_DEVICE_ACTION_RESUME:
		shi_ite_set_state(data, SHI_STATE_READY_TO_RECV);
		break;
	default:
		ret = -ENOTSUP;
		break;
	}

	return ret;
}
#endif

/* Assume only one peripheral */
PM_DEVICE_DT_INST_DEFINE(0, shi_ite_pm_cb);

static const struct ec_host_cmd_periph_api ec_host_cmd_api = {
	.init = shi_ite_periph_init_context,
	.send = shi_ite_periph_send,
};

static const struct shi_it8xxx2_cfg shi_cfg = {
	.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(0),
	.cs = GPIO_DT_SPEC_GET_BY_IDX(DT_DRV_INST(0), cs_gpios, 0),
};

static struct shi_it8xxx2_data shi_data = {
	.shi_state = SHI_STATE_DISABLED,
	.in_msg_size = 0,
};

DEVICE_DT_INST_DEFINE(0, shi_ite_init, PM_DEVICE_DT_INST_GET(0), &shi_data, &shi_cfg, POST_KERNEL,
		      CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &ec_host_cmd_api);
