[PATCH v5 2/3] hwmon:(pmbus/xdp720) Add support for efuse xdp730
From: ASHISH YADAV
Date: Tue Jun 09 2026 - 03:29:28 EST
From: Ashish Yadav <ashish.yadav@xxxxxxxxxxxx>
Adds support for the Infineon XDP730 Digital eFuse Controller by
updating the existing XDP720 driver.
Signed-off-by: Ashish Yadav <ashish.yadav@xxxxxxxxxxxx>
---
XDP720/XDP730 Digital eFuse Controllers provides accurate system telemetry
(V, I, P, T) and reports analog current at the IMON pin for post-processing.
Both parts share the same PMBus register map and direct-format
coefficients; they differ in the GIMON gain step exposed via the
TELEMETRY_AVG register (bit 10) and in the VDD_VIN pin number
(XDP720: pin 9, XDP730: pin 20).
The Current and Power measurement depends on the RIMON and GIMON values.
The GIMON (microA/A) depends on the 10th bit of TELEMETRY_AVG PMBUS Register.
The value of RIMON (kohm) can be provided by the user through device tree using
infineon,rimon-micro-ohms property.
---
drivers/hwmon/pmbus/Kconfig | 2 +-
drivers/hwmon/pmbus/xdp720.c | 76 +++++++++++++++++++++++++-----------
2 files changed, 54 insertions(+), 24 deletions(-)
diff --git a/drivers/hwmon/pmbus/Kconfig b/drivers/hwmon/pmbus/Kconfig
index 8f4bff375ecb..a9e86d92b044 100644
--- a/drivers/hwmon/pmbus/Kconfig
+++ b/drivers/hwmon/pmbus/Kconfig
@@ -715,7 +715,7 @@ config SENSORS_XDP720
tristate "Infineon XDP720 family"
help
If you say yes here you get hardware monitoring support for Infineon
- XDP720.
+ XDP720 and XDP730 Digital eFuse Controllers.
This driver can also be built as a module. If so, the module will
be called xdp720.
diff --git a/drivers/hwmon/pmbus/xdp720.c b/drivers/hwmon/pmbus/xdp720.c
index 8729a771f216..0f106c13e7ca 100644
--- a/drivers/hwmon/pmbus/xdp720.c
+++ b/drivers/hwmon/pmbus/xdp720.c
@@ -1,6 +1,11 @@
// SPDX-License-Identifier: GPL-2.0+
/*
- * Hardware monitoring driver for Infineon XDP720 Digital eFuse Controller
+ * Hardware monitoring driver for Infineon XDP720 / XDP730 Digital
+ * eFuse Controllers.
+ *
+ * Both parts share the same PMBus register map and direct-format
+ * coefficients; they differ in the GIMON gain step exposed via
+ * the TELEMETRY_AVG register and in the VDD_VIN pin number.
*
* Copyright (c) 2026 Infineon Technologies. All rights reserved.
*/
@@ -20,6 +25,18 @@
*/
#define XDP720_DEFAULT_RIMON 2000000000 /* 2k ohm */
#define XDP720_TELEMETRY_AVG 0xE9
+#define XDP720_TELEMETRY_AVG_GIMON BIT(10) /* high/low GIMON select */
+
+/* Chip identifiers carried in OF match-data and i2c_device_id->driver_data. */
+enum xdp720_chip_id {
+ CHIP_XDP720 = 0,
+ CHIP_XDP730,
+};
+
+struct xdp720_data {
+ enum xdp720_chip_id id;
+ struct pmbus_driver_info info;
+};
static struct pmbus_driver_info xdp720_info = {
.pages = 1,
@@ -56,16 +73,18 @@ static struct pmbus_driver_info xdp720_info = {
static int xdp720_probe(struct i2c_client *client)
{
- struct pmbus_driver_info *info;
+ struct xdp720_data *data;
int ret;
u32 rimon;
int gimon;
- info = devm_kmemdup(&client->dev, &xdp720_info, sizeof(*info),
- GFP_KERNEL);
- if (!info)
+ data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
+ if (!data)
return -ENOMEM;
+ data->id = (enum xdp720_chip_id)(uintptr_t)i2c_get_match_data(client);
+ data->info = xdp720_info;
+
ret = devm_regulator_get_enable(&client->dev, "vdd-vin");
if (ret)
return dev_err_probe(&client->dev, ret,
@@ -77,36 +96,47 @@ static int xdp720_probe(struct i2c_client *client)
return ret;
}
- ret >>= 10; /* 10th bit of TELEMETRY_AVG REG for GIMON Value */
- ret &= GENMASK(0, 0);
- if (ret == 1)
- gimon = 18200; /* output gain 18.2 microA/A */
- else
- gimon = 9100; /* output gain 9.1 microA/A */
+ /* Bit 10 of TELEMETRY_AVG selects the GIMON gain step in microA/A */
+ switch (data->id) {
+ case CHIP_XDP720:
+ gimon = (ret & XDP720_TELEMETRY_AVG_GIMON) ? 18200 : 9100;
+ dev_info(&client->dev, "Initialised XDP720 instance\n");
+ break;
+ case CHIP_XDP730:
+ gimon = (ret & XDP720_TELEMETRY_AVG_GIMON) ? 20000 : 10000;
+ dev_info(&client->dev, "Initialised XDP730 instance\n");
+ break;
+ default:
+ return -EINVAL;
+ }
- if (of_property_read_u32(client->dev.of_node,
- "infineon,rimon-micro-ohms", &rimon))
- rimon = XDP720_DEFAULT_RIMON; /* Default if not set via DT */
+ if (device_property_read_u32(&client->dev,
+ "infineon,rimon-micro-ohms", &rimon))
+ rimon = XDP720_DEFAULT_RIMON; /* Default if not in FW */
if (rimon == 0)
return -EINVAL;
/* Adapt the current and power scale for each instance */
- info->m[PSC_CURRENT_OUT] = DIV64_U64_ROUND_CLOSEST((u64)
- info->m[PSC_CURRENT_OUT] * rimon * gimon, 1000000000000ULL);
- info->m[PSC_POWER] = DIV64_U64_ROUND_CLOSEST((u64)
- info->m[PSC_POWER] * rimon * gimon, 1000000000000000ULL);
-
- return pmbus_do_probe(client, info);
+ data->info.m[PSC_CURRENT_OUT] = DIV64_U64_ROUND_CLOSEST((u64)
+ data->info.m[PSC_CURRENT_OUT] * rimon * gimon,
+ 1000000000000ULL);
+ data->info.m[PSC_POWER] = DIV64_U64_ROUND_CLOSEST((u64)
+ data->info.m[PSC_POWER] * rimon * gimon,
+ 1000000000000000ULL);
+
+ return pmbus_do_probe(client, &data->info);
}
static const struct of_device_id xdp720_of_match[] = {
- { .compatible = "infineon,xdp720" },
+ { .compatible = "infineon,xdp720", .data = (void *)CHIP_XDP720 },
+ { .compatible = "infineon,xdp730", .data = (void *)CHIP_XDP730 },
{}
};
MODULE_DEVICE_TABLE(of, xdp720_of_match);
static const struct i2c_device_id xdp720_id[] = {
- { "xdp720" },
+ { "xdp720", CHIP_XDP720 },
+ { "xdp730", CHIP_XDP730 },
{}
};
MODULE_DEVICE_TABLE(i2c, xdp720_id);
@@ -123,6 +153,6 @@ static struct i2c_driver xdp720_driver = {
module_i2c_driver(xdp720_driver);
MODULE_AUTHOR("Ashish Yadav <ashish.yadav@xxxxxxxxxxxx>");
-MODULE_DESCRIPTION("PMBus driver for Infineon XDP720 Digital eFuse Controller");
+MODULE_DESCRIPTION("PMBus driver for Infineon XDP720/XDP730 Digital eFuse Controllers");
MODULE_LICENSE("GPL");
MODULE_IMPORT_NS("PMBUS");
--
2.39.5