|
| 1 | +From 984090311edebbf7f3b246230f567847540b66bd Mon Sep 17 00:00:00 2001 |
| 2 | +From: Vadim Pasternak <vadimp@nvidia.com> |
| 3 | +Date: Wed, 14 Jan 2026 19:19:20 +0200 |
| 4 | +Subject: [PATCH backport 6.1 1/1] hwmon:(pmbus/xdpe1a2g7b) XDPE1A2G7B Digital |
| 5 | + Multi-phase Controller Driver |
| 6 | + |
| 7 | +Add the pmbus driver for the Infineon XDPE1A2G7B Digital Multi-phase |
| 8 | +Controller. |
| 9 | + |
| 10 | +Signed-off-by: Ashish Yadav <ashish.yadav@infineon.com> |
| 11 | +--- |
| 12 | + drivers/hwmon/pmbus/Kconfig | 9 +++ |
| 13 | + drivers/hwmon/pmbus/Makefile | 1 + |
| 14 | + drivers/hwmon/pmbus/pmbus.h | 2 +- |
| 15 | + drivers/hwmon/pmbus/pmbus_core.c | 4 ++ |
| 16 | + drivers/hwmon/pmbus/xdpe1a2g7b.c | 97 ++++++++++++++++++++++++++++++++ |
| 17 | + 5 files changed, 112 insertions(+), 1 deletion(-) |
| 18 | + create mode 100644 drivers/hwmon/pmbus/xdpe1a2g7b.c |
| 19 | + |
| 20 | +diff --git a/drivers/hwmon/pmbus/Kconfig b/drivers/hwmon/pmbus/Kconfig |
| 21 | +index 571427e53..1eabc51d6 100644 |
| 22 | +--- a/drivers/hwmon/pmbus/Kconfig |
| 23 | ++++ b/drivers/hwmon/pmbus/Kconfig |
| 24 | +@@ -472,6 +472,15 @@ config SENSORS_XDPE152 |
| 25 | + This driver can also be built as a module. If so, the module will |
| 26 | + be called xdpe152c4. |
| 27 | + |
| 28 | ++config SENSORS_XDPE1A2G7B |
| 29 | ++ tristate "Infineon XDPE1A2G7B" |
| 30 | ++ help |
| 31 | ++ If you say yes here you get hardware monitoring support for Infineon |
| 32 | ++ XDPE1A2G7B. |
| 33 | ++ |
| 34 | ++ This driver can also be built as a module. If so, the module will |
| 35 | ++ be called xdpe1a2g7b. |
| 36 | ++ |
| 37 | + config SENSORS_XDPE122 |
| 38 | + tristate "Infineon XDPE122 family" |
| 39 | + help |
| 40 | +diff --git a/drivers/hwmon/pmbus/Makefile b/drivers/hwmon/pmbus/Makefile |
| 41 | +index 186e2ecc6..ed15ebae5 100644 |
| 42 | +--- a/drivers/hwmon/pmbus/Makefile |
| 43 | ++++ b/drivers/hwmon/pmbus/Makefile |
| 44 | +@@ -50,5 +50,6 @@ obj-$(CONFIG_SENSORS_UCD9000) += ucd9000.o |
| 45 | + obj-$(CONFIG_SENSORS_UCD9200) += ucd9200.o |
| 46 | + obj-$(CONFIG_SENSORS_XDPE122) += xdpe12284.o |
| 47 | + obj-$(CONFIG_SENSORS_XDPE152) += xdpe152c4.o |
| 48 | ++obj-$(CONFIG_SENSORS_XDPE1A2G7B) += xdpe1a2g7b.o |
| 49 | + obj-$(CONFIG_SENSORS_ZL6100) += zl6100.o |
| 50 | + obj-$(CONFIG_SENSORS_PIM4328) += pim4328.o |
| 51 | +diff --git a/drivers/hwmon/pmbus/pmbus.h b/drivers/hwmon/pmbus/pmbus.h |
| 52 | +index 0bbb8ae93..62a6908d7 100644 |
| 53 | +--- a/drivers/hwmon/pmbus/pmbus.h |
| 54 | ++++ b/drivers/hwmon/pmbus/pmbus.h |
| 55 | +@@ -407,7 +407,7 @@ enum pmbus_sensor_classes { |
| 56 | + #define PMBUS_PAGE_VIRTUAL BIT(31) /* Page is virtual */ |
| 57 | + |
| 58 | + enum pmbus_data_format { linear = 0, ieee754, direct, vid }; |
| 59 | +-enum vrm_version { vr11 = 0, vr12, vr13, imvp9, amd625mv }; |
| 60 | ++enum vrm_version { vr11 = 0, vr12, vr13, imvp9, amd625mv, nvidia195mv }; |
| 61 | + |
| 62 | + /* PMBus revision identifiers */ |
| 63 | + #define PMBUS_REV_10 0x00 /* PMBus revision 1.0 */ |
| 64 | +diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c |
| 65 | +index 4b73c7b27..43502f730 100644 |
| 66 | +--- a/drivers/hwmon/pmbus/pmbus_core.c |
| 67 | ++++ b/drivers/hwmon/pmbus/pmbus_core.c |
| 68 | +@@ -816,6 +816,10 @@ static s64 pmbus_reg2data_vid(struct pmbus_data *data, |
| 69 | + if (val >= 0x0 && val <= 0xd8) |
| 70 | + rv = DIV_ROUND_CLOSEST(155000 - val * 625, 100); |
| 71 | + break; |
| 72 | ++ case nvidia195mv: |
| 73 | ++ if (val >= 0x01) |
| 74 | ++ rv = 195 + (val - 1) * 5; |
| 75 | ++ break; |
| 76 | + } |
| 77 | + return rv; |
| 78 | + } |
| 79 | +diff --git a/drivers/hwmon/pmbus/xdpe1a2g7b.c b/drivers/hwmon/pmbus/xdpe1a2g7b.c |
| 80 | +new file mode 100644 |
| 81 | +index 000000000..c7e230dc8 |
| 82 | +--- /dev/null |
| 83 | ++++ b/drivers/hwmon/pmbus/xdpe1a2g7b.c |
| 84 | +@@ -0,0 +1,97 @@ |
| 85 | ++// SPDX-License-Identifier: GPL-2.0+ |
| 86 | ++/* |
| 87 | ++ * Hardware monitoring driver for Infineon Multi-phase Digital VR Controllers |
| 88 | ++ * |
| 89 | ++ * Copyright (c) 2026 Infineon Technologies. All rights reserved. |
| 90 | ++ */ |
| 91 | ++ |
| 92 | ++#include <linux/err.h> |
| 93 | ++#include <linux/i2c.h> |
| 94 | ++#include <linux/init.h> |
| 95 | ++#include <linux/kernel.h> |
| 96 | ++#include <linux/module.h> |
| 97 | ++#include "pmbus.h" |
| 98 | ++ |
| 99 | ++#define XDPE1A2G7B_PAGE_NUM 2 |
| 100 | ++#define XDPE122_NVIDIA_195MV 0x1E /* NVIDIA mode 1.95mV */ |
| 101 | ++ |
| 102 | ++static struct pmbus_driver_info xdpe1a2g7b_info = { |
| 103 | ++ .pages = XDPE1A2G7B_PAGE_NUM, |
| 104 | ++ .format[PSC_VOLTAGE_IN] = linear, |
| 105 | ++ .format[PSC_VOLTAGE_OUT] = vid, |
| 106 | ++ .format[PSC_TEMPERATURE] = linear, |
| 107 | ++ .format[PSC_CURRENT_IN] = linear, |
| 108 | ++ .format[PSC_CURRENT_OUT] = linear, |
| 109 | ++ .format[PSC_POWER] = linear, |
| 110 | ++ .func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | |
| 111 | ++ PMBUS_HAVE_IIN | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | |
| 112 | ++ PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP2 | PMBUS_HAVE_STATUS_TEMP | |
| 113 | ++ PMBUS_HAVE_POUT | PMBUS_HAVE_PIN | PMBUS_HAVE_STATUS_INPUT, |
| 114 | ++ .func[1] = PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | |
| 115 | ++ PMBUS_HAVE_IIN | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | |
| 116 | ++ PMBUS_HAVE_POUT | PMBUS_HAVE_PIN | PMBUS_HAVE_STATUS_INPUT, |
| 117 | ++}; |
| 118 | ++ |
| 119 | ++static int xdpe1a2g7b_identify(struct i2c_client *client, |
| 120 | ++ struct pmbus_driver_info *info) |
| 121 | ++{ |
| 122 | ++ u8 vout_params; |
| 123 | ++ int i, ret; |
| 124 | ++ |
| 125 | ++ for (i = 0; i < info->pages; i++) { |
| 126 | ++ /* Read the register with VOUT for VID Code Type. */ |
| 127 | ++ ret = pmbus_read_byte_data(client, i, PMBUS_VOUT_MODE); |
| 128 | ++ if (ret < 0) |
| 129 | ++ return ret; |
| 130 | ++ |
| 131 | ++ vout_params = ret & GENMASK(4, 0); |
| 132 | ++ |
| 133 | ++ switch (vout_params) { |
| 134 | ++ case XDPE122_NVIDIA_195MV: |
| 135 | ++ info->vrm_version[i] = nvidia195mv; |
| 136 | ++ break; |
| 137 | ++ default: |
| 138 | ++ return -EINVAL; |
| 139 | ++ } |
| 140 | ++ } |
| 141 | ++ |
| 142 | ++ return 0; |
| 143 | ++} |
| 144 | ++ |
| 145 | ++static int xdpe1a2g7b_probe(struct i2c_client *client) |
| 146 | ++{ |
| 147 | ++ struct pmbus_driver_info *info; |
| 148 | ++ |
| 149 | ++ info = devm_kmemdup(&client->dev, &xdpe1a2g7b_info, sizeof(*info), |
| 150 | ++ GFP_KERNEL); |
| 151 | ++ if (!info) |
| 152 | ++ return -ENOMEM; |
| 153 | ++ |
| 154 | ++ info->identify = xdpe1a2g7b_identify; |
| 155 | ++ |
| 156 | ++ return pmbus_do_probe(client, info); |
| 157 | ++} |
| 158 | ++ |
| 159 | ++static const struct i2c_device_id xdpe1a2g7b_id[] = { { "xdpe1a2g7b" }, {} }; |
| 160 | ++ |
| 161 | ++MODULE_DEVICE_TABLE(i2c, xdpe1a2g7b_id); |
| 162 | ++ |
| 163 | ++static const struct of_device_id __maybe_unused |
| 164 | ++ xdpe1a2g7b_of_match[] = { { .compatible = "infineon,xdpe1a2g7b" }, {} }; |
| 165 | ++MODULE_DEVICE_TABLE(of, xdpe1a2g7b_of_match); |
| 166 | ++ |
| 167 | ++static struct i2c_driver xdpe1a2g7b_driver = { |
| 168 | ++ .driver = { |
| 169 | ++ .name = "xdpe1a2g7b", |
| 170 | ++ .of_match_table = of_match_ptr(xdpe1a2g7b_of_match), |
| 171 | ++ }, |
| 172 | ++ .probe_new = xdpe1a2g7b_probe, |
| 173 | ++ .id_table = xdpe1a2g7b_id, |
| 174 | ++}; |
| 175 | ++ |
| 176 | ++module_i2c_driver(xdpe1a2g7b_driver); |
| 177 | ++ |
| 178 | ++MODULE_AUTHOR("Ashish Yadav <ashish.yadav@infineon.com>"); |
| 179 | ++MODULE_DESCRIPTION("PMBus driver for Infineon XDPE1A2G7B"); |
| 180 | ++MODULE_LICENSE("GPL"); |
| 181 | ++MODULE_IMPORT_NS(PMBUS); |
| 182 | +-- |
| 183 | +2.34.1 |
| 184 | + |
0 commit comments