diff options
author | Jett Rink <jettrink@chromium.org> | 2018-08-07 14:52:04 -0600 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2018-08-23 17:42:49 -0700 |
commit | 7487f9eef6159b9b3253b4d30e9dd0b114bd07e1 (patch) | |
tree | 21b506771c042375da02ff0f1171b7f6712d699b | |
parent | eab2576658393d15af7fc55e97e827951cafa05e (diff) | |
download | chrome-ec-7487f9eef6159b9b3253b4d30e9dd0b114bd07e1.tar.gz |
sn5s330: add low power mode
Add a low power mode method for PPCs behind a new config.
Implement the low power method for SN5S330 based off of TI AE
recommendation.
BRANCH=none
BUG=b:111520593,b:111006203
TEST=CL stack produce lower power during bip hibernate
Change-Id: Icd22f88a8f65c2cd5ab1c95b0750b1eb61e91923
Signed-off-by: Jett Rink <jettrink@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/1166183
Commit-Ready: ChromeOS CL Exonerator Bot <chromiumos-cl-exonerator@appspot.gserviceaccount.com>
Reviewed-by: Furquan Shaikh <furquan@chromium.org>
-rw-r--r-- | common/usbc_ppc.c | 13 | ||||
-rw-r--r-- | driver/ppc/sn5s330.c | 57 | ||||
-rw-r--r-- | driver/ppc/sn5s330.h | 39 | ||||
-rw-r--r-- | include/usbc_ppc.h | 19 |
4 files changed, 106 insertions, 22 deletions
diff --git a/common/usbc_ppc.c b/common/usbc_ppc.c index 7011309cf1..0961ba6e83 100644 --- a/common/usbc_ppc.c +++ b/common/usbc_ppc.c @@ -86,6 +86,19 @@ int ppc_vbus_sink_enable(int port, int enable) return ppc_chips[port].drv->vbus_sink_enable(port, enable); } +int ppc_enter_low_power_mode(int port) +{ + const struct ppc_config_t *const ppc = &ppc_chips[port]; + + if ((port < 0) || (port >= ppc_cnt)) + return EC_ERROR_INVAL; + + if (ppc->drv->enter_low_power_mode) + return ppc->drv->enter_low_power_mode(port); + else + return EC_ERROR_UNIMPLEMENTED; +} + int ppc_vbus_source_enable(int port, int enable) { if ((port < 0) || (port >= ppc_cnt)) diff --git a/driver/ppc/sn5s330.c b/driver/ppc/sn5s330.c index 9855ab1d89..904a968a03 100644 --- a/driver/ppc/sn5s330.c +++ b/driver/ppc/sn5s330.c @@ -514,6 +514,54 @@ static int sn5s330_discharge_vbus(int port, int enable) return EC_SUCCESS; } +static int sn5s330_enter_low_power_mode(int port) +{ + int rv; + + /* Turn off both SRC and SNK FETs */ + rv = clr_flags(port, SN5S330_FUNC_SET3, + SN5S330_PP1_EN | SN5S330_PP2_EN); + + if (rv) { + CPRINTS("ppc p%d: Could not disable both FETS (%d)", port, rv); + return rv; + } + + /* Turn off Vconn power */ + rv = clr_flags(port, SN5S330_FUNC_SET4, SN5S330_VCONN_EN); + + if (rv) { + CPRINTS("ppc p%d: Could not disable Vconn (%d)", port, rv); + return rv; + } + + /* Turn off SBU path */ + rv = clr_flags(port, SN5S330_FUNC_SET2, SN5S330_SBU_EN); + + if (rv) { + CPRINTS("ppc p%d: Could not disable SBU path (%d)", port, rv); + return rv; + } + + /* + * Turn off the Over Voltage Protection circuits. Needs to happen after + * FETs are disabled, otherwise OVP can automatically turned back on. + * Since FETs are off, any over voltage does not make it to the board + * side of the PPC. + */ + rv = clr_flags(port, SN5S330_FUNC_SET9, + SN5S330_FORCE_OVP_EN_SBU | SN5S330_FORCE_ON_VBUS_OVP | + SN5S330_FORCE_ON_VBUS_UVP); + + if (rv) { + CPRINTS("ppc p%d: Could not disable OVP circuit (%d)", port, + rv); + return rv; + } + + return EC_SUCCESS; +} + #ifdef CONFIG_USBC_PPC_VCONN static int sn5s330_set_vconn(int port, int enable) { @@ -600,17 +648,18 @@ const struct ppc_drv sn5s330_drv = { .is_sourcing_vbus = &sn5s330_is_sourcing_vbus, .vbus_sink_enable = &sn5s330_vbus_sink_enable, .vbus_source_enable = &sn5s330_vbus_source_enable, + .set_vbus_source_current_limit = &sn5s330_set_vbus_source_current_limit, + .discharge_vbus = &sn5s330_discharge_vbus, + .enter_low_power_mode = &sn5s330_enter_low_power_mode, #ifdef CONFIG_CMD_PPC_DUMP .reg_dump = &sn5s330_dump, -#endif /* defined(CONFIG_CMD_PPC_DUMP) */ +#endif #ifdef CONFIG_USB_PD_VBUS_DETECT_PPC .is_vbus_present = &sn5s330_is_vbus_present, -#endif /* defined(CONFIG_USB_PD_VBUS_DETECT_PPC) */ +#endif #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/driver/ppc/sn5s330.h b/driver/ppc/sn5s330.h index 2b17a1d46a..fcb41204ef 100644 --- a/driver/ppc/sn5s330.h +++ b/driver/ppc/sn5s330.h @@ -86,34 +86,37 @@ enum sn5s330_pp_idx { #define SN5S330_ILIM_3_30 12 /* FUNC_SET_2 */ -#define SN5S330_SBU_EN (1 << 4) +#define SN5S330_SBU_EN (1 << 4) /* FUNC_SET_3 */ -#define SN5S330_PP1_EN (1 << 0) -#define SN5S330_PP2_EN (1 << 1) -#define SN5S330_VBUS_DISCH_EN (1 << 2) -#define SN5S330_SET_RCP_MODE_PP1 (1 << 5) -#define SN5S330_SET_RCP_MODE_PP2 (1 << 6) +#define SN5S330_PP1_EN (1 << 0) +#define SN5S330_PP2_EN (1 << 1) +#define SN5S330_VBUS_DISCH_EN (1 << 2) +#define SN5S330_SET_RCP_MODE_PP1 (1 << 5) +#define SN5S330_SET_RCP_MODE_PP2 (1 << 6) /* FUNC_SET_4 */ -#define SN5S330_VCONN_EN (1 << 0) -#define SN5S330_CC_POLARITY (1 << 1) -#define SN5S330_CC_EN (1 << 4) -#define SN5S330_VCONN_ILIM_SEL (1 << 5) +#define SN5S330_VCONN_EN (1 << 0) +#define SN5S330_CC_POLARITY (1 << 1) +#define SN5S330_CC_EN (1 << 4) +#define SN5S330_VCONN_ILIM_SEL (1 << 5) /* FUNC_SET_9 */ -#define SN5S330_PP2_CONFIG (1 << 2) -#define SN5S330_OVP_EN_CC (1 << 4) -#define SN5S330_CONFIG_UVP (1 << 5) +#define SN5S330_FORCE_OVP_EN_SBU (1 << 1) +#define SN5S330_PP2_CONFIG (1 << 2) +#define SN5S330_OVP_EN_CC (1 << 4) +#define SN5S330_CONFIG_UVP (1 << 5) +#define SN5S330_FORCE_ON_VBUS_OVP (1 << 6) +#define SN5S330_FORCE_ON_VBUS_UVP (1 << 7) /* INT_STATUS_REG3 */ -#define SN5S330_VBUS_GOOD (1 << 0) +#define SN5S330_VBUS_GOOD (1 << 0) /* INT_STATUS_REG4 */ -#define SN5S330_DIG_RES (1 << 0) -#define SN5S330_DB_BOOT (1 << 1) -#define SN5S330_VSAFE0V_STAT (1 << 2) -#define SN5S330_VSAFE0V_MASK (1 << 3) +#define SN5S330_DIG_RES (1 << 0) +#define SN5S330_DB_BOOT (1 << 1) +#define SN5S330_VSAFE0V_STAT (1 << 2) +#define SN5S330_VSAFE0V_MASK (1 << 3) /* * INT_MASK_RISE/FALL_EDGE_1 diff --git a/include/usbc_ppc.h b/include/usbc_ppc.h index d65fa79f0e..a93f7e7109 100644 --- a/include/usbc_ppc.h +++ b/include/usbc_ppc.h @@ -106,6 +106,15 @@ struct ppc_drv { */ int (*is_vbus_present)(int port); #endif /* defined(CONFIG_USB_PD_VBUS_DETECT_PPC) */ + + /** + * Optional method to put the PPC into its lowest power state. In this + * state it should still fire interrupts if Vbus changes etc. + * + * @param port: The Type-C port number. + * @return EC_SUCCESS on success, error otherwise. + */ + int (*enter_low_power_mode)(int port); }; struct ppc_config_t { @@ -203,4 +212,14 @@ int ppc_vbus_source_enable(int port, int enable); */ void board_overcurrent_event(int port); +/** + * Put the PPC into its lowest power state. In this state it should still fire + * interrupts if Vbus changes etc. This is called by board-specific code when + * appropriate. + * + * @param port: The Type-C port number. + * @return EC_SUCCESS on success, error otherwise. + */ +int ppc_enter_low_power_mode(int port); + #endif /* !defined(__CROS_EC_USBC_PPC_H) */ |