summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/build.mk1
-rw-r--r--common/usb_charger.c11
-rw-r--r--common/usb_common.c20
-rw-r--r--common/usb_pd_flags.c65
-rw-r--r--common/usb_pd_protocol.c76
-rw-r--r--driver/tcpm/tcpci.c35
-rw-r--r--include/config.h7
-rw-r--r--include/usb_pd_flags.h88
-rw-r--r--zephyr/CMakeLists.txt3
9 files changed, 248 insertions, 58 deletions
diff --git a/common/build.mk b/common/build.mk
index 867dcf465f..a1a956f9ab 100644
--- a/common/build.mk
+++ b/common/build.mk
@@ -52,6 +52,7 @@ common-$(CONFIG_BODY_DETECTION)+=body_detection.o
common-$(CONFIG_CAPSENSE)+=capsense.o
common-$(CONFIG_CEC)+=cec.o
common-$(CONFIG_CBI_EEPROM)+=cbi.o cbi_eeprom.o
+common-$(CONFIG_USB_PD_FLAGS)+=usb_pd_flags.o
common-$(CONFIG_CBI_GPIO)+=cbi.o cbi_gpio.o
ifeq ($(HAS_MOCK_CHARGE_MANAGER),)
common-$(CONFIG_CHARGE_MANAGER)+=charge_manager.o
diff --git a/common/usb_charger.c b/common/usb_charger.c
index 20031a9469..b8e8038811 100644
--- a/common/usb_charger.c
+++ b/common/usb_charger.c
@@ -22,6 +22,7 @@
#include "task.h"
#include "usb_charge.h"
#include "usb_pd.h"
+#include "usb_pd_flags.h"
#include "usbc_ppc.h"
#include "util.h"
@@ -81,11 +82,11 @@ void usb_charger_vbus_change(int port, int vbus_level)
usb_charger_reset_charge(port);
#endif
-#if (defined(CONFIG_USB_PD_VBUS_DETECT_CHARGER) \
- || defined(CONFIG_USB_PD_VBUS_DETECT_PPC))
- /* USB PD task */
- task_wake(PD_PORT_TO_TASK_ID(port));
-#endif
+ if ((get_usb_pd_vbus_detect() == USB_PD_VBUS_DETECT_CHARGER) ||
+ (get_usb_pd_vbus_detect() == USB_PD_VBUS_DETECT_PPC)) {
+ /* USB PD task */
+ task_wake(PD_PORT_TO_TASK_ID(port));
+ }
}
void usb_charger_reset_charge(int port)
diff --git a/common/usb_common.c b/common/usb_common.c
index 2515caf287..786bd118cf 100644
--- a/common/usb_common.c
+++ b/common/usb_common.c
@@ -25,6 +25,7 @@
#include "usb_mux.h"
#include "usb_pd.h"
#include "usb_pd_dpm.h"
+#include "usb_pd_flags.h"
#include "usb_pd_tcpm.h"
#include "usbc_ocp.h"
#include "usbc_ppc.h"
@@ -851,12 +852,17 @@ void pd_set_vbus_discharge(int port, int enable)
mutex_lock(&discharge_lock[port]);
enable &= !board_vbus_source_enabled(port);
- if (IS_ENABLED(CONFIG_USB_PD_DISCHARGE_GPIO))
+ if (get_usb_pd_discharge() == USB_PD_DISCHARGE_GPIO) {
gpio_discharge_vbus(port, enable);
- else if (IS_ENABLED(CONFIG_USB_PD_DISCHARGE_TCPC))
+ } else if (get_usb_pd_discharge() == USB_PD_DISCHARGE_TCPC) {
+#ifdef CONFIG_USB_PD_DISCHARGE_PPC
tcpc_discharge_vbus(port, enable);
- else if (IS_ENABLED(CONFIG_USB_PD_DISCHARGE_PPC))
+#endif
+ } else if (get_usb_pd_discharge() == USB_PD_DISCHARGE_PPC) {
+#ifdef CONFIG_USB_PD_DISCHARGE_PPC
ppc_discharge_vbus(port, enable);
+#endif
+ }
mutex_unlock(&discharge_lock[port]);
}
@@ -884,6 +890,10 @@ void pd_deferred_resume(int port)
}
#endif /* CONFIG_USB_PD_TCPM_TCPCI */
+__overridable int pd_snk_is_vbus_provided(int port)
+{
+ return EC_SUCCESS;
+}
/*
* Check the specified Vbus level
@@ -893,8 +903,10 @@ void pd_deferred_resume(int port)
*/
__overridable bool pd_check_vbus_level(int port, enum vbus_level level)
{
- if (IS_ENABLED(CONFIG_USB_PD_VBUS_DETECT_TCPC))
+ if (IS_ENABLED(CONFIG_USB_PD_VBUS_DETECT_TCPC) &&
+ (get_usb_pd_vbus_detect() == USB_PD_VBUS_DETECT_TCPC)) {
return tcpm_check_vbus_level(port, level);
+ }
else if (level == VBUS_PRESENT)
return pd_snk_is_vbus_provided(port);
else
diff --git a/common/usb_pd_flags.c b/common/usb_pd_flags.c
new file mode 100644
index 0000000000..9328c03346
--- /dev/null
+++ b/common/usb_pd_flags.c
@@ -0,0 +1,65 @@
+/* Copyright 2021 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.
+ */
+
+/*
+ * Contains USB PD accessors definition
+ */
+
+#include "common.h"
+#include "config.h"
+#include "usb_pd_flags.h"
+
+static union usb_pd_runtime_flags usb_pd_flags;
+BUILD_ASSERT(sizeof(usb_pd_flags) == sizeof(uint32_t));
+
+enum usb_pd_vbus_detect get_usb_pd_vbus_detect(void)
+{
+ if (IS_ENABLED(CONFIG_USB_PD_RUNTIME_FLAGS))
+ return (enum usb_pd_vbus_detect) usb_pd_flags.vbus_detect;
+ else if (IS_ENABLED(CONFIG_USB_PD_VBUS_DETECT_TCPC))
+ return (enum usb_pd_vbus_detect)USB_PD_VBUS_DETECT_TCPC;
+ else if (IS_ENABLED(CONFIG_USD_PD_VBUS_DETECT_GPIO))
+ return (enum usb_pd_vbus_detect)USB_PD_VBUS_DETECT_GPIO;
+ else if (IS_ENABLED(CONFIG_USB_PD_VBUS_DETECT_PPC))
+ return (enum usb_pd_vbus_detect)USB_PD_VBUS_DETECT_PPC;
+ else if (IS_ENABLED(CONFIG_USB_PD_VBUS_DETECT_CHARGER))
+ return (enum usb_pd_vbus_detect)USB_PD_VBUS_DETECT_CHARGER;
+ else
+ return (enum usb_pd_vbus_detect)USB_PD_VBUS_DETECT_NONE;
+}
+
+enum usb_pd_discharge get_usb_pd_discharge(void)
+{
+ if (IS_ENABLED(CONFIG_USB_PD_RUNTIME_FLAGS))
+ return (enum usb_pd_discharge)usb_pd_flags.discharge;
+ else if (IS_ENABLED(CONFIG_USB_PD_DISCHARGE_TCPC))
+ return (enum usb_pd_discharge)USB_PD_DISCHARGE_TCPC;
+ else if (IS_ENABLED(CONFIG_USD_PD_DISCHARGE_GPIO))
+ return (enum usb_pd_discharge)USB_PD_DISCHARGE_GPIO;
+ else if (IS_ENABLED(CONFIG_USB_PD_DISCHARGE_PPC))
+ return (enum usb_pd_discharge)USB_PD_DISCHARGE_PPC;
+ else
+ return (enum usb_pd_discharge)USB_PD_DISCHARGE_NONE;
+}
+
+enum usb_pd_charger_otg get_usb_pd_charger_otg(void)
+{
+ return usb_pd_flags.charger_otg;
+}
+
+void set_usb_pd_vbus_detect(enum usb_pd_vbus_detect vbus_detect)
+{
+ usb_pd_flags.vbus_detect = vbus_detect;
+}
+
+void set_usb_pd_discharge(enum usb_pd_discharge discharge)
+{
+ usb_pd_flags.discharge = discharge;
+}
+
+void set_usb_pd_charger_otg(enum usb_pd_charger_otg charger_otg)
+{
+ usb_pd_flags.charger_otg = charger_otg;
+}
diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c
index 07b50363b9..abf75e8004 100644
--- a/common/usb_pd_protocol.c
+++ b/common/usb_pd_protocol.c
@@ -29,6 +29,7 @@
#include "usb_common.h"
#include "usb_mux.h"
#include "usb_pd.h"
+#include "usb_pd_flags.h"
#include "usb_pd_tcpm.h"
#include "usb_pd_tcpc.h"
#include "usbc_ocp.h"
@@ -1570,10 +1571,10 @@ static void handle_data_request(int port, uint32_t head,
if ((pd[port].task_state == PD_STATE_SNK_DISCOVERY)
|| (pd[port].task_state == PD_STATE_SNK_TRANSITION)
|| (pd[port].task_state == PD_STATE_SNK_REQUESTED)
-#ifdef CONFIG_USB_PD_VBUS_DETECT_NONE
- || (pd[port].task_state ==
- PD_STATE_SNK_HARD_RESET_RECOVER)
-#endif
+ || ((get_usb_pd_vbus_detect() ==
+ USB_PD_VBUS_DETECT_NONE)
+ && (pd[port].task_state ==
+ PD_STATE_SNK_HARD_RESET_RECOVER))
|| (pd[port].task_state == PD_STATE_SNK_READY)) {
#ifdef CONFIG_USB_PD_REV30
/*
@@ -4098,52 +4099,58 @@ void pd_task(void *u)
case PD_STATE_SNK_HARD_RESET_RECOVER:
if (pd[port].last_state != pd[port].task_state)
pd[port].flags |= PD_FLAGS_CHECK_IDENTITY;
-#ifdef CONFIG_USB_PD_VBUS_DETECT_NONE
- /*
- * Can't measure vbus state so this is the maximum
- * recovery time for the source.
- */
- if (pd[port].last_state != pd[port].task_state)
- set_state_timeout(port, get_time().val +
+
+ if (get_usb_pd_vbus_detect() ==
+ USB_PD_VBUS_DETECT_NONE) {
+ /*
+ * Can't measure vbus state so this is the
+ * maximum recovery time for the source.
+ */
+ if (pd[port].last_state != pd[port].task_state)
+ set_state_timeout(port, get_time().val +
PD_T_SAFE_0V +
PD_T_SRC_RECOVER_MAX +
PD_T_SRC_TURN_ON,
PD_STATE_SNK_DISCONNECTED);
-#else
- /* Wait for VBUS to go low and then high*/
- if (pd[port].last_state != pd[port].task_state) {
- snk_hard_reset_vbus_off = 0;
- set_state_timeout(port,
+ } else {
+#ifndef CONFIG_USB_PD_VBUS_DETECT_NONE
+ /* Wait for VBUS to go low and then high*/
+ if (pd[port].last_state !=
+ pd[port].task_state) {
+ snk_hard_reset_vbus_off = 0;
+ set_state_timeout(port,
get_time().val +
PD_T_SAFE_0V,
hard_reset_count <
PD_HARD_RESET_COUNT ?
PD_STATE_HARD_RESET_SEND :
PD_STATE_SNK_DISCOVERY);
- }
+ }
- if (!pd_is_vbus_present(port) &&
- !snk_hard_reset_vbus_off) {
- /* VBUS has gone low, reset timeout */
- snk_hard_reset_vbus_off = 1;
- set_state_timeout(port,
+ if (!pd_is_vbus_present(port) &&
+ !snk_hard_reset_vbus_off) {
+ /* VBUS has gone low, reset timeout */
+ snk_hard_reset_vbus_off = 1;
+ set_state_timeout(port,
get_time().val +
PD_T_SRC_RECOVER_MAX +
PD_T_SRC_TURN_ON,
PD_STATE_SNK_DISCONNECTED);
- }
- if (pd_is_vbus_present(port) &&
- snk_hard_reset_vbus_off) {
- /* VBUS went high again */
- set_state(port, PD_STATE_SNK_DISCOVERY);
- timeout = 10*MSEC;
- }
+ }
+ if (pd_is_vbus_present(port) &&
+ snk_hard_reset_vbus_off) {
+ /* VBUS went high again */
+ set_state(port, PD_STATE_SNK_DISCOVERY);
+ timeout = 10*MSEC;
+ }
- /*
- * Don't need to set timeout because VBUS changing
- * will trigger an interrupt and wake us up.
- */
+ /*
+ * Don't need to set timeout because VBUS
+ * changing will trigger an interrupt and
+ * wake us up.
+ */
#endif
+ }
break;
case PD_STATE_SNK_DISCOVERY:
/* Wait for source cap expired only if we are enabled */
@@ -4172,7 +4179,8 @@ void pd_task(void *u)
int batt_soc = usb_get_battery_soc();
if (batt_soc < CONFIG_USB_PD_RESET_MIN_BATT_SOC ||
- battery_get_disconnect_state() != BATTERY_NOT_DISCONNECTED)
+ battery_get_disconnect_state() !=
+ BATTERY_NOT_DISCONNECTED)
pd[port].flags |=
PD_FLAGS_SNK_WAITING_BATT;
else
diff --git a/driver/tcpm/tcpci.c b/driver/tcpm/tcpci.c
index 73a4b68295..1e08e0967d 100644
--- a/driver/tcpm/tcpci.c
+++ b/driver/tcpm/tcpci.c
@@ -21,6 +21,7 @@
#include "usb_common.h"
#include "usb_mux.h"
#include "usb_pd.h"
+#include "usb_pd_flags.h"
#include "usb_pd_tcpc.h"
#include "usb_pd_tcpm.h"
#include "util.h"
@@ -321,14 +322,20 @@ static int init_alert_mask(int port)
* Create mask of alert events that will cause the TCPC to
* signal the TCPM via the Alert# gpio line.
*/
- mask = TCPC_REG_ALERT_TX_SUCCESS | TCPC_REG_ALERT_TX_FAILED |
- TCPC_REG_ALERT_TX_DISCARDED | TCPC_REG_ALERT_RX_STATUS |
- TCPC_REG_ALERT_RX_HARD_RST | TCPC_REG_ALERT_CC_STATUS |
- TCPC_REG_ALERT_FAULT
-#ifdef CONFIG_USB_PD_VBUS_DETECT_TCPC
- | TCPC_REG_ALERT_POWER_STATUS
-#endif
- ;
+ if (get_usb_pd_vbus_detect() == USB_PD_VBUS_DETECT_TCPC) {
+ mask = TCPC_REG_ALERT_TX_SUCCESS | TCPC_REG_ALERT_TX_FAILED |
+ TCPC_REG_ALERT_TX_DISCARDED | TCPC_REG_ALERT_RX_STATUS |
+ TCPC_REG_ALERT_RX_HARD_RST | TCPC_REG_ALERT_CC_STATUS |
+ TCPC_REG_ALERT_FAULT
+ | TCPC_REG_ALERT_POWER_STATUS
+ ;
+ } else {
+ mask = TCPC_REG_ALERT_TX_SUCCESS | TCPC_REG_ALERT_TX_FAILED |
+ TCPC_REG_ALERT_TX_DISCARDED | TCPC_REG_ALERT_RX_STATUS |
+ TCPC_REG_ALERT_RX_HARD_RST | TCPC_REG_ALERT_CC_STATUS |
+ TCPC_REG_ALERT_FAULT
+ ;
+ }
/* TCPCI Rev2 includes SAFE0V alerts */
if (TCPC_FLAGS_VSAFE0V(tcpc_config[port].flags))
@@ -361,11 +368,11 @@ static int init_power_status_mask(int port)
uint8_t mask;
int rv;
-#ifdef CONFIG_USB_PD_VBUS_DETECT_TCPC
- mask = TCPC_REG_POWER_STATUS_VBUS_PRES;
-#else
- mask = 0;
-#endif
+ if (get_usb_pd_vbus_detect() == USB_PD_VBUS_DETECT_TCPC)
+ mask = TCPC_REG_POWER_STATUS_VBUS_PRES;
+ else
+ mask = 0;
+
rv = tcpc_write(port, TCPC_REG_POWER_STATUS_MASK , mask);
return rv;
@@ -1142,7 +1149,7 @@ static void tcpci_check_vbus_changed(int port, int alert, uint32_t *pd_event)
tcpc_vbus[port] = BIT(VBUS_SAFE0V);
}
- if (IS_ENABLED(CONFIG_USB_PD_VBUS_DETECT_TCPC) &&
+ if ((get_usb_pd_vbus_detect() == USB_PD_VBUS_DETECT_TCPC) &&
IS_ENABLED(CONFIG_USB_CHARGER)) {
/* Update charge manager with new VBUS state */
usb_charger_vbus_change(port,
diff --git a/include/config.h b/include/config.h
index f74c9f82c9..5c0975c713 100644
--- a/include/config.h
+++ b/include/config.h
@@ -4236,6 +4236,13 @@
#undef CONFIG_USB_PD_DEBUG_LEVEL
/*
+ * Define if this board is using runtime flags instead of build time configs
+ * to control USB PD properties.
+ */
+#define CONFIG_USB_PD_FLAGS
+#undef CONFIG_USB_PD_RUNTIME_FLAGS
+
+/*
* Define if this board can enable VBUS discharge (eg. through a GPIO-controlled
* discharge circuit, or through port controller registers) to discharge VBUS
* rapidly on disconnect. Will be defined automatically when one of the below
diff --git a/include/usb_pd_flags.h b/include/usb_pd_flags.h
new file mode 100644
index 0000000000..71932de885
--- /dev/null
+++ b/include/usb_pd_flags.h
@@ -0,0 +1,88 @@
+/* Copyright 2021 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.
+ */
+
+/*
+ * Contains USB PD flags definition and accessors
+ */
+#ifndef __CROS_EC_USB_PD_FLAGS_H
+#define __CROS_EC_USB_PD_FLAGS_H
+
+#include "stdint.h"
+
+/*
+ * USB PD VBUS detect (0-2)
+ */
+enum usb_pd_vbus_detect {
+ USB_PD_VBUS_DETECT_NONE = 0,
+ USB_PD_VBUS_DETECT_TCPC = 1,
+ USB_PD_VBUS_DETECT_GPIO = 2,
+ USB_PD_VBUS_DETECT_PPC = 3,
+ USB_PD_VBUS_DETECT_CHARGER = 4
+};
+
+/*
+ * USB PD DISCHARGE (Bits 3-4)
+ */
+enum usb_pd_discharge {
+ USB_PD_DISCHARGE_NONE = 0,
+ USB_PD_DISCHARGE_TCPC = 1,
+ USB_PD_DISCHARGE_GPIO = 2,
+ USB_PD_DISCHARGE_PPC = 3
+};
+
+/*
+ * USB PD Charger OTG (Bit 5)
+ */
+enum usb_pd_charger_otg {
+ USB_PD_CHARGER_OTG_DISABLED = 0,
+ USB_PD_CHARGER_OTG_ENABLED = 1
+};
+
+union usb_pd_runtime_flags {
+ struct {
+ enum usb_pd_vbus_detect vbus_detect : 3;
+ enum usb_pd_discharge discharge : 2;
+ enum usb_pd_charger_otg charger_otg : 1;
+ uint32_t reserved : 26;
+ };
+ uint32_t raw_value;
+};
+
+/**
+ * Set VBUS detect type from USB_PD_FLAGS.
+ */
+void set_usb_pd_vbus_detect(enum usb_pd_vbus_detect vbus_detect);
+
+/**
+ * Get VBUS detect type from USB_PD_FLAGS.
+ *
+ * @return the VBUS detect type.
+ */
+enum usb_pd_vbus_detect get_usb_pd_vbus_detect(void);
+
+/**
+ * Set USB PD discharge type from USB_PD_FLAGS.
+ */
+void set_usb_pd_discharge(enum usb_pd_discharge discharge);
+
+/**
+ * Get USB PD discharge type from USB_PD_FLAGS.
+ *
+ * @return the USB PD discharge type.
+ */
+enum usb_pd_discharge get_usb_pd_discharge(void);
+
+/**
+ * Set USB PD charger OTG from USB_PD_FLAGS.
+ */
+void set_usb_pd_charger_otg(enum usb_pd_charger_otg charger_otg);
+
+/**
+ * Get USB PD charger OTG from USB_PD_FLAGS.
+ *
+ * @return the USB PD charger OTG.
+ */
+enum usb_pd_charger_otg get_usb_pd_charger_otg(void);
+#endif /* __CROS_EC_USB_PD_FLAGS_H */
diff --git a/zephyr/CMakeLists.txt b/zephyr/CMakeLists.txt
index cb85bf2154..e896f6d841 100644
--- a/zephyr/CMakeLists.txt
+++ b/zephyr/CMakeLists.txt
@@ -308,7 +308,8 @@ zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USB_POWER_DELIVERY
"${PLATFORM_EC}/common/usbc/usbc_task.c"
"${PLATFORM_EC}/common/usbc/usb_pd_timer.c"
"${PLATFORM_EC}/common/usbc/usb_sm.c"
- "${PLATFORM_EC}/common/usbc_intr_task.c")
+ "${PLATFORM_EC}/common/usbc_intr_task.c"
+ "${PLATFORM_EC}/common/usb_pd_flags.c")
zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_CONSOLE_CMD_CHARGEN
"${PLATFORM_EC}/common/chargen.c")