Beispiel #1
0
static int anx7688_init(int port)
{
	int rv = 0;
	int mask = 0;

	/*
	 * 7688 POWER_STATUS[6] is not reliable for tcpci_tcpm_init() to poll
	 * due to it is default 0 in HW, and we cannot write TCPC until it is
	 * ready, or something goes wrong. (Issue 52772)
	 * Instead we poll TCPC 0x50:0xe7 bit6 here to make sure bootdone is
	 * ready(50ms). Then PD main flow can process cc debounce in 50ms ~
	 * 100ms to follow cts.
	 */
	while (1) {
		rv = i2c_read8(I2C_PORT_TCPC, ANX7688_USBC_ADDR,
			       ANX7688_REG_RAMCTRL, &mask);

		if (rv == EC_SUCCESS && (mask & ANX7688_REG_RAMCTRL_BOOT_DONE))
			break;
		msleep(10);
	}

	rv = tcpci_tcpm_drv.init(port);
	if (rv)
		return rv;

	rv = tcpc_read16(port, TCPC_REG_ALERT_MASK, &mask);
	if (rv)
		return rv;

	/* enable vendor specific alert */
	mask |= ANX7688_VENDOR_ALERT;
	rv = tcpc_write16(port, TCPC_REG_ALERT_MASK, mask);
	return rv;
}
Beispiel #2
0
static void anx7688_tcpc_alert(int port)
{
	int alert, rv;

	rv = tcpc_read16(port, TCPC_REG_ALERT, &alert);
	/* process and clear alert status */
	tcpci_tcpm_drv.tcpc_alert(port);

	if (!rv && (alert & ANX7688_VENDOR_ALERT))
		anx7688_update_hpd_enable(port);
}
Beispiel #3
0
static int tcpci_tcpm_get_message(int port, uint32_t *payload, int *head)
{
	int rv, cnt, reg = TCPC_REG_RX_DATA;

	rv = tcpc_read(port, TCPC_REG_RX_BYTE_CNT, &cnt);

	rv |= tcpc_read16(port, TCPC_REG_RX_HDR, (int *)head);

	if (rv == EC_SUCCESS && cnt > 0) {
		tcpc_lock(port, 1);
		rv = tcpc_xfer(port,
			       (uint8_t *)&reg, 1, (uint8_t *)payload,
			       cnt, I2C_XFER_SINGLE);
		tcpc_lock(port, 0);
	}

	/* Read complete, clear RX status alert bit */
	tcpc_write16(port, TCPC_REG_ALERT, TCPC_REG_ALERT_RX_STATUS);

	return rv;
}
Beispiel #4
0
static int anx74xx_tcpm_get_message(int port, uint32_t *payload, int *head)
{
	int reg = 0, rv = EC_SUCCESS;
	int len = 0;

	/* Fetch the header */
	rv |= tcpc_read16(port, ANX74XX_REG_PD_HEADER, &reg);
	if (rv) {
		*head = 0;
		/* Clear receive message interrupt bit(bit-0) */
		tcpc_read(port, ANX74XX_REG_IRQ_SOURCE_RECV_MSG, &reg);
		tcpc_write(port, ANX74XX_REG_IRQ_SOURCE_RECV_MSG,
			 reg & (~0x01));

		return EC_ERROR_UNKNOWN;
	}
	*head = reg;
	len = PD_HEADER_CNT(*head) * 4;
	if (!len) {
		/* Clear receive message interrupt bit(bit-0) */
		tcpc_read(port, ANX74XX_REG_IRQ_SOURCE_RECV_MSG, &reg);
		tcpc_write(port, ANX74XX_REG_IRQ_SOURCE_RECV_MSG,
			 reg & (~0x01));
		return EC_SUCCESS;
	}

	/* Receive message : assuming payload have enough
	 * memory allocated
	 */
	rv |= anx74xx_read_pd_obj(port, (uint8_t *)payload, len);
	if (rv) {
		*head = 0;
		return EC_ERROR_UNKNOWN;
	}

	return rv;
}
Beispiel #5
0
static int tcpm_alert_status(int port, int *alert)
{
	/* Read TCPC Alert register */
	return tcpc_read16(port, TCPC_REG_ALERT, alert);
}