]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
hwmon:(pmbus/xdpe1a2g7b) Add support for xdpe1a2g5b/7b controllers
authorAshish Yadav <ashish.yadav@infineon.com>
Mon, 23 Feb 2026 05:08:04 +0000 (10:38 +0530)
committerGuenter Roeck <linux@roeck-us.net>
Tue, 31 Mar 2026 02:45:05 +0000 (19:45 -0700)
Add the pmbus driver for Infineon Digital Multi-phase XDPE1A2G5B and
XDPE1A2G7B controllers.

Signed-off-by: Ashish Yadav <ashish.yadav@infineon.com>
Link: https://lore.kernel.org/r/20260223050804.4287-4-Ashish.Yadav@infineon.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
drivers/hwmon/pmbus/Kconfig
drivers/hwmon/pmbus/Makefile
drivers/hwmon/pmbus/xdpe1a2g7b.c [new file with mode: 0644]

index fc1273abe35784e4d70b964df8891c146293a6a0..a4513fc6bc265a93a00ff1aabae0c9391bf7edbe 100644 (file)
@@ -711,6 +711,15 @@ config SENSORS_XDPE152
          This driver can also be built as a module. If so, the module will
          be called xdpe152c4.
 
+config SENSORS_XDPE1A2G7B
+       tristate "Infineon XDPE1A2G7B"
+       help
+         If you say yes here you get hardware monitoring support for Infineon
+         XDPE1A2G5B and XDPE1A2G7B.
+
+         This driver can also be built as a module. If so, the module will
+         be called xdpe1a2g7b.
+
 config SENSORS_XDPE122
        tristate "Infineon XDPE122 family"
        help
index d6c86924f887700025bb998e9fa74bbd7e6d1e9f..d592d8c77bec3d5ed8382ac5f82bc1e432dfb259 100644 (file)
@@ -70,6 +70,7 @@ obj-$(CONFIG_SENSORS_UCD9200) += ucd9200.o
 obj-$(CONFIG_SENSORS_XDP710)   += xdp710.o
 obj-$(CONFIG_SENSORS_XDPE122)  += xdpe12284.o
 obj-$(CONFIG_SENSORS_XDPE152)  += xdpe152c4.o
+obj-$(CONFIG_SENSORS_XDPE1A2G7B)       += xdpe1a2g7b.o
 obj-$(CONFIG_SENSORS_ZL6100)   += zl6100.o
 obj-$(CONFIG_SENSORS_PIM4328)  += pim4328.o
 obj-$(CONFIG_SENSORS_CRPS)     += crps.o
diff --git a/drivers/hwmon/pmbus/xdpe1a2g7b.c b/drivers/hwmon/pmbus/xdpe1a2g7b.c
new file mode 100644 (file)
index 0000000..1755e35
--- /dev/null
@@ -0,0 +1,119 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Hardware monitoring driver for Infineon Multi-phase Digital XDPE1A2G5B
+ * and XDPE1A2G7B Controllers
+ *
+ * Copyright (c) 2026 Infineon Technologies. All rights reserved.
+ */
+
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include "pmbus.h"
+
+#define XDPE1A2G7B_PAGE_NUM 2
+#define XDPE1A2G7B_NVIDIA_195MV 0x1E /* NVIDIA mode 1.95mV, VID step is 5mV */
+
+static int xdpe1a2g7b_identify(struct i2c_client *client,
+                              struct pmbus_driver_info *info)
+{
+       u8 vout_params;
+       int vout_mode;
+
+       /*
+        * XDPE1A2G5B and XDPE1A2G7B support both Linear and NVIDIA PWM VID data
+        * formats via VOUT_MODE. Note that the device pages/loops are not fully
+        * independent: configuration is shared, so programming each page/loop
+        * separately is not supported.
+        */
+       vout_mode = pmbus_read_byte_data(client, 0, PMBUS_VOUT_MODE);
+       if (vout_mode < 0)
+               return vout_mode;
+
+       switch (vout_mode >> 5) {
+       case 0:
+               info->format[PSC_VOLTAGE_OUT] = linear;
+               return 0;
+       case 1:
+               info->format[PSC_VOLTAGE_OUT] = vid;
+               vout_params = vout_mode & GENMASK(4, 0);
+               /* Check for VID Code Type */
+               switch (vout_params) {
+               case XDPE1A2G7B_NVIDIA_195MV:
+                       /* VID vrm_version for PAGE0 and PAGE1 */
+                       info->vrm_version[0] = nvidia195mv;
+                       info->vrm_version[1] = nvidia195mv;
+                       break;
+               default:
+                       return -EINVAL;
+               }
+               break;
+       default:
+               return -ENODEV;
+       }
+
+       return 0;
+}
+
+static struct pmbus_driver_info xdpe1a2g7b_info = {
+       .pages = XDPE1A2G7B_PAGE_NUM,
+       .identify = xdpe1a2g7b_identify,
+       .format[PSC_VOLTAGE_IN] = linear,
+       .format[PSC_TEMPERATURE] = linear,
+       .format[PSC_CURRENT_IN] = linear,
+       .format[PSC_CURRENT_OUT] = linear,
+       .format[PSC_POWER] = linear,
+       .func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT |
+                  PMBUS_HAVE_IIN | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT |
+                  PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP2 | PMBUS_HAVE_STATUS_TEMP |
+                  PMBUS_HAVE_POUT | PMBUS_HAVE_PIN | PMBUS_HAVE_STATUS_INPUT,
+       .func[1] = PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT |
+                  PMBUS_HAVE_IIN | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT |
+                  PMBUS_HAVE_PIN | PMBUS_HAVE_POUT | PMBUS_HAVE_STATUS_INPUT,
+};
+
+static int xdpe1a2g7b_probe(struct i2c_client *client)
+{
+       struct pmbus_driver_info *info;
+
+       info = devm_kmemdup(&client->dev, &xdpe1a2g7b_info, sizeof(*info),
+                           GFP_KERNEL);
+       if (!info)
+               return -ENOMEM;
+
+       return pmbus_do_probe(client, info);
+}
+
+static const struct i2c_device_id xdpe1a2g7b_id[] = {
+       { "xdpe1a2g5b" },
+       { "xdpe1a2g7b" },
+       {}
+};
+
+MODULE_DEVICE_TABLE(i2c, xdpe1a2g7b_id);
+
+static const struct of_device_id __maybe_unused xdpe1a2g7b_of_match[] = {
+       { .compatible = "infineon,xdpe1a2g5b" },
+       { .compatible = "infineon,xdpe1a2g7b" },
+       {}
+};
+
+MODULE_DEVICE_TABLE(of, xdpe1a2g7b_of_match);
+
+static struct i2c_driver xdpe1a2g7b_driver = {
+       .driver = {
+               .name = "xdpe1a2g7b",
+               .of_match_table = of_match_ptr(xdpe1a2g7b_of_match),
+       },
+       .probe = xdpe1a2g7b_probe,
+       .id_table = xdpe1a2g7b_id,
+};
+
+module_i2c_driver(xdpe1a2g7b_driver);
+
+MODULE_AUTHOR("Ashish Yadav <ashish.yadav@infineon.com>");
+MODULE_DESCRIPTION("PMBus driver for Infineon XDPE1A2G5B/7B");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("PMBUS");