hwmon: (pmbus/xdp720) Add support for efuse xdp730

Adds support for the Infineon XDP730 Digital eFuse Controller by
updating the existing XDP720 driver.

Signed-off-by: Ashish Yadav <ashish.yadav@infineon.com>
Link: https://lore.kernel.org/r/20260609072231.15486-3-Ashish.Yadav@infineon.com
[groeck: Fixed conflicts in xdp720_id declaration]
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
This commit is contained in:
Ashish Yadav authored and Guenter Roeck committed 2026-06-09 08:23:18 -07:00
1 parent adf2bba494
commit 7c264a7d07
2 files changed
+53 -23

No files matched your search

+1 -1
View File
@@ -780,7 +780,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.
+52 -22
View File
@@ -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);
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, info);
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[] = {
{ .name = "xdp720" },
{ .name = "xdp720", .driver_data = CHIP_XDP720 },
{ .name = "xdp730", .driver_data = 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@infineon.com>");
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");