/*
 * Copyright 2017 NXP
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */
#include <common.h>
#include <i2c.h>
#include <time.h>
#include "tcpc.h"

#ifdef DEBUG
#define tcpc_debug_log(port, fmt, args...) tcpc_log(port, fmt, ##args)
#else
#define tcpc_debug_log(port, fmt, args...)
#endif

static bool tcpc_pd_sink_check_charging(struct tcpc_port *port);

static int tcpc_log(struct tcpc_port *port, const char *fmt, ...)
{
	va_list args;
	int i;

	va_start(args, fmt);
	i = vscnprintf(port->log_p, port->log_size, fmt, args);
	va_end(args);

	port->log_size -= i;
	port->log_p += i;

	return i;
}

int tcpc_set_cc_to_source(struct tcpc_port *port)
{
	uint8_t valb;
	int err;

	if (port == NULL)
		return -EINVAL;

	valb = (TCPC_ROLE_CTRL_CC_RP << TCPC_ROLE_CTRL_CC1_SHIFT) |
			(TCPC_ROLE_CTRL_CC_RP << TCPC_ROLE_CTRL_CC2_SHIFT) |
			(TCPC_ROLE_CTRL_RP_VAL_DEF <<
			 TCPC_ROLE_CTRL_RP_VAL_SHIFT);

	err = dm_i2c_write(port->i2c_dev, TCPC_ROLE_CTRL, &valb, 1);
	if (err)
		tcpc_log(port, "%s dm_i2c_write failed, err %d\n", __func__, err);
	return err;
}

int tcpc_set_cc_to_sink(struct tcpc_port *port)
{
	uint8_t valb;
	int err;

	if (port == NULL)
		return -EINVAL;

	valb = (TCPC_ROLE_CTRL_CC_RD << TCPC_ROLE_CTRL_CC1_SHIFT) |
			(TCPC_ROLE_CTRL_CC_RD << TCPC_ROLE_CTRL_CC2_SHIFT);

	err = dm_i2c_write(port->i2c_dev, TCPC_ROLE_CTRL, &valb, 1);
	if (err)
		tcpc_log(port, "%s dm_i2c_write failed, err %d\n", __func__, err);
	return err;
}


int tcpc_set_plug_orientation(struct tcpc_port *port, enum typec_cc_polarity polarity)
{
	uint8_t valb;
	int err;

	if (port == NULL)
		return -EINVAL;

	err = dm_i2c_read(port->i2c_dev, TCPC_TCPC_CTRL, &valb, 1);
	if (err) {
		tcpc_log(port, "%s dm_i2c_read failed, err %d\n", __func__, err);
		return -EIO;
	}

	if (polarity == TYPEC_POLARITY_CC2)
		valb |= TCPC_TCPC_CTRL_ORIENTATION;
	else
		valb &= ~TCPC_TCPC_CTRL_ORIENTATION;

	err = dm_i2c_write(port->i2c_dev, TCPC_TCPC_CTRL, &valb, 1);
	if (err) {
		tcpc_log(port, "%s dm_i2c_write failed, err %d\n", __func__, err);
		return -EIO;
	}

	return 0;
}

int tcpc_get_cc_status(struct tcpc_port *port, enum typec_cc_polarity *polarity, enum typec_cc_state *state)
{

	uint8_t valb_cc, cc2, cc1;
	int err;

	if (port == NULL || polarity == NULL || state == NULL)
		return -EINVAL;

	err = dm_i2c_read(port->i2c_dev, TCPC_CC_STATUS, (uint8_t *)&valb_cc, 1);
	if (err) {
		tcpc_log(port, "%s dm_i2c_read failed, err %d\n", __func__, err);
		return -EIO;
	}

	tcpc_debug_log(port, "cc status 0x%x\n", valb_cc);

	cc2 = (valb_cc >> TCPC_CC_STATUS_CC2_SHIFT) & TCPC_CC_STATUS_CC2_MASK;
	cc1 = (valb_cc >> TCPC_CC_STATUS_CC1_SHIFT) & TCPC_CC_STATUS_CC1_MASK;

	if (valb_cc & TCPC_CC_STATUS_LOOK4CONN)
		return -EFAULT;

	*state = TYPEC_STATE_OPEN;

	if (valb_cc & TCPC_CC_STATUS_TERM) {
		if (cc2) {
			*polarity = TYPEC_POLARITY_CC2;

			switch (cc2) {
			case 0x1:
				*state = TYPEC_STATE_SNK_DEFAULT;
				tcpc_log(port, "SNK.Default on CC2\n");
				break;
			case 0x2:
				*state = TYPEC_STATE_SNK_POWER15;
				tcpc_log(port, "SNK.Power1.5 on CC2\n");
				break;
			case 0x3:
				*state = TYPEC_STATE_SNK_POWER30;
				tcpc_log(port, "SNK.Power3.0 on CC2\n");
				break;
			}
		} else if (cc1) {
			*polarity = TYPEC_POLARITY_CC1;

			switch (cc1) {
			case 0x1:
				*state = TYPEC_STATE_SNK_DEFAULT;
				tcpc_log(port, "SNK.Default on CC1\n");
				break;
			case 0x2:
				*state = TYPEC_STATE_SNK_POWER15;
				tcpc_log(port, "SNK.Power1.5 on CC1\n");
				break;
			case 0x3:
				*state = TYPEC_STATE_SNK_POWER30;
				tcpc_log(port, "SNK.Power3.0 on CC1\n");
				break;
			}
		} else {
			*state = TYPEC_STATE_OPEN;
			return -EPERM;
		}

	} else {
		if (cc2) {
			*polarity = TYPEC_POLARITY_CC2;

			switch (cc2) {
			case 0x1:
				if (cc1 == 0x1) {
					*state = TYPEC_STATE_SRC_BOTH_RA;
					tcpc_log(port, "SRC.Ra on both CC1 and CC2\n");
				} else if (cc1 == 0x2) {
					*state = TYPEC_STATE_SRC_RD_RA;
					tcpc_log(port, "SRC.Ra on CC2, SRC.Rd on CC1\n");
				} else if (cc1 == 0x0) {
					tcpc_log(port, "SRC.Ra only on CC2\n");
					return -EFAULT;
				} else
					return -EFAULT;
				break;
			case 0x2:
				if (cc1 == 0x1) {
					*state = TYPEC_STATE_SRC_RD_RA;
					tcpc_log(port, "SRC.Ra on CC1, SRC.Rd on CC2\n");
				} else if (cc1 == 0x0) {
					*state = TYPEC_STATE_SRC_RD;
					tcpc_log(port, "SRC.Rd on CC2\n");
				} else
					return -EFAULT;
				break;
			case 0x3:
				*state = TYPEC_STATE_SRC_RESERVED;
				return -EFAULT;
			}
		} else if (cc1) {
			*polarity = TYPEC_POLARITY_CC1;

			switch (cc1) {
			case 0x1:
				tcpc_log(port, "SRC.Ra only on CC1\n");
				return -EFAULT;
			case 0x2:
				*state = TYPEC_STATE_SRC_RD;
				tcpc_log(port, "SRC.Rd on CC1\n");
				break;
			case 0x3:
				*state = TYPEC_STATE_SRC_RESERVED;
				return -EFAULT;
			}
		} else {
			*state = TYPEC_STATE_OPEN;
			return -EPERM;
		}
	}

	return 0;
}

int tcpc_clear_alert(struct tcpc_port *port, uint16_t clear_mask)
{
	int err;

	if (port == NULL)
		return -EINVAL;

	err = dm_i2c_write(port->i2c_dev, TCPC_ALERT, (const uint8_t *)&clear_mask, 2);
	if (err) {
		tcpc_log(port, "%s dm_i2c_write failed, err %d\n", __func__, err);
		return -EIO;
	}

	return 0;
}

int tcpc_send_command(struct tcpc_port *port, uint8_t command)
{
	int err;

	if (port == NULL)
		return -EINVAL;

	err = dm_i2c_write(port->i2c_dev, TCPC_COMMAND, (const uint8_t *)&command, 1);
	if (err) {
		tcpc_log(port, "%s dm_i2c_write failed, err %d\n", __func__, err);
		return -EIO;
	}

	return 0;
}

int tcpc_polling_reg(struct tcpc_port *port, uint8_t reg,
	uint8_t reg_width, uint16_t mask, uint16_t value, ulong timeout_ms)
{
	uint16_t val = 0;
	int err;
	ulong start;

	if (port == NULL)
		return -EINVAL;

	tcpc_debug_log(port, "%s reg 0x%x, mask 0x%x, value 0x%x\n", __func__, reg, mask, value);

	/* TCPC registers is 8 bits or 16 bits */
	if (reg_width != 1 && reg_width != 2)
		return -EINVAL;

	start = get_timer(0);	/* Get current timestamp */
	do {
		err = dm_i2c_read(port->i2c_dev, reg, (uint8_t *)&val, reg_width);
		if (err)
			return -EIO;

		if ((val & mask) == value)
			return 0;
	} while (get_timer(0) < (start + timeout_ms));

	return -ETIME;
}

void tcpc_print_log(struct tcpc_port *port)
{
	if (port == NULL)
		return;

	if (port->log_print == port->log_p) /*nothing to output*/
		return;

	printf("%s", port->log_print);

	port->log_print = port->log_p;
}

int tcpc_setup_dfp_mode(struct tcpc_port *port)
{
	enum typec_cc_polarity pol;
	enum typec_cc_state state;
	int ret;

	if (port == NULL)
		return -EINVAL;

	if (tcpc_pd_sink_check_charging(port)) {
		tcpc_log(port, "%s: Can't apply DFP mode when PD is charging\n",
			__func__);
		return -EPERM;
	}

	tcpc_set_cc_to_source(port);

	ret = tcpc_send_command(port, TCPC_CMD_LOOK4CONNECTION);
	if (ret)
		return ret;

	/* At least wait tCcStatusDelay + tTCPCFilter + tCcTCPCSampleRate (max) = 200us + 500us + ?ms
	 * PTN5110 datasheet does not contain the sample rate value, according other productions,
	 * the sample rate is at ms level, about 2 ms -10ms. So wait 100ms should be enough.
	 */
	mdelay(100);

	ret = tcpc_polling_reg(port, TCPC_ALERT, 2, TCPC_ALERT_CC_STATUS, TCPC_ALERT_CC_STATUS, 100);
	if (ret) {
		tcpc_log(port, "%s: Polling ALERT register, TCPC_ALERT_CC_STATUS bit failed, ret = %d\n",
			__func__, ret);
		return ret;
	}

	ret = tcpc_get_cc_status(port, &pol, &state);
	tcpc_clear_alert(port, TCPC_ALERT_CC_STATUS);

	if (!ret) {
		/* If presenting as Rd/audio mode/open, return */
		if (state != TYPEC_STATE_SRC_RD_RA && state != TYPEC_STATE_SRC_RD)
			return -EPERM;

		if (pol == TYPEC_POLARITY_CC1)
			tcpc_debug_log(port, "polarity cc1\n");
		else
			tcpc_debug_log(port, "polarity cc2\n");

		if (port->ss_sel_func)
			port->ss_sel_func(pol);

		ret = tcpc_set_plug_orientation(port, pol);
		if (ret)
			return ret;

		/* Enable source vbus default voltage */
		ret = tcpc_send_command(port, TCPC_CMD_SRC_VBUS_DEFAULT);
		if (ret)
			return ret;

		/* The max vbus on time is 200ms, we add margin 100ms */
		mdelay(300);

	}

	return 0;
}

int tcpc_setup_ufp_mode(struct tcpc_port *port)
{
	enum typec_cc_polarity pol;
	enum typec_cc_state state;
	int ret;

	if (port == NULL)
		return -EINVAL;

	/* Check if the PD charge is working. If not, need to configure CC role for UFP */
	if (!tcpc_pd_sink_check_charging(port)) {

		/* Disable the source vbus once it is enabled by DFP mode */
		tcpc_disable_src_vbus(port);

		tcpc_set_cc_to_sink(port);

		ret = tcpc_send_command(port, TCPC_CMD_LOOK4CONNECTION);
		if (ret)
			return ret;

		/* At least wait tCcStatusDelay + tTCPCFilter + tCcTCPCSampleRate (max) = 200us + 500us + ?ms
		 * PTN5110 datasheet does not contain the sample rate value, according other productions,
		 * the sample rate is at ms level, about 2 ms -10ms. So wait 100ms should be enough.
		 */
		mdelay(100);

		ret = tcpc_polling_reg(port, TCPC_ALERT, 2, TCPC_ALERT_CC_STATUS, TCPC_ALERT_CC_STATUS, 100);
		if (ret) {
			tcpc_log(port, "%s: Polling ALERT register, TCPC_ALERT_CC_STATUS bit failed, ret = %d\n",
				__func__, ret);
			return ret;
		}

		ret = tcpc_get_cc_status(port, &pol, &state);
		tcpc_clear_alert(port, TCPC_ALERT_CC_STATUS);

	} else {
		ret = tcpc_get_cc_status(port, &pol, &state);
	}

	if (!ret) {
		/* If presenting not as sink, then return */
		if (state != TYPEC_STATE_SNK_DEFAULT && state != TYPEC_STATE_SNK_POWER15 &&
			state != TYPEC_STATE_SNK_POWER30)
			return -EPERM;

		if (pol == TYPEC_POLARITY_CC1)
			tcpc_debug_log(port, "polarity cc1\n");
		else
			tcpc_debug_log(port, "polarity cc2\n");

		if (port->ss_sel_func)
			port->ss_sel_func(pol);

		ret = tcpc_set_plug_orientation(port, pol);
		if (ret)
			return ret;
	}

	return 0;
}

int tcpc_disable_src_vbus(struct tcpc_port *port)
{
	int ret;

	if (port == NULL)
		return -EINVAL;

	/* Disable VBUS*/
	ret = tcpc_send_command(port, TCPC_CMD_DISABLE_SRC_VBUS);
	if (ret)
		return ret;

	/* The max vbus off time is 0.5ms, we add margin 0.5 ms */
	mdelay(1);

	return 0;
}

static int tcpc_pd_receive_message(struct tcpc_port *port, struct pd_message *msg)
{
	int ret;
	uint8_t cnt;
	uint16_t val;

	if (port == NULL)
		return -EINVAL;

	/* Generally the max tSenderResponse is 30ms, max tTypeCSendSourceCap is 200ms, we set the timeout to 500ms */
	ret = tcpc_polling_reg(port, TCPC_ALERT, 2, TCPC_ALERT_RX_STATUS, TCPC_ALERT_RX_STATUS, 500);
	if (ret) {
		tcpc_log(port, "%s: Polling ALERT register, TCPC_ALERT_RX_STATUS bit failed, ret = %d\n",
			__func__, ret);
		return ret;
	}

	cnt = 0;
	ret = dm_i2c_read(port->i2c_dev, TCPC_RX_BYTE_CNT, (uint8_t *)&cnt, 1);
	if (ret)
		return -EIO;

	if (cnt > 0) {
		ret = dm_i2c_read(port->i2c_dev, TCPC_RX_BUF_FRAME_TYPE, (uint8_t *)msg, cnt);
		if (ret)
			return -EIO;

		/* Clear RX status alert bit */
		val = TCPC_ALERT_RX_STATUS;
		ret = dm_i2c_write(port->i2c_dev, TCPC_ALERT, (const uint8_t *)&val, 2);
		if (ret)
			return -EIO;
	}

	return cnt;
}

static int tcpc_pd_transmit_message(struct tcpc_port *port, struct pd_message *msg_p, uint8_t bytes)
{
	int ret;
	uint8_t valb;
	uint16_t val;

	if (port == NULL)
		return -EINVAL;

	if (msg_p == NULL || bytes <= 0)
		return -EINVAL;

	ret = dm_i2c_write(port->i2c_dev, TCPC_TX_BYTE_CNT, (const uint8_t *)&bytes, 1);
	if (ret)
		return -EIO;

	ret = dm_i2c_write(port->i2c_dev, TCPC_TX_HDR, (const uint8_t *)&(msg_p->header), bytes);
	if (ret)
		return -EIO;

	valb = (3 << TCPC_TRANSMIT_RETRY_SHIFT) | (TCPC_TX_SOP << TCPC_TRANSMIT_TYPE_SHIFT);
	ret = dm_i2c_write(port->i2c_dev, TCPC_TRANSMIT, (const uint8_t *)&valb, 1);
	if (ret)
		return -EIO;

	/* Max tReceive is 1.1ms, we set to 5ms timeout */
	ret = tcpc_polling_reg(port, TCPC_ALERT, 2, TCPC_ALERT_TX_SUCCESS, TCPC_ALERT_TX_SUCCESS, 5);
	if (ret) {
		if (ret == -ETIME) {
			ret = dm_i2c_read(port->i2c_dev, TCPC_ALERT, (uint8_t *)&val, 2);
			if (ret)
				return -EIO;

			if (val & TCPC_ALERT_TX_FAILED)
				tcpc_log(port, "%s: PD TX FAILED, ALERT = 0x%x\n", __func__, val);

			if (val & TCPC_ALERT_TX_DISCARDED)
				tcpc_log(port, "%s: PD TX DISCARDED, ALERT = 0x%x\n", __func__, val);

		} else {
			tcpc_log(port, "%s: Polling ALERT register, TCPC_ALERT_TX_SUCCESS bit failed, ret = %d\n",
				__func__, ret);
		}
	} else {
		port->tx_msg_id = (port->tx_msg_id + 1) & PD_HEADER_ID_MASK;
	}

	/* Clear ALERT status */
	val &= (TCPC_ALERT_TX_FAILED | TCPC_ALERT_TX_DISCARDED | TCPC_ALERT_TX_SUCCESS);
	ret = dm_i2c_write(port->i2c_dev, TCPC_ALERT, (const uint8_t *)&val, 2);
	if (ret)
		return -EIO;

	return ret;
}

static void tcpc_log_source_caps(struct tcpc_port *port, uint32_t *caps, unsigned int capcount)
{
	int i;

	for (i = 0; i < capcount; i++) {
		u32 pdo = caps[i];
		enum pd_pdo_type type = pdo_type(pdo);

		tcpc_log(port, "PDO %d: type %d, ",
			 i, type);

		switch (type) {
		case PDO_TYPE_FIXED:
			tcpc_log(port, "%u mV, %u mA [%s%s%s%s%s%s]\n",
				  pdo_fixed_voltage(pdo),
				  pdo_max_current(pdo),
				  (pdo & PDO_FIXED_DUAL_ROLE) ?
							"R" : "",
				  (pdo & PDO_FIXED_SUSPEND) ?
							"S" : "",
				  (pdo & PDO_FIXED_HIGHER_CAP) ?
							"H" : "",
				  (pdo & PDO_FIXED_USB_COMM) ?
							"U" : "",
				  (pdo & PDO_FIXED_DATA_SWAP) ?
							"D" : "",
				  (pdo & PDO_FIXED_EXTPOWER) ?
							"E" : "");
			break;
		case PDO_TYPE_VAR:
			tcpc_log(port, "%u-%u mV, %u mA\n",
				  pdo_min_voltage(pdo),
				  pdo_max_voltage(pdo),
				  pdo_max_current(pdo));
			break;
		case PDO_TYPE_BATT:
			tcpc_log(port, "%u-%u mV, %u mW\n",
				  pdo_min_voltage(pdo),
				  pdo_max_voltage(pdo),
				  pdo_max_power(pdo));
			break;
		default:
			tcpc_log(port, "undefined\n");
			break;
		}
	}
}

static int tcpc_pd_select_pdo(uint32_t *caps, uint32_t capcount, uint32_t max_snk_mv, uint32_t max_snk_ma)
{
	unsigned int i, max_mw = 0, max_mv = 0;
	int ret = -EINVAL;

	/*
	 * Select the source PDO providing the most power while staying within
	 * the board's voltage limits. Prefer PDO providing exp
	 */
	for (i = 0; i < capcount; i++) {
		u32 pdo = caps[i];
		enum pd_pdo_type type = pdo_type(pdo);
		unsigned int mv, ma, mw;

		if (type == PDO_TYPE_FIXED)
			mv = pdo_fixed_voltage(pdo);
		else
			mv = pdo_min_voltage(pdo);

		if (type == PDO_TYPE_BATT) {
			mw = pdo_max_power(pdo);
		} else {
			ma = min(pdo_max_current(pdo),
				 max_snk_ma);
			mw = ma * mv / 1000;
		}

		/* Perfer higher voltages if available */
		if ((mw > max_mw || (mw == max_mw && mv > max_mv)) &&
		    mv <= max_snk_mv) {
			ret = i;
			max_mw = mw;
			max_mv = mv;
		}
	}

	return ret;
}

static int tcpc_pd_build_request(struct tcpc_port *port,
										uint32_t *caps,
										uint32_t capcount,
										uint32_t max_snk_mv,
										uint32_t max_snk_ma,
										uint32_t max_snk_mw,
										uint32_t operating_snk_mw,
										uint32_t *rdo)
{
	unsigned int mv, ma, mw, flags;
	unsigned int max_ma, max_mw;
	enum pd_pdo_type type;
	int index;
	u32 pdo;

	index = tcpc_pd_select_pdo(caps, capcount, max_snk_mv, max_snk_ma);
	if (index < 0)
		return -EINVAL;

	pdo = caps[index];
	type = pdo_type(pdo);

	if (type == PDO_TYPE_FIXED)
		mv = pdo_fixed_voltage(pdo);
	else
		mv = pdo_min_voltage(pdo);

	/* Select maximum available current within the board's power limit */
	if (type == PDO_TYPE_BATT) {
		mw = pdo_max_power(pdo);
		ma = 1000 * min(mw, max_snk_mw) / mv;
	} else {
		ma = min(pdo_max_current(pdo),
			 1000 * max_snk_mw / mv);
	}
	ma = min(ma, max_snk_ma);

	/* XXX: Any other flags need to be set? */
	flags = 0;

	/* Set mismatch bit if offered power is less than operating power */
	mw = ma * mv / 1000;
	max_ma = ma;
	max_mw = mw;
	if (mw < operating_snk_mw) {
		flags |= RDO_CAP_MISMATCH;
		max_mw = operating_snk_mw;
		max_ma = max_mw * 1000 / mv;
	}

	if (type == PDO_TYPE_BATT) {
		*rdo = RDO_BATT(index + 1, mw, max_mw, flags);

		tcpc_log(port, "Requesting PDO %d: %u mV, %u mW%s\n",
			 index, mv, mw,
			 flags & RDO_CAP_MISMATCH ? " [mismatch]" : "");
	} else {
		*rdo = RDO_FIXED(index + 1, ma, max_ma, flags);

		tcpc_log(port, "Requesting PDO %d: %u mV, %u mA%s\n",
			 index, mv, ma,
			 flags & RDO_CAP_MISMATCH ? " [mismatch]" : "");
	}

	return 0;
}

static void tcpc_pd_sink_process(struct tcpc_port *port)
{
	int ret;
	uint8_t msgtype;
	uint32_t objcnt;
	struct pd_message msg;
	enum pd_sink_state pd_state = WAIT_SOURCE_CAP;

	while (tcpc_pd_receive_message(port, &msg) > 0) {

		msgtype = pd_header_type(msg.header);
		objcnt = pd_header_cnt_le(msg.header);

		tcpc_debug_log(port, "get msg, type %d, cnt %d\n", msgtype, objcnt);

		switch (pd_state) {
		case WAIT_SOURCE_CAP:
		case SINK_READY:
			if (msgtype != PD_DATA_SOURCE_CAP)
				continue;

			uint32_t *caps = (uint32_t *)&msg.payload;
			uint32_t rdo = 0;

			tcpc_log_source_caps(port, caps, objcnt);

			tcpc_pd_build_request(port, caps, objcnt,
				port->cfg.max_snk_mv, port->cfg.max_snk_ma,
				port->cfg.max_snk_mw, port->cfg.op_snk_mv,
				&rdo);

			memset(&msg, 0, sizeof(msg));
			msg.header = PD_HEADER(PD_DATA_REQUEST, 0, 0, port->tx_msg_id, 1);  /* power sink, data device, id 0, len 1 */
			msg.payload[0] = rdo;

			ret = tcpc_pd_transmit_message(port, &msg, 6);
			if (ret)
				tcpc_log(port, "send request failed\n");
			else
				pd_state = WAIT_SOURCE_ACCEPT;

			break;
		case WAIT_SOURCE_ACCEPT:
			if (objcnt > 0) /* Should be ctrl message */
				continue;

			if (msgtype == PD_CTRL_ACCEPT) {
				pd_state = WAIT_SOURCE_READY;
				tcpc_log(port, "Source accept request\n");
			} else if (msgtype == PD_CTRL_REJECT) {
				tcpc_log(port, "Source reject request\n");
				return;
			}

			break;
		case WAIT_SOURCE_READY:
			if (objcnt > 0) /* Should be ctrl message */
				continue;

			if (msgtype == PD_CTRL_PS_RDY) {
				tcpc_log(port, "PD source ready!\n");
				pd_state = SINK_READY;
			}

			break;
		default:
			tcpc_log(port, "unexpect status: %u\n", pd_state);
			break;
		}
	}
}

static bool tcpc_pd_sink_check_charging(struct tcpc_port *port)
{
	uint8_t valb;
	int err;
	enum typec_cc_polarity pol;
	enum typec_cc_state state;

	if (port == NULL)
		return false;

	/* Check the CC status, must be sink */
	err = tcpc_get_cc_status(port, &pol, &state);
	if (err || (state != TYPEC_STATE_SNK_POWER15
		&& state != TYPEC_STATE_SNK_POWER30
		&& state != TYPEC_STATE_SNK_DEFAULT)) {
		tcpc_debug_log(port, "TCPC wrong state for PD charging, err = %d, CC = 0x%x\n",
			err, state);
		return false;
	}

	/* Check the VBUS PRES and SINK VBUS for dead battery */
	err = dm_i2c_read(port->i2c_dev, TCPC_POWER_STATUS, &valb, 1);
	if (err) {
		tcpc_debug_log(port, "%s dm_i2c_read failed, err %d\n", __func__, err);
		return false;
	}

	if (!(valb & TCPC_POWER_STATUS_VBUS_PRES)) {
		tcpc_debug_log(port, "VBUS NOT PRES \n");
		return false;
	}

	if (!(valb & TCPC_POWER_STATUS_SINKING_VBUS)) {
		tcpc_debug_log(port, "SINK VBUS is not enabled for dead battery\n");
		return false;
	}

	return true;
}

static int tcpc_pd_sink_init(struct tcpc_port *port)
{
	uint8_t valb;
	uint16_t val;
	int err;
	enum typec_cc_polarity pol;
	enum typec_cc_state state;

	if (port == NULL)
		return -EINVAL;

	port->pd_state = UNATTACH;

	/* Check the VBUS PRES and SINK VBUS for dead battery */
	err = dm_i2c_read(port->i2c_dev, TCPC_POWER_STATUS, &valb, 1);
	if (err) {
		tcpc_log(port, "%s dm_i2c_read failed, err %d\n", __func__, err);
		return -EIO;
	}

	if (!(valb & TCPC_POWER_STATUS_VBUS_PRES)) {
		tcpc_debug_log(port, "VBUS NOT PRES \n");
		return -EPERM;
	}

	if (!(valb & TCPC_POWER_STATUS_SINKING_VBUS)) {
		tcpc_debug_log(port, "SINK VBUS is not enabled for dead battery\n");
		return -EPERM;
	}

	err = dm_i2c_read(port->i2c_dev, TCPC_ALERT, (uint8_t *)&val, 2);
	if (err) {
		tcpc_log(port, "%s dm_i2c_read failed, err %d\n", __func__, err);
		return -EIO;
	}

	if (!(val & TCPC_ALERT_CC_STATUS)) {
		tcpc_debug_log(port, "CC STATUS not detected for dead battery\n");
		return -EPERM;
	}

	err = tcpc_get_cc_status(port, &pol, &state);
	if (err || (state != TYPEC_STATE_SNK_POWER15
		&& state != TYPEC_STATE_SNK_POWER30
		&& state != TYPEC_STATE_SNK_DEFAULT)) {
		tcpc_log(port, "TCPC wrong state for dead battery, err = %d, CC = 0x%x\n",
			err, state);
		return -EPERM;
	} else
		port->pd_state = ATTACHED;

	dm_i2c_read(port->i2c_dev, TCPC_POWER_CTRL, (uint8_t *)&valb, 1);
	valb &= ~TCPC_POWER_CTRL_AUTO_DISCH_DISCO; /* disable AutoDischargeDisconnect */
	dm_i2c_write(port->i2c_dev, TCPC_POWER_CTRL, (const uint8_t *)&valb, 1);

	/* As sink role */
	valb = 0x00;
	err = dm_i2c_write(port->i2c_dev, TCPC_MSG_HDR_INFO, (const uint8_t *)&valb, 1);
	if (err) {
		tcpc_log(port, "%s dm_i2c_read failed, err %d\n", __func__, err);
		return -EIO;
	}

	/* Enable rx */
	valb = TCPC_RX_DETECT_SOP | TCPC_RX_DETECT_HARD_RESET;
	err = dm_i2c_write(port->i2c_dev, TCPC_RX_DETECT, (const uint8_t *)&valb, 1);
	if (err) {
		tcpc_log(port, "%s dm_i2c_read failed, err %d\n", __func__, err);
		return -EIO;
	}

	tcpc_pd_sink_process(port);

	return 0;
}

int tcpc_init(struct tcpc_port *port, struct tcpc_port_config config, ss_mux_sel ss_sel_func)
{
	int ret;
	uint8_t valb;
	uint16_t vid, pid;
	struct udevice *bus;
	struct udevice *i2c_dev = NULL;

	memset(port, 0, sizeof(struct tcpc_port));

	if (port == NULL)
		return -EINVAL;

	port->cfg = config;
	port->tx_msg_id = 0;
	port->ss_sel_func = ss_sel_func;
	port->log_p = (char *)&(port->logbuffer);
	port->log_size = TCPC_LOG_BUFFER_SIZE;
	port->log_print = port->log_p;
	memset(&(port->logbuffer), 0, TCPC_LOG_BUFFER_SIZE);

	ret = uclass_get_device_by_seq(UCLASS_I2C, port->cfg.i2c_bus, &bus);
	if (ret) {
		printf("%s: Can't find bus\n", __func__);
		return -EINVAL;
	}

	ret = dm_i2c_probe(bus, port->cfg.addr, 0, &i2c_dev);
	if (ret) {
		printf("%s: Can't find device id=0x%x\n",
			__func__, config.addr);
		return -ENODEV;
	}

	port->i2c_dev = i2c_dev;

	/* Check the Initialization Status bit in 1s */
	ret = tcpc_polling_reg(port, TCPC_POWER_STATUS, 1, TCPC_POWER_STATUS_UNINIT, 0, 1000);
	if (ret) {
		tcpc_log(port, "%s: Polling TCPC POWER STATUS Initialization Status bit failed, ret = %d\n",
			__func__, ret);
		return ret;
	}

	/* Clear AllRegistersResetToDefault */
	valb = 0x80;
	ret = dm_i2c_write(port->i2c_dev, TCPC_FAULT_STATUS, (const uint8_t *)&valb, 1);
	if (ret) {
		tcpc_log(port, "%s dm_i2c_read failed, err %d\n", __func__, ret);
		return -EIO;
	}

	/* Read Vendor ID and Product ID */
	ret = dm_i2c_read(port->i2c_dev, TCPC_VENDOR_ID, (uint8_t *)&vid, 2);
	if (ret) {
		tcpc_log(port, "%s dm_i2c_read failed, err %d\n", __func__, ret);
		return -EIO;
	}

	ret = dm_i2c_read(port->i2c_dev, TCPC_PRODUCT_ID, (uint8_t *)&pid, 2);
	if (ret) {
		tcpc_log(port, "%s dm_i2c_read failed, err %d\n", __func__, ret);
		return -EIO;
	}

	tcpc_log(port, "TCPC:  Vendor ID [0x%x], Product ID [0x%x]\n", vid, pid);

	if (port->cfg.port_type == TYPEC_PORT_UFP
		|| port->cfg.port_type == TYPEC_PORT_DRP)
		tcpc_pd_sink_init(port);

	tcpc_clear_alert(port, 0xffff);

	tcpc_print_log(port);

	return 0;
}
