/*
 * Copyright (c) 2020 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/device.h>
#include <soc.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/drivers/espi.h>
#include <zephyr/logging/log_ctrl.h>
#include <zephyr/logging/log.h>
#include "espi_oob_handler.h"

LOG_MODULE_DECLARE(espi, CONFIG_ESPI_LOG_LEVEL);

struct oob_header {
	uint8_t dest_slave_addr;
	uint8_t oob_cmd_code;
	uint8_t byte_cnt;
	uint8_t src_slave_addr;
};

#ifdef CONFIG_ESPI_OOB_CHANNEL_RX_ASYNC

#define OOB_THREAD_STACK_SIZE  512ul
#define OOB_THREAD_PRIORITY    K_PRIO_COOP(5)
#define OOB_THREAD_WAIT        -1

/* Thread to process asynchronous callbacks */
void espihub_thread(void *p1, void *p2, void *p3);

void temperature_timer(struct k_timer *timer_id);

K_TIMER_DEFINE(temp_timer, temperature_timer, NULL);
K_THREAD_DEFINE(espihub_thrd_id, OOB_THREAD_STACK_SIZE, espihub_thread,
		NULL, NULL, NULL,
		OOB_THREAD_PRIORITY, K_INHERIT_PERMS, OOB_THREAD_WAIT);

K_MSGQ_DEFINE(from_host, sizeof(uint8_t), 8, 4);

struct thread_context {
	const struct device  *espi_dev;
	int                  cycles;
};

static struct thread_context context;
static bool need_temp;
#endif

static struct espi_oob_packet resp_pckt;
static uint8_t buf[MAX_ESPI_BUF_LEN];

static int request_temp(const struct device *dev)
{
	int ret;
	struct oob_header oob_hdr;
	struct espi_oob_packet req_pckt;

	LOG_WRN("%s", __func__);

	oob_hdr.dest_slave_addr = PCH_DEST_SLV_ADDR;
	oob_hdr.oob_cmd_code = OOB_CMDCODE;
	oob_hdr.byte_cnt = 1;
	oob_hdr.src_slave_addr = SRC_SLV_ADDR;

	/* Packetize OOB request */
	req_pckt.buf = (uint8_t *)&oob_hdr;
	req_pckt.len = sizeof(struct oob_header);

	ret = espi_send_oob(dev, &req_pckt);
	if (ret) {
		LOG_ERR("OOB Tx failed %d", ret);
		return ret;
	}

	return 0;
}

static int retrieve_packet(const struct device *dev, uint8_t *sender)
{
	int ret;

#ifdef CONFIG_ESPI_OOB_CHANNEL_RX_ASYNC
	/* Note that no data is in the item */
	uint8_t response_len;

	if (k_msgq_num_used_get(&from_host) == 0U) {
		return -EINVAL;
	}

	k_msgq_get(&from_host, &response_len, K_FOREVER);
#endif

	resp_pckt.buf = (uint8_t *)&buf;
	resp_pckt.len = MAX_ESPI_BUF_LEN;

	ret = espi_receive_oob(dev, &resp_pckt);
	if (ret) {
		LOG_ERR("OOB Rx failed %d", ret);
		return ret;
	}

	LOG_INF("OOB transaction completed rcvd: %d bytes", resp_pckt.len);
	for (int i = 0; i < resp_pckt.len; i++) {
		LOG_INF("%x ", buf[i]);
	}

	if (sender) {
		*sender = buf[OOB_RESPONSE_SENDER_INDEX];
	}

	return 0;
}

int get_pch_temp_sync(const struct device *dev)
{
	int ret;

	for (int i = 0; i < MIN_GET_TEMP_CYCLES; i++) {
		ret = request_temp(dev);
		if (ret) {
			LOG_ERR("OOB req failed %d", ret);
			return ret;
		}

		ret = retrieve_packet(dev, NULL);
		if (ret) {
			LOG_ERR("OOB retrieve failed %d", ret);
			return ret;
		}
	}

	return 0;
}

int get_pch_temp_async(const struct device *dev)
{
#if !defined(CONFIG_ESPI_OOB_CHANNEL) || \
	!defined(CONFIG_ESPI_OOB_CHANNEL_RX_ASYNC)
	return -ENOTSUP;
#else
	context.espi_dev = dev;
	context.cycles = MIN_GET_TEMP_CYCLES;

	k_thread_start(espihub_thrd_id);
	k_thread_join(espihub_thrd_id, K_FOREVER);

	return 0;
#endif
}

#ifdef CONFIG_ESPI_OOB_CHANNEL_RX_ASYNC

void oob_rx_handler(const struct device *dev, struct espi_callback *cb,
		    struct espi_event event)
{
	uint8_t last_resp_len = event.evt_details;

	LOG_WRN("%s", __func__);
	/* Post for post-processing in a thread
	 * Should not attempt to retrieve in callback context
	 */
	k_msgq_put(&from_host, &last_resp_len, K_NO_WAIT);
}


void temperature_timer(struct k_timer *timer_id)
{
	LOG_WRN("%s", __func__);
	need_temp = true;
}

void espihub_thread(void *p1, void *p2, void *p3)
{
	int ret;
	uint8_t temp;
	uint8_t sender;

	LOG_DBG("%s", __func__);
	k_timer_start(&temp_timer, K_MSEC(100), K_MSEC(100));
	while (context.cycles > 0) {
		k_msleep(50);

		ret = retrieve_packet(context.espi_dev, &sender);
		if (!ret) {
			switch (sender) {
			case PCH_DEST_SLV_ADDR:
				LOG_INF("PCH response");
				/* Any other checks */
				if (resp_pckt.len == OOB_RESPONSE_LEN) {
					temp = buf[OOB_RESPONSE_DATA_INDEX];
					LOG_INF("Temp %d", temp);
				} else {
					LOG_ERR("Incorrect size response");
				}

				break;
			default:
				LOG_INF("Other host sender %x", sender);
			}
		} else {
			LOG_ERR("Failure to retrieve temp %d", ret);
		}

		/* Decrease cycles in both cases failure/success */
		context.cycles--;

		if (need_temp) {
			request_temp(context.espi_dev);
			need_temp = false;
		}
	}

	k_timer_stop(&temp_timer);
}
#endif /* CONFIG_ESPI_OOB_CHANNEL_RX_ASYNC */
