diff options
-rw-r--r-- | common/build.mk | 1 | ||||
-rw-r--r-- | common/usb_charger.c | 11 | ||||
-rw-r--r-- | common/usb_common.c | 20 | ||||
-rw-r--r-- | common/usb_pd_flags.c | 65 | ||||
-rw-r--r-- | common/usb_pd_protocol.c | 76 | ||||
-rw-r--r-- | driver/tcpm/tcpci.c | 35 | ||||
-rw-r--r-- | include/config.h | 7 | ||||
-rw-r--r-- | include/usb_pd_flags.h | 88 | ||||
-rw-r--r-- | zephyr/CMakeLists.txt | 3 |
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") |