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

#define DT_DRV_COMPAT nuvoton_npcx_shi

#include "ec_host_cmd_backend_shi.h"

#include <zephyr/drivers/clock_control.h>
#include <zephyr/drivers/pinctrl.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 <soc_miwu.h>

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

LOG_MODULE_REGISTER(host_cmd_shi_npcx, CONFIG_EC_HC_LOG_LEVEL);

/* Driver convenience defines */
#define HAL_INSTANCE(dev) (struct shi_reg *)(((const struct shi_npcx_config *)(dev)->config)->base)

/* Full output buffer size */
#define SHI_OBUF_FULL_SIZE     DT_INST_PROP(0, buffer_tx_size)
/* Full input buffer size  */
#define SHI_IBUF_FULL_SIZE     DT_INST_PROP(0, buffer_rx_size)
/* Configure the IBUFLVL2 = the size of V3 protocol header */
#define SHI_IBUFLVL2_THRESHOLD (sizeof(struct ec_host_cmd_request_header))
/* Half output buffer size */
#define SHI_OBUF_HALF_SIZE     (SHI_OBUF_FULL_SIZE / 2)
/* Half input buffer size */
#define SHI_IBUF_HALF_SIZE     (SHI_IBUF_FULL_SIZE / 2)

/*
 * Timeout to wait for SHI request packet
 *
 * This affects the slowest SPI clock we can support. A delay of 8192 us permits a 512-byte request
 * at 500 KHz, assuming the SPI controller starts sending bytes as soon as it asserts chip select.
 * That's as slow as we would practically want to run the SHI interface, since running it slower
 * significantly impacts firmware update times.
 */
#define EC_SHI_CMD_RX_TIMEOUT_US 8192

/*
 * The AP blindly clocks back bytes over the SPI interface looking for a framing byte.
 * So this preamble must always precede the actual response packet.
 */
#define EC_SHI_OUT_PREAMBLE_LENGTH 2

/*
 * Space allocation of the past-end status byte (EC_SHI_PAST_END) in the out_msg buffer.
 */
#define EC_SHI_PAST_END_LENGTH 1

/*
 * Space allocation of the frame status byte (EC_SHI_FRAME_START) in the out_msg buffer.
 */
#define EC_SHI_FRAME_START_LENGTH 1

/*
 * Offset of output parameters needs to account for pad and framing bytes and
 * one last past-end byte at the end so any additional bytes clocked out by
 * the AP will have a known and identifiable value.
 */
#define EC_SHI_PROTO3_OVERHEAD (EC_SHI_PAST_END_LENGTH + EC_SHI_FRAME_START_LENGTH)

/*
 * Our input and output msg buffers. These must be large enough for our largest
 * message, including protocol overhead. The pointers after the protocol
 * overhead, as passed to the host command handler, must be 32-bit aligned.
 */
#define SHI_OUT_START_PAD (4 * (EC_SHI_FRAME_START_LENGTH / 4 + 1))
#define SHI_OUT_END_PAD   (4 * (EC_SHI_PAST_END_LENGTH / 4 + 1))

enum shi_npcx_state {
	SHI_STATE_NONE = -1,
	/* SHI not enabled (initial state, and when chipset is off) */
	SHI_STATE_DISABLED = 0,
	/* Ready to receive next request */
	SHI_STATE_READY_TO_RECV,
	/* Receiving request */
	SHI_STATE_RECEIVING,
	/* Processing request */
	SHI_STATE_PROCESSING,
	/* Canceling response since CS deasserted and output NOT_READY byte */
	SHI_STATE_CNL_RESP_NOT_RDY,
	/* Sending response */
	SHI_STATE_SENDING,
	/* Received data is invalid */
	SHI_STATE_BAD_RECEIVED_DATA,
};

/* Device config */
struct shi_npcx_config {
	/* Serial Host Interface (SHI) base address */
	uintptr_t base;
	/* Clock configuration */
	struct npcx_clk_cfg clk_cfg;
	/* Pin control configuration */
	const struct pinctrl_dev_config *pcfg;
	/* Chip-select interrupts */
	int irq;
	struct npcx_wui shi_cs_wui;
};

struct shi_npcx_data {
	struct ec_host_cmd_rx_ctx *rx_ctx;
	struct ec_host_cmd_tx_buf *tx;
	/* Communication status */
	enum shi_npcx_state state;
	enum shi_npcx_state last_error_state;
	uint8_t *rx_msg;          /* Entry pointer of msg rx buffer   */
	uint8_t *tx_msg;          /* Entry pointer of msg tx buffer   */
	volatile uint8_t *rx_buf; /* Entry pointer of receive buffer  */
	volatile uint8_t *tx_buf; /* Entry pointer of transmit buffer */
	uint16_t sz_sending;      /* Size of sending data in bytes    */
	uint16_t sz_request;      /* Request bytes need to receive    */
	uint16_t sz_response;     /* Response bytes need to receive   */
	uint64_t rx_deadline;     /* Deadline of receiving            */
	/* Buffers */
	uint8_t out_msg_padded[SHI_OUT_START_PAD + CONFIG_EC_HOST_CMD_BACKEND_SHI_MAX_RESPONSE +
			       SHI_OUT_END_PAD] __aligned(4);
	uint8_t *const out_msg;
	uint8_t in_msg[CONFIG_EC_HOST_CMD_BACKEND_SHI_MAX_REQUEST] __aligned(4);
};

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

#define EC_HOST_CMD_SHI_NPCX_DEFINE(_name)                                                         \
	static struct ec_host_cmd_shi_npcx_ctx _name##_hc_shi_npcx;                                \
	struct ec_host_cmd_backend _name = {                                                       \
		.api = &ec_host_cmd_api,                                                           \
		.ctx = (struct ec_host_cmd_shi_npcx_ctx *)&_name##_hc_shi_npcx,                    \
	}

/* Forward declaration */
static void shi_npcx_reset_prepare(const struct device *dev);

/* Read pointer of input or output buffer by consecutive reading */
static uint32_t shi_npcx_read_buf_pointer(struct shi_reg *const inst)
{
	uint8_t stat;

	/* Wait for two consecutive equal values read */
	do {
		stat = inst->IBUFSTAT;
	} while (stat != inst->IBUFSTAT);

	return (uint32_t)stat;
}

/*
 * Valid offset of SHI output buffer to write.
 * When SIMUL bit is set, IBUFPTR can be used instead of OBUFPTR
 */
static uint32_t shi_npcx_valid_obuf_offset(struct shi_reg *const inst)
{
	return (shi_npcx_read_buf_pointer(inst) + EC_SHI_OUT_PREAMBLE_LENGTH) % SHI_OBUF_FULL_SIZE;
}

/*
 * This routine write SHI next half output buffer from msg buffer
 */
static void shi_npcx_write_half_outbuf(const struct device *dev)
{
	struct shi_npcx_data *data = dev->data;

	const uint32_t size = MIN(SHI_OBUF_HALF_SIZE, data->sz_response - data->sz_sending);
	uint8_t *obuf_ptr = (uint8_t *)data->tx_buf;
	const uint8_t *obuf_end = obuf_ptr + size;
	uint8_t *msg_ptr = data->tx_msg;

	/* Fill half output buffer */
	while (obuf_ptr != obuf_end) {
		*obuf_ptr++ = *msg_ptr++;
	}

	data->sz_sending += size;
	data->tx_buf = obuf_ptr;
	data->tx_msg = msg_ptr;
}

/*
 * This routine read SHI input buffer to msg buffer until
 * we have received a certain number of bytes
 */
static int shi_npcx_read_inbuf_wait(const struct device *dev, uint32_t szbytes)
{
	struct shi_npcx_data *data = dev->data;
	struct shi_reg *const inst = HAL_INSTANCE(dev);

	/* Copy data to msg buffer from input buffer */
	for (uint32_t i = 0; i < szbytes; i++, data->rx_ctx->len++) {
		/*
		 * If input buffer pointer equals pointer which wants to read,
		 * it means data is not ready.
		 */
		while (data->rx_buf == inst->IBUF + shi_npcx_read_buf_pointer(inst)) {
			if (k_cycle_get_64() >= data->rx_deadline) {
				return 0;
			}
		}

		/* Copy data to msg buffer */
		*data->rx_msg++ = *data->rx_buf++;
	}
	return 1;
}

/* This routine fills out all SHI output buffer with status byte */
static void shi_npcx_fill_out_status(struct shi_reg *const inst, uint8_t status)
{
	uint8_t start, end;
	volatile uint8_t *fill_ptr;
	volatile uint8_t *fill_end;
	volatile uint8_t *obuf_end;

	/*
	 * Disable interrupts in case the interfere by the other interrupts.
	 * Use __disable_irq/__enable_irq instead of using irq_lock/irq_unlock
	 * here because irq_lock/irq_unlock leave some system exceptions (like
	 * SVC, NMI, and faults) still enabled.
	 */
	__disable_irq();

	/*
	 * Fill out output buffer with status byte and leave a gap for PREAMBLE.
	 * The gap guarantees the synchronization. The critical section should
	 * be done within this gap. No racing happens.
	 */
	start = shi_npcx_valid_obuf_offset(inst);
	end = (start + SHI_OBUF_FULL_SIZE - EC_SHI_OUT_PREAMBLE_LENGTH) % SHI_OBUF_FULL_SIZE;

	fill_ptr = inst->OBUF + start;
	fill_end = inst->OBUF + end;
	obuf_end = inst->OBUF + SHI_OBUF_FULL_SIZE;
	while (fill_ptr != fill_end) {
		*fill_ptr++ = status;
		if (fill_ptr == obuf_end) {
			fill_ptr = inst->OBUF;
		}
	}

	/* End of critical section */
	__enable_irq();
}

/* This routine handles shi received unexpected data */
static void shi_npcx_bad_received_data(const struct device *dev)
{
	struct shi_npcx_data *data = dev->data;
	struct shi_reg *const inst = HAL_INSTANCE(dev);

	/* State machine mismatch, timeout, or protocol we can't handle. */
	shi_npcx_fill_out_status(inst, EC_SHI_RX_BAD_DATA);
	data->state = SHI_STATE_BAD_RECEIVED_DATA;

	LOG_ERR("SHI bad data recv");
	LOG_DBG("BAD-");
	LOG_HEXDUMP_DBG(data->in_msg, data->rx_ctx->len, "in_msg=");

	/* Reset shi's state machine for error recovery */
	shi_npcx_reset_prepare(dev);

	LOG_DBG("END");
}

/*
 * This routine write SHI output buffer from msg buffer over halt of it.
 * It make sure we have enough time to handle next operations.
 */
static void shi_npcx_write_first_pkg_outbuf(const struct device *dev, uint16_t szbytes)
{
	struct shi_npcx_data *data = dev->data;
	struct shi_reg *const inst = HAL_INSTANCE(dev);
	uint8_t size, offset;
	volatile uint8_t *obuf_ptr;
	volatile uint8_t *obuf_end;
	uint8_t *msg_ptr;
	uint32_t half_buf_remain; /* Remains in half buffer are free to write */

	/* Start writing at our current OBUF position */
	offset = shi_npcx_valid_obuf_offset(inst);
	obuf_ptr = inst->OBUF + offset;
	msg_ptr = data->tx_msg;

	/* Fill up to OBUF mid point, or OBUF end */
	half_buf_remain = SHI_OBUF_HALF_SIZE - (offset % SHI_OBUF_HALF_SIZE);
	size = MIN(half_buf_remain, szbytes - data->sz_sending);
	obuf_end = obuf_ptr + size;
	while (obuf_ptr != obuf_end) {
		*obuf_ptr++ = *msg_ptr++;
	}

	/* Track bytes sent for later accounting */
	data->sz_sending += size;

	/* Write data to beginning of OBUF if we've reached the end */
	if (obuf_ptr == inst->OBUF + SHI_IBUF_FULL_SIZE) {
		obuf_ptr = inst->OBUF;
	}

	/* Fill next half output buffer */
	size = MIN(SHI_OBUF_HALF_SIZE, szbytes - data->sz_sending);
	obuf_end = obuf_ptr + size;
	while (obuf_ptr != obuf_end) {
		*obuf_ptr++ = *msg_ptr++;
	}

	/* Track bytes sent / last OBUF position written for later accounting */
	data->sz_sending += size;
	data->tx_buf = obuf_ptr;
	data->tx_msg = msg_ptr;
}

static void shi_npcx_handle_host_package(const struct device *dev)
{
	struct shi_npcx_data *data = dev->data;
	struct shi_reg *const inst = HAL_INSTANCE(dev);
	uint32_t sz_inbuf_int = data->sz_request / SHI_IBUF_HALF_SIZE;
	uint32_t cnt_inbuf_int = data->rx_ctx->len / SHI_IBUF_HALF_SIZE;

	if (sz_inbuf_int - cnt_inbuf_int) {
		/* Need to receive data from buffer */
		return;
	}

	uint32_t remain_bytes = data->sz_request - data->rx_ctx->len;

	/* Read remaining bytes from input buffer */
	if (!shi_npcx_read_inbuf_wait(dev, remain_bytes)) {
		return shi_npcx_bad_received_data(dev);
	}

	/* Move to processing state */
	data->state = SHI_STATE_PROCESSING;
	LOG_DBG("PRC-");

	/* Fill output buffer to indicate we`re processing request */
	shi_npcx_fill_out_status(inst, EC_SHI_PROCESSING);
	data->out_msg[0] = EC_SHI_FRAME_START;

	/* Wake-up the HC handler thread */
	k_sem_give(&data->rx_ctx->handler_owns);
}

static int shi_npcx_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;
}

static void shi_npcx_parse_header(const struct device *dev)
{
	struct shi_npcx_data *data = dev->data;

	/* We're now inside a transaction */
	data->state = SHI_STATE_RECEIVING;
	LOG_DBG("RV-");

	/* Setup deadline time for receiving */
	data->rx_deadline = k_cycle_get_64() + k_us_to_cyc_near64(EC_SHI_CMD_RX_TIMEOUT_US);

	/* Wait for version, command, length bytes */
	if (!shi_npcx_read_inbuf_wait(dev, 3)) {
		return shi_npcx_bad_received_data(dev);
	}

	if (data->in_msg[0] == EC_HOST_REQUEST_VERSION) {
		/* Protocol version 3 */
		struct ec_host_cmd_request_header *r =
			(struct ec_host_cmd_request_header *)data->in_msg;
		int pkt_size;

		/*
		 * If request is over half of input buffer, we need to modify the algorithm again.
		 */
		__ASSERT_NO_MSG(sizeof(*r) < SHI_IBUF_HALF_SIZE);

		/* Wait for the rest of the command header */
		if (!shi_npcx_read_inbuf_wait(dev, sizeof(*r) - 3)) {
			return shi_npcx_bad_received_data(dev);
		}

		/* Check how big the packet should be */
		pkt_size = shi_npcx_host_request_expected_size(r);
		if (pkt_size == 0 || pkt_size > sizeof(data->in_msg)) {
			return shi_npcx_bad_received_data(dev);
		}

		/* Computing total bytes need to receive */
		data->sz_request = pkt_size;

		shi_npcx_handle_host_package(dev);
	} else {
		/* Invalid version number */
		return shi_npcx_bad_received_data(dev);
	}
}

static void shi_npcx_sec_ibf_int_enable(struct shi_reg *const inst, int enable)
{
	if (enable) {
		/* Setup IBUFLVL2 threshold and enable it */
		inst->SHICFG5 |= BIT(NPCX_SHICFG5_IBUFLVL2DIS);
		SET_FIELD(inst->SHICFG5, NPCX_SHICFG5_IBUFLVL2, SHI_IBUFLVL2_THRESHOLD);
		inst->SHICFG5 &= ~BIT(NPCX_SHICFG5_IBUFLVL2DIS);

		/* Enable IBHF2 event */
		inst->EVENABLE2 |= BIT(NPCX_EVENABLE2_IBHF2EN);
	} else {
		/* Disable IBHF2 event first */
		inst->EVENABLE2 &= ~BIT(NPCX_EVENABLE2_IBHF2EN);

		/* Disable IBUFLVL2 and set threshold back to zero */
		inst->SHICFG5 |= BIT(NPCX_SHICFG5_IBUFLVL2DIS);
		SET_FIELD(inst->SHICFG5, NPCX_SHICFG5_IBUFLVL2, 0);
	}
}

/* This routine copies SHI half input buffer data to msg buffer */
static void shi_npcx_read_half_inbuf(const struct device *dev)
{
	struct shi_npcx_data *data = dev->data;

	/*
	 * Copy to read buffer until reaching middle/top address of
	 * input buffer or completing receiving data
	 */
	do {
		/* Restore data to msg buffer */
		*data->rx_msg++ = *data->rx_buf++;
		data->rx_ctx->len++;
	} while (data->rx_ctx->len % SHI_IBUF_HALF_SIZE && data->rx_ctx->len != data->sz_request);
}

/*
 * Avoid spamming the console with prints every IBF / IBHF interrupt, if
 * we find ourselves in an unexpected state.
 */
static void shi_npcx_log_unexpected_state(const struct device *dev, char *isr_name)
{
	struct shi_npcx_data *data = dev->data;

	if (data->state != data->last_error_state) {
		LOG_ERR("Unexpected state %d in %s ISR", data->state, isr_name);
	}

	data->last_error_state = data->state;
}

static void shi_npcx_handle_cs_assert(const struct device *dev)
{
	struct shi_reg *const inst = HAL_INSTANCE(dev);
	struct shi_npcx_data *data = dev->data;

	/* If not enabled, ignore glitches on SHI_CS_L */
	if (data->state == SHI_STATE_DISABLED) {
		return;
	}

	/* NOT_READY should be sent and there're no spi transaction now. */
	if (data->state == SHI_STATE_CNL_RESP_NOT_RDY) {
		return;
	}

	/* Chip select is low = asserted */
	if (data->state != SHI_STATE_READY_TO_RECV) {
		/* State machine should be reset in EVSTAT_EOR ISR */
		LOG_ERR("Unexpected state %d in CS ISR", data->state);
		return;
	}

	LOG_DBG("CSL-");

	/*
	 * Clear possible EOR event from previous transaction since it's
	 * irrelevant now that CS is re-asserted.
	 */
	inst->EVSTAT = BIT(NPCX_EVSTAT_EOR);
}

static void shi_npcx_handle_cs_deassert(const struct device *dev)
{
	struct shi_reg *const inst = HAL_INSTANCE(dev);
	struct shi_npcx_data *data = dev->data;

	/*
	 * If the buffer is still used by the host command.
	 * Change state machine for response handler.
	 */
	if (data->state == SHI_STATE_PROCESSING) {
		/*
		 * Mark not ready to prevent the other
		 * transaction immediately
		 */
		shi_npcx_fill_out_status(inst, EC_SHI_NOT_READY);

		data->state = SHI_STATE_CNL_RESP_NOT_RDY;

		/*
		 * Disable SHI interrupt, it will remain disabled until shi_send_response_packet()
		 * is called and CS is asserted for a new transaction.
		 */
		irq_disable(DT_INST_IRQN(0));

		LOG_DBG("CNL-");
		return;
		/* Next transaction but we're not ready */
	} else if (data->state == SHI_STATE_CNL_RESP_NOT_RDY) {
		return;
	}

	/* Error state for checking*/
	if (data->state != SHI_STATE_SENDING) {
		shi_npcx_log_unexpected_state(dev, "CSNRE");
	}

	/* reset SHI and prepare to next transaction again */
	shi_npcx_reset_prepare(dev);
	LOG_DBG("END\n");
}

static void shi_npcx_handle_input_buf_half_full(const struct device *dev)
{
	struct shi_reg *const inst = HAL_INSTANCE(dev);
	struct shi_npcx_data *data = dev->data;

	if (data->state == SHI_STATE_RECEIVING) {
		/* Read data from input to msg buffer */
		shi_npcx_read_half_inbuf(dev);
		return shi_npcx_handle_host_package(dev);
	} else if (data->state == SHI_STATE_SENDING) {
		/* Write data from msg buffer to output buffer */
		if (data->tx_buf == inst->OBUF + SHI_OBUF_FULL_SIZE) {
			/* Write data from bottom address again */
			data->tx_buf = inst->OBUF;
			shi_npcx_write_half_outbuf(dev);
		}
	} else if (data->state == SHI_STATE_PROCESSING) {
		/* Wait for host to handle request */
	} else {
		/* Unexpected status */
		shi_npcx_log_unexpected_state(dev, "IBHF");
	}
}

static void shi_npcx_handle_input_buf_full(const struct device *dev)
{
	struct shi_npcx_data *data = dev->data;
	struct shi_reg *const inst = HAL_INSTANCE(dev);

	if (data->state == SHI_STATE_RECEIVING) {
		/* read data from input to msg buffer */
		shi_npcx_read_half_inbuf(dev);
		/* Read to bottom address again */
		data->rx_buf = inst->IBUF;
		return shi_npcx_handle_host_package(dev);
	} else if (data->state == SHI_STATE_SENDING) {
		/* Write data from msg buffer to output buffer */
		if (data->tx_buf == inst->OBUF + SHI_OBUF_HALF_SIZE) {
			shi_npcx_write_half_outbuf(dev);
		}

		return;
	} else if (data->state == SHI_STATE_PROCESSING) {
		/* Wait for host to handle request */
		return;
	}

	/* Unexpected status */
	shi_npcx_log_unexpected_state(dev, "IBF");
}

static void shi_npcx_isr(const struct device *dev)
{
	struct shi_reg *const inst = HAL_INSTANCE(dev);
	uint8_t stat;
	uint8_t stat2;

	/* Read status register and clear interrupt status early */
	stat = inst->EVSTAT;
	inst->EVSTAT = stat;
	stat2 = inst->EVSTAT2;

	/* SHI CS pin is asserted in EVSTAT2 */
	if (IS_BIT_SET(stat2, NPCX_EVSTAT2_CSNFE)) {
		/* Clear pending bit of CSNFE */
		inst->EVSTAT2 = BIT(NPCX_EVSTAT2_CSNFE);
		LOG_DBG("CSNFE-");

		/*
		 * BUSY bit is set when SHI_CS is asserted. If not, leave it for
		 * SHI_CS de-asserted event.
		 */
		if (!IS_BIT_SET(inst->SHICFG2, NPCX_SHICFG2_BUSY)) {
			LOG_DBG("CSNB-");
			return;
		}

		shi_npcx_handle_cs_assert(dev);
	}

	/*
	 * End of data for read/write transaction. i.e. SHI_CS is deasserted.
	 * Host completed or aborted transaction
	 *
	 * EOR has the limitation that it will not be set even if the SHI_CS is deasserted without
	 * SPI clocks. The new SHI module introduce the CSNRE bit which will be set when SHI_CS is
	 * deasserted regardless of SPI clocks.
	 */
	if (IS_BIT_SET(stat2, NPCX_EVSTAT2_CSNRE)) {
		/* Clear pending bit of CSNRE */
		inst->EVSTAT2 = BIT(NPCX_EVSTAT2_CSNRE);

		/*
		 * We're not in proper state.
		 * Mark not ready to abort next transaction
		 */
		LOG_DBG("CSH-");
		return shi_npcx_handle_cs_deassert(dev);
	}

	/*
	 * The number of bytes received reaches the size of
	 * protocol V3 header(=8) after CS asserted.
	 */
	if (IS_BIT_SET(stat2, NPCX_EVSTAT2_IBHF2)) {
		/* Clear IBHF2 */
		inst->EVSTAT2 = BIT(NPCX_EVSTAT2_IBHF2);
		LOG_DBG("HDR-");

		/* Disable second IBF interrupt and start to parse header */
		shi_npcx_sec_ibf_int_enable(inst, 0);
		shi_npcx_parse_header(dev);
	}

	/*
	 * Indicate input/output buffer pointer reaches the half buffer size.
	 * Transaction is processing.
	 */
	if (IS_BIT_SET(stat, NPCX_EVSTAT_IBHF)) {
		return shi_npcx_handle_input_buf_half_full(dev);
	}

	/*
	 * Indicate input/output buffer pointer reaches the full buffer size.
	 * Transaction is processing.
	 */
	if (IS_BIT_SET(stat, NPCX_EVSTAT_IBF)) {
		return shi_npcx_handle_input_buf_full(dev);
	}
}

static void shi_npcx_reset_prepare(const struct device *dev)
{
	struct shi_reg *const inst = HAL_INSTANCE(dev);
	struct shi_npcx_data *data = dev->data;
	uint32_t i;

	data->state = SHI_STATE_DISABLED;

	irq_disable(DT_INST_IRQN(0));

	/* Disable SHI unit to clear all status bits */
	inst->SHICFG1 &= ~BIT(NPCX_SHICFG1_EN);

	/* Initialize parameters of next transaction */
	data->rx_msg = data->in_msg;
	data->tx_msg = data->out_msg;
	data->rx_buf = inst->IBUF;
	data->tx_buf = inst->OBUF;
	data->rx_ctx->len = 0;
	data->sz_sending = 0;
	data->sz_request = 0;
	data->sz_response = 0;

	/*
	 * Fill output buffer to indicate we`re
	 * ready to receive next transaction.
	 */
	for (i = 1; i < SHI_OBUF_FULL_SIZE; i++) {
		inst->OBUF[i] = EC_SHI_RECEIVING;
	}
	inst->OBUF[0] = EC_SHI_RX_READY;

	/* SHI/Host Write/input buffer wrap-around enable */
	inst->SHICFG1 = BIT(NPCX_SHICFG1_IWRAP) | BIT(NPCX_SHICFG1_WEN) | BIT(NPCX_SHICFG1_EN);

	data->state = SHI_STATE_READY_TO_RECV;
	data->last_error_state = SHI_STATE_NONE;

	shi_npcx_sec_ibf_int_enable(inst, 1);
	irq_enable(DT_INST_IRQN(0));

	LOG_DBG("RDY-");
}

static int shi_npcx_enable(const struct device *dev)
{
	const struct device *clk_dev = DEVICE_DT_GET(NPCX_CLK_CTRL_NODE);
	const struct shi_npcx_config *const config = dev->config;
	int ret;

	ret = clock_control_on(clk_dev, (clock_control_subsys_t)&config->clk_cfg);
	if (ret < 0) {
		LOG_ERR("Turn on SHI clock fail %d", ret);
		return ret;
	}

	shi_npcx_reset_prepare(dev);
	npcx_miwu_irq_disable(&config->shi_cs_wui);

	/* Configure pin control for SHI */
	ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT);
	if (ret < 0) {
		LOG_ERR("shi_npcx pinctrl setup failed (%d)", ret);
		return ret;
	}

	NVIC_ClearPendingIRQ(DT_INST_IRQN(0));
	npcx_miwu_irq_enable(&config->shi_cs_wui);
	irq_enable(DT_INST_IRQN(0));

	return 0;
}

static int shi_npcx_disable(const struct device *dev)
{
	const struct device *clk_dev = DEVICE_DT_GET(NPCX_CLK_CTRL_NODE);
	const struct shi_npcx_config *const config = dev->config;
	struct shi_npcx_data *data = dev->data;
	int ret;

	data->state = SHI_STATE_DISABLED;

	irq_disable(DT_INST_IRQN(0));
	npcx_miwu_irq_disable(&config->shi_cs_wui);

	/* Configure pin control back to GPIO */
	ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_SLEEP);
	if (ret < 0) {
		LOG_ERR("KB Raw pinctrl setup failed (%d)", ret);
		return ret;
	}

	ret = clock_control_off(clk_dev, (clock_control_subsys_t)&config->clk_cfg);
	if (ret < 0) {
		LOG_ERR("Turn off SHI clock fail %d", ret);
		return ret;
	}

	return 0;
}

static int shi_npcx_init_registers(const struct device *dev)
{
	int ret;
	const struct shi_npcx_config *const config = dev->config;
	struct shi_reg *const inst = HAL_INSTANCE(dev);
	const struct device *clk_dev = DEVICE_DT_GET(NPCX_CLK_CTRL_NODE);

	/* Turn on shi device clock first */
	ret = clock_control_on(clk_dev, (clock_control_subsys_t)&config->clk_cfg);
	if (ret < 0) {
		LOG_ERR("Turn on SHI clock fail %d", ret);
		return ret;
	}

	/* If booter doesn't set the host interface type */
	if (!NPCX_BOOTER_IS_HIF_TYPE_SET()) {
		npcx_host_interface_sel(NPCX_HIF_TYPE_ESPI_SHI);
	}

	/*
	 * SHICFG1 (SHI Configuration 1) setting
	 * [7] - IWRAP	= 1: Wrap input buffer to the first address
	 * [6] - CPOL	= 0: Sampling on rising edge and output on falling edge
	 * [5] - DAS	= 0: return STATUS reg data after Status command
	 * [4] - AUTOBE	= 0: Automatically update the OBES bit in STATUS reg
	 * [3] - AUTIBF	= 0: Automatically update the IBFS bit in STATUS reg
	 * [2] - WEN    = 0: Enable host write to input buffer
	 * [1] - Reserved 0
	 * [0] - ENABLE	= 0: Disable SHI at the beginning
	 */
	inst->SHICFG1 = BIT(NPCX_SHICFG1_IWRAP);

	/*
	 * SHICFG2 (SHI Configuration 2) setting
	 * [7] - Reserved 0
	 * [6] - REEVEN = 0: Restart events are not used
	 * [5] - Reserved 0
	 * [4] - REEN   = 0: Restart transactions are not used
	 * [3] - SLWU   = 0: Seem-less wake-up is enabled by default
	 * [2] - ONESHOT= 0: WEN is cleared at the end of a write transaction
	 * [1] - BUSY   = 0: SHI bus is busy 0: idle.
	 * [0] - SIMUL	= 1: Turn on simultaneous Read/Write
	 */
	inst->SHICFG2 = BIT(NPCX_SHICFG2_SIMUL);

	/*
	 * EVENABLE (Event Enable) setting
	 * [7] - IBOREN = 0: Input buffer overrun interrupt enable
	 * [6] - STSREN = 0: status read interrupt disable
	 * [5] - EOWEN  = 0: End-of-Data for Write Transaction Interrupt Enable
	 * [4] - EOREN  = 1: End-of-Data for Read Transaction Interrupt Enable
	 * [3] - IBHFEN = 1: Input Buffer Half Full Interrupt Enable
	 * [2] - IBFEN  = 1: Input Buffer Full Interrupt Enable
	 * [1] - OBHEEN = 0: Output Buffer Half Empty Interrupt Enable
	 * [0] - OBEEN  = 0: Output Buffer Empty Interrupt Enable
	 */
	inst->EVENABLE =
		BIT(NPCX_EVENABLE_EOREN) | BIT(NPCX_EVENABLE_IBHFEN) | BIT(NPCX_EVENABLE_IBFEN);

	/*
	 * EVENABLE2 (Event Enable 2) setting
	 * [2] - CSNFEEN = 1: SHI_CS Falling Edge Interrupt Enable
	 * [1] - CSNREEN = 1: SHI_CS Rising Edge Interrupt Enable
	 * [0] - IBHF2EN = 0: Input Buffer Half Full 2 Interrupt Enable
	 */
	inst->EVENABLE2 = BIT(NPCX_EVENABLE2_CSNREEN) | BIT(NPCX_EVENABLE2_CSNFEEN);

	/* Clear SHI events status register */
	inst->EVSTAT = 0xff;

	npcx_miwu_interrupt_configure(&config->shi_cs_wui, NPCX_MIWU_MODE_EDGE, NPCX_MIWU_TRIG_LOW);

	/* SHI interrupt installation */
	IRQ_CONNECT(DT_INST_IRQN(0), DT_INST_IRQ(0, priority), shi_npcx_isr, DEVICE_DT_INST_GET(0),
		    0);

	shi_npcx_enable(dev);

	return ret;
}

static int shi_npcx_init(const struct device *dev)
{
	int ret;

	ret = shi_npcx_init_registers(dev);
	if (ret) {
		return ret;
	}
	pm_device_init_suspended(dev);

	return pm_device_runtime_enable(dev);
}

static int shi_npcx_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_npcx_ctx *hc_shi = (struct ec_host_cmd_shi_npcx_ctx *)backend->ctx;
	struct shi_npcx_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;
	tx->buf = data->out_msg_padded + SHI_OUT_START_PAD;
	tx->len_max = CONFIG_EC_HOST_CMD_BACKEND_SHI_MAX_RESPONSE;

	return 0;
}

static int shi_npcx_backend_send(const struct ec_host_cmd_backend *backend)
{
	struct ec_host_cmd_shi_npcx_ctx *hc_shi = (struct ec_host_cmd_shi_npcx_ctx *)backend->ctx;
	struct shi_npcx_data *data = hc_shi->dev->data;
	uint8_t *out_buf = data->out_msg + EC_SHI_FRAME_START_LENGTH;

	/*
	 * Disable interrupts. This routine is not called from interrupt context and buffer
	 * underrun will likely occur if it is preempted after writing its initial reply byte.
	 * Also, we must be sure our state doesn't unexpectedly change, in case we're expected
	 * to take RESP_NOT_RDY actions.
	 */
	__disable_irq();

	if (data->state == SHI_STATE_PROCESSING) {
		/* Append our past-end byte, which we reserved space for. */
		((uint8_t *)out_buf)[data->tx->len] = EC_SHI_PAST_END;

		/* Computing sending bytes of response */
		data->sz_response = data->tx->len + EC_SHI_PROTO3_OVERHEAD;

		/* Start to fill output buffer with msg buffer */
		shi_npcx_write_first_pkg_outbuf(hc_shi->dev, data->sz_response);

		/* Transmit the reply */
		data->state = SHI_STATE_SENDING;
		LOG_DBG("SND-");
	} else if (data->state == SHI_STATE_CNL_RESP_NOT_RDY) {
		/*
		 * If we're not processing, then the AP has already terminated
		 * the transaction, and won't be listening for a response.
		 * Reset state machine for next transaction.
		 */
		shi_npcx_reset_prepare(hc_shi->dev);
		LOG_DBG("END\n");
	} else {
		LOG_ERR("Unexpected state %d in response handler", data->state);
	}

	__enable_irq();
	return 0;
}

static const struct ec_host_cmd_backend_api ec_host_cmd_api = {
	.init = shi_npcx_backend_init,
	.send = shi_npcx_backend_send,
};

#ifdef CONFIG_PM_DEVICE
static int shi_npcx_pm_cb(const struct device *dev, enum pm_device_action action)
{
	int ret = 0;

	switch (action) {
	case PM_DEVICE_ACTION_SUSPEND:
		shi_npcx_disable(dev);
		break;
	case PM_DEVICE_ACTION_RESUME:
		shi_npcx_enable(dev);
		break;
	default:
		ret = -ENOTSUP;
		break;
	}

	return ret;
}
#endif

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

PINCTRL_DT_INST_DEFINE(0);
static const struct shi_npcx_config shi_cfg = {
	.base = DT_INST_REG_ADDR(0),
	.clk_cfg = NPCX_DT_CLK_CFG_ITEM(0),
	.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(0),
	.irq = DT_INST_IRQN(0),
	.shi_cs_wui = NPCX_DT_WUI_ITEM_BY_NAME(0, shi_cs_wui),
};

static struct shi_npcx_data shi_data = {
	.state = SHI_STATE_DISABLED,
	.last_error_state = SHI_STATE_NONE,
	.out_msg = shi_data.out_msg_padded + SHI_OUT_START_PAD - EC_SHI_FRAME_START_LENGTH,
};

DEVICE_DT_INST_DEFINE(0, shi_npcx_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_NPCX_DEFINE(ec_host_cmd_shi_npcx);

struct ec_host_cmd_backend *ec_host_cmd_backend_get_shi_npcx(void)
{
	return &ec_host_cmd_shi_npcx;
}

#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_npcx());
	return 0;
}
SYS_INIT(host_cmd_init, POST_KERNEL, CONFIG_EC_HOST_CMD_INIT_PRIORITY);
#endif
