From: Ashish Yadav Date: Tue, 9 Jun 2026 07:22:30 +0000 (+0530) Subject: hwmon: (pmbus/xdp720) Add support for efuse xdp730 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7c264a7d077586a64656ea10559ce6ab69377534;p=thirdparty%2Fkernel%2Flinux.git 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 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 --- diff --git a/drivers/hwmon/pmbus/Kconfig b/drivers/hwmon/pmbus/Kconfig index f330dc3f21fe5..c8cda160b5f8e 100644 --- a/drivers/hwmon/pmbus/Kconfig +++ b/drivers/hwmon/pmbus/Kconfig @@ -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. diff --git a/drivers/hwmon/pmbus/xdp720.c b/drivers/hwmon/pmbus/xdp720.c index 60491e9217bfb..88f076e3d15bc 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[] = { - { .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 "); -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");