summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/typec/tcpm/tcpm.c17
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;