/*
 * Copyright (c) 2023 The Chromium OS Authors.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/devicetree.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/usb_c/usbc.h>

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(main, LOG_LEVEL_DBG);

#include "power_ctrl.h"

#define PORT1_NODE		DT_NODELABEL(port1)
#define PORT1_POWER_ROLE	DT_ENUM_IDX(DT_NODELABEL(port1), power_role)

/* A Source power role evauates to 1. See usbc_tc.h: TC_ROLE_SOURCE */
#if (PORT1_POWER_ROLE != 1)
#error "Unsupported board: Only Source device supported"
#endif

#define SOURCE_PDO(node_id, prop, idx)	(DT_PROP_BY_IDX(node_id, prop, idx)),

/* usbc.rst port data object start */
/**
 * @brief A structure that encapsulates Port data.
 */
static struct port1_data_t {
	/** Source Capabilities */
	uint32_t src_caps[DT_PROP_LEN(DT_NODELABEL(port1), source_pdos)];
	/** Number of Source Capabilities */
	int src_cap_cnt;
	/** CC Rp value */
	int rp;
	/** Sink Request RDO */
	union pd_rdo sink_request;
	/** Requested Object Pos */
	int obj_pos;
	/** VCONN CC line*/
	enum tc_cc_polarity vconn_pol;
	/** True if power supply is ready */
	bool ps_ready;
	/** True if power supply should transition to a new level */
	bool ps_tran_start;
	/** Log Sink Requested RDO to console */
	atomic_t show_sink_request;
} port1_data = {
	.rp = DT_ENUM_IDX(DT_NODELABEL(port1), typec_power_opmode),
	.src_caps = {DT_FOREACH_PROP_ELEM(DT_NODELABEL(port1), source_pdos, SOURCE_PDO)},
	.src_cap_cnt = DT_PROP_LEN(DT_NODELABEL(port1), source_pdos),
};

/* usbc.rst port data object end */

static void dump_sink_request_rdo(const uint32_t rdo)
{
	union pd_rdo request;

	request.raw_value = rdo;

	LOG_INF("REQUEST RDO: %08x", rdo);
	LOG_INF("\tObject Position:\t %d", request.fixed.object_pos);
	LOG_INF("\tGiveback:\t\t %d", request.fixed.giveback);
	LOG_INF("\tCapability Mismatch:\t %d", request.fixed.cap_mismatch);
	LOG_INF("\tUSB Comm Capable:\t %d", request.fixed.usb_comm_capable);
	LOG_INF("\tNo USB Suspend:\t\t %d", request.fixed.no_usb_suspend);
	LOG_INF("\tUnchunk Ext MSG Support: %d", request.fixed.unchunked_ext_msg_supported);
	LOG_INF("\tOperating Current:\t %d mA",
			PD_CONVERT_FIXED_PDO_CURRENT_TO_MA(request.fixed.operating_current));
	if (request.fixed.giveback) {
		LOG_INF("\tMax Operating Current:\t %d mA",
		PD_CONVERT_FIXED_PDO_CURRENT_TO_MA(request.fixed.min_or_max_operating_current));
	} else {
		LOG_INF("\tMin Operating Current:\t %d mA",
		PD_CONVERT_FIXED_PDO_CURRENT_TO_MA(request.fixed.min_or_max_operating_current));
	}
}

/* usbc.rst callbacks start */
/**
 * @brief PE calls this function when it needs to set the Rp on CC
 */
int port1_policy_cb_get_src_rp(const struct device *dev,
			       enum tc_rp_value *rp)
{
	struct port1_data_t *dpm_data = usbc_get_dpm_data(dev);

	*rp = dpm_data->rp;

	return 0;
}

/**
 * @brief PE calls this function to Enable (5V) or Disable (0V) the
 *	  Power Supply
 */
int port1_policy_cb_src_en(const struct device *dev, bool en)
{
	source_ctrl_set(en ? SOURCE_5V : SOURCE_0V);

	return 0;
}

/**
 * @brief PE calls this function to Enable or Disable VCONN
 */
int port1_policy_cb_vconn_en(const struct device *dev, enum tc_cc_polarity pol, bool en)
{
	struct port1_data_t *dpm_data = usbc_get_dpm_data(dev);

	dpm_data->vconn_pol = pol;

	if (en == false) {
		/* Disable VCONN on CC1 and CC2 */
		vconn_ctrl_set(VCONN_OFF);
	} else if (pol == TC_POLARITY_CC1) {
		/* set VCONN on CC1 */
		vconn_ctrl_set(VCONN1_ON);
	} else {
		/* set VCONN on CC2 */
		vconn_ctrl_set(VCONN2_ON);
	}

	return 0;
}

/**
 * @brief PE calls this function to get the Source Caps that will be sent
 *	  to the Sink
 */
int port1_policy_cb_get_src_caps(const struct device *dev,
			const uint32_t **pdos, uint32_t *num_pdos)
{
	struct port1_data_t *dpm_data = usbc_get_dpm_data(dev);

	*pdos = dpm_data->src_caps;
	*num_pdos = dpm_data->src_cap_cnt;

	return 0;
}

/**
 * @brief PE calls this function to verify that a Sink's request if valid
 */
static enum usbc_snk_req_reply_t port1_policy_cb_check_sink_request(const struct device *dev,
					const uint32_t request_msg)
{
	struct port1_data_t *dpm_data = usbc_get_dpm_data(dev);
	union pd_fixed_supply_pdo_source pdo;
	uint32_t obj_pos;
	uint32_t op_current;

	dpm_data->sink_request.raw_value = request_msg;
	obj_pos = dpm_data->sink_request.fixed.object_pos;
	op_current =
		PD_CONVERT_FIXED_PDO_CURRENT_TO_MA(dpm_data->sink_request.fixed.operating_current);

	if (obj_pos == 0 || obj_pos > dpm_data->src_cap_cnt) {
		return SNK_REQUEST_REJECT;
	}

	pdo.raw_value = dpm_data->src_caps[obj_pos - 1];

	if (dpm_data->sink_request.fixed.operating_current > pdo.max_current) {
		return SNK_REQUEST_REJECT;
	}

	dpm_data->obj_pos = obj_pos;

	atomic_set_bit(&port1_data.show_sink_request, 0);

	/*
	 * Clear PS ready. This will be set to true after PS is ready after
	 * it transitions to the new level.
	 */
	port1_data.ps_ready = false;

	return SNK_REQUEST_VALID;
}

/**
 * @brief PE calls this function to check if the Power Supply is at the requested
 *	  level
 */
static bool port1_policy_cb_is_ps_ready(const struct device *dev)
{
	struct port1_data_t *dpm_data = usbc_get_dpm_data(dev);


	/* Return true to inform that the Power Supply is ready */
	return dpm_data->ps_ready;
}

/**
 * @brief PE calls this function to check if the Present Contract is still
 *	  valid
 */
static bool port1_policy_cb_present_contract_is_valid(const struct device *dev,
					const uint32_t present_contract)
{
	struct port1_data_t *dpm_data = usbc_get_dpm_data(dev);
	union pd_fixed_supply_pdo_source pdo;
	union pd_rdo request;
	uint32_t obj_pos;
	uint32_t op_current;

	request.raw_value = present_contract;
	obj_pos = request.fixed.object_pos;
	op_current = PD_CONVERT_FIXED_PDO_CURRENT_TO_MA(request.fixed.operating_current);

	if (obj_pos == 0 || obj_pos > dpm_data->src_cap_cnt) {
		return false;
	}

	pdo.raw_value = dpm_data->src_caps[obj_pos - 1];

	if (request.fixed.operating_current > pdo.max_current) {
		return false;
	}

	return true;
}

/* usbc.rst callbacks end */

/* usbc.rst notify start */
static void port1_notify(const struct device *dev,
			      const enum usbc_policy_notify_t policy_notify)
{
	struct port1_data_t *dpm_data = usbc_get_dpm_data(dev);

	switch (policy_notify) {
	case PROTOCOL_ERROR:
		break;
	case MSG_DISCARDED:
		break;
	case MSG_ACCEPT_RECEIVED:
		break;
	case MSG_REJECTED_RECEIVED:
		break;
	case MSG_NOT_SUPPORTED_RECEIVED:
		break;
	case TRANSITION_PS:
		dpm_data->ps_tran_start = true;
		break;
	case PD_CONNECTED:
		break;
	case NOT_PD_CONNECTED:
		break;
	case DATA_ROLE_IS_UFP:
		break;
	case DATA_ROLE_IS_DFP:
		break;
	case PORT_PARTNER_NOT_RESPONSIVE:
		LOG_INF("Port Partner not PD Capable");
		break;
	case HARD_RESET_RECEIVED:
		/*
		 * This notification is sent from the PE_SRC_Transition_to_default
		 * state and requires the following:
		 *	1: Vconn should be turned OFF
		 *	2: Reset of the local hardware
		 */

		/* Power off VCONN */
		vconn_ctrl_set(VCONN_OFF);
		/* Transition PS to Default level */
		source_ctrl_set(SOURCE_5V);
		break;
	default:
	}
}
/* usbc.rst notify end */

/* usbc.rst check start */
bool port1_policy_check(const struct device *dev,
			const enum usbc_policy_check_t policy_check)
{
	struct port1_data_t *dpm_data = usbc_get_dpm_data(dev);

	switch (policy_check) {
	case CHECK_POWER_ROLE_SWAP:
		/* Reject power role swaps */
		return false;
	case CHECK_DATA_ROLE_SWAP_TO_DFP:
		/* Accept data role swap to DFP */
		return true;
	case CHECK_DATA_ROLE_SWAP_TO_UFP:
		/* Reject data role swap to UFP */
		return false;
	case CHECK_SRC_PS_AT_DEFAULT_LEVEL:
		/*
		 * This check is sent from the PE_SRC_Transition_to_default
		 * state and requires the following:
		 *	1: Vconn should be turned ON
		 *	2: Return TRUE when Power Supply is at default level
		 */

		/* Power on VCONN */
		vconn_ctrl_set(dpm_data->vconn_pol);

		/* PS should be at default level after receiving a Hard Reset */
		return true;
	default:
		/* Reject all other policy checks */
		return false;

	}
}
/* usbc.rst check end */

int main(void)
{
	const struct device *usbc_port1;

	/* Get the device for this port */
	usbc_port1 = DEVICE_DT_GET(PORT1_NODE);
	if (!device_is_ready(usbc_port1)) {
		LOG_ERR("PORT1 device not ready");
		return 0;
	}

	/* usbc.rst register start */
	/* Register USB-C Callbacks */

	/* Register Policy Check callback */
	usbc_set_policy_cb_check(usbc_port1, port1_policy_check);
	/* Register Policy Notify callback */
	usbc_set_policy_cb_notify(usbc_port1, port1_notify);
	/* Register Policy callback to set the Rp on CC lines */
	usbc_set_policy_cb_get_src_rp(usbc_port1, port1_policy_cb_get_src_rp);
	/* Register Policy callback to enable or disable power supply */
	usbc_set_policy_cb_src_en(usbc_port1, port1_policy_cb_src_en);
	/* Register Policy callback to enable or disable vconn */
	usbc_set_vconn_control_cb(usbc_port1, port1_policy_cb_vconn_en);
	/* Register Policy callback to send the source caps to the sink */
	usbc_set_policy_cb_get_src_caps(usbc_port1, port1_policy_cb_get_src_caps);
	/* Register Policy callback to check if the sink request is valid */
	usbc_set_policy_cb_check_sink_request(usbc_port1, port1_policy_cb_check_sink_request);
	/* Register Policy callback to check if the power supply is ready */
	usbc_set_policy_cb_is_ps_ready(usbc_port1, port1_policy_cb_is_ps_ready);
	/* Register Policy callback to check if Present Contract is still valid */
	usbc_set_policy_cb_present_contract_is_valid(usbc_port1,
				port1_policy_cb_present_contract_is_valid);

	/* usbc.rst register end */

	/* usbc.rst user data start */
	/* Set Application port data object. This object is passed to the policy callbacks */
	usbc_set_dpm_data(usbc_port1, &port1_data);
	/* usbc.rst user data end */

	/* Flag to show sink request */
	port1_data.show_sink_request = ATOMIC_INIT(0);

	/* Init power supply transition start */
	port1_data.ps_tran_start = false;
	/* Init power supply ready */
	port1_data.ps_ready = false;

	/* usbc.rst usbc start */
	/* Start the USB-C Subsystem */
	usbc_start(usbc_port1);
	/* usbc.rst usbc end */

	while (1) {
		/* Perform Application Specific functions */

		/* Transition PS to new level */
		if (port1_data.ps_tran_start) {
			/*
			 * Transition Power Supply to new voltage.
			 * Okay if this blocks.
			 */
			source_ctrl_set(port1_data.obj_pos);
			port1_data.ps_ready = true;
			port1_data.ps_tran_start = false;
		}

		/* Display Sink Requests */
		if (atomic_test_and_clear_bit(&port1_data.show_sink_request, 0)) {
			/* Display the Sink request */
			dump_sink_request_rdo(port1_data.sink_request.raw_value);
		}
		/* Arbitrary delay */
		k_msleep(10);
	}

	return 0;
}
