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.

[1]https://patchwork.kernel.org/patch/10342299/

Signed-off-by: Li Jun <jun...@nxp.com>
---
 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",
-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to