]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
usb: typec: ucsi: psy: Fix ucsi_psy_get_current_now in non-PD cases
authorBenson Leung <bleung@chromium.org>
Mon, 8 Dec 2025 17:48:47 +0000 (17:48 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 17 Dec 2025 13:43:13 +0000 (14:43 +0100)
current_now would always return 0 in for non-PD power sources, and the
negotiated current based on the Request RDO in PD mode.

For USB Type-C current or legacy Default USB cases current_now will present
the max value of those modes, as that is the equivalent of the Request RDO
in PD.

Also, current_now will now return 0 when the port is disconnected to match
the same behavior of current_max.

Signed-off-by: Benson Leung <bleung@chromium.org>
Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Link: https://patch.msgid.link/20251208174918.289394-2-bleung@chromium.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/typec/ucsi/psy.c

index 3abe9370ffaaf0fc2596a914cf6a7c74eee99a3f..b828719e33df646c0c0b39e190b27c9887bb0efe 100644 (file)
@@ -202,10 +202,28 @@ static int ucsi_psy_get_current_max(struct ucsi_connector *con,
 static int ucsi_psy_get_current_now(struct ucsi_connector *con,
                                    union power_supply_propval *val)
 {
-       if (UCSI_CONSTAT(con, PWR_OPMODE) == UCSI_CONSTAT_PWR_OPMODE_PD)
-               val->intval = rdo_op_current(con->rdo) * 1000;
-       else
+       if (!UCSI_CONSTAT(con, CONNECTED)) {
                val->intval = 0;
+               return 0;
+       }
+
+       switch (UCSI_CONSTAT(con, PWR_OPMODE)) {
+       case UCSI_CONSTAT_PWR_OPMODE_PD:
+               val->intval = rdo_op_current(con->rdo) * 1000;
+               break;
+       case UCSI_CONSTAT_PWR_OPMODE_TYPEC1_5:
+               val->intval = UCSI_TYPEC_1_5_CURRENT * 1000;
+               break;
+       case UCSI_CONSTAT_PWR_OPMODE_TYPEC3_0:
+               val->intval = UCSI_TYPEC_3_0_CURRENT * 1000;
+               break;
+       case UCSI_CONSTAT_PWR_OPMODE_BC:
+       case UCSI_CONSTAT_PWR_OPMODE_DEFAULT:
+       /* UCSI can't tell b/w DCP/CDP or USB2/3x1/3x2 SDP chargers */
+       default:
+               val->intval = UCSI_TYPEC_DEFAULT_CURRENT * 1000;
+               break;
+       }
        return 0;
 }