diff options
-rw-r--r-- | drivers/usb/typec/tcpm/tcpm.c | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c index aedc8bb9532a..2ad5e14a6867 100644 --- a/drivers/usb/typec/tcpm/tcpm.c +++ b/drivers/usb/typec/tcpm/tcpm.c @@ -459,6 +459,12 @@ struct tcpm_port { /* Auto vbus discharge status */ bool auto_vbus_discharge_enabled; + /* + * When set, port requests PD_P_SNK_STDBY_MW upon entering SNK_DISCOVERY and + * the actual currrent limit after RX of PD_CTRL_PSRDY for PD link, + * SNK_READY for non-pd link. + */ + bool slow_charger_loop; #ifdef CONFIG_DEBUG_FS struct dentry *dentry; struct mutex logbuffer_lock; /* log buffer access lock */ @@ -4047,9 +4053,11 @@ static void run_state_machine(struct tcpm_port *port) break; case SNK_DISCOVERY: if (port->vbus_present) { - tcpm_set_current_limit(port, - tcpm_get_current_limit(port), - 5000); + u32 current_lim = tcpm_get_current_limit(port); + + if (port->slow_charger_loop || (current_lim > PD_P_SNK_STDBY_MW / 5)) + current_lim = PD_P_SNK_STDBY_MW / 5; + tcpm_set_current_limit(port, current_lim, 5000); tcpm_set_charge(port, true); tcpm_set_state(port, SNK_WAIT_CAPABILITIES, 0); break; @@ -4161,6 +4169,8 @@ static void run_state_machine(struct tcpm_port *port) port->pwr_opmode = TYPEC_PWR_MODE_PD; } + if (!port->pd_capable && port->slow_charger_loop) + tcpm_set_current_limit(port, tcpm_get_current_limit(port), 5000); tcpm_swap_complete(port, 0); tcpm_typec_connect(port); mod_enable_frs_delayed_work(port, 0); @@ -5763,6 +5773,7 @@ static int tcpm_fw_get_caps(struct tcpm_port *port, port->typec_caps.type = ret; port->port_type = port->typec_caps.type; + port->slow_charger_loop = fwnode_property_read_bool(fwnode, "slow-charger-loop"); if (port->port_type == TYPEC_PORT_SNK) goto sink; |