Hi,
On 17-04-18 08:01, Li Jun wrote:
This patch is a further update for rdo based on [1], which
removed max_snk_ma/mv/mw but kept operating_snk_mw.
operating_snk_mw is only used to judge capability mismatch,
per PD spec, we can achieve this via compare the selected
source PDO and matching sink PDO, also after patch [1], we
don't limit the PDO matching between the same type, so the
rdo operating and max current/power calculation should be
updated accordingly.
I do not believe that this is correct, lets take a device
with a fusb302 tcpc with the following PDO-s:
PDO_FIXED(5000, 400, PDO_FIXED_FLAGS)
PDO_VAR(5000, 12000, 3000);
And an operating_snk_mw of 2500mW then according to your
new code a charger which supplies 12V 2A will now get
the mismatch bit set even though it is delivering 24W.
I really don't see any way to fix this and I believe we
should just keep the operating_snk_mw field.
Regards
Hans
[1]https://patchwork.kernel.org/patch/10342299/
Signed-off-by: Li Jun <jun.li@xxxxxxx>
---
drivers/usb/typec/tcpm.c | 52 ++++++++++++++++++++++++++++++------------------
1 file changed, 33 insertions(+), 19 deletions(-)
diff --git a/drivers/usb/typec/tcpm.c b/drivers/usb/typec/tcpm.c
index 27192083..0be04b3 100644
--- a/drivers/usb/typec/tcpm.c
+++ b/drivers/usb/typec/tcpm.c
@@ -1854,28 +1854,42 @@ static int tcpm_pd_build_request(struct tcpm_port *port, u32 *rdo)
else
mv = pdo_min_voltage(pdo);
- /* Select maximum available current within the sink pdo's limit */
- if (type == PDO_TYPE_BATT) {
- mw = min_power(pdo, matching_snk_pdo);
- ma = 1000 * mw / mv;
- } else {
- ma = min_current(pdo, matching_snk_pdo);
- mw = ma * mv / 1000;
- }
-
flags = RDO_USB_COMM | RDO_NO_SUSPEND;
- /* Set mismatch bit if offered power is less than operating power */
- max_ma = ma;
- max_mw = mw;
- if (mw < port->operating_snk_mw) {
- flags |= RDO_CAP_MISMATCH;
- if (type == PDO_TYPE_BATT &&
- (pdo_max_power(matching_snk_pdo) > pdo_max_power(pdo)))
- max_mw = pdo_max_power(matching_snk_pdo);
- else if (pdo_max_current(matching_snk_pdo) >
- pdo_max_current(pdo))
+ switch (type) {
+ case PDO_TYPE_FIXED:
+ case PDO_TYPE_VAR:
+ if (pdo_type(matching_snk_pdo) == PDO_TYPE_BATT)
+ max_ma = pdo_max_power(matching_snk_pdo) * 1000 / mv;
+ else
max_ma = pdo_max_current(matching_snk_pdo);
+
+ if (max_ma > pdo_max_current(pdo)) {
+ flags |= RDO_CAP_MISMATCH;
+ ma = pdo_max_current(pdo);
+ } else {
+ ma = max_ma;
+ }
+ break;
+ case PDO_TYPE_BATT:
+ if (pdo_type(matching_snk_pdo) == PDO_TYPE_BATT)
+ max_mw = pdo_max_power(matching_snk_pdo);
+ else
+ max_mw = pdo_max_current(matching_snk_pdo) *
+ pdo_min_voltage(matching_snk_pdo) /
+ 1000;
+
+ if (max_mw > pdo_max_power(pdo)) {
+ flags |= RDO_CAP_MISMATCH;
+ mw = pdo_max_power(pdo);
+ } else {
+ mw = max_mw;
+ }
+
+ ma = mw * 1000 / mv;
+ break;
+ default:
+ break;
}
tcpm_log(port, "cc=%d cc1=%d cc2=%d vbus=%d vconn=%s polarity=%d",
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html