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

#define DT_DRV_COMPAT ite_it8xxx2_shi

#include "ec_host_cmd_backend_shi.h"

#include <chip_chipregs.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/backend.h>
#include <zephyr/mgmt/ec_host_cmd/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_BACKEND_SHI_MAX_REQUEST <= SPI_RX_MAX_FIFO_SIZE,
	     "SHI max request size is too big");
BUILD_ASSERT(CONFIG_EC_HOST_CMD_BACKEND_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 ec_host_cmd_rx_ctx *rx_ctx;
	struct ec_host_cmd_tx_buf *tx;
	struct gpio_callback cs_cb;
	/* Current state */
	enum shi_state_machine shi_state;
	/* Buffers */
	uint8_t in_msg[SPI_RX_MAX_FIFO_SIZE] __aligned(4);
	uint8_t out_msg[SPI_TX_MAX_FIFO_SIZE] __aligned(4);
};

struct ec_host_cmd_shi_ite_ctx {
	/* SHI device instance */
	const struct device *dev;
};

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);

#define EC_HOST_CMD_SHI_ITE_DEFINE(_name)                                                          \
	static struct ec_host_cmd_shi_ite_ctx _name##_hc_shi_ite;                                  \
	struct ec_host_cmd_backend _name = {                                                       \
		.api = &ec_host_cmd_api,                                                           \
		.ctx = (struct ec_host_cmd_shi_ite_ctx *)&_name##_hc_shi_ite,                      \
	}

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_backend_send(const struct ec_host_cmd_backend *backend)
{
	struct ec_host_cmd_shi_ite_ctx *hc_shi = (struct ec_host_cmd_shi_ite_ctx *)backend->ctx;
	struct shi_it8xxx2_data *data = hc_shi->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));

	/* Data to sent are already at "out_msg + sizeof(out_preamble)" memory address(tx buf
	 * assigned in the init function), prepared by the handler.
	 * Append our past-end byte, which we reserved space for.
	 */
	memset(&data->out_msg[sizeof(out_preamble) + data->tx->len], EC_SHI_PAST_END,
	       EC_SHI_PAST_END_LENGTH);

	tx_size = data->tx->len + EC_SHI_PREAMBLE_LENGTH + EC_SHI_PAST_END_LENGTH;

	/* Transmit the reply */
	shi_ite_response_host_data(hc_shi->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 (rx_ctx->buf) */
	shi_ite_host_request_data(data->in_msg, sizeof(*r));

	/* Protocol version 3 */
	if (r->prtcl_ver == EC_HOST_REQUEST_VERSION) {
		/* Check how big the packet should be */
		data->rx_ctx->len = shi_ite_host_request_expected_size(r);

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

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

		ec_host_cmd_rx_notify();
	} 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(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;
	}

	/* 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_backend_init(const struct ec_host_cmd_backend *backend,
				struct ec_host_cmd_rx_ctx *rx_ctx, struct ec_host_cmd_tx_buf *tx)
{
	struct ec_host_cmd_shi_ite_ctx *hc_shi = (struct ec_host_cmd_shi_ite_ctx *)backend->ctx;
	struct shi_it8xxx2_data *data;

	hc_shi->dev = DEVICE_DT_INST_GET(0);
	if (!device_is_ready(hc_shi->dev)) {
		return -ENODEV;
	}

	data = hc_shi->dev->data;
	data->rx_ctx = rx_ctx;
	data->tx = tx;

	rx_ctx->buf = data->in_msg;
	rx_ctx->len_max = CONFIG_EC_HOST_CMD_BACKEND_SHI_MAX_REQUEST;
	tx->buf = data->out_msg + sizeof(out_preamble);
	data->tx->len_max = CONFIG_EC_HOST_CMD_BACKEND_SHI_MAX_RESPONSE;

	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_backend_api ec_host_cmd_api = {
	.init = shi_ite_backend_init,
	.send = shi_ite_backend_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,
};

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);

EC_HOST_CMD_SHI_ITE_DEFINE(ec_host_cmd_shi_ite);

struct ec_host_cmd_backend *ec_host_cmd_backend_get_shi_ite(void)
{
	return &ec_host_cmd_shi_ite;
}

#if DT_NODE_EXISTS(DT_CHOSEN(zephyr_host_cmd_shi_backend)) &&                                      \
	defined(CONFIG_EC_HOST_CMD_INITIALIZE_AT_BOOT)
static int host_cmd_init(void)
{
	ec_host_cmd_init(ec_host_cmd_backend_get_shi_ite());
	return 0;
}
SYS_INIT(host_cmd_init, POST_KERNEL, CONFIG_EC_HOST_CMD_INIT_PRIORITY);
#endif
