/*
 * Copyright 2022 The Chromium OS Authors
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT st_stm32_ucpd

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(ucpd_stm32, CONFIG_USBC_LOG_LEVEL);

#include <zephyr/device.h>
#include <zephyr/sys/util.h>
#include <zephyr/kernel.h>
#include <soc.h>
#include <stddef.h>
#include <zephyr/math/ilog2.h>
#include <stm32_ll_system.h>
#include <zephyr/irq.h>

#include "ucpd_stm32_priv.h"

static void config_tcpc_irq(void);

/**
 * @brief UCPD TX ORDSET values
 */
static int ucpd_txorderset[] = {
	/* SOP ORDSET */
	LL_UCPD_ORDERED_SET_SOP,
	/* SOP PRIME ORDSET */
	LL_UCPD_ORDERED_SET_SOP1,
	/* SOP PRIME PRIME ORDSET */
	LL_UCPD_ORDERED_SET_SOP2,
	/* SOP PRIME DEBUG ORDSET */
	LL_UCPD_ORDERED_SET_SOP1_DEBUG,
	/* SOP PRIME PRIME DEBUG ORDSET */
	LL_UCPD_ORDERED_SET_SOP2_DEBUG,
	/* HARD RESET ORDSET */
	LL_UCPD_ORDERED_SET_HARD_RESET,
	/* CABLE RESET ORDSET */
	LL_UCPD_ORDERED_SET_CABLE_RESET,
};

/**
 * @brief Test for a goodCRC message
 *
 * @retval true if message is goodCRC, else false
 */
static bool ucpd_msg_is_good_crc(union pd_header header)
{
	/*
	 * Good CRC is a control message (no data objects) with GOOD_CRC
	 * message type in the header.
	 */
	return (header.number_of_data_objects == 0 &&
		header.extended == 0 &&
		header.message_type == PD_CTRL_GOOD_CRC);
}

#ifdef CONFIG_SOC_SERIES_STM32G0X
/**
 * @brief Apply the UCPD CC1 and CC2 pin configurations.
 *
 *        UCPDx_STROBE: UCPDx pull-down configuration strobe:
 *                      when UCPDx is enabled, with CC1 and CC2 pin UCPD
 *                      control bits configured: apply that configuration.
 */
static void update_stm32g0x_cc_line(UCPD_TypeDef *ucpd_port)
{
	if ((uint32_t)(ucpd_port) == UCPD1_BASE) {
		SYSCFG->CFGR1 |= SYSCFG_CFGR1_UCPD1_STROBE_Msk;
	} else {
		SYSCFG->CFGR1 |= SYSCFG_CFGR1_UCPD2_STROBE_Msk;
	}
}
#endif

/**
 * @brief Transmits a data byte from the TX data buffer
 */
static void ucpd_tx_data_byte(const struct device *dev)
{
	struct tcpc_data *data = dev->data;
	const struct tcpc_config *const config = dev->config;
	int index = data->ucpd_tx_active_buffer->msg_index++;

	LL_UCPD_WriteData(config->ucpd_port,
			  data->ucpd_tx_active_buffer->data.msg[index]);
}

/**
 * @brief Receives a data byte and store it in the RX data buffer
 */
static void ucpd_rx_data_byte(const struct device *dev)
{
	struct tcpc_data *data = dev->data;
	const struct tcpc_config *const config = dev->config;

	if (data->ucpd_rx_byte_count < UCPD_BUF_LEN) {
		data->ucpd_rx_buffer[data->ucpd_rx_byte_count++] =
			LL_UCPD_ReadData(config->ucpd_port);
	}
}

/**
 * @brief Enables or Disables TX interrupts
 */
static void ucpd_tx_interrupts_enable(const struct device *dev, bool enable)
{
	const struct tcpc_config *const config = dev->config;
	uint32_t imr;

	imr = LL_UCPD_ReadReg(config->ucpd_port, IMR);

	if (enable) {
		LL_UCPD_WriteReg(config->ucpd_port, ICR, UCPD_ICR_TX_INT_MASK);
		LL_UCPD_WriteReg(config->ucpd_port, IMR,
				 imr | UCPD_IMR_TX_INT_MASK);
	} else {
		LL_UCPD_WriteReg(config->ucpd_port, IMR,
				 imr & ~UCPD_IMR_TX_INT_MASK);
	}
}

/**
 * @brief Initializes the RX and TX state machine variables
 */
static void stm32_ucpd_state_init(const struct device *dev)
{
	struct tcpc_data *data = dev->data;

	/* Init variables used to manage tx process */
	data->ucpd_tx_request = 0;
	data->tx_retry_count = 0;
	data->ucpd_tx_state = STATE_IDLE;

	/* Init variables used to manage rx */
	data->ucpd_rx_sop_prime_enabled = false;
	data->ucpd_rx_msg_active = false;
	data->ucpd_rx_bist_mode = false;

	/* Vconn tracking variable */
	data->ucpd_vconn_enable = false;
}

/**
 * @brief Get the CC enable mask. The mask indicates which CC line
 *        is enabled.
 *
 * @retval CC Enable mask (bit 0: CC1, bit 1: CC2)
 */
static uint32_t ucpd_get_cc_enable_mask(const struct device *dev)
{
	struct tcpc_data *data = dev->data;
	const struct tcpc_config *const config = dev->config;
	uint32_t mask = UCPD_CR_CCENABLE_Msk;

	/*
	 * When VCONN is enabled, it is supplied on the CC line that's
	 * not being used for Power Delivery messages.
	 */
	if (data->ucpd_vconn_enable) {
		uint32_t cr = LL_UCPD_ReadReg(config->ucpd_port, CR);
		int pol = (cr & UCPD_CR_PHYCCSEL);

		/* Dissable CC line that's used for VCONN */
		mask &= ~BIT(UCPD_CR_CCENABLE_Pos + !pol);
	}

	return mask;
}

/**
 * @brief Get the state of the CC1 and CC2 lines
 *
 * @retval 0 on success
 * @retval -EIO on failure
 */
static int ucpd_get_cc(const struct device *dev,
		       enum tc_cc_voltage_state *cc1,
		       enum tc_cc_voltage_state *cc2)
{
	const struct tcpc_config *const config = dev->config;
	int vstate_cc1;
	int vstate_cc2;
	int anamode;
	uint32_t sr;
	uint32_t cc_msk;

	/*
	 * cc_voltage_state is determined from vstate_cc bit field in the
	 * status register. The meaning of the value vstate_cc depends on
	 * current value of ANAMODE (src/snk).
	 *
	 * vstate_cc maps directly to cc_state from tcpci spec when
	 * ANAMODE(snk) = 1, but needs to be modified slightly for case
	 * ANAMODE(src) = 0.
	 *
	 * If presenting Rp (source), then need to do a circular shift of
	 * vstate_ccx value:
	 *     vstate_cc | cc_state
	 *     ------------------
	 *        0     ->    1
	 *        1     ->    2
	 *        2     ->    0
	 */

	/* Get vstate_ccx values and power role */
	sr = LL_UCPD_ReadReg(config->ucpd_port, SR);

	/* Get Rp or Rd active */
	anamode = LL_UCPD_GetRole(config->ucpd_port);
	vstate_cc1 = (sr & UCPD_SR_TYPEC_VSTATE_CC1_Msk) >>
		     UCPD_SR_TYPEC_VSTATE_CC1_Pos;

	vstate_cc2 = (sr & UCPD_SR_TYPEC_VSTATE_CC2_Msk) >>
		     UCPD_SR_TYPEC_VSTATE_CC2_Pos;

	/* Do circular shift if port == source */
	if (anamode) {
		if (vstate_cc1 != STM32_UCPD_SR_VSTATE_RA) {
			vstate_cc1 += 4;
		}
		if (vstate_cc2 != STM32_UCPD_SR_VSTATE_RA) {
			vstate_cc2 += 4;
		}
	} else {
		if (vstate_cc1 != STM32_UCPD_SR_VSTATE_OPEN) {
			vstate_cc1 = (vstate_cc1 + 1) % 3;
		}
		if (vstate_cc2 != STM32_UCPD_SR_VSTATE_OPEN) {
			vstate_cc2 = (vstate_cc2 + 1) % 3;
		}
	}

	/* CC connection detection */
	cc_msk = ucpd_get_cc_enable_mask(dev);

	/* CC1 connection detection */
	if (cc_msk & UCPD_CR_CCENABLE_0) {
		*cc1 = vstate_cc1;
	} else {
		*cc1 = TC_CC_VOLT_OPEN;
	}

	/* CC2 connection detection */
	if (cc_msk & UCPD_CR_CCENABLE_1) {
		*cc2 = vstate_cc2;
	} else {
		*cc2 = TC_CC_VOLT_OPEN;
	}

	return 0;
}

/**
 * @brief Enable or Disable VCONN
 *
 * @retval 0 on success
 * @retval -EIO on failure
 * @retval -ENOTSUP if not supported
 */
static int ucpd_set_vconn(const struct device *dev, bool enable)
{
	struct tcpc_data *data = dev->data;
	const struct tcpc_config *const config = dev->config;
	int cr;
	int ret;

	if (data->vconn_cb == NULL) {
		return -ENOTSUP;
	}

	/* Update VCONN on/off status. Do this before getting cc enable mask */
	data->ucpd_vconn_enable = enable;

	cr = LL_UCPD_ReadReg(config->ucpd_port, CR);
	cr &= ~UCPD_CR_CCENABLE_Msk;
	cr |= ucpd_get_cc_enable_mask(dev);

	/* Apply cc pull resistor change */
	LL_UCPD_WriteReg(config->ucpd_port, CR, cr);

#ifdef CONFIG_SOC_SERIES_STM32G0X
	update_stm32g0x_cc_line(config->ucpd_port);
#endif

	/* Get CC line that VCONN is active on */
	data->ucpd_vconn_cc = (cr & UCPD_CR_CCENABLE_0) ?
				TC_POLARITY_CC2 : TC_POLARITY_CC1;

	/* Call user supplied callback to set vconn */
	ret = data->vconn_cb(dev, data->ucpd_vconn_cc, enable);

	return ret;
}

/**
 * @brief Discharge VCONN
 *
 * @retval 0 on success
 * @retval -EIO on failure
 * @retval -ENOTSUP if not supported
 */
static int ucpd_vconn_discharge(const struct device *dev, bool enable)
{
	struct tcpc_data *data = dev->data;
	const struct tcpc_config *const config = dev->config;

	/* VCONN should not be discharged while it's enabled */
	if (data->ucpd_vconn_enable) {
		return -EIO;
	}

	if (data->vconn_discharge_cb) {
		/* Use DPM supplied VCONN Discharge */
		return data->vconn_discharge_cb(dev, data->ucpd_vconn_cc, enable);
	}

	/* Use TCPC VCONN Discharge */
	if (enable) {
		LL_UCPD_VconnDischargeEnable(config->ucpd_port);
	} else {
		LL_UCPD_VconnDischargeDisable(config->ucpd_port);
	}

#ifdef CONFIG_SOC_SERIES_STM32G0X
	update_stm32g0x_cc_line(config->ucpd_port);
#endif

	return 0;
}

/**
 * @brief Sets the value of the CC pull up resistor used when operating as a Source
 *
 * @retval 0 on success
 */
static int ucpd_select_rp_value(const struct device *dev, enum tc_rp_value rp)
{
	struct tcpc_data *data = dev->data;

	data->rp = rp;

	return 0;
}

/**
 * @brief Gets the value of the CC pull up resistor used when operating as a Source
 *
 * @retval 0 on success
 */
static int ucpd_get_rp_value(const struct device *dev, enum tc_rp_value *rp)
{
	struct tcpc_data *data = dev->data;

	*rp = data->rp;

	return 0;
}

/**
 * @brief Set the CC pull up or pull down resistors
 *
 * @retval 0 on success
 * @retval -EIO on failure
 */
static int ucpd_set_cc(const struct device *dev,
		       enum tc_cc_pull cc_pull)
{
	const struct tcpc_config *const config = dev->config;
	struct tcpc_data *data = dev->data;
	uint32_t cr;

	cr = LL_UCPD_ReadReg(config->ucpd_port, CR);

	/*
	 * Always set ANASUBMODE to match desired Rp. TCPM layer has a valid
	 * range of 0, 1, or 2. This range maps to 1, 2, or 3 in ucpd for
	 * ANASUBMODE.
	 */
	cr &= ~UCPD_CR_ANASUBMODE_Msk;
	cr |= STM32_UCPD_CR_ANASUBMODE_VAL(UCPD_RP_TO_ANASUB(data->rp));

	/* Disconnect both pull from both CC lines for R_open case */
	cr &= ~UCPD_CR_CCENABLE_Msk;
	/* Set ANAMODE if cc_pull is Rd */
	if (cc_pull == TC_CC_RD) {
		cr |= (UCPD_CR_ANAMODE | UCPD_CR_CCENABLE_Msk);
		/* Clear ANAMODE if cc_pull is Rp */
	} else if (cc_pull == TC_CC_RP) {
		cr &= ~(UCPD_CR_ANAMODE);
		cr |= ucpd_get_cc_enable_mask(dev);
	}

	/* Update pull values */
	LL_UCPD_WriteReg(config->ucpd_port, CR, cr);

#ifdef CONFIG_SOC_SERIES_STM32G0X
	update_stm32g0x_cc_line(config->ucpd_port);
#endif

	return 0;
}

/**
 * @brief Set the polarity of the CC line, which is the active CC line
 *        used for power delivery.
 *
 * @retval 0 on success
 * @retval -EIO on failure
 * @retval -ENOTSUP if polarity is not supported
 */
static int ucpd_cc_set_polarity(const struct device *dev,
				enum tc_cc_polarity polarity)
{
	const struct tcpc_config *const config = dev->config;
	uint32_t cr;

	cr = LL_UCPD_ReadReg(config->ucpd_port, CR);

	/*
	 * Polarity impacts the PHYCCSEL, CCENABLE, and CCxTCDIS fields. This
	 * function is called when polarity is updated at TCPM layer. STM32Gx
	 * only supports POLARITY_CC1 or POLARITY_CC2 and this is stored in the
	 * PHYCCSEL bit in the CR register.
	 */

	if (polarity == TC_POLARITY_CC1) {
		cr &= ~UCPD_CR_PHYCCSEL;
	} else if (polarity == TC_POLARITY_CC2) {
		cr |= UCPD_CR_PHYCCSEL;
	} else {
		return -ENOTSUP;
	}

	/* Update polarity */
	LL_UCPD_WriteReg(config->ucpd_port, CR, cr);

	return 0;
}

/**
 * @brief Enable or Disable Power Delivery
 *
 * @retval 0 on success
 * @retval -EIO on failure
 */
static int ucpd_set_rx_enable(const struct device *dev, bool enable)
{
	const struct tcpc_config *const config = dev->config;
	uint32_t imr;
	uint32_t cr;

	imr = LL_UCPD_ReadReg(config->ucpd_port, IMR);
	cr = LL_UCPD_ReadReg(config->ucpd_port, CR);

	/*
	 * USB PD receiver enable is controlled by the bit PHYRXEN in
	 * UCPD_CR. Enable Rx interrupts when RX PD decoder is active.
	 */
	if (enable) {
		/* Clear the RX alerts bits */
		LL_UCPD_WriteReg(config->ucpd_port, ICR, UCPD_ICR_RX_INT_MASK);
		imr |= UCPD_IMR_RX_INT_MASK;
		cr |= UCPD_CR_PHYRXEN;
		LL_UCPD_WriteReg(config->ucpd_port, IMR, imr);
		LL_UCPD_WriteReg(config->ucpd_port, CR, cr);
	} else {
		imr &= ~UCPD_IMR_RX_INT_MASK;
		cr &= ~UCPD_CR_PHYRXEN;
		LL_UCPD_WriteReg(config->ucpd_port, CR, cr);
		LL_UCPD_WriteReg(config->ucpd_port, IMR, imr);
	}

	return 0;
}

/**
 * @brief Set the Power and Data role used when sending goodCRC messages
 *
 * @retval 0 on success
 * @retval -EIO on failure
 */
static int ucpd_set_roles(const struct device *dev,
			  enum tc_power_role power_role,
			  enum tc_data_role data_role)
{
	struct tcpc_data *data = dev->data;

	data->msg_header.pr = power_role;
	data->msg_header.dr = data_role;

	return 0;
}

/**
 * @brief Enable the reception of SOP Prime messages
 *
 * @retval 0 on success
 * @retval -EIO on failure
 */
static int ucpd_sop_prime_enable(const struct device *dev, bool enable)
{
	struct tcpc_data *data = dev->data;

	/* Update static variable used to filter SOP//SOP'' messages */
	data->ucpd_rx_sop_prime_enabled = enable;

	return 0;
}

/**
 * @brief State transmitting a message
 */
static void ucpd_start_transmit(const struct device *dev,
				enum ucpd_tx_msg msg_type)
{
	struct tcpc_data *data = dev->data;
	const struct tcpc_config *const config = dev->config;
	enum pd_packet_type type;
	uint32_t cr;
	uint32_t imr;

	cr = LL_UCPD_ReadReg(config->ucpd_port, CR);

	/* Select the correct tx descriptor */
	data->ucpd_tx_active_buffer = &data->ucpd_tx_buffers[msg_type];
	type = data->ucpd_tx_active_buffer->type;

	if (type == PD_PACKET_TX_HARD_RESET) {
		/*
		 * From RM0440 45.4.4:
		 * In order to facilitate generation of a Hard Reset, a special
		 * code of TXMODE field is used. No other fields need to be
		 * written. On writing the correct code, the hardware forces
		 * Hard Reset Tx under the correct (optimal) timings with
		 * respect to an on-going Tx message, which (if still in
		 * progress) is cleanly terminated by truncating the current
		 * sequence and directly appending an EOP K-code sequence. No
		 * specific interrupt is generated relating to this truncation
		 * event.
		 *
		 * Because Hard Reset can interrupt ongoing Tx operations, it is
		 * started differently than all other tx messages. Only need to
		 * enable hard reset interrupts, and then set a bit in the CR
		 * register to initiate.
		 */
		/* Enable interrupt for Hard Reset sent/discarded */
		LL_UCPD_WriteReg(config->ucpd_port, ICR,
				 UCPD_ICR_HRSTDISCCF | UCPD_ICR_HRSTSENTCF);

		imr = LL_UCPD_ReadReg(config->ucpd_port, IMR);
		imr |= UCPD_IMR_HRSTDISCIE | UCPD_IMR_HRSTSENTIE;
		LL_UCPD_WriteReg(config->ucpd_port, IMR, imr);

		/* Initiate Hard Reset */
		cr |= UCPD_CR_TXHRST;
		LL_UCPD_WriteReg(config->ucpd_port, CR, cr);
	} else if (type != PD_PACKET_MSG_INVALID) {
		int msg_len = 0;
		int mode;

		/*
		 * These types are normal transmission, TXMODE = 0. To transmit
		 * regular message, control or data, requires the following:
		 *     1. Set TXMODE:
		 *          Normal -> 0
		 *          Cable Reset -> 1
		 *          Bist -> 2
		 *     2. Set TX_ORDSETR based on message type
		 *     3. Set TX_PAYSZR which must account for 2 bytes of header
		 *     4. Configure DMA (optional if DMA is desired)
		 *     5. Enable transmit interrupts
		 *     6. Start TX by setting TXSEND in CR
		 *
		 */

		/*
		 * Set tx length parameter (in bytes). Note the count field in
		 * the header is number of 32 bit objects. Also, the length
		 * field must account for the 2 header bytes.
		 */
		if (type == PD_PACKET_TX_BIST_MODE_2) {
			mode = LL_UCPD_TXMODE_BIST_CARRIER2;
		} else if (type == PD_PACKET_CABLE_RESET) {
			mode = LL_UCPD_TXMODE_CABLE_RESET;
		} else {
			mode = LL_UCPD_TXMODE_NORMAL;
			msg_len = data->ucpd_tx_active_buffer->msg_len;
		}

		LL_UCPD_WriteTxPaySize(config->ucpd_port, msg_len);

		/* Set tx mode */
		cr &= ~UCPD_CR_TXMODE_Msk;
		cr |= mode;
		LL_UCPD_WriteReg(config->ucpd_port, CR, cr);

		/* Index into ordset enum for start of packet */
		if (type <= PD_PACKET_CABLE_RESET) {
			LL_UCPD_WriteTxOrderSet(config->ucpd_port,
						ucpd_txorderset[type]);
		}

		/* Reset msg byte index */
		data->ucpd_tx_active_buffer->msg_index = 0;

		/* Enable interrupts */
		ucpd_tx_interrupts_enable(dev, 1);

		/* Trigger ucpd peripheral to start pd message transmit */
		LL_UCPD_SendMessage(config->ucpd_port);
	}
}

/**
 * @brief Set the current state of the TX state machine
 */
static void ucpd_set_tx_state(const struct device *dev, enum ucpd_state state)
{
	struct tcpc_data *data = dev->data;

	data->ucpd_tx_state = state;
}

/**
 * @brief Wrapper function for calling alert handler
 */
static void ucpd_notify_handler(struct alert_info *info, enum tcpc_alert alert)
{
	if (info->handler) {
		info->handler(info->dev, info->data, alert);
	}
}

/**
 * @brief This is the TX state machine
 */
static void ucpd_manage_tx(struct alert_info *info)
{
	struct tcpc_data *data = info->dev->data;
	enum ucpd_tx_msg msg_src = TX_MSG_NONE;
	union pd_header hdr;

	if (atomic_test_and_clear_bit(&info->evt, UCPD_EVT_HR_REQ)) {
		/*
		 * Hard reset control messages are treated as a priority. The
		 * control message will already be set up as it comes from the
		 * PRL layer like any other PD ctrl/data message. So just need
		 * to indicate the correct message source and set the state to
		 * hard reset here.
		 */
		ucpd_set_tx_state(info->dev, STATE_HARD_RESET);
		msg_src = TX_MSG_TCPM;
		data->ucpd_tx_request &= ~BIT(msg_src);
	}

	switch (data->ucpd_tx_state) {
	case STATE_IDLE:
		if (data->ucpd_tx_request & MSG_GOOD_CRC_MASK) {
			ucpd_set_tx_state(info->dev, STATE_ACTIVE_CRC);
			msg_src = TX_MSG_GOOD_CRC;
		} else if (data->ucpd_tx_request & MSG_TCPM_MASK) {
			if (atomic_test_and_clear_bit(&info->evt, UCPD_EVT_RX_MSG)) {
				/*
				 * USB-PD Specification rev 3.0, section 6.10
				 * On receiving a received message, the protocol
				 * layer shall discard any pending message.
				 *
				 * Since the pending message from the PRL has
				 * not been sent yet, it needs to be discarded
				 * based on the received message event.
				 */
				ucpd_notify_handler(info, TCPC_ALERT_TRANSMIT_MSG_DISCARDED);
				data->ucpd_tx_request &= ~MSG_TCPM_MASK;
			} else if (!data->ucpd_rx_msg_active) {
				ucpd_set_tx_state(info->dev, STATE_ACTIVE_TCPM);
				msg_src = TX_MSG_TCPM;
				/* Save msgID required for GoodCRC check */
				hdr.raw_value =
					data->ucpd_tx_buffers[TX_MSG_TCPM].data.header;
				data->msg_id_match = hdr.message_id;
				data->tx_retry_max = hdr.specification_revision == PD_REV30 ?
						     UCPD_N_RETRY_COUNT_REV30 :
						     UCPD_N_RETRY_COUNT_REV20;
			}
		}

		/* If state is not idle, then start tx message */
		if (data->ucpd_tx_state != STATE_IDLE) {
			data->ucpd_tx_request &= ~BIT(msg_src);
			data->tx_retry_count = 0;
		}
		break;

	case STATE_ACTIVE_TCPM:
		/*
		 * Check if tx msg has finished. For TCPM messages
		 * transmit is not complete until a GoodCRC message
		 * matching the msgID just sent is received. But, a tx
		 * message can fail due to collision or underrun,
		 * etc. If that failure occurs, dont' wait for GoodCrc
		 * and just go to failure path.
		 */
		if (atomic_test_and_clear_bit(&info->evt, UCPD_EVT_TX_MSG_SUCCESS)) {
			ucpd_set_tx_state(info->dev, STATE_WAIT_CRC_ACK);
			/* Start the GoodCRC RX Timer */
			k_timer_start(&data->goodcrc_rx_timer, K_USEC(1000), K_NO_WAIT);
		} else if (atomic_test_and_clear_bit(&info->evt, UCPD_EVT_TX_MSG_DISC) ||
			  atomic_test_and_clear_bit(&info->evt, UCPD_EVT_TX_MSG_FAIL)) {
			if (data->tx_retry_count < data->tx_retry_max) {
				if (atomic_test_and_clear_bit(&info->evt, UCPD_EVT_RX_MSG)) {
					/*
					 * A message was received so there is no
					 * need to retry this tx message which
					 * had failed to send previously.
					 * Likely, due to the wire
					 * being active from the message that
					 * was just received.
					 */
					ucpd_set_tx_state(info->dev,
							  STATE_IDLE);
					ucpd_notify_handler(info,
							TCPC_ALERT_TRANSMIT_MSG_DISCARDED);
					ucpd_set_tx_state(info->dev,
							  STATE_IDLE);
				} else {
					/*
					 * Tx attempt failed. Remain in this
					 * state, but trigger new tx attempt.
					 */
					msg_src = TX_MSG_TCPM;
					data->tx_retry_count++;
				}
			} else {
				enum tcpc_alert status;

				status = (atomic_test_and_clear_bit(&info->evt,
								UCPD_EVT_TX_MSG_FAIL)) ?
					 TCPC_ALERT_TRANSMIT_MSG_FAILED :
					 TCPC_ALERT_TRANSMIT_MSG_DISCARDED;
				ucpd_set_tx_state(info->dev, STATE_IDLE);
				ucpd_notify_handler(info, status);
			}
		}
		break;

	case STATE_ACTIVE_CRC:
		if (atomic_test_bit(&info->evt, UCPD_EVT_TX_MSG_SUCCESS) ||
				atomic_test_bit(&info->evt, UCPD_EVT_TX_MSG_FAIL) ||
				atomic_test_bit(&info->evt, UCPD_EVT_TX_MSG_DISC)) {
			atomic_clear_bit(&info->evt, UCPD_EVT_TX_MSG_SUCCESS);
			atomic_clear_bit(&info->evt, UCPD_EVT_TX_MSG_FAIL);
			atomic_clear_bit(&info->evt, UCPD_EVT_TX_MSG_DISC);
			ucpd_set_tx_state(info->dev, STATE_IDLE);
			if (atomic_test_and_clear_bit(&info->evt, UCPD_EVT_TX_MSG_FAIL)) {
				LOG_INF("ucpd: Failed to send GoodCRC!");
			} else if (atomic_test_and_clear_bit(&info->evt, UCPD_EVT_TX_MSG_DISC)) {
				LOG_INF("ucpd: GoodCRC message discarded!");
			}
		}
		break;

	case STATE_WAIT_CRC_ACK:
		if (atomic_test_and_clear_bit(&info->evt, UCPD_EVT_RX_GOOD_CRC) &&
		    data->ucpd_crc_id == data->msg_id_match) {
			/* GoodCRC with matching ID was received */
			ucpd_notify_handler(info, TCPC_ALERT_TRANSMIT_MSG_SUCCESS);
			ucpd_set_tx_state(info->dev, STATE_IDLE);
		} else if (k_timer_status_get(&data->goodcrc_rx_timer)) {
			/* Stop the GoodCRC RX Timer */
			k_timer_stop(&data->goodcrc_rx_timer);

			/* GoodCRC w/out match or timeout waiting */
			if (data->tx_retry_count < data->tx_retry_max) {
				ucpd_set_tx_state(info->dev, STATE_ACTIVE_TCPM);
				msg_src = TX_MSG_TCPM;
				data->tx_retry_count++;
			} else {
				ucpd_set_tx_state(info->dev, STATE_IDLE);
				ucpd_notify_handler(info, TCPC_ALERT_TRANSMIT_MSG_FAILED);
			}
		} else if (atomic_test_and_clear_bit(&info->evt, UCPD_EVT_RX_MSG)) {
			/*
			 * In the case of a collision, it's possible the port
			 * partner may not send a GoodCRC and instead send the
			 * message that was colliding. If a message is received
			 * in this state, then treat it as a discard from an
			 * incoming message.
			 */
			ucpd_notify_handler(info, TCPC_ALERT_TRANSMIT_MSG_DISCARDED);
			ucpd_set_tx_state(info->dev, STATE_IDLE);
		}
		break;

	case STATE_HARD_RESET:
		if (atomic_test_bit(&info->evt, UCPD_EVT_HR_DONE) ||
		    atomic_test_bit(&info->evt, UCPD_EVT_HR_FAIL)) {
			atomic_clear_bit(&info->evt, UCPD_EVT_HR_DONE);
			atomic_clear_bit(&info->evt, UCPD_EVT_HR_FAIL);
			/* HR complete, reset tx state values */
			ucpd_set_tx_state(info->dev, STATE_IDLE);
			data->ucpd_tx_request = 0;
			data->tx_retry_count = 0;
		}
		break;
	}

	/*
	 * NOTE: TX_MSG_GOOD_CRC messages are sent from the ISR to reduce latency
	 * when sending those messages, so don't resend them here.
	 *
	 * If msg_src is valid and not a TX_MSG_GOOD_CRC, then start transmit.
	 */
	if (msg_src != TX_MSG_GOOD_CRC && msg_src > TX_MSG_NONE) {
		ucpd_start_transmit(info->dev, msg_src);
	}
}

/**
 * @brief Alert handler
 */
static void ucpd_alert_handler(struct k_work *item)
{
	struct alert_info *info = CONTAINER_OF(item, struct alert_info, work);
	struct tcpc_data *data = info->dev->data;

	if (atomic_test_and_clear_bit(&info->evt, UCPD_EVT_EVENT_CC)) {
		ucpd_notify_handler(info, TCPC_ALERT_CC_STATUS);
	}

	if (atomic_test_and_clear_bit(&info->evt, UCPD_EVT_HARD_RESET_RECEIVED)) {
		ucpd_notify_handler(info, TCPC_ALERT_HARD_RESET_RECEIVED);
	}

	if (atomic_test_and_clear_bit(&info->evt, UCPD_EVT_RX_MSG)) {
		ucpd_notify_handler(info, TCPC_ALERT_MSG_STATUS);
	}

	/*
	 * USB-PD messages are initiated in TCPM stack (PRL
	 * layer). However, GoodCRC messages are initiated within the
	 * UCPD driver based on USB-PD rx messages. These 2 types of
	 * transmit paths are managed via events.
	 *
	 * UCPD generated GoodCRC messages, are the priority path as
	 * they must be sent immediately following a successful USB-PD
	 * rx message. As long as a transmit operation is not underway,
	 * then a transmit message will be started upon request. The ISR
	 * routine sets the event to indicate that the transmit
	 * operation is complete.
	 *
	 * Hard reset requests are sent as a TCPM message, but in terms
	 * of the ucpd transmitter, they are treated as a 3rd tx msg
	 * source since they can interrupt an ongoing tx msg, and there
	 * is no requirement to wait for a GoodCRC reply message.
	 */

	if (atomic_test_and_clear_bit(&info->evt, UCPD_EVT_GOOD_CRC_REQ)) {
		data->ucpd_tx_request |= MSG_GOOD_CRC_MASK;
	}

	if (atomic_test_and_clear_bit(&info->evt, UCPD_EVT_TCPM_MSG_REQ)) {
		data->ucpd_tx_request |= MSG_TCPM_MASK;
	}

	/*
	 * Manage PD tx messages. The state machine may need to be
	 * called more than once. For instance, if
	 * the task is woken at the completion of sending a GoodCRC,
	 * there may be a TCPM message request pending and just changing
	 * the state back to idle would not trigger start of transmit.
	 */
	do {
		ucpd_manage_tx(info);
	} while (data->ucpd_tx_state != STATE_IDLE);
}

/**
 * @brief Sends a goodCRC message
 */
static void ucpd_send_good_crc(const struct device *dev,
			       union pd_header rx_header)
{
	struct tcpc_data *data = dev->data;
	const struct tcpc_config *const config = dev->config;
	union pd_header tx_header;
	enum pd_packet_type tx_type;
	struct alert_info *info = &data->alert_info;

	/*
	 * A GoodCRC message shall be sent by receiver to ack that the previous
	 * message was correctly received. The GoodCRC message shall return the
	 * rx message's msg_id field. The one exception is for GoodCRC messages,
	 * which do not generate a GoodCRC response
	 */
	if (ucpd_msg_is_good_crc(rx_header)) {
		return;
	}

	/*
	 * Get the rx ordered set code just detected. SOP -> SOP''_Debug are in
	 * the same order as enum tcpc_packet_type and so can be used
	 * directly.
	 */
	tx_type = LL_UCPD_ReadRxOrderSet(config->ucpd_port);

	/*
	 * PD Header(SOP):
	 *   Extended   b15    -> set to 0 for control messages
	 *   Count      b14:12 -> number of 32 bit data objects = 0 for ctrl msg
	 *   MsgID      b11:9  -> running byte counter (extracted from rx msg)
	 *   Power Role b8     -> stored in static, from set_msg_header()
	 *   Spec Rev   b7:b6  -> PD spec revision (extracted from rx msg)
	 *   Data Role  b5     -> stored in static, from set_msg_header
	 *   Msg Type   b4:b0  -> data or ctrl type = PD_CTRL_GOOD_CRC
	 */
	/* construct header message */
	tx_header.message_type = PD_CTRL_GOOD_CRC;
	if (tx_type == PD_PACKET_SOP) {
		tx_header.port_power_role = data->msg_header.pr;
		tx_header.port_data_role = data->msg_header.dr;
	} else {
		tx_header.port_power_role = 0;
		tx_header.port_data_role = 0;
	}
	tx_header.message_id = rx_header.message_id;
	tx_header.number_of_data_objects = 0;
	tx_header.specification_revision = rx_header.specification_revision;
	tx_header.extended = 0;

	/* Good CRC is header with no other objects */
	data->ucpd_tx_buffers[TX_MSG_GOOD_CRC].msg_len = MSG_HEADER_SIZE;
	data->ucpd_tx_buffers[TX_MSG_GOOD_CRC].data.header =
		tx_header.raw_value;
	data->ucpd_tx_buffers[TX_MSG_GOOD_CRC].type = tx_type;

	/* Notify ucpd task that a GoodCRC message tx request is pending */
	atomic_set_bit(&info->evt, UCPD_EVT_GOOD_CRC_REQ);

	/* Send TX_MSG_GOOD_CRC message here to reduce latency */
	ucpd_start_transmit(dev, TX_MSG_GOOD_CRC);
}

/**
 * @brief Transmit a power delivery message
 *
 * @retval 0 on success
 * @retval -EFAULT on failure
 */
static int ucpd_transmit_data(const struct device *dev,
			      struct pd_msg *msg)
{
	struct tcpc_data *data = dev->data;

	/* Length in bytes = (4 * object len) + 2 header bytes */
	int len = PD_CONVERT_PD_HEADER_COUNT_TO_BYTES(msg->header.number_of_data_objects) + 2;

	if (len > UCPD_BUF_LEN) {
		return -EFAULT;
	}

	/* Store tx msg info in TCPM msg descriptor */
	data->ucpd_tx_buffers[TX_MSG_TCPM].msg_len = len;
	data->ucpd_tx_buffers[TX_MSG_TCPM].type = msg->type;
	data->ucpd_tx_buffers[TX_MSG_TCPM].data.header = msg->header.raw_value;

	/* Copy msg objects to ucpd data buffer, after 2 header bytes */
	memcpy(data->ucpd_tx_buffers[TX_MSG_TCPM].data.msg + 2,
	       (uint8_t *)msg->data, len - 2);

	/*
	 * Check for hard reset message here. A different event is used for hard
	 * resets as they are able to interrupt ongoing transmit, and should
	 * have priority over any pending message.
	 */
	if (msg->type == PD_PACKET_TX_HARD_RESET) {
		atomic_set_bit(&data->alert_info.evt, UCPD_EVT_HR_REQ);
	} else {
		atomic_set_bit(&data->alert_info.evt, UCPD_EVT_TCPM_MSG_REQ);
	}

	/* Start transmission */
	k_work_submit(&data->alert_info.work);

	return 0;
}

/**
 * @brief Tests if a received Power Delivery message is pending
 *
 * @retval true if message is pending, else false
 */
static bool ucpd_is_rx_pending_msg(const struct device *dev,
				   enum pd_packet_type *type)
{
	struct tcpc_data *data = dev->data;
	bool ret;

	ret = (*(uint32_t *)data->ucpd_rx_buffer > 0);

	if (ret & (type != NULL)) {
		*type = *(uint16_t *)data->ucpd_rx_buffer;
	}

	return ret;
}

/**
 * @brief Retrieves the Power Delivery message from the TCPC
 *
 * @retval number of bytes received
 * @retval -EIO on no message to retrieve
 * @retval -EFAULT on buf being NULL
 */
static int ucpd_receive_data(const struct device *dev, struct pd_msg *msg)
{
	struct tcpc_data *data = dev->data;
	int ret = 0;

	if (msg == NULL) {
		return -EFAULT;
	}

	/* Make sure we have a message to retrieve */
	if (!ucpd_is_rx_pending_msg(dev, NULL)) {
		return -EIO;
	}

	msg->type = *(uint16_t *)data->ucpd_rx_buffer;
	msg->header.raw_value = *((uint16_t *)data->ucpd_rx_buffer + 1);
	msg->len = PD_CONVERT_PD_HEADER_COUNT_TO_BYTES(msg->header.number_of_data_objects);
	memcpy(msg->data, (data->ucpd_rx_buffer +
			   PACKET_TYPE_SIZE +
			   MSG_HEADER_SIZE), msg->len);
	ret = msg->len + MSG_HEADER_SIZE;

	/* All done. Clear type and header */
	*(uint32_t *)data->ucpd_rx_buffer = 0;

	return ret;
}

/**
 * @brief Enable or Disable BIST Test mode
 *
 * return 0 on success
 * return -EIO on failure
 */
static int ucpd_set_bist_test_mode(const struct device *dev,
				   bool enable)
{
	struct tcpc_data *data = dev->data;

	data->ucpd_rx_bist_mode = enable;
	LOG_INF("ucpd: Bist test mode = %d", enable);

	return 0;
}

/**
 * @brief UCPD interrupt handler
 */
static void ucpd_isr(const struct device *dev_inst[])
{
	const struct device *dev;
	const struct tcpc_config *config;
	struct tcpc_data *data;
	uint32_t sr;
	struct alert_info *info;
	uint32_t tx_done_mask = UCPD_SR_TXUND |
				UCPD_SR_TXMSGSENT |
				UCPD_SR_TXMSGABT |
				UCPD_SR_TXMSGDISC |
				UCPD_SR_HRSTSENT |
				UCPD_SR_HRSTDISC;

#if DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) > 1
	/*
	 * Multiple UCPD ports are available
	 */

	uint32_t sr0;
	uint32_t sr1;

	/*
	 * Since the UCPD peripherals share the same interrupt line, determine
	 * which one generated the interrupt.
	 */

	/* Read UCPD1 and UCPD2 Status Registers */

	sr0 =
	LL_UCPD_ReadReg(((const struct tcpc_config *)dev_inst[0]->config)->ucpd_port, SR);
	sr1 =
	LL_UCPD_ReadReg(((const struct tcpc_config *)dev_inst[1]->config)->ucpd_port, SR);

	if (sr0) {
		dev = dev_inst[0];
	} else if (sr1) {
		dev = dev_inst[1];
	} else {
		/*
		 * The interrupt was triggered by some other device sharing this
		 * interrupt line.
		 */
		return;
	}
#else
	/*
	 * Only one UCPD port available
	 */

	dev = dev_inst[0];
#endif /* Get the UCPD port that initiated that interrupt  */

	config = dev->config;
	data = dev->data;
	info = &data->alert_info;

	/* Read the status register */
	sr = LL_UCPD_ReadReg(config->ucpd_port, SR);

	/* Check for CC events, set event to wake PD task */
	if (sr & (UCPD_SR_TYPECEVT1 | UCPD_SR_TYPECEVT2)) {
		/* Set CC event bit */
		atomic_set_bit(&info->evt, UCPD_EVT_EVENT_CC);
	}

	/*
	 * Check for Tx events. tx_mask includes all status bits related to the
	 * end of a USB-PD tx message. If any of these bits are set, the
	 * transmit attempt is completed. Set an event to notify ucpd tx state
	 * machine that transmit operation is complete.
	 */
	if (sr & tx_done_mask) {
		/* Check for tx message complete */
		if (sr & UCPD_SR_TXMSGSENT) {
			atomic_set_bit(&info->evt, UCPD_EVT_TX_MSG_SUCCESS);
		} else if (sr & (UCPD_SR_TXMSGABT | UCPD_SR_TXUND)) {
			atomic_set_bit(&info->evt, UCPD_EVT_TX_MSG_FAIL);
		} else if (sr & (UCPD_SR_TXMSGDISC | UCPD_SR_HRSTDISC)) {
			atomic_set_bit(&info->evt, UCPD_EVT_TX_MSG_DISC);
		} else if (sr & UCPD_SR_HRSTSENT) {
			atomic_set_bit(&info->evt, UCPD_EVT_HR_DONE);
		} else if (sr & UCPD_SR_HRSTDISC) {
			atomic_set_bit(&info->evt, UCPD_EVT_HR_FAIL);
		}

		/* Disable Tx interrupts */
		ucpd_tx_interrupts_enable(dev, 0);
	}

	/* Check for data register empty */
	if (sr & UCPD_SR_TXIS) {
		ucpd_tx_data_byte(dev);
	}

	/* Check for Rx Events */
	/* Check first for start of new message */
	if (sr & UCPD_SR_RXORDDET) {
		/* Add message type to pd message buffer */
		*(uint16_t *)data->ucpd_rx_buffer =
			LL_UCPD_ReadRxOrderSet(config->ucpd_port);

		data->ucpd_rx_byte_count = 2;
		data->ucpd_rx_msg_active = true;
	}
	/* Check for byte received */
	if (sr & UCPD_SR_RXNE) {
		ucpd_rx_data_byte(dev);
	}

	/* Check for end of message */
	if (sr & UCPD_SR_RXMSGEND) {
		data->ucpd_rx_msg_active = false;
		/* Check for errors */
		if (!(sr & UCPD_SR_RXERR)) {
			enum pd_packet_type type;
			union pd_header rx_header;
			int good_crc;

			type = *(uint16_t *)data->ucpd_rx_buffer;
			rx_header.raw_value =
				*((uint16_t *)data->ucpd_rx_buffer + 1);
			good_crc = ucpd_msg_is_good_crc(rx_header);

			/*
			 * Don't pass GoodCRC control messages to the TCPM
			 * layer. In addition, need to filter for SOP'/SOP''
			 * packets if those are not enabled. SOP'/SOP''
			 * reception is controlled by a static variable. The
			 * hardware orderset detection pattern can't be changed
			 * without disabling the ucpd peripheral.
			 */
			if (!good_crc && (data->ucpd_rx_sop_prime_enabled ||
					  type == PD_PACKET_SOP)) {

				/*
				 * If BIST test mode is active, then still need
				 * to send GoodCRC reply, but there is no need
				 * to send the message up to the tcpm layer.
				 */
				if (!data->ucpd_rx_bist_mode) {
					atomic_set_bit(&info->evt, UCPD_EVT_RX_MSG);
				}
				/* Send GoodCRC message (if required) */
				ucpd_send_good_crc(dev, rx_header);
			} else if (good_crc) {
				atomic_set_bit(&info->evt, UCPD_EVT_RX_GOOD_CRC);
				data->ucpd_crc_id = rx_header.message_id;
			}
		} else {
			/* Rx message is complete, but there were bit errors */
			LOG_ERR("ucpd: rx message error");
		}
	}
	/* Check for fault conditions */
	if (sr & UCPD_SR_RXHRSTDET) {
		/* hard reset received */
		atomic_set_bit(&info->evt, UCPD_EVT_HARD_RESET_RECEIVED);
	}

	/* Clear interrupts now that PD events have been set */
	LL_UCPD_WriteReg(config->ucpd_port, ICR, sr & UCPD_ICR_ALL_INT_MASK);

	/* Notify application of events */
	k_work_submit(&info->work);
}

/**
 * @brief Dump a set of TCPC registers
 *
 * @retval 0 on success
 * @retval -EIO on failure
 */
static int ucpd_dump_std_reg(const struct device *dev)
{
	const struct tcpc_config *const config = dev->config;

	LOG_INF("CFGR1: %08x", LL_UCPD_ReadReg(config->ucpd_port, CFG1));
	LOG_INF("CFGR2: %08x", LL_UCPD_ReadReg(config->ucpd_port, CFG2));
	LOG_INF("CR:    %08x", LL_UCPD_ReadReg(config->ucpd_port, CR));
	LOG_INF("IMR:   %08x", LL_UCPD_ReadReg(config->ucpd_port, IMR));
	LOG_INF("SR:    %08x", LL_UCPD_ReadReg(config->ucpd_port, SR));
	LOG_INF("ICR:   %08x\n", LL_UCPD_ReadReg(config->ucpd_port, ICR));

	return 0;
}

/**
 * @brief Sets the alert function that's called when an interrupt is triggered
 *        due to a TCPC alert
 *
 * @retval 0 on success
 * @retval -EINVAL on failure
 */
static int ucpd_set_alert_handler_cb(const struct device *dev,
				     tcpc_alert_handler_cb_t handler, void *alert_data)
{
	struct tcpc_data *data = dev->data;

	data->alert_info.handler = handler;
	data->alert_info.data = alert_data;

	return 0;
}

/**
 * @brief Sets a callback that can enable or disable VCONN if the TCPC is
 *        unable to or the system is configured in a way that does not use
 *        the VCONN control capabilities of the TCPC
 *
 */
static void ucpd_set_vconn_cb(const struct device *dev,
			      tcpc_vconn_control_cb_t vconn_cb)
{
	struct tcpc_data *data = dev->data;

	data->vconn_cb = vconn_cb;
}

/**
 * @brief Sets a callback that can discharge VCONN if the TCPC is
 *        unable to or the system is configured in a way that does not use
 *        the VCONN discharge capabilities of the TCPC
 *
 */
static void ucpd_set_vconn_discharge_cb(const struct device *dev,
					tcpc_vconn_discharge_cb_t cb)
{
	struct tcpc_data *data = dev->data;

	data->vconn_discharge_cb = cb;
}

/**
 * @brief UCPD interrupt init
 */
static void ucpd_isr_init(const struct device *dev)
{
	const struct tcpc_config *const config = dev->config;
	struct tcpc_data *data = dev->data;
	struct alert_info *info = &data->alert_info;

	/* Init GoodCRC Receive timer */
	k_timer_init(&data->goodcrc_rx_timer, NULL, NULL);

	/* Disable all alert bits */
	LL_UCPD_WriteReg(config->ucpd_port, IMR, 0);

	/* Clear all alert handler */
	ucpd_set_alert_handler_cb(dev, NULL, NULL);

	/* Save device structure for use in the alert handlers */
	info->dev = dev;

	/* Initialize the work handler */
	k_work_init(&info->work, ucpd_alert_handler);

	/* Configure CC change alerts */
	LL_UCPD_WriteReg(config->ucpd_port, IMR,
			 UCPD_IMR_TYPECEVT1IE | UCPD_IMR_TYPECEVT2IE);
	LL_UCPD_WriteReg(config->ucpd_port, ICR,
			 UCPD_ICR_TYPECEVT1CF | UCPD_ICR_TYPECEVT2CF);

	/* SOP'/SOP'' must be enabled via TCPCI call */
	data->ucpd_rx_sop_prime_enabled = false;

	stm32_ucpd_state_init(dev);

	/* Configure and enable the IRQ */
	config_tcpc_irq();
}

/**
 * @brief Initializes the TCPC
 *
 * @retval 0 on success
 * @retval -EIO on failure
 */
static int ucpd_init(const struct device *dev)
{
	const struct tcpc_config *const config = dev->config;
	struct tcpc_data *data = dev->data;
	uint32_t cfg1;
	int ret;

	LOG_DBG("Pinctrl signals configuration");
	ret = pinctrl_apply_state(config->ucpd_pcfg, PINCTRL_STATE_DEFAULT);
	if (ret < 0) {
		LOG_ERR("USB pinctrl setup failed (%d)", ret);
		return ret;
	}

	/*
	 * The UCPD port is disabled in the LL_UCPD_Init function
	 *
	 * NOTE: For proper Power Management operation, this function
	 *       should not be used because it circumvents the zephyr
	 *	 clock API. Instead, DTS clock settings and the zephyr
	 *	 clock API should be used to enable clocks.
	 */
	ret = LL_UCPD_Init(config->ucpd_port,
			   (LL_UCPD_InitTypeDef *)&config->ucpd_params);

	if (ret == SUCCESS) {
		/* Init Rp to USB */
		data->rp = TC_RP_USB;

		/*
		 * Set RXORDSETEN field to control which types of ordered sets the PD
		 * receiver must receive.
		 */
		cfg1 = LL_UCPD_ReadReg(config->ucpd_port, CFG1);
		cfg1 |= LL_UCPD_ORDERSET_SOP | LL_UCPD_ORDERSET_SOP1 |
			LL_UCPD_ORDERSET_SOP2 | LL_UCPD_ORDERSET_HARDRST;
		LL_UCPD_WriteReg(config->ucpd_port, CFG1, cfg1);

		/* Enable UCPD port */
		LL_UCPD_Enable(config->ucpd_port);

		/* Enable Dead Battery Support */
		if (config->ucpd_dead_battery) {
#ifdef CONFIG_SOC_SERIES_STM32G0X
			uint32_t cr;

			cr = LL_UCPD_ReadReg(config->ucpd_port, CR);
			cr |= UCPD_CR_DBATTEN;
			LL_UCPD_WriteReg(config->ucpd_port, CR, cr);
			update_stm32g0x_cc_line(config->ucpd_port);
#else
			CLEAR_BIT(PWR->CR3, PWR_CR3_UCPD_DBDIS);
#endif
		}

		/* Initialize the isr */
		ucpd_isr_init(dev);
	} else {
		return -EIO;
	}

	return 0;
}

static const struct tcpc_driver_api driver_api = {
	.init = ucpd_init,
	.set_alert_handler_cb = ucpd_set_alert_handler_cb,
	.get_cc = ucpd_get_cc,
	.set_rx_enable = ucpd_set_rx_enable,
	.is_rx_pending_msg = ucpd_is_rx_pending_msg,
	.receive_data = ucpd_receive_data,
	.transmit_data = ucpd_transmit_data,
	.select_rp_value = ucpd_select_rp_value,
	.get_rp_value = ucpd_get_rp_value,
	.set_cc = ucpd_set_cc,
	.set_roles = ucpd_set_roles,
	.set_vconn_cb = ucpd_set_vconn_cb,
	.set_vconn_discharge_cb = ucpd_set_vconn_discharge_cb,
	.set_vconn = ucpd_set_vconn,
	.vconn_discharge = ucpd_vconn_discharge,
	.set_cc_polarity = ucpd_cc_set_polarity,
	.dump_std_reg = ucpd_dump_std_reg,
	.set_bist_test_mode = ucpd_set_bist_test_mode,
	.sop_prime_enable = ucpd_sop_prime_enable,
};

#define DEV_INST_INIT(n) dev_inst[n] = DEVICE_DT_INST_GET(n);
static void config_tcpc_irq(void)
{
	static int inst_num;
	static const struct device
	*dev_inst[DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT)];

	/* Initialize and enable shared irq on last instance */
	if (++inst_num == DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT)) {
		DT_INST_FOREACH_STATUS_OKAY(DEV_INST_INIT)

		IRQ_CONNECT(DT_INST_IRQN(0),
			    DT_INST_IRQ(0, priority),
			    ucpd_isr, dev_inst, 0);

		irq_enable(DT_INST_IRQN(0));
	}
}

BUILD_ASSERT(DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) > 0,
	     "No compatible STM32 TCPC instance found");

#define TCPC_DRIVER_INIT(inst)								\
	PINCTRL_DT_INST_DEFINE(inst);							\
	static struct tcpc_data drv_data_##inst;					\
	static const struct tcpc_config drv_config_##inst = {				\
		.ucpd_pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst),			\
		.ucpd_port = (UCPD_TypeDef *)DT_INST_REG_ADDR(inst),			\
		.ucpd_params.psc_ucpdclk = ilog2(DT_INST_PROP(inst, psc_ucpdclk)),	\
		.ucpd_params.transwin = DT_INST_PROP(inst, transwin) - 1,		\
		.ucpd_params.IfrGap = DT_INST_PROP(inst, ifrgap) - 1,			\
		.ucpd_params.HbitClockDiv = DT_INST_PROP(inst, hbitclkdiv) - 1,		\
		.ucpd_dead_battery = DT_INST_PROP(inst, dead_battery),			\
	};										\
	DEVICE_DT_INST_DEFINE(inst,							\
			      &ucpd_init,						\
			      NULL,							\
			      &drv_data_##inst,						\
			      &drv_config_##inst,					\
			      POST_KERNEL,						\
			      CONFIG_USBC_INIT_PRIORITY,				\
			      &driver_api);

DT_INST_FOREACH_STATUS_OKAY(TCPC_DRIVER_INIT)
