[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20210716093916.1516845-1-kyletso@google.com>
Date: Fri, 16 Jul 2021 17:39:16 +0800
From: Kyle Tso <kyletso@...gle.com>
To: linux@...ck-us.net, heikki.krogerus@...ux.intel.com,
gregkh@...uxfoundation.org
Cc: badhri@...gle.com, linux-usb@...r.kernel.org,
linux-kernel@...r.kernel.org, Kyle Tso <kyletso@...gle.com>
Subject: [PATCH] usb: typec: tcpm: Support non-PD mode
tcpm.c could work well without PD capabilities. Do not block the probe
if capabilities are not defined in fwnode and skip the PD power
negotiation in the state machine.
Signed-off-by: Kyle Tso <kyletso@...gle.com>
---
drivers/usb/typec/tcpm/tcpm.c | 50 ++++++++++++++++++++---------------
1 file changed, 29 insertions(+), 21 deletions(-)
diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c
index 5b22a1c931a9..a42de5e17d24 100644
--- a/drivers/usb/typec/tcpm/tcpm.c
+++ b/drivers/usb/typec/tcpm/tcpm.c
@@ -3914,6 +3914,8 @@ static void run_state_machine(struct tcpm_port *port)
if (port->ams == POWER_ROLE_SWAP ||
port->ams == FAST_ROLE_SWAP)
tcpm_ams_finish(port);
+ if (!port->nr_src_pdo)
+ tcpm_set_state(port, SRC_READY, 0);
port->upcoming_state = SRC_SEND_CAPABILITIES;
tcpm_ams_start(port, POWER_NEGOTIATION);
break;
@@ -4161,7 +4163,10 @@ static void run_state_machine(struct tcpm_port *port)
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);
+ if (!port->nr_snk_pdo)
+ tcpm_set_state(port, SNK_READY, 0);
+ else
+ tcpm_set_state(port, SNK_WAIT_CAPABILITIES, 0);
break;
}
/*
@@ -5939,15 +5944,17 @@ static int tcpm_fw_get_caps(struct tcpm_port *port,
/* Get source pdos */
ret = fwnode_property_count_u32(fwnode, "source-pdos");
- if (ret <= 0)
- return -EINVAL;
+ if (ret < 0)
+ ret = 0;
port->nr_src_pdo = min(ret, PDO_MAX_OBJECTS);
- ret = fwnode_property_read_u32_array(fwnode, "source-pdos",
- port->src_pdo, port->nr_src_pdo);
- if ((ret < 0) || tcpm_validate_caps(port, port->src_pdo,
- port->nr_src_pdo))
- return -EINVAL;
+ if (port->nr_src_pdo) {
+ ret = fwnode_property_read_u32_array(fwnode, "source-pdos",
+ port->src_pdo, port->nr_src_pdo);
+ if ((ret < 0) || tcpm_validate_caps(port, port->src_pdo,
+ port->nr_src_pdo))
+ return -EINVAL;
+ }
if (port->port_type == TYPEC_PORT_SRC)
return 0;
@@ -5963,19 +5970,21 @@ static int tcpm_fw_get_caps(struct tcpm_port *port,
sink:
/* Get sink pdos */
ret = fwnode_property_count_u32(fwnode, "sink-pdos");
- if (ret <= 0)
- return -EINVAL;
+ if (ret < 0)
+ ret = 0;
port->nr_snk_pdo = min(ret, PDO_MAX_OBJECTS);
- ret = fwnode_property_read_u32_array(fwnode, "sink-pdos",
- port->snk_pdo, port->nr_snk_pdo);
- if ((ret < 0) || tcpm_validate_caps(port, port->snk_pdo,
- port->nr_snk_pdo))
- return -EINVAL;
+ if (port->nr_snk_pdo) {
+ ret = fwnode_property_read_u32_array(fwnode, "sink-pdos",
+ port->snk_pdo, port->nr_snk_pdo);
+ if ((ret < 0) || tcpm_validate_caps(port, port->snk_pdo,
+ port->nr_snk_pdo))
+ return -EINVAL;
- if (fwnode_property_read_u32(fwnode, "op-sink-microwatt", &mw) < 0)
- return -EINVAL;
- port->operating_snk_mw = mw / 1000;
+ if (fwnode_property_read_u32(fwnode, "op-sink-microwatt", &mw) < 0)
+ return -EINVAL;
+ port->operating_snk_mw = mw / 1000;
+ }
port->self_powered = fwnode_property_read_bool(fwnode, "self-powered");
@@ -6283,9 +6292,8 @@ struct tcpm_port *tcpm_register_port(struct device *dev, struct tcpc_dev *tcpc)
int err;
if (!dev || !tcpc ||
- !tcpc->get_vbus || !tcpc->set_cc || !tcpc->get_cc ||
- !tcpc->set_polarity || !tcpc->set_vconn || !tcpc->set_vbus ||
- !tcpc->set_pd_rx || !tcpc->set_roles || !tcpc->pd_transmit)
+ !tcpc->get_vbus || !tcpc->set_cc || !tcpc->get_cc || !tcpc->set_polarity ||
+ !tcpc->set_vconn || !tcpc->set_vbus || !tcpc->set_roles)
return ERR_PTR(-EINVAL);
port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL);
--
2.32.0.402.g57bb445576-goog
Powered by blists - more mailing lists