From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pl1-f173.google.com (mail-pl1-f173.google.com [209.85.214.173]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B41EF25D53B for ; Mon, 8 Dec 2025 17:53:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.173 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765216401; cv=none; b=bKwDpYHhuXBaO8cnS+zuAE39dNFAn+R75TGsMGslOUnx1AkCmnH8HyM3kJNDsXdl4aJhZfwXBnSesXWyFXsZ3R1N8HwizwDAMZwmyGOSHUX2E/SGqSgknk/ntHuyszLnJ0wtw5V9uB8Xib/zJkXv2UJ/RhTXhRf16HBjY8uUVc0= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765216401; c=relaxed/simple; bh=6HXocaqFPwCDChHGBH4gzoZDeMN6an2hZV1HfduO/V0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=M15bCXL5mnE4po7Ja3LSp0Iv/bebViLN/6clhkcI7aiwjlAHLsvs81jcTmWgW1/HARjP5hlZ5wqJkb/5ZqFMltj9t0Z+XvNpO3tjkmYzO9TBp5Yq7kGvQPh9hZrkVltMX0HtEXwXVTS6V1m7xq8R6U61U9Pe3DAf9ucuHtxk6mw= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org; spf=pass smtp.mailfrom=chromium.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b=Tnf5Hbs1; arc=none smtp.client-ip=209.85.214.173 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=chromium.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="Tnf5Hbs1" Received: by mail-pl1-f173.google.com with SMTP id d9443c01a7336-29812589890so66200775ad.3 for ; Mon, 08 Dec 2025 09:53:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1765216399; x=1765821199; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=tW5pItU4svWCt1M5wdhqb0PfxqTPpmGpoyx3h41byA4=; b=Tnf5Hbs1zjkbNuHQH7ZTpkStT7N1MLvW7YcBkw4KciJvvyIALUltDFZ5VDHYd5EQbK piA+Tm9+PT6vI3qg3R6fMQ6fVRLPEu6f7fnyF8WMGNpXM4AZolpxwT7g7aWhBnsv/S8u JyC7riJuR7smCPxJcIJKgeP9rYiecBFWMbxGw= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765216399; x=1765821199; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=tW5pItU4svWCt1M5wdhqb0PfxqTPpmGpoyx3h41byA4=; b=QNEYa5LY4exXIcWGFdtB2hK+7r4LDp75A9XSOuWb6UiinSYHD9SRplcAR9YrCV+OzG fJ7jvzx4L3qbClJQXhmHRd4NANvYYaI3MCcz0u4RBXSvG2lmhlkAn6jvgyH8ZzaNatiG aPEZAukuo4QXMdwYSJDzyq23RwJeKhaVK+Bud3e2r4i9eSviKIrHFhZkRMEGlCM+tA4X fL3m9B1c/OK+Ore571pDeYAZgJ5k/gdbYbBn2TFruTA7Ulb7cSdX1e459oYHxBynTmYf ktRxb4l58GB8KfCDRUSEgsVGYMi+gkefZXgwC3G1QO1Ut6TNozV/34T0kHmEUjp1ClWE RlmA== X-Forwarded-Encrypted: i=1; AJvYcCUX45pUC/D8i1U+HDBFaXLy/N2D8xhcBS4pC+sX26QZ6/EOnc3jCoibyXWlzTa7aa4ho1wBD4H5wD0EVbY=@vger.kernel.org X-Gm-Message-State: AOJu0YxtS/P/gv4qZfrgCORTueN+4NX9LRY4NA+PG+T2AAYBIgz0obBO vaaUG3Sf8eTimKAslrEgHnQJ5zUSCkOznUv8CMtMsAYYkxs1B5qBRBGTb9X9U131wg== X-Gm-Gg: ASbGncsa8ngNZph3miCPvVmhpyZCvPyovyLtWn4QAn4t+ybSiZS02dgCIQbEMSYRu4b 8C84EbntfKd5BNimNTD2M49O6cBjqix+TBQroEATGNXV7TeS+KPf9SDewzt5OwPjP2fAWt+wYoQ zFQWLcZWYUTM3lRLH2KJTdzG1fZECbV6S61oNtdA8BqkZgC7BrS3h2ejb8GsdYtu1bGY3eynUyd IGkXN2ktwAUZlgnBF/vF1gxlo4crCXQaurot55J7VJD19zt1J7ixDjyN25OOys3JIOufYlIZukt CVwBeZe7Mqs7CVrxa0KKy0LSqtd/77f6NGLEgh9utktUJWlDnOZW0U95NdUE0Ve7oueBVTYQkCm mIQXgS0K312ca7DcJILjV0DZGIgqr6r82WxxKX7ewU2HtDfXXKzInuHVwtsdQsydHNnBg6PypyH jQxeI6qBdj++BNtdeVzUS/RBSbk3UrEZF2iTkIMswD1CLuSpIEZQj1RnZmVZ6XmmLbBQu9c7Puq 2Qr X-Google-Smtp-Source: AGHT+IFzrVt400U3f2GHLcMT0+O1P0Ob2hFQ7HmMj4TKsBtv4UNnVsBlVxH3dbFgYw+t2GKnP8jhUA== X-Received: by 2002:a17:902:ce01:b0:29a:5ce:b467 with SMTP id d9443c01a7336-29df5dd4c29mr66419465ad.54.1765216399039; Mon, 08 Dec 2025 09:53:19 -0800 (PST) Received: from decatoncale.c.googlers.com.com (167.178.83.34.bc.googleusercontent.com. [34.83.178.167]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-29daeaab9f1sm130375675ad.72.2025.12.08.09.53.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 08 Dec 2025 09:53:17 -0800 (PST) From: Benson Leung To: heikki.krogerus@linux.intel.com, sebastian.reichel@collabora.com, gregkh@linuxfoundation.org, jthies@google.com Cc: bleung@google.com, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, Benson Leung Subject: [PATCH 2/2] usb: typec: ucsi: psy: Fix voltage and current max for non-Fixed PDOs Date: Mon, 8 Dec 2025 17:48:48 +0000 Message-ID: <20251208174918.289394-3-bleung@chromium.org> X-Mailer: git-send-email 2.52.0.223.gf5cc29aaa4-goog In-Reply-To: <20251208174918.289394-1-bleung@chromium.org> References: <20251208174918.289394-1-bleung@chromium.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit ucsi_psy_get_voltage_max and ucsi_psy_get_current_max are calculated using whichever pdo is in the last position of the src_pdos array, presuming it to be a fixed pdo, so the pdo_fixed_voltage or pdo_max_current helpers are used on that last pdo. However, non-Fixed PDOs such as Battery PDOs, Augmented PDOs (used for AVS and for PPS) may exist, and are always at the end of the array if they do. In the event one of these more advanced chargers are attached the helpers for fixed return mangled values. Here's an example case of a Google Pixel Flex Dual Port 67W USB-C Fast Charger with PPS support: POWER_SUPPLY_NAME=ucsi-source-psy-cros_ec_ucsi.4.auto2 POWER_SUPPLY_TYPE=USB POWER_SUPPLY_CHARGE_TYPE=Standard POWER_SUPPLY_USB_TYPE=C [PD] PD_PPS PD_DRP POWER_SUPPLY_ONLINE=1 POWER_SUPPLY_VOLTAGE_MIN=5000000 POWER_SUPPLY_VOLTAGE_MAX=13400000 POWER_SUPPLY_VOLTAGE_NOW=20000000 POWER_SUPPLY_CURRENT_MAX=5790000 POWER_SUPPLY_CURRENT_NOW=3250000 Voltage Max is reading as 13.4V, but that's an incorrect decode of the PPS APDO in the last position. Same goes for CURRENT_MAX. 5.79A is incorrect. Instead, enumerate through the src_pdos and filter just for Fixed PDOs for now, and find the one with the highest voltage and current respectively. After, from the same charger: POWER_SUPPLY_NAME=ucsi-source-psy-cros_ec_ucsi.4.auto2 POWER_SUPPLY_TYPE=USB POWER_SUPPLY_CHARGE_TYPE=Standard POWER_SUPPLY_USB_TYPE=C [PD] PD_PPS PD_DRP POWER_SUPPLY_ONLINE=1 POWER_SUPPLY_VOLTAGE_MIN=5000000 POWER_SUPPLY_VOLTAGE_MAX=20000000 POWER_SUPPLY_VOLTAGE_NOW=20000000 POWER_SUPPLY_CURRENT_MAX=4000000 POWER_SUPPLY_CURRENT_NOW=3250000 Signed-off-by: Benson Leung --- drivers/usb/typec/ucsi/psy.c | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/drivers/usb/typec/ucsi/psy.c b/drivers/usb/typec/ucsi/psy.c index b828719e33df..c8ebab8ba7e7 100644 --- a/drivers/usb/typec/ucsi/psy.c +++ b/drivers/usb/typec/ucsi/psy.c @@ -112,15 +112,20 @@ static int ucsi_psy_get_voltage_max(struct ucsi_connector *con, union power_supply_propval *val) { u32 pdo; + int max_voltage = 0; switch (UCSI_CONSTAT(con, PWR_OPMODE)) { case UCSI_CONSTAT_PWR_OPMODE_PD: - if (con->num_pdos > 0) { - pdo = con->src_pdos[con->num_pdos - 1]; - val->intval = pdo_fixed_voltage(pdo) * 1000; - } else { - val->intval = 0; + for (int i = 0; i < con->num_pdos; i++) { + int pdo_voltage = 0; + + pdo = con->src_pdos[i]; + if (pdo_type(pdo) == PDO_TYPE_FIXED) + pdo_voltage = pdo_fixed_voltage(pdo) * 1000; + max_voltage = (pdo_voltage > max_voltage) ? pdo_voltage + : max_voltage; } + val->intval = max_voltage; break; case UCSI_CONSTAT_PWR_OPMODE_TYPEC3_0: case UCSI_CONSTAT_PWR_OPMODE_TYPEC1_5: @@ -168,6 +173,7 @@ static int ucsi_psy_get_current_max(struct ucsi_connector *con, union power_supply_propval *val) { u32 pdo; + int max_current = 0; if (!UCSI_CONSTAT(con, CONNECTED)) { val->intval = 0; @@ -176,12 +182,16 @@ static int ucsi_psy_get_current_max(struct ucsi_connector *con, switch (UCSI_CONSTAT(con, PWR_OPMODE)) { case UCSI_CONSTAT_PWR_OPMODE_PD: - if (con->num_pdos > 0) { - pdo = con->src_pdos[con->num_pdos - 1]; - val->intval = pdo_max_current(pdo) * 1000; - } else { - val->intval = 0; + for (int i = 0; i < con->num_pdos; i++) { + int pdo_current = 0; + + pdo = con->src_pdos[i]; + if (pdo_type(pdo) == PDO_TYPE_FIXED) + pdo_current = pdo_max_current(pdo) * 1000; + max_current = (pdo_current > max_current) ? pdo_current + : max_current; } + val->intval = max_current; break; case UCSI_CONSTAT_PWR_OPMODE_TYPEC1_5: val->intval = UCSI_TYPEC_1_5_CURRENT * 1000; -- 2.52.0.223.gf5cc29aaa4-goog