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

#include <string.h>

#include <zephyr/device.h>
#include <zephyr/drivers/espi.h>
#include <zephyr/logging/log.h>
#include <zephyr/mgmt/ec_host_cmd/backend.h>
#include <zephyr/mgmt/ec_host_cmd/ec_host_cmd.h>

LOG_MODULE_REGISTER(host_cmd_espi, CONFIG_EC_HC_LOG_LEVEL);

#define RX_HEADER_SIZE (sizeof(struct ec_host_cmd_request_header))

/* eSPI Host Command state */
enum ec_host_cmd_espi_state {
	/* Interface is disabled */
	ESPI_STATE_DISABLED,
	/* Ready to receive next request */
	ESPI_STATE_READY_TO_RECV,
	/* Processing request */
	ESPI_STATE_PROCESSING,
	/* Processing request */
	ESPI_STATE_SENDING,
	ESPI_STATE_COUNT,
};

struct ec_host_cmd_espi_ctx {
	/* eSPI device instance */
	const struct device *espi_dev;
	/* Context for read operation */
	struct ec_host_cmd_rx_ctx *rx_ctx;
	/* Transmit buffer */
	struct ec_host_cmd_tx_buf *tx;
	/* eSPI callback */
	struct espi_callback espi_cb;
	/* eSPI Host Command state */
	enum ec_host_cmd_espi_state state;
};

#define EC_HOST_CMD_ESPI_DEFINE(_name)                                                             \
	static struct ec_host_cmd_espi_ctx _name##_hc_espi;                                        \
	struct ec_host_cmd_backend _name = {                                                       \
		.api = &ec_host_cmd_api,                                                           \
		.ctx = (struct ec_host_cmd_espi_ctx *)&_name##_hc_espi,                            \
	}

static void espi_handler(const struct device *dev, struct espi_callback *cb,
			 struct espi_event espi_evt)
{
	struct ec_host_cmd_espi_ctx *hc_espi =
		CONTAINER_OF(cb, struct ec_host_cmd_espi_ctx, espi_cb);
	uint16_t event_type = (uint16_t)espi_evt.evt_details;
	/* tx stores the shared memory buf pointer and size, so use it */
	const struct ec_host_cmd_request_header *rx_header = hc_espi->tx->buf;
	const size_t shared_size = hc_espi->tx->len_max;
	const uint16_t rx_valid_data_size = rx_header->data_len + RX_HEADER_SIZE;

	if (event_type != ESPI_PERIPHERAL_EC_HOST_CMD) {
		return;
	}

	/* Make sure we've received a Host Command in a good state not to override buffers for
	 * a Host Command that is currently being processed. There is a moment between sending
	 * a response and setting state to ESPI_STATE_READY_TO_RECV when we can receive a new
	 * host command, so accept the sending state as well.
	 */
	if (hc_espi->state != ESPI_STATE_READY_TO_RECV && hc_espi->state != ESPI_STATE_SENDING) {
		LOG_ERR("Received HC in bad state");
		return;
	}

	/* Only support version 3 and make sure the number of bytes to copy is not
	 * bigger than rx buf size or the shared memory size
	 */
	if (rx_header->prtcl_ver != 3 ||
	    rx_valid_data_size > CONFIG_EC_HOST_CMD_HANDLER_RX_BUFFER_SIZE ||
	    rx_valid_data_size > shared_size) {
		memcpy(hc_espi->rx_ctx->buf, (void *)rx_header, RX_HEADER_SIZE);
		hc_espi->rx_ctx->len = RX_HEADER_SIZE;
	} else {
		memcpy(hc_espi->rx_ctx->buf, (void *)rx_header, rx_valid_data_size);
		hc_espi->rx_ctx->len = rx_valid_data_size;
	}

	/* Even in case of errors, let the general handler send response */
	hc_espi->state = ESPI_STATE_PROCESSING;
	ec_host_cmd_rx_notify();
}

static int ec_host_cmd_espi_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_espi_ctx *hc_espi = (struct ec_host_cmd_espi_ctx *)backend->ctx;

	hc_espi->state = ESPI_STATE_DISABLED;

	if (!device_is_ready(hc_espi->espi_dev)) {
		return -ENODEV;
	}

	hc_espi->rx_ctx = rx_ctx;
	hc_espi->tx = tx;

	espi_init_callback(&hc_espi->espi_cb, espi_handler, ESPI_BUS_PERIPHERAL_NOTIFICATION);
	espi_add_callback(hc_espi->espi_dev, &hc_espi->espi_cb);
	/* Use shared memory as the tx buffer */
	espi_read_lpc_request(hc_espi->espi_dev, ECUSTOM_HOST_CMD_GET_PARAM_MEMORY,
			      (uint32_t *)&tx->buf);
	espi_read_lpc_request(hc_espi->espi_dev, ECUSTOM_HOST_CMD_GET_PARAM_MEMORY_SIZE,
			      &tx->len_max);

	/* Set the max len for RX as the min of buffer to store data and shared memory. */
	hc_espi->rx_ctx->len_max =
		MIN(CONFIG_EC_HOST_CMD_HANDLER_RX_BUFFER_SIZE, hc_espi->tx->len_max);

	hc_espi->state = ESPI_STATE_READY_TO_RECV;

	return 0;
}

static int ec_host_cmd_espi_send(const struct ec_host_cmd_backend *backend)
{
	struct ec_host_cmd_espi_ctx *hc_espi = (struct ec_host_cmd_espi_ctx *)backend->ctx;
	struct ec_host_cmd_response_header *resp_hdr = hc_espi->tx->buf;
	uint32_t result = resp_hdr->result;
	int ret;

	/* Ignore in-progress on eSPI since interface is synchronous anyway */
	if (result == EC_HOST_CMD_IN_PROGRESS)
		return 0;

	hc_espi->state = ESPI_STATE_SENDING;

	/* Data to transfer are already in the tx buffer (shared memory) */
	ret = espi_write_lpc_request(hc_espi->espi_dev, ECUSTOM_HOST_CMD_SEND_RESULT, &result);
	hc_espi->state = ESPI_STATE_READY_TO_RECV;

	return ret;
}

static const struct ec_host_cmd_backend_api ec_host_cmd_api = {
	.init = &ec_host_cmd_espi_init,
	.send = &ec_host_cmd_espi_send,
};

EC_HOST_CMD_ESPI_DEFINE(ec_host_cmd_espi);
struct ec_host_cmd_backend *ec_host_cmd_backend_get_espi(const struct device *dev)
{
	((struct ec_host_cmd_espi_ctx *)(ec_host_cmd_espi.ctx))->espi_dev = dev;
	return &ec_host_cmd_espi;
}

#if DT_NODE_EXISTS(DT_CHOSEN(zephyr_host_cmd_espi_backend)) &&                                     \
	defined(CONFIG_EC_HOST_CMD_INITIALIZE_AT_BOOT)
static int host_cmd_init(void)
{
	const struct device *const dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_host_cmd_espi_backend));

	ec_host_cmd_init(ec_host_cmd_backend_get_espi(dev));
	return 0;
}
SYS_INIT(host_cmd_init, POST_KERNEL, CONFIG_EC_HOST_CMD_INIT_PRIORITY);
#endif
