diff --git a/common/usbc_ppc.c b/common/usbc_ppc.c index 081cef811f..9614660468 100644 --- a/common/usbc_ppc.c +++ b/common/usbc_ppc.c @@ -26,6 +26,14 @@ int ppc_is_sourcing_vbus(int port) return ppc_chips[port].drv->is_sourcing_vbus(port); } +int ppc_set_vbus_source_current_limit(int port, enum tcpc_rp_value rp) +{ + if ((port < 0) || (port >= ppc_cnt)) + return EC_ERROR_INVAL; + + return ppc_chips[port].drv->set_vbus_source_current_limit(port, rp); +} + int ppc_vbus_sink_enable(int port, int enable) { if ((port < 0) || (port >= ppc_cnt)) diff --git a/driver/ppc/sn5s330.c b/driver/ppc/sn5s330.c index 1a06c830db..1f4d20eb76 100644 --- a/driver/ppc/sn5s330.c +++ b/driver/ppc/sn5s330.c @@ -444,6 +444,42 @@ static int sn5s330_is_sourcing_vbus(int port) return is_sourcing_vbus; } +static int sn5s330_set_vbus_source_current_limit(int port, + enum tcpc_rp_value rp) +{ + int regval; + int status; + + status = read_reg(port, SN5S330_FUNC_SET1, ®val); + if (status) + return status; + + /* + * Note that we chose the lowest current limit setting that is just + * above indicated Rp value. This is because these are minimum values + * and we must be able to provide the current that we advertise. + */ + regval &= ~0x1F; /* The current limit settings are 4:0. */ + switch (rp) { + case TYPEC_RP_3A0: + regval |= SN5S330_ILIM_3_06; + break; + + case TYPEC_RP_1A5: + regval |= SN5S330_ILIM_1_62; + break; + + case TYPEC_RP_USB: + default: + regval |= SN5S330_ILIM_0_63; + break; + }; + + status = write_reg(port, SN5S330_FUNC_SET1, regval); + + return status; +} + static int sn5s330_vbus_sink_enable(int port, int enable) { return sn5s330_pp_fet_enable(port, SN5S330_PP2, !!enable); @@ -503,4 +539,5 @@ 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) */ + .set_vbus_source_current_limit = &sn5s330_set_vbus_source_current_limit, }; diff --git a/include/usbc_ppc.h b/include/usbc_ppc.h index 83fac5cad9..9fc8e61f91 100644 --- a/include/usbc_ppc.h +++ b/include/usbc_ppc.h @@ -7,6 +7,7 @@ #define __CROS_EC_USBC_PPC_H #include "common.h" +#include "usb_pd_tcpm.h" /* Common APIs for USB Type-C Power Path Controllers (PPC) */ @@ -47,6 +48,15 @@ struct ppc_drv { */ int (*vbus_source_enable)(int port, int enable); + /** + * Set the Vbus source path current limit + * + * @param port: The Type-C port number. + * @param rp: The Rp value which to approximately set the current limit. + * @return EC_SUCCESS on success, error otherwise. + */ + int (*set_vbus_source_current_limit)(int port, enum tcpc_rp_value rp); + #ifdef CONFIG_CMD_PPC_DUMP /** * Perform a register dump of the PPC. @@ -103,6 +113,15 @@ int ppc_is_vbus_present(int port, int *vbus_present); */ int ppc_is_sourcing_vbus(int port); +/** + * Set the Vbus source path current limit + * + * @param port: The Type-C port number. + * @param rp: The Rp value which to approximately set the current limit. + * @return EC_SUCCESS on success, error otherwise. + */ +int ppc_set_vbus_source_current_limit(int port, enum tcpc_rp_value rp); + /** * Turn on/off the charge path FET, such that current flows into the * system.