summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/usb_pd_protocol.c6
-rw-r--r--common/usbc_ppc.c4
-rw-r--r--driver/build.mk1
-rw-r--r--driver/ppc/nx20p3483.c326
-rw-r--r--driver/ppc/nx20p3483.h106
-rw-r--r--driver/ppc/sn5s330.c8
-rw-r--r--include/config.h15
-rw-r--r--include/usbc_ppc.h13
8 files changed, 475 insertions, 4 deletions
diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c
index 12b1546217..2f25e06564 100644
--- a/common/usb_pd_protocol.c
+++ b/common/usb_pd_protocol.c
@@ -321,9 +321,9 @@ static inline int pd_is_vbus_present(int port)
static void set_polarity(int port, int polarity)
{
tcpm_set_polarity(port, polarity);
-#ifdef CONFIG_USBC_PPC
+#ifdef CONFIG_USBC_PPC_POLARITY
ppc_set_polarity(port, polarity);
-#endif /* defined(CONFIG_USBC_PPC) */
+#endif /* defined(CONFIG_USBC_PPC_POLARITY) */
}
#ifdef CONFIG_USBC_VCONN
@@ -337,7 +337,7 @@ static void set_vconn(int port, int enable)
* "make before break" electrical requirements when swapping anyway.
*/
tcpm_set_vconn(port, enable);
-#ifdef CONFIG_USBC_PPC
+#ifdef CONFIG_USBC_PPC_VCONN
ppc_set_vconn(port, enable);
#endif
}
diff --git a/common/usbc_ppc.c b/common/usbc_ppc.c
index 6ff79a17bf..7011309cf1 100644
--- a/common/usbc_ppc.c
+++ b/common/usbc_ppc.c
@@ -42,6 +42,7 @@ int ppc_is_sourcing_vbus(int port)
return ppc_chips[port].drv->is_sourcing_vbus(port);
}
+#ifdef CONFIG_USBC_PPC_POLARITY
int ppc_set_polarity(int port, int polarity)
{
if ((port < 0) || (port >= ppc_cnt))
@@ -49,6 +50,7 @@ int ppc_set_polarity(int port, int polarity)
return ppc_chips[port].drv->set_polarity(port, polarity);
}
+#endif
int ppc_set_vbus_source_current_limit(int port, enum tcpc_rp_value rp)
{
@@ -66,6 +68,7 @@ int ppc_discharge_vbus(int port, int enable)
return ppc_chips[port].drv->discharge_vbus(port, enable);
}
+#ifdef CONFIG_USBC_PPC_VCONN
int ppc_set_vconn(int port, int enable)
{
if ((port < 0) || (port >= ppc_cnt))
@@ -73,6 +76,7 @@ int ppc_set_vconn(int port, int enable)
return ppc_chips[port].drv->set_vconn(port, enable);
}
+#endif
int ppc_vbus_sink_enable(int port, int enable)
{
diff --git a/driver/build.mk b/driver/build.mk
index 23eb0a2d65..924a76eecd 100644
--- a/driver/build.mk
+++ b/driver/build.mk
@@ -116,6 +116,7 @@ driver-$(CONFIG_USB_MUX_VIRTUAL)+=usb_mux_virtual.o
# Type-C Power Path Controllers (PPC)
driver-$(CONFIG_USBC_PPC_SN5S330)+=ppc/sn5s330.o
+driver-$(CONFIG_USBC_PPC_NX20P3483)+=ppc/nx20p3483.o
# video converters
driver-$(CONFIG_MCDP28X0)+=mcdp28x0.o
diff --git a/driver/ppc/nx20p3483.c b/driver/ppc/nx20p3483.c
new file mode 100644
index 0000000000..7a3893443e
--- /dev/null
+++ b/driver/ppc/nx20p3483.c
@@ -0,0 +1,326 @@
+/* Copyright 2018 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/* NX20P3483 USB-C Power Path Controller */
+
+#include "common.h"
+#include "console.h"
+#include "driver/ppc/nx20p3483.h"
+#include "gpio.h"
+#include "hooks.h"
+#include "i2c.h"
+#include "system.h"
+#include "usb_charge.h"
+#include "usb_pd_tcpm.h"
+#include "usbc_ppc.h"
+#include "util.h"
+
+#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args)
+#define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args)
+
+#define NX20P3483_DB_EXIT_FAIL_THRESHOLD 10
+
+static uint32_t irq_pending; /* Bitmask of ports signaling an interrupt. */
+static int db_exit_fail_count[CONFIG_USB_PD_PORT_COUNT];
+
+static int read_reg(uint8_t port, int reg, int *regval)
+{
+ return i2c_read8(ppc_chips[port].i2c_port,
+ ppc_chips[port].i2c_addr,
+ reg,
+ regval);
+}
+
+static int write_reg(uint8_t port, int reg, int regval)
+{
+ return i2c_write8(ppc_chips[port].i2c_port,
+ ppc_chips[port].i2c_addr,
+ reg,
+ regval);
+}
+
+static int nx20p3483_is_sourcing_vbus(int port)
+{
+ int mode;
+ int rv;
+
+ rv = read_reg(port, NX20P3483_DEVICE_STATUS_REG, &mode);
+ if (rv) {
+ CPRINTS("p%d: Failed to determine NX20P device status! (%d)",
+ port, rv);
+ return 0;
+ }
+
+ return ((mode & NX20P3483_DEVICE_MODE_MASK) == NX20P3483_MODE_5V_SRC);
+}
+
+static int nx20p3483_set_vbus_source_current_limit(int port,
+ enum tcpc_rp_value rp)
+{
+ int regval;
+ int status;
+
+ status = read_reg(port, NX20P3483_5V_SRC_OCP_THRESHOLD_REG, &regval);
+ if (status)
+ return status;
+
+ regval &= ~NX20P3483_ILIM_MASK;
+ switch (rp) {
+ case TYPEC_RP_3A0:
+ regval |= NX20P3483_ILIM_3_000;
+ break;
+
+ case TYPEC_RP_1A5:
+ regval |= NX20P3483_ILIM_1_600;
+ break;
+
+ case TYPEC_RP_USB:
+ default:
+ regval |= NX20P3483_ILIM_0_600;
+ break;
+ };
+
+
+ return write_reg(port, NX20P3483_5V_SRC_OCP_THRESHOLD_REG, regval);
+}
+
+static int nx20p3483_discharge_vbus(int port, int enable)
+{
+ int regval;
+ int status;
+
+ status = read_reg(port, NX20P3483_DEVICE_CONTROL_REG, &regval);
+ if (status)
+ return status;
+
+ if (enable)
+ regval |= NX20P3483_CTRL_VBUSDIS_EN;
+ else
+ regval &= ~NX20P3483_CTRL_VBUSDIS_EN;
+
+ status = write_reg(port, NX20P3483_DEVICE_CONTROL_REG, regval);
+ if (status) {
+ CPRINTS("Failed to %s vbus discharge",
+ enable ? "enable" : "disable");
+ return status;
+ }
+
+ return EC_SUCCESS;
+}
+
+static int nx20p3483_vbus_sink_enable(int port, int enable)
+{
+ int status;
+ int rv;
+
+ enable = !!enable;
+ /*
+ * IF PPC_CFG_FLAGS_GPIO_CONTROL is set, then the SNK/SRC switch
+ * control is driven by the EC. Otherwise, it's controlled directly by
+ * the TCPC and only need to check the status.
+ */
+ if (ppc_chips[port].flags & PPC_CFG_FLAGS_GPIO_CONTROL) {
+
+ /* If enable, makes sure that SRC mode is disabled */
+ if (enable)
+ gpio_set_level(ppc_chips[port].src_gpio, 0);
+
+ /* Set SNK mode based on enable */
+ gpio_set_level(ppc_chips[port].snk_gpio, enable);
+ }
+
+ /* Verify switch status register */
+ rv = read_reg(port, NX20P3483_SWITCH_STATUS_REG, &status);
+ if (rv)
+ return rv;
+ status = !!(status & NX20P3483_HVSNK_STS);
+ return (status == enable) ? EC_SUCCESS : EC_ERROR_UNKNOWN;
+}
+
+static int nx20p3483_vbus_source_enable(int port, int enable)
+{
+ int status;
+ int rv;
+
+ enable = !!enable;
+ /*
+ * IF PPC_CFG_FLAGS_GPIO_CONTROL is set, then the SNK/SRC switch
+ * control is driven by the EC. Otherwise, it's controlled directly by
+ * the TCPC and only need to check the status.
+ */
+ if (ppc_chips[port].flags & PPC_CFG_FLAGS_GPIO_CONTROL) {
+
+ /* If enable, makes sure that SNK mode is disabled */
+ if (enable)
+ gpio_set_level(ppc_chips[port].snk_gpio, 0);
+
+ /* Set SRC mode based on enable */
+ gpio_set_level(ppc_chips[port].src_gpio, enable);
+ }
+
+ /* Verify switch status register */
+ rv = read_reg(port, NX20P3483_SWITCH_STATUS_REG, &status);
+ if (rv)
+ return rv;
+ status = !!(status & NX20P3483_5VSRC_STS);
+ return (status == enable) ? EC_SUCCESS : EC_ERROR_UNKNOWN;
+}
+
+static int nx20p3483_init(int port)
+{
+ int reg;
+ int mask;
+ int rv;
+
+ /* Set VBUS over voltage threshold (OVLO) */
+ rv = read_reg(port, NX20P3483_OVLO_THRESHOLD_REG, &reg);
+ if (rv)
+ return rv;
+ /* OVLO threshold is 3 bit field */
+ reg &= ~NX20P3483_OVLO_THRESHOLD_MASK;
+ /* Set SNK OVP to 23.0 V */
+ reg |= NX20P3483_OVLO_23_0;
+ rv = write_reg(port, NX20P3483_OVLO_THRESHOLD_REG, reg);
+ if (rv)
+ return rv;
+
+ /* Mask interrupts for interrupt 2 register */
+ mask = ~NX20P3483_INT2_EN_ERR;
+ rv = write_reg(port, NX20P3483_INTERRUPT2_MASK_REG, mask);
+ if (rv)
+ return rv;
+
+ /* Mask interrupts for interrupt 1 register */
+ mask = ~(NX20P3483_INT1_OC_5VSRC | NX20P3483_INT1_DBEXIT_ERR);
+ rv = write_reg(port, NX20P3483_INTERRUPT1_MASK_REG, mask);
+ if (rv)
+ return rv;
+
+ /* Clear any pending interrupts by reading interrupt registers */
+ read_reg(port, NX20P3483_INTERRUPT1_REG, &reg);
+ read_reg(port, NX20P3483_INTERRUPT2_REG, &reg);
+
+ /* Make sure that dead battery mode is exited */
+ rv = read_reg(port, NX20P3483_DEVICE_CONTROL_REG, &reg);
+ if (rv)
+ return rv;
+ reg |= NX20P3483_CTRL_DB_EXIT;
+ rv = write_reg(port, NX20P3483_DEVICE_CONTROL_REG, reg);
+ if (rv)
+ return rv;
+
+ return EC_SUCCESS;
+}
+
+static void nx20p3483_handle_interrupt(int port)
+{
+ int reg;
+ int control_reg;
+
+ /*
+ * Read interrupt 1 status register. Note, interrupt register is
+ * automatically cleared by reading.
+ */
+ read_reg(port, NX20P3483_INTERRUPT1_REG, &reg);
+
+ /* Check for DBEXIT error */
+ if (reg & NX20P3483_INT1_DBEXIT_ERR) {
+ int mask_reg;
+
+ /*
+ * This failure is not expected. If for some reason, this
+ * keeps happening, then log an error and mask the interrupt to
+ * prevent interrupt floods.
+ */
+ if (++db_exit_fail_count[port] >=
+ NX20P3483_DB_EXIT_FAIL_THRESHOLD) {
+ CPRINTS("Port %d PPC failed to exit DB mode", port);
+ if (read_reg(port, NX20P3483_INTERRUPT1_MASK_REG,
+ &mask_reg)) {
+ mask_reg |= NX20P3483_INT1_DBEXIT_ERR;
+ write_reg(port, NX20P3483_INTERRUPT1_MASK_REG,
+ mask_reg);
+ }
+ }
+ read_reg(port, NX20P3483_DEVICE_CONTROL_REG, &control_reg);
+ reg |= NX20P3483_CTRL_DB_EXIT;
+ write_reg(port, NX20P3483_DEVICE_CONTROL_REG, control_reg);
+ }
+
+ /* Check for 5V OC interrupt */
+ if (reg & NX20P3483_INT1_OC_5VSRC) {
+ /*
+ * TODO (b/69935262): The overcurrent action hasn't
+ * been completed yet, but is required for TI PPC. When that
+ * work is complete, tie it in here.
+ */
+ }
+
+ /*
+ * Read interrupt 2 status register. Note, interrupt register is
+ * automatically cleared by reading.
+ */
+ /*
+ * TODO (b/75272421): Not sure if any of these interrupts
+ * will be used. Might want to use EN_ERR which tracks when both
+ * SNK_EN and SRC_EN are set. However, since for the Analogix TCPC
+ * these values aren't controlled by the EC directly, not sure what
+ * action if any can be taken.
+ */
+ read_reg(port, NX20P3483_INTERRUPT2_REG, &reg);
+}
+
+static void nx20p3483_irq_deferred(void)
+{
+ int i;
+ uint32_t pending = atomic_read_clear(&irq_pending);
+
+ for (i = 0; i < CONFIG_USB_PD_PORT_COUNT; i++)
+ if ((1 << i) & pending)
+ nx20p3483_handle_interrupt(i);
+}
+DECLARE_DEFERRED(nx20p3483_irq_deferred);
+
+void nx20p3483_interrupt(int port)
+{
+ atomic_or(&irq_pending, (1 << port));
+ hook_call_deferred(&nx20p3483_irq_deferred_data, 0);
+}
+
+#ifdef CONFIG_CMD_PPC_DUMP
+static int nx20p3483_dump(int port)
+{
+ int reg_addr;
+ int reg;
+ int rv;
+
+ ccprintf("Port %d NX20P3483 registers\n", port);
+ for (reg_addr = NX20P3483_DEVICE_ID_REG; reg_addr <=
+ NX20P3483_DEVICE_CONTROL_REG; reg_addr++) {
+ rv = read_reg(port, reg_addr, &reg);
+ if (rv) {
+ ccprintf("nx20p: Failed to read register 0x%x\n",
+ reg_addr);
+ return rv;
+ }
+ ccprintf("[0x%02x]: 0x%02x\n", reg_addr, reg);
+ }
+
+ return EC_SUCCESS;
+}
+#endif /* defined(CONFIG_CMD_PPC_DUMP) */
+
+const struct ppc_drv nx20p3483_drv = {
+ .init = &nx20p3483_init,
+ .is_sourcing_vbus = &nx20p3483_is_sourcing_vbus,
+ .vbus_sink_enable = &nx20p3483_vbus_sink_enable,
+ .vbus_source_enable = &nx20p3483_vbus_source_enable,
+#ifdef CONFIG_CMD_PPC_DUMP
+ .reg_dump = &nx20p3483_dump,
+#endif /* defined(CONFIG_CMD_PPC_DUMP) */
+ .set_vbus_source_current_limit =
+ &nx20p3483_set_vbus_source_current_limit,
+ .discharge_vbus = &nx20p3483_discharge_vbus,
+};
diff --git a/driver/ppc/nx20p3483.h b/driver/ppc/nx20p3483.h
new file mode 100644
index 0000000000..a85a0b72b4
--- /dev/null
+++ b/driver/ppc/nx20p3483.h
@@ -0,0 +1,106 @@
+/* Copyright 2018 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/* NX20P3483 Type-C Power Path Controller */
+
+#ifndef __CROS_EC_NX20P3483_H
+#define __CROS_EC_NX20P3483_H
+
+#define NX20P3483_ADDR0 0xE0
+#define NX20P3483_ADDR1 0xE2
+#define NX20P3483_ADDR2 0xE4
+#define NX20P3483_ADDR3 0xE6
+
+/* NX20P3483 register addresses */
+#define NX20P3483_DEVICE_ID_REG 0x00
+#define NX20P3483_DEVICE_STATUS_REG 0x01
+#define NX20P3483_SWITCH_CONTROL_REG 0x02
+#define NX20P3483_SWITCH_STATUS_REG 0x03
+#define NX20P3483_INTERRUPT1_REG 0x04
+#define NX20P3483_INTERRUPT2_REG 0x05
+#define NX20P3483_INTERRUPT1_MASK_REG 0x06
+#define NX20P3483_INTERRUPT2_MASK_REG 0x07
+#define NX20P3483_OVLO_THRESHOLD_REG 0x08
+#define NX20P3483_HV_SRC_OCP_THRESHOLD_REG 0x09
+#define NX20P3483_5V_SRC_OCP_THRESHOLD_REG 0x0A
+#define NX20P3483_DEVICE_CONTROL_REG 0x0B
+
+/* Device Control Register */
+#define NX20P3483_CTRL_FRS_AT (1 << 3)
+#define NX20P3483_CTRL_DB_EXIT (1 << 2)
+#define NX20P3483_CTRL_VBUSDIS_EN (1 << 1)
+#define NX20P3483_CTRL_LDO_SD (1 << 0)
+
+/* Device Status Modes */
+#define NX20P3483_DEVICE_MODE_MASK 0x7
+#define NX20P3483_MODE_DEAD_BATTERY 0
+#define NX20P3483_MODE_HV_SNK 1
+#define NX20P3483_MODE_5V_SRC 2
+#define NX20P3483_MODE_HV_SRC 3
+#define NX20P3483_MODE_STANDBY 4
+
+/* Switch Status Register */
+#define NX20P3483_HVSNK_STS (1 << 0)
+#define NX20P3483_HVSRC_STS (1 << 1)
+#define NX20P3483_5VSRC_STS (1 << 2)
+
+/* Internal 5V VBUS Switch Current Limit Settings (min) */
+#define NX20P3483_ILIM_MASK 0xF
+#define NX20P3483_ILIM_0_400 0
+#define NX20P3483_ILIM_0_600 1
+#define NX20P3483_ILIM_0_800 2
+#define NX20P3483_ILIM_1_000 3
+#define NX20P3483_ILIM_1_200 4
+#define NX20P3483_ILIM_1_400 5
+#define NX20P3483_ILIM_1_600 6
+#define NX20P3483_ILIM_1_800 7
+#define NX20P3483_ILIM_2_000 8
+#define NX20P3483_ILIM_2_200 9
+#define NX20P3483_ILIM_2_400 10
+#define NX20P3483_ILIM_2_600 11
+#define NX20P3483_ILIM_2_800 12
+#define NX20P3483_ILIM_3_000 13
+#define NX20P3483_ILIM_3_200 14
+#define NX20P3483_ILIM_3_400 15
+
+/* HV VBUS over voltage threshold settings V_mV*/
+#define NX20P3483_OVLO_THRESHOLD_MASK 0x7
+#define NX20P3483_OVLO_06_0 0
+#define NX20P3483_OVLO_06_8 1
+#define NX20P3483_OVLO_10_0 2
+#define NX20P3483_OVLO_11_5 3
+#define NX20P3483_OVLO_14_0 4
+#define NX20P3483_OVLO_17_0 5
+#define NX20P3483_OVLO_23_0 6
+
+/* Interrupt 1 Register Bits */
+#define NX20P3483_INT1_DBEXIT_ERR (1 << 7)
+#define NX20P3483_INT1_OV_5VSRC (1 << 4)
+#define NX20P3483_INT1_RCP_5VSRC (1 << 3)
+#define NX20P3483_INT1_SC_5VSRC (1 << 2)
+#define NX20P3483_INT1_OC_5VSRC (1 << 1)
+#define NX20P3483_INT1_OTP (1 << 0)
+
+/* Interrupt 2 Register Bits */
+#define NX20P3483_INT2_EN_ERR (1 << 7)
+#define NX20P3483_INT2_RCP_HVSNK (1 << 6)
+#define NX20P3483_INT2_SC_HVSNK (1 << 5)
+#define NX20P3483_INT2_OV_HVSNK (1 << 4)
+#define NX20P3483_INT2_RCP_HVSRC (1 << 3)
+#define NX20P3483_INT2_SC_HVSRC (1 << 2)
+#define NX20P3483_INT2_OC_HVSRC (1 << 1)
+#define NX20P3483_INT2_OV_HVSRC (1 << 0)
+
+struct ppc_drv;
+extern const struct ppc_drv nx20p3483_drv;
+
+/**
+ * Interrupt Handler for the NX20P3483.
+ *
+ * @param port: The Type-C port which triggered the interrupt.
+ */
+void nx20p3483_interrupt(int port);
+
+#endif /* defined(__CROS_EC_NX20P3483_H) */
diff --git a/driver/ppc/sn5s330.c b/driver/ppc/sn5s330.c
index 25fa7ae022..e0abf3aacf 100644
--- a/driver/ppc/sn5s330.c
+++ b/driver/ppc/sn5s330.c
@@ -456,6 +456,7 @@ static int sn5s330_is_sourcing_vbus(int port)
return is_sourcing_vbus;
}
+#ifdef CONFIG_USBC_PPC_POLARITY
static int sn5s330_set_polarity(int port, int polarity)
{
int regval;
@@ -472,6 +473,7 @@ static int sn5s330_set_polarity(int port, int polarity)
return write_reg(port, SN5S330_FUNC_SET4, regval);
}
+#endif
static int sn5s330_set_vbus_source_current_limit(int port,
enum tcpc_rp_value rp)
@@ -533,6 +535,7 @@ static int sn5s330_discharge_vbus(int port, int enable)
return EC_SUCCESS;
}
+#ifdef CONFIG_USBC_PPC_VCONN
static int sn5s330_set_vconn(int port, int enable)
{
int regval;
@@ -549,6 +552,7 @@ static int sn5s330_set_vconn(int port, int enable)
return write_reg(port, SN5S330_FUNC_SET4, regval);
}
+#endif
static int sn5s330_vbus_sink_enable(int port, int enable)
{
@@ -623,8 +627,12 @@ const struct ppc_drv sn5s330_drv = {
#ifdef CONFIG_USB_PD_VBUS_DETECT_PPC
.is_vbus_present = &sn5s330_is_vbus_present,
#endif /* defined(CONFIG_USB_PD_VBUS_DETECT_PPC) */
+#ifdef CONFIG_USBC_PPC_POLARITY
.set_polarity = &sn5s330_set_polarity,
+#endif
.set_vbus_source_current_limit = &sn5s330_set_vbus_source_current_limit,
.discharge_vbus = &sn5s330_discharge_vbus,
+#ifdef CONFIG_USBC_PPC_VCONN
.set_vconn = &sn5s330_set_vconn,
+#endif
};
diff --git a/include/config.h b/include/config.h
index 985c017cfb..62a8bb75b0 100644
--- a/include/config.h
+++ b/include/config.h
@@ -2894,9 +2894,16 @@
/* USB Product ID. */
#undef CONFIG_USB_PID
+/* PPC needs to be informed of CC polarity */
+#undef CONFIG_USBC_PPC_POLARITY
+
/* USB Type-C Power Path Controllers (PPC) */
+#undef CONFIG_USBC_PPC_NX20P3483
#undef CONFIG_USBC_PPC_SN5S330
+/* PPC is capable of providing VCONN */
+#undef CONFIG_USBC_PPC_VCONN
+
/* Support for USB type-c superspeed mux */
#undef CONFIG_USBC_SS_MUX
@@ -3344,10 +3351,16 @@
/*****************************************************************************/
/* Define CONFIG_USBC_PPC if board has a USB Type-C Power Path Controller. */
-#if defined(CONFIG_USBC_PPC_SN5S330)
+#if defined(CONFIG_USBC_PPC_SN5S330) || defined(CONFIG_USBC_PPC_NX20P3483)
#define CONFIG_USBC_PPC
#endif /* "has a PPC" */
+/* The TI SN5S330 supports VCONN and needs to be informed of CC polarity */
+#if defined(CONFIG_USBC_PPC_SN5S330)
+#define CONFIG_USBC_PPC_POLARITY
+#define CONFIG_USBC_PPC_VCONN
+#endif
+
/*****************************************************************************/
/*
* Define CONFIG_USB_PD_VBUS_MEASURE_CHARGER if the charger on the board
diff --git a/include/usbc_ppc.h b/include/usbc_ppc.h
index 54142b2921..1995654536 100644
--- a/include/usbc_ppc.h
+++ b/include/usbc_ppc.h
@@ -48,6 +48,7 @@ struct ppc_drv {
*/
int (*vbus_source_enable)(int port, int enable);
+#ifdef CONFIG_USBC_PPC_POLARITY
/**
* Inform the PPC of the polarity of the CC pins.
*
@@ -56,6 +57,7 @@ struct ppc_drv {
* @return EC_SUCCESS on success, error otherwise.
*/
int (*set_polarity)(int port, int polarity);
+#endif
/**
* Set the Vbus source path current limit
@@ -75,6 +77,7 @@ struct ppc_drv {
*/
int (*discharge_vbus)(int port, int enable);
+#ifdef CONFIG_USBC_PPC_VCONN
/**
* Turn on/off the VCONN FET.
*
@@ -82,6 +85,7 @@ struct ppc_drv {
* @param enable: 1: enable VCONN FET 0: disable VCONN FET.
*/
int (*set_vconn)(int port, int enable);
+#endif
#ifdef CONFIG_CMD_PPC_DUMP
/**
@@ -104,9 +108,18 @@ struct ppc_drv {
#endif /* defined(CONFIG_USB_PD_VBUS_DETECT_PPC) */
};
+
+/* PPC SNK/SRC switch control driven by EC GPIO */
+#define PPC_CFG_FLAGS_GPIO_CONTROL (1 << 0)
+
struct ppc_config_t {
+ /* Used for PPC_CFG_FLAGS_* defined above */
+ uint32_t flags;
int i2c_port;
int i2c_addr;
+ /* snk|src_gpio only required if PPC_CFG_FLAGS_GPIO_CONTROL is set */
+ enum gpio_signal snk_gpio;
+ enum gpio_signal src_gpio;
const struct ppc_drv *drv;
};