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:
1 parent
adf2bba494
commit
7c264a7d07
2 files changed
+53
-23
No files matched your search
@@ -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.
|
||||
|
||||
@@ -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");
|
||||
Reference in new issue
Block a user