* [PATCH 1/4] dt-bindings: hwmon: Add MPS mp2993
[not found] <20240607090544.466833-1-noahwang.wang@outlook.com>
@ 2024-06-07 9:05 ` Noah Wang
2024-06-07 9:27 ` Krzysztof Kozlowski
2024-06-07 9:05 ` [PATCH 2/4] hwmon: add MP2993 driver Noah Wang
` (2 subsequent siblings)
3 siblings, 1 reply; 8+ messages in thread
From: Noah Wang @ 2024-06-07 9:05 UTC (permalink / raw)
To: robh, krzk+dt, linux, conor+dt, jdelvare
Cc: corbet, Delphine_CC_Chiu, peteryin.openbmc, javier.carrasco.cruz,
patrick.rudolph, bhelgaas, lukas, devicetree, linux-kernel,
linux-hwmon, linux-doc, linux-i2c, Noah Wang
Add support for MPS mp2993 controller
Signed-off-by: Noah Wang <noahwang.wang@outlook.com>
---
Documentation/devicetree/bindings/trivial-devices.yaml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Documentation/devicetree/bindings/trivial-devices.yaml b/Documentation/devicetree/bindings/trivial-devices.yaml
index 0a419453d183..01cc431eb59e 100644
--- a/Documentation/devicetree/bindings/trivial-devices.yaml
+++ b/Documentation/devicetree/bindings/trivial-devices.yaml
@@ -292,6 +292,8 @@ properties:
- mps,mp2973
# Monolithic Power Systems Inc. multi-phase controller mp2975
- mps,mp2975
+ # Monolithic Power Systems Inc. multi-phase controller mp2993
+ - mps,mp2993
# Monolithic Power Systems Inc. multi-phase hot-swap controller mp5990
- mps,mp5990
# Monolithic Power Systems Inc. synchronous step-down converter mpq8785
--
2.25.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 2/4] hwmon: add MP2993 driver
[not found] <20240607090544.466833-1-noahwang.wang@outlook.com>
2024-06-07 9:05 ` [PATCH 1/4] dt-bindings: hwmon: Add MPS mp2993 Noah Wang
@ 2024-06-07 9:05 ` Noah Wang
2024-06-10 16:21 ` Guenter Roeck
2024-06-07 9:05 ` [PATCH 3/4] dt-bindings: hwmon: Add MPS mp9941 Noah Wang
2024-06-07 9:05 ` [PATCH 4/4] hwmon: add MP9941 driver Noah Wang
3 siblings, 1 reply; 8+ messages in thread
From: Noah Wang @ 2024-06-07 9:05 UTC (permalink / raw)
To: robh, krzk+dt, linux, conor+dt, jdelvare
Cc: corbet, Delphine_CC_Chiu, peteryin.openbmc, javier.carrasco.cruz,
patrick.rudolph, bhelgaas, lukas, devicetree, linux-kernel,
linux-hwmon, linux-doc, linux-i2c, Noah Wang
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=y, Size: 12700 bytes --]
Add support for MPS VR controller mp2993. This driver exposes
telemetry and limit value readings and writtings.
Signed-off-by: Noah Wang <noahwang.wang@outlook.com>
---
Documentation/hwmon/index.rst | 1 +
Documentation/hwmon/mp2993.rst | 150 ++++++++++++++++++
MAINTAINERS | 7 +
drivers/hwmon/pmbus/Kconfig | 9 ++
drivers/hwmon/pmbus/Makefile | 1 +
drivers/hwmon/pmbus/mp2993.c | 269 +++++++++++++++++++++++++++++++++
6 files changed, 437 insertions(+)
create mode 100644 Documentation/hwmon/mp2993.rst
create mode 100644 drivers/hwmon/pmbus/mp2993.c
diff --git a/Documentation/hwmon/index.rst b/Documentation/hwmon/index.rst
index 03d313af469a..9d9d55b889f2 100644
--- a/Documentation/hwmon/index.rst
+++ b/Documentation/hwmon/index.rst
@@ -166,6 +166,7 @@ Hardware Monitoring Kernel Drivers
mp2856
mp2888
mp2975
+ mp2993
mp5023
mp5990
mpq8785
diff --git a/Documentation/hwmon/mp2993.rst b/Documentation/hwmon/mp2993.rst
new file mode 100644
index 000000000000..a14bb30969f9
--- /dev/null
+++ b/Documentation/hwmon/mp2993.rst
@@ -0,0 +1,150 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Kernel driver mp2993
+====================
+
+Supported chips:
+
+ * MPS mp2993
+
+ Prefix: 'mp2993'
+
+ * Datasheet
+ https://scnbwymvp-my.sharepoint.com/:f:/g/personal/admin_scnbwy_com/Eth4kX1_J1hMsaASHiOYL4QBHU5a75r-tRfLKbHnJFdKLQ?e=vxj3DF
+
+Author:
+
+ Noah Wang <noahwang.wang@outlook.com>
+
+Description
+-----------
+
+This driver implements support for Monolithic Power Systems, Inc. (MPS)
+MP2993 Dual Loop Digital Multi-phase Controller.
+
+Device compliant with:
+
+- PMBus rev 1.3 interface.
+
+The driver exports the following attributes via the 'sysfs' files
+for input voltage:
+
+**in1_input**
+
+**in1_label**
+
+**in1_crit**
+
+**in1_crit_alarm**
+
+**in1_lcrit**
+
+**in1_lcrit_alarm**
+
+**in1_max**
+
+**in1_max_alarm**
+
+**in1_min**
+
+**in1_min_alarm**
+
+The driver provides the following attributes for output voltage:
+
+**in2_input**
+
+**in2_label**
+
+**in2_crit**
+
+**in2_crit_alarm**
+
+**in2_lcrit**
+
+**in2_lcrit_alarm**
+
+**in3_input**
+
+**in3_label**
+
+**in3_crit**
+
+**in3_crit_alarm**
+
+**in3_lcrit**
+
+**in3_lcrit_alarm**
+
+The driver provides the following attributes for input current:
+
+**curr1_input**
+
+**curr1_label**
+
+**curr1_max**
+
+**curr1_max_alarm**
+
+The driver provides the following attributes for output current:
+
+**curr2_input**
+
+**curr2_label**
+
+**curr2_crit**
+
+**curr2_crit_alarm**
+
+**curr2_max**
+
+**curr2_max_alarm**
+
+**curr3_input**
+
+**curr3_label**
+
+**curr3_crit**
+
+**curr3_crit_alarm**
+
+**curr3_max**
+
+**curr3_max_alarm**
+
+The driver provides the following attributes for input power:
+
+**power1_input**
+
+**power1_label**
+
+The driver provides the following attributes for output power:
+
+**power2_input**
+
+**power2_label**
+
+**power3_input**
+
+**power3_label**
+
+The driver provides the following attributes for temperature:
+
+**temp1_input**
+
+**temp1_crit**
+
+**temp1_crit_alarm**
+
+**temp1_max**
+
+**temp1_max_alarm**
+
+**temp2_input**
+
+**temp2_crit**
+
+**temp2_crit_alarm**
+
+**temp2_max**
+
+**temp2_max_alarm**
diff --git a/MAINTAINERS b/MAINTAINERS
index 8754ac2c259d..f47f3e13b004 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -15258,6 +15258,13 @@ S: Maintained
F: Documentation/devicetree/bindings/leds/backlight/mps,mp3309c.yaml
F: drivers/video/backlight/mp3309c.c
++MPS MP2993 DRIVER
++M: Noah Wang <noahwang.wang@outlook.com>
++L: linux-hwmon@vger.kernel.org
++S: Maintained
++F: Documentation/hwmon/mp2993.rst
++F: drivers/hwmon/pmbus/mp2993.c
+
MR800 AVERMEDIA USB FM RADIO DRIVER
M: Alexey Klimov <klimov.linux@gmail.com>
L: linux-media@vger.kernel.org
diff --git a/drivers/hwmon/pmbus/Kconfig b/drivers/hwmon/pmbus/Kconfig
index 08e82c457356..d875d31ce84c 100644
--- a/drivers/hwmon/pmbus/Kconfig
+++ b/drivers/hwmon/pmbus/Kconfig
@@ -346,6 +346,15 @@ config SENSORS_MP2975
This driver can also be built as a module. If so, the module will
be called mp2975.
+config SENSORS_MP2993
+ tristate "MPS MP2993"
+ help
+ If you say yes here you get hardware monitoring support for MPS
+ MP2993 Dual Loop Digital Multi-Phase Controller.
+
+ This driver can also be built as a module. If so, the module will
+ be called mp2993.
+
config SENSORS_MP2975_REGULATOR
depends on SENSORS_MP2975 && REGULATOR
bool "Regulator support for MPS MP2975"
diff --git a/drivers/hwmon/pmbus/Makefile b/drivers/hwmon/pmbus/Makefile
index 2279b3327bbf..312d3f0c0540 100644
--- a/drivers/hwmon/pmbus/Makefile
+++ b/drivers/hwmon/pmbus/Makefile
@@ -37,6 +37,7 @@ obj-$(CONFIG_SENSORS_MAX8688) += max8688.o
obj-$(CONFIG_SENSORS_MP2856) += mp2856.o
obj-$(CONFIG_SENSORS_MP2888) += mp2888.o
obj-$(CONFIG_SENSORS_MP2975) += mp2975.o
+obj-$(CONFIG_SENSORS_MP2993) += mp2993.o
obj-$(CONFIG_SENSORS_MP5023) += mp5023.o
obj-$(CONFIG_SENSORS_MP5990) += mp5990.o
obj-$(CONFIG_SENSORS_MPQ7932) += mpq7932.o
diff --git a/drivers/hwmon/pmbus/mp2993.c b/drivers/hwmon/pmbus/mp2993.c
new file mode 100644
index 000000000000..43432b8d4faf
--- /dev/null
+++ b/drivers/hwmon/pmbus/mp2993.c
@@ -0,0 +1,269 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Hardware monitoring driver for MPS Multi-phase Digital VR Controllers(MP2993)
+ */
+
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include "pmbus.h"
+
+#define MP2993_VOUT_OVUV_UINT 125
+#define MP2993_VOUT_OVUV_DIV 64
+#define MP2993_VIN_LIMIT_UINT 1
+#define MP2993_VIN_LIMIT_DIV 8
+#define MP2993_READ_VIN_UINT 1
+#define MP2993_READ_VIN_DIV 32
+
+#define MP2993_PAGE_NUM 2
+
+#define MP2993_RAIL1_FUNC (PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT | \
+ PMBUS_HAVE_IOUT | PMBUS_HAVE_POUT | \
+ PMBUS_HAVE_TEMP | PMBUS_HAVE_PIN | \
+ PMBUS_HAVE_IIN | \
+ PMBUS_HAVE_STATUS_VOUT | \
+ PMBUS_HAVE_STATUS_IOUT | \
+ PMBUS_HAVE_STATUS_TEMP | \
+ PMBUS_HAVE_STATUS_INPUT)
+
+#define MP2993_RAIL2_FUNC (PMBUS_HAVE_VOUT | PMBUS_HAVE_IOUT | \
+ PMBUS_HAVE_POUT | PMBUS_HAVE_TEMP | \
+ PMBUS_HAVE_STATUS_VOUT | \
+ PMBUS_HAVE_STATUS_IOUT | \
+ PMBUS_HAVE_STATUS_TEMP | \
+ PMBUS_HAVE_STATUS_INPUT)
+
+/* Converts a linear11 data exponent to a specified value */
+static u16 mp2993_linear11_exponent_transfer(u16 word, u16 expect_exponent)
+{
+ s16 exponent, mantissa, target_exponent;
+
+ exponent = ((s16)word) >> 11;
+ mantissa = ((s16)((word & 0x7ff) << 5)) >> 5;
+ target_exponent = (s16)((expect_exponent & 0x1f) << 11) >> 11;
+
+ if (exponent > target_exponent)
+ mantissa = mantissa << (exponent - target_exponent);
+ else
+ mantissa = mantissa >> (target_exponent - exponent);
+
+ return (mantissa & 0x7ff) | ((expect_exponent << 11) & 0xf800);
+}
+
+static int
+mp2993_set_vout_format(struct i2c_client *client, int page, int format)
+{
+ int ret;
+
+ ret = i2c_smbus_write_byte_data(client, PMBUS_PAGE, page);
+ if (ret < 0)
+ return ret;
+
+ ret = i2c_smbus_write_byte_data(client, PMBUS_VOUT_MODE, format);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static int mp2993_identify(struct i2c_client *client, struct pmbus_driver_info *info)
+{
+ int ret;
+
+ /* Set vout to direct format for rail1. */
+ ret = mp2993_set_vout_format(client, 0, PB_VOUT_MODE_DIRECT);
+ if (ret < 0)
+ return ret;
+
+ /* Set vout to direct format for rail2. */
+ ret = mp2993_set_vout_format(client, 1, PB_VOUT_MODE_DIRECT);
+ if (ret < 0)
+ return ret;
+
+ return ret;
+}
+
+static int mp2993_read_word_data(struct i2c_client *client, int page, int phase,
+ int reg)
+{
+ int ret;
+
+ switch (reg) {
+ case PMBUS_VOUT_OV_FAULT_LIMIT:
+ case PMBUS_VOUT_UV_FAULT_LIMIT:
+ ret = pmbus_read_word_data(client, page, phase, reg);
+ if (ret < 0)
+ return ret;
+
+ ret = DIV_ROUND_CLOSEST(ret * MP2993_VOUT_OVUV_UINT, MP2993_VOUT_OVUV_DIV);
+ break;
+ case PMBUS_OT_FAULT_LIMIT:
+ case PMBUS_OT_WARN_LIMIT:
+ /*
+ * The MP2993 ot fault limit value and ot warn limit value
+ * per rail are always the same, so only PMBUS_OT_FAULT_LIMIT
+ * and PMBUS_OT_WARN_LIMIT register in page 0 are defined to
+ * indicates the limit value.
+ */
+ ret = pmbus_read_word_data(client, 0, phase, reg);
+ break;
+ case PMBUS_READ_VIN:
+ /* The MP2993 vin scale is (1/32V)/Lsb */
+ ret = pmbus_read_word_data(client, page, phase, reg);
+ if (ret < 0)
+ return ret;
+
+ ret = DIV_ROUND_CLOSEST((ret & GENMASK(9, 0)) * MP2993_READ_VIN_UINT,
+ MP2993_READ_VIN_DIV);
+ break;
+ case PMBUS_VIN_OV_FAULT_LIMIT:
+ case PMBUS_VIN_OV_WARN_LIMIT:
+ case PMBUS_VIN_UV_WARN_LIMIT:
+ case PMBUS_VIN_UV_FAULT_LIMIT:
+ /* The MP2993 vin limit scale is (1/8V)/Lsb */
+ ret = pmbus_read_word_data(client, page, phase, reg);
+ if (ret < 0)
+ return ret;
+
+ ret = DIV_ROUND_CLOSEST((ret & GENMASK(7, 0)) * MP2993_VIN_LIMIT_UINT,
+ MP2993_VIN_LIMIT_DIV);
+ break;
+ case PMBUS_READ_IOUT:
+ case PMBUS_READ_IIN:
+ case PMBUS_IIN_OC_WARN_LIMIT:
+ case PMBUS_IOUT_OC_FAULT_LIMIT:
+ case PMBUS_IOUT_OC_WARN_LIMIT:
+ case PMBUS_READ_VOUT:
+ case PMBUS_READ_PIN:
+ case PMBUS_READ_POUT:
+ case PMBUS_READ_TEMPERATURE_1:
+ ret = -ENODATA;
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+static int mp2993_write_word_data(struct i2c_client *client, int page, int reg,
+ u16 word)
+{
+ int ret;
+
+ switch (reg) {
+ case PMBUS_VOUT_OV_FAULT_LIMIT:
+ case PMBUS_VOUT_UV_FAULT_LIMIT:
+ ret = DIV_ROUND_CLOSEST(word * MP2993_VOUT_OVUV_DIV, MP2993_VOUT_OVUV_UINT);
+ ret = pmbus_write_word_data(client, 0, reg, ret);
+ break;
+ case PMBUS_OT_FAULT_LIMIT:
+ case PMBUS_OT_WARN_LIMIT:
+ /*
+ * The MP2993 ot fault limit value and ot warn limit value
+ * per rail are always the same, so only PMBUS_OT_FAULT_LIMIT
+ * and PMBUS_OT_WARN_LIMIT register in page 0 are defined to
+ * config the ot limit value.
+ */
+ ret = pmbus_write_word_data(client, 0, reg, word);
+ break;
+ case PMBUS_VIN_OV_FAULT_LIMIT:
+ case PMBUS_VIN_OV_WARN_LIMIT:
+ case PMBUS_VIN_UV_WARN_LIMIT:
+ case PMBUS_VIN_UV_FAULT_LIMIT:
+ /* The MP2993 vin limit scale is (1/8V)/Lsb */
+ ret = pmbus_write_word_data(client, 0, reg,
+ DIV_ROUND_CLOSEST(word * MP2993_VIN_LIMIT_DIV,
+ MP2993_VIN_LIMIT_UINT));
+ break;
+ case PMBUS_IIN_OC_WARN_LIMIT:
+ /*
+ * The PMBUS_IIN_OC_WARN_LIMIT of MP2993 is linear11 format,
+ * and the exponent is a constant value(5'b00000), so the
+ * exponent of word parameter should be converted to 5'b00000.
+ */
+ ret = pmbus_write_word_data(client, page, reg,
+ mp2993_linear11_exponent_transfer(word, 0x00));
+ break;
+ //
+ case PMBUS_IOUT_OC_FAULT_LIMIT:
+ case PMBUS_IOUT_OC_WARN_LIMIT:
+ /*
+ * The PMBUS_IOUT_OC_FAULT_LIMIT and PMBUS_IOUT_OC_WARN_LIMIT
+ * of MP2993 can be regarded as linear11 format, and the
+ * exponent is a 5'b00001 or 5'b00000. To ensure a larger
+ * range of limit value, so the exponent of word parameter
+ * should be converted to 5'b00001.
+ */
+ ret = pmbus_write_word_data(client, page, reg,
+ mp2993_linear11_exponent_transfer(word, 0x01));
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+static struct pmbus_driver_info mp2993_info = {
+ .pages = MP2993_PAGE_NUM,
+ .format[PSC_VOLTAGE_IN] = direct,
+ .format[PSC_CURRENT_IN] = linear,
+ .format[PSC_CURRENT_OUT] = linear,
+ .format[PSC_TEMPERATURE] = direct,
+ .format[PSC_POWER] = linear,
+ .format[PSC_VOLTAGE_OUT] = direct,
+
+ .m[PSC_VOLTAGE_OUT] = 1,
+ .R[PSC_VOLTAGE_OUT] = 3,
+ .b[PSC_VOLTAGE_OUT] = 0,
+
+ .m[PSC_VOLTAGE_IN] = 1,
+ .R[PSC_VOLTAGE_IN] = 0,
+ .b[PSC_VOLTAGE_IN] = 0,
+
+ .m[PSC_TEMPERATURE] = 1,
+ .R[PSC_TEMPERATURE] = 0,
+ .b[PSC_TEMPERATURE] = 0,
+
+ .func[0] = MP2993_RAIL1_FUNC,
+ .func[1] = MP2993_RAIL2_FUNC,
+ .read_word_data = mp2993_read_word_data,
+ .write_word_data = mp2993_write_word_data,
+ .identify = mp2993_identify,
+};
+
+static int mp2993_probe(struct i2c_client *client)
+{
+ return pmbus_do_probe(client, &mp2993_info);
+}
+
+static const struct i2c_device_id mp2993_id[] = {
+ {"mp2993", 0},
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, mp2993_id);
+
+static const struct of_device_id __maybe_unused mp2993_of_match[] = {
+ {.compatible = "mps,mp2993"},
+ {}
+};
+MODULE_DEVICE_TABLE(of, mp2993_of_match);
+
+static struct i2c_driver mp2993_driver = {
+ .driver = {
+ .name = "mp2993",
+ .of_match_table = mp2993_of_match,
+ },
+ .probe = mp2993_probe,
+ .id_table = mp2993_id,
+};
+
+module_i2c_driver(mp2993_driver);
+
+MODULE_AUTHOR("Noah Wang <noahwang.wang@outlook.com>");
+MODULE_DESCRIPTION("PMBus driver for MPS MP2993");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS(PMBUS);
--
2.25.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 3/4] dt-bindings: hwmon: Add MPS mp9941
[not found] <20240607090544.466833-1-noahwang.wang@outlook.com>
2024-06-07 9:05 ` [PATCH 1/4] dt-bindings: hwmon: Add MPS mp2993 Noah Wang
2024-06-07 9:05 ` [PATCH 2/4] hwmon: add MP2993 driver Noah Wang
@ 2024-06-07 9:05 ` Noah Wang
2024-06-07 9:28 ` Krzysztof Kozlowski
2024-06-07 9:05 ` [PATCH 4/4] hwmon: add MP9941 driver Noah Wang
3 siblings, 1 reply; 8+ messages in thread
From: Noah Wang @ 2024-06-07 9:05 UTC (permalink / raw)
To: robh, krzk+dt, linux, conor+dt, jdelvare
Cc: corbet, Delphine_CC_Chiu, peteryin.openbmc, javier.carrasco.cruz,
patrick.rudolph, bhelgaas, lukas, devicetree, linux-kernel,
linux-hwmon, linux-doc, linux-i2c, Noah Wang
Add support for MPS mp9941 controller
Signed-off-by: Noah Wang <noahwang.wang@outlook.com>
---
Documentation/devicetree/bindings/trivial-devices.yaml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Documentation/devicetree/bindings/trivial-devices.yaml b/Documentation/devicetree/bindings/trivial-devices.yaml
index 01cc431eb59e..3b0355fcb9e5 100644
--- a/Documentation/devicetree/bindings/trivial-devices.yaml
+++ b/Documentation/devicetree/bindings/trivial-devices.yaml
@@ -296,6 +296,8 @@ properties:
- mps,mp2993
# Monolithic Power Systems Inc. multi-phase hot-swap controller mp5990
- mps,mp5990
+ # Monolithic Power Systems Inc. digital step-down converter mp9941
+ - mps,mp9941
# Monolithic Power Systems Inc. synchronous step-down converter mpq8785
- mps,mpq8785
# Temperature sensor with integrated fan control
--
2.25.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 4/4] hwmon: add MP9941 driver
[not found] <20240607090544.466833-1-noahwang.wang@outlook.com>
` (2 preceding siblings ...)
2024-06-07 9:05 ` [PATCH 3/4] dt-bindings: hwmon: Add MPS mp9941 Noah Wang
@ 2024-06-07 9:05 ` Noah Wang
2024-06-10 16:18 ` Guenter Roeck
3 siblings, 1 reply; 8+ messages in thread
From: Noah Wang @ 2024-06-07 9:05 UTC (permalink / raw)
To: robh, krzk+dt, linux, conor+dt, jdelvare
Cc: corbet, Delphine_CC_Chiu, peteryin.openbmc, javier.carrasco.cruz,
patrick.rudolph, bhelgaas, lukas, devicetree, linux-kernel,
linux-hwmon, linux-doc, linux-i2c, Noah Wang
Add support for MPS step-down converter mp9941. This driver exposes
telemetry and limit value readings and writtings.
Signed-off-by: Noah Wang <noahwang.wang@outlook.com>
---
Documentation/hwmon/index.rst | 1 +
Documentation/hwmon/mp9941.rst | 92 +++++++++
MAINTAINERS | 7 +
drivers/hwmon/pmbus/Kconfig | 9 +
drivers/hwmon/pmbus/Makefile | 1 +
drivers/hwmon/pmbus/mp9941.c | 328 +++++++++++++++++++++++++++++++++
6 files changed, 438 insertions(+)
create mode 100644 Documentation/hwmon/mp9941.rst
create mode 100644 drivers/hwmon/pmbus/mp9941.c
diff --git a/Documentation/hwmon/index.rst b/Documentation/hwmon/index.rst
index 9d9d55b889f2..9ff8149d9a9d 100644
--- a/Documentation/hwmon/index.rst
+++ b/Documentation/hwmon/index.rst
@@ -169,6 +169,7 @@ Hardware Monitoring Kernel Drivers
mp2993
mp5023
mp5990
+ mp9941
mpq8785
nct6683
nct6775
diff --git a/Documentation/hwmon/mp9941.rst b/Documentation/hwmon/mp9941.rst
new file mode 100644
index 000000000000..1274fa20e256
--- /dev/null
+++ b/Documentation/hwmon/mp9941.rst
@@ -0,0 +1,92 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Kernel driver mp9941
+====================
+
+Supported chips:
+
+ * MPS mp9941
+
+ Prefix: 'mp9941'
+
+ * Datasheet
+ https://scnbwymvp-my.sharepoint.com/:f:/g/personal/admin_scnbwy_com/Eth4kX1_J1hMsaASHiOYL4QBHU5a75r-tRfLKbHnJFdKLQ?e=vxj3DF
+
+Author:
+
+ Noah Wang <noahwang.wang@outlook.com>
+
+Description
+-----------
+
+This driver implements support for Monolithic Power Systems, Inc. (MPS)
+MP9941 digital step-down converter.
+
+Device compliant with:
+
+- PMBus rev 1.3 interface.
+
+The driver exports the following attributes via the 'sysfs' files
+for input voltage:
+
+**in1_input**
+
+**in1_label**
+
+**in1_crit**
+
+**in1_crit_alarm**
+
+The driver provides the following attributes for output voltage:
+
+**in2_input**
+
+**in2_label**
+
+**in2_lcrit**
+
+**in2_lcrit_alarm**
+
+**in2_rated_max**
+
+**in2_rated_min**
+
+The driver provides the following attributes for input current:
+
+**curr1_input**
+
+**curr1_label**
+
+**curr1_max**
+
+**curr1_max_alarm**
+
+The driver provides the following attributes for output current:
+
+**curr2_input**
+
+**curr2_label**
+
+The driver provides the following attributes for input power:
+
+**power1_input**
+
+**power1_label**
+
+The driver provides the following attributes for output power:
+
+**power2_input**
+
+**power2_label**
+
+The driver provides the following attributes for temperature:
+
+**temp1_input**
+
+**temp1_crit**
+
+**temp1_crit_alarm**
+
+**temp1_max**
+
+**temp1_max_alarm**
diff --git a/MAINTAINERS b/MAINTAINERS
index f47f3e13b004..d4600533a3ee 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -15265,6 +15265,13 @@ F: drivers/video/backlight/mp3309c.c
+F: Documentation/hwmon/mp2993.rst
+F: drivers/hwmon/pmbus/mp2993.c
++MPS MP9941 DRIVER
++M: Noah Wang <noahwang.wang@outlook.com>
++L: linux-hwmon@vger.kernel.org
++S: Maintained
++F: Documentation/hwmon/mp9941.rst
++F: drivers/hwmon/pmbus/mp9941.c
+
MR800 AVERMEDIA USB FM RADIO DRIVER
M: Alexey Klimov <klimov.linux@gmail.com>
L: linux-media@vger.kernel.org
diff --git a/drivers/hwmon/pmbus/Kconfig b/drivers/hwmon/pmbus/Kconfig
index d875d31ce84c..7d32cfc19820 100644
--- a/drivers/hwmon/pmbus/Kconfig
+++ b/drivers/hwmon/pmbus/Kconfig
@@ -380,6 +380,15 @@ config SENSORS_MP5990
This driver can also be built as a module. If so, the module will
be called mp5990.
+config SENSORS_MP9941
+ tristate "MPS MP9941"
+ help
+ If you say yes here you get hardware monitoring support for MPS
+ MP9941.
+
+ This driver can also be built as a module. If so, the module will
+ be called mp9941.
+
config SENSORS_MPQ7932_REGULATOR
bool "Regulator support for MPQ7932"
depends on SENSORS_MPQ7932 && REGULATOR
diff --git a/drivers/hwmon/pmbus/Makefile b/drivers/hwmon/pmbus/Makefile
index 312d3f0c0540..6c7177fde355 100644
--- a/drivers/hwmon/pmbus/Makefile
+++ b/drivers/hwmon/pmbus/Makefile
@@ -40,6 +40,7 @@ obj-$(CONFIG_SENSORS_MP2975) += mp2975.o
obj-$(CONFIG_SENSORS_MP2993) += mp2993.o
obj-$(CONFIG_SENSORS_MP5023) += mp5023.o
obj-$(CONFIG_SENSORS_MP5990) += mp5990.o
+obj-$(CONFIG_SENSORS_MP9941) += mp9941.o
obj-$(CONFIG_SENSORS_MPQ7932) += mpq7932.o
obj-$(CONFIG_SENSORS_MPQ8785) += mpq8785.o
obj-$(CONFIG_SENSORS_PLI1209BC) += pli1209bc.o
diff --git a/drivers/hwmon/pmbus/mp9941.c b/drivers/hwmon/pmbus/mp9941.c
new file mode 100644
index 000000000000..d24e98671e16
--- /dev/null
+++ b/drivers/hwmon/pmbus/mp9941.c
@@ -0,0 +1,328 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Hardware monitoring driver for MPS Multi-phase Digital VR Controllers(MP9941)
+ */
+
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include "pmbus.h"
+
+/*
+ * Vender specific registers. The MFR_ICC_MAX(0x02) is used to
+ * config the iin scale. The MFR_RESO_SET(0xC7) is used to
+ * config the vout format. The MFR_VR_MULTI_CONFIG_R1(0x0D) is
+ * used to identify the vout vid step.
+ */
+#define MFR_ICC_MAX 0x02
+#define MFR_RESO_SET 0xC7
+#define MFR_VR_MULTI_CONFIG_R1 0x0D
+
+#define MP9941_VIN_LIMIT_UINT 1
+#define MP9941_VIN_LIMIT_DIV 8
+#define MP9941_READ_VIN_UINT 1
+#define MP9941_READ_VIN_DIV 32
+
+#define MP9941_PAGE_NUM 1
+
+#define MP9941_RAIL1_FUNC (PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT | \
+ PMBUS_HAVE_IOUT | PMBUS_HAVE_POUT | \
+ PMBUS_HAVE_TEMP | PMBUS_HAVE_PIN | \
+ PMBUS_HAVE_IIN | \
+ PMBUS_HAVE_STATUS_VOUT | \
+ PMBUS_HAVE_STATUS_IOUT | \
+ PMBUS_HAVE_STATUS_TEMP | \
+ PMBUS_HAVE_STATUS_INPUT)
+
+struct mp9941_data {
+ struct pmbus_driver_info info;
+ int vid_resolution;
+};
+
+#define to_mp9941_data(x) container_of(x, struct mp9941_data, info)
+
+static int mp2993_set_vout_format(struct i2c_client *client)
+{
+ int ret;
+
+ ret = i2c_smbus_write_byte_data(client, PMBUS_PAGE, 0);
+ if (ret < 0)
+ return ret;
+
+ ret = i2c_smbus_read_word_data(client, MFR_RESO_SET);
+ if (ret < 0)
+ return ret;
+
+ /*
+ * page = 0, MFR_RESO_SET[7:6] defines the vout format
+ * 2'b11 set the vout format as direct
+ */
+ ret = (ret & ~GENMASK(7, 6)) | FIELD_PREP(GENMASK(7, 6), 3);
+
+ ret = i2c_smbus_write_word_data(client, MFR_RESO_SET, ret);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static int
+mp2993_identify_vid_resolution(struct i2c_client *client, struct pmbus_driver_info *info)
+{
+ struct mp9941_data *data = to_mp9941_data(info);
+ int ret;
+
+ /*
+ * page = 2, MFR_VR_MULTI_CONFIG_R1[4:4] defines rail1 vid step value
+ * 1'b0 represents the vid step value is 10mV
+ * 1'b1 represents the vid step value is 5mV
+ */
+ ret = i2c_smbus_write_byte_data(client, PMBUS_PAGE, 2);
+ if (ret < 0)
+ return ret;
+
+ ret = i2c_smbus_read_word_data(client, MFR_VR_MULTI_CONFIG_R1);
+ if (ret < 0)
+ return ret;
+
+ if (FIELD_GET(GENMASK(4, 4), ret))
+ data->vid_resolution = 5;
+ else
+ data->vid_resolution = 10;
+
+ return 0;
+}
+
+static int mp9941_identify_iin_scale(struct i2c_client *client)
+{
+ int ret;
+
+ ret = i2c_smbus_write_byte_data(client, PMBUS_PAGE, 0);
+ if (ret < 0)
+ return ret;
+
+ ret = i2c_smbus_read_word_data(client, MFR_RESO_SET);
+ if (ret < 0)
+ return ret;
+
+ ret = (ret & ~GENMASK(3, 2)) | FIELD_PREP(GENMASK(3, 2), 0);
+
+ ret = i2c_smbus_write_word_data(client, MFR_RESO_SET, ret);
+ if (ret < 0)
+ return ret;
+
+ /*
+ * page = 2, MFR_ICC_MAX[15:13] defines the iin scale
+ * 3'b000 set the iout scale as 0.5A/Lsb
+ */
+ ret = i2c_smbus_write_byte_data(client, PMBUS_PAGE, 2);
+ if (ret < 0)
+ return ret;
+
+ ret = i2c_smbus_read_word_data(client, MFR_ICC_MAX);
+ if (ret < 0)
+ return ret;
+
+ ret = (ret & ~GENMASK(15, 13)) | FIELD_PREP(GENMASK(15, 13), 0);
+ ret = i2c_smbus_write_word_data(client, MFR_ICC_MAX, ret);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static int mp9941_identify(struct i2c_client *client, struct pmbus_driver_info *info)
+{
+ int ret;
+
+ ret = mp9941_identify_iin_scale(client);
+ if (ret < 0)
+ return ret;
+
+ ret = mp2993_identify_vid_resolution(client, info);
+ if (ret < 0)
+ return ret;
+
+ ret = mp2993_set_vout_format(client);
+ if (ret < 0)
+ return ret;
+
+ return ret;
+}
+
+static int mp9941_read_word_data(struct i2c_client *client, int page, int phase,
+ int reg)
+{
+ const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
+ struct mp9941_data *data = to_mp9941_data(info);
+ int ret;
+
+ switch (reg) {
+ case PMBUS_READ_VIN:
+ /* The MP9941 vin scale is (1/32V)/Lsb */
+ ret = pmbus_read_word_data(client, page, phase, reg);
+ if (ret < 0)
+ return ret;
+
+ ret = DIV_ROUND_CLOSEST((ret & GENMASK(9, 0)) * MP9941_READ_VIN_UINT,
+ MP9941_READ_VIN_DIV);
+ break;
+ case PMBUS_READ_IIN:
+ ret = pmbus_read_word_data(client, page, phase, reg);
+ if (ret < 0)
+ return ret;
+
+ ret = ret & GENMASK(10, 0);
+ break;
+ case PMBUS_VIN_OV_FAULT_LIMIT:
+ /* The MP9941 vin ov limit scale is (1/8V)/Lsb */
+ ret = pmbus_read_word_data(client, page, phase, reg);
+ if (ret < 0)
+ return ret;
+
+ ret = DIV_ROUND_CLOSEST((ret & GENMASK(7, 0)) * MP9941_VIN_LIMIT_UINT,
+ MP9941_VIN_LIMIT_DIV);
+ break;
+ case PMBUS_IIN_OC_WARN_LIMIT:
+ ret = pmbus_read_word_data(client, page, phase, reg);
+ if (ret < 0)
+ return ret;
+
+ ret = ret & GENMASK(7, 0);
+ break;
+ case PMBUS_VOUT_UV_FAULT_LIMIT:
+ case PMBUS_MFR_VOUT_MIN:
+ case PMBUS_MFR_VOUT_MAX:
+ /*
+ * The vout scale is set to 1mV/Lsb(using r/m/b scale).
+ * But the vout uv limit and vout max/min scale is 1VID/Lsb,
+ * so the vout uv limit and vout max/min value should be
+ * multiplied by vid resolution.
+ */
+ ret = pmbus_read_word_data(client, page, phase, reg);
+ if (ret < 0)
+ return ret;
+
+ ret = ret * data->vid_resolution;
+ break;
+ case PMBUS_READ_IOUT:
+ case PMBUS_READ_POUT:
+ case PMBUS_READ_TEMPERATURE_1:
+ case PMBUS_READ_VOUT:
+ case PMBUS_READ_PIN:
+ case PMBUS_OT_FAULT_LIMIT:
+ case PMBUS_OT_WARN_LIMIT:
+ ret = -ENODATA;
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+static int mp9941_write_word_data(struct i2c_client *client, int page, int reg,
+ u16 word)
+{
+ const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
+ struct mp9941_data *data = to_mp9941_data(info);
+ int ret;
+
+ switch (reg) {
+ case PMBUS_VIN_OV_FAULT_LIMIT:
+ /* The MP9941 vin ov limit scale is (1/8V)/Lsb */
+ ret = pmbus_write_word_data(client, page, reg,
+ DIV_ROUND_CLOSEST(word * MP9941_VIN_LIMIT_DIV,
+ MP9941_VIN_LIMIT_UINT));
+ break;
+ case PMBUS_VOUT_UV_FAULT_LIMIT:
+ case PMBUS_MFR_VOUT_MIN:
+ case PMBUS_MFR_VOUT_MAX:
+ ret = pmbus_write_word_data(client, page, reg,
+ DIV_ROUND_CLOSEST(word, data->vid_resolution));
+ break;
+ case PMBUS_IIN_OC_WARN_LIMIT:
+ case PMBUS_OT_FAULT_LIMIT:
+ case PMBUS_OT_WARN_LIMIT:
+ ret = -ENODATA;
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+static const struct pmbus_driver_info mp9941_info = {
+ .pages = MP9941_PAGE_NUM,
+ .format[PSC_VOLTAGE_IN] = direct,
+ .format[PSC_CURRENT_IN] = direct,
+ .format[PSC_CURRENT_OUT] = linear,
+ .format[PSC_POWER] = linear,
+ .format[PSC_TEMPERATURE] = direct,
+ .format[PSC_VOLTAGE_OUT] = direct,
+
+ .m[PSC_TEMPERATURE] = 1,
+ .R[PSC_TEMPERATURE] = 0,
+ .b[PSC_TEMPERATURE] = 0,
+
+ .m[PSC_VOLTAGE_IN] = 1,
+ .R[PSC_VOLTAGE_IN] = 0,
+ .b[PSC_VOLTAGE_IN] = 0,
+
+ .m[PSC_CURRENT_IN] = 2,
+ .R[PSC_CURRENT_IN] = 0,
+ .b[PSC_CURRENT_IN] = 0,
+
+ .m[PSC_VOLTAGE_OUT] = 1,
+ .R[PSC_VOLTAGE_OUT] = 3,
+ .b[PSC_VOLTAGE_OUT] = 0,
+
+ .func[0] = MP9941_RAIL1_FUNC,
+ .read_word_data = mp9941_read_word_data,
+ .write_word_data = mp9941_write_word_data,
+ .identify = mp9941_identify,
+};
+
+static int mp9941_probe(struct i2c_client *client)
+{
+ struct mp9941_data *data;
+
+ data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ memcpy(&data->info, &mp9941_info, sizeof(mp9941_info));
+
+ return pmbus_do_probe(client, &data->info);
+}
+
+static const struct i2c_device_id mp9941_id[] = {
+ {"mp9941", 0},
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, mp9941_id);
+
+static const struct of_device_id __maybe_unused mp9941_of_match[] = {
+ {.compatible = "mps,mp9941"},
+ {}
+};
+MODULE_DEVICE_TABLE(of, mp9941_of_match);
+
+static struct i2c_driver mp9941_driver = {
+ .driver = {
+ .name = "mp9941",
+ .of_match_table = mp9941_of_match,
+ },
+ .probe = mp9941_probe,
+ .id_table = mp9941_id,
+};
+
+module_i2c_driver(mp9941_driver);
+
+MODULE_AUTHOR("Noah Wang <noahwang.wang@outlook.com>");
+MODULE_DESCRIPTION("PMBus driver for MPS MP9941");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS(PMBUS);
--
2.25.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH 1/4] dt-bindings: hwmon: Add MPS mp2993
2024-06-07 9:05 ` [PATCH 1/4] dt-bindings: hwmon: Add MPS mp2993 Noah Wang
@ 2024-06-07 9:27 ` Krzysztof Kozlowski
0 siblings, 0 replies; 8+ messages in thread
From: Krzysztof Kozlowski @ 2024-06-07 9:27 UTC (permalink / raw)
To: Noah Wang, robh, krzk+dt, linux, conor+dt, jdelvare
Cc: corbet, Delphine_CC_Chiu, peteryin.openbmc, javier.carrasco.cruz,
patrick.rudolph, bhelgaas, lukas, devicetree, linux-kernel,
linux-hwmon, linux-doc, linux-i2c
On 07/06/2024 11:05, Noah Wang wrote:
> Add support for MPS mp2993 controller
>
> Signed-off-by: Noah Wang <noahwang.wang@outlook.com>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
---
This is an automated instruction, just in case, because many review tags
are being ignored. If you know the process, you can skip it (please do
not feel offended by me posting it here - no bad intentions intended).
If you do not know the process, here is a short explanation:
Please add Acked-by/Reviewed-by/Tested-by tags when posting new
versions, under or above your Signed-off-by tag. Tag is "received", when
provided in a message replied to you on the mailing list. Tools like b4
can help here. However, there's no need to repost patches *only* to add
the tags. The upstream maintainer will do that for tags received on the
version they apply.
https://elixir.bootlin.com/linux/v6.5-rc3/source/Documentation/process/submitting-patches.rst#L577
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 3/4] dt-bindings: hwmon: Add MPS mp9941
2024-06-07 9:05 ` [PATCH 3/4] dt-bindings: hwmon: Add MPS mp9941 Noah Wang
@ 2024-06-07 9:28 ` Krzysztof Kozlowski
0 siblings, 0 replies; 8+ messages in thread
From: Krzysztof Kozlowski @ 2024-06-07 9:28 UTC (permalink / raw)
To: Noah Wang, robh, krzk+dt, linux, conor+dt, jdelvare
Cc: corbet, Delphine_CC_Chiu, peteryin.openbmc, javier.carrasco.cruz,
patrick.rudolph, bhelgaas, lukas, devicetree, linux-kernel,
linux-hwmon, linux-doc, linux-i2c
On 07/06/2024 11:05, Noah Wang wrote:
> Add support for MPS mp9941 controller
>
> Signed-off-by: Noah Wang <noahwang.wang@outlook.com>
> ---
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 4/4] hwmon: add MP9941 driver
2024-06-07 9:05 ` [PATCH 4/4] hwmon: add MP9941 driver Noah Wang
@ 2024-06-10 16:18 ` Guenter Roeck
0 siblings, 0 replies; 8+ messages in thread
From: Guenter Roeck @ 2024-06-10 16:18 UTC (permalink / raw)
To: Noah Wang, robh, krzk+dt, conor+dt, jdelvare
Cc: corbet, Delphine_CC_Chiu, peteryin.openbmc, javier.carrasco.cruz,
patrick.rudolph, bhelgaas, lukas, devicetree, linux-kernel,
linux-hwmon, linux-doc, linux-i2c
On 6/7/24 02:05, Noah Wang wrote:
> Add support for MPS step-down converter mp9941. This driver exposes
> telemetry and limit value readings and writtings.
>
> Signed-off-by: Noah Wang <noahwang.wang@outlook.com>
> ---
> Documentation/hwmon/index.rst | 1 +
> Documentation/hwmon/mp9941.rst | 92 +++++++++
> MAINTAINERS | 7 +
> drivers/hwmon/pmbus/Kconfig | 9 +
> drivers/hwmon/pmbus/Makefile | 1 +
> drivers/hwmon/pmbus/mp9941.c | 328 +++++++++++++++++++++++++++++++++
> 6 files changed, 438 insertions(+)
> create mode 100644 Documentation/hwmon/mp9941.rst
> create mode 100644 drivers/hwmon/pmbus/mp9941.c
>
> diff --git a/Documentation/hwmon/index.rst b/Documentation/hwmon/index.rst
> index 9d9d55b889f2..9ff8149d9a9d 100644
> --- a/Documentation/hwmon/index.rst
> +++ b/Documentation/hwmon/index.rst
> @@ -169,6 +169,7 @@ Hardware Monitoring Kernel Drivers
> mp2993
> mp5023
> mp5990
> + mp9941
> mpq8785
> nct6683
> nct6775
> diff --git a/Documentation/hwmon/mp9941.rst b/Documentation/hwmon/mp9941.rst
> new file mode 100644
> index 000000000000..1274fa20e256
> --- /dev/null
> +++ b/Documentation/hwmon/mp9941.rst
> @@ -0,0 +1,92 @@
> +.. SPDX-License-Identifier: GPL-2.0
> +
> +Kernel driver mp9941
> +====================
> +
> +Supported chips:
> +
> + * MPS mp9941
> +
> + Prefix: 'mp9941'
> +
> + * Datasheet
> + https://scnbwymvp-my.sharepoint.com/:f:/g/personal/admin_scnbwy_com/Eth4kX1_J1hMsaASHiOYL4QBHU5a75r-tRfLKbHnJFdKLQ?e=vxj3DF
> +
> +Author:
> +
> + Noah Wang <noahwang.wang@outlook.com>
> +
> +Description
> +-----------
> +
> +This driver implements support for Monolithic Power Systems, Inc. (MPS)
> +MP9941 digital step-down converter.
> +
> +Device compliant with:
> +
> +- PMBus rev 1.3 interface.
> +
> +The driver exports the following attributes via the 'sysfs' files
> +for input voltage:
> +
> +**in1_input**
> +
> +**in1_label**
> +
> +**in1_crit**
> +
> +**in1_crit_alarm**
> +
> +The driver provides the following attributes for output voltage:
> +
> +**in2_input**
> +
> +**in2_label**
> +
> +**in2_lcrit**
> +
> +**in2_lcrit_alarm**
> +
> +**in2_rated_max**
> +
> +**in2_rated_min**
> +
> +The driver provides the following attributes for input current:
> +
> +**curr1_input**
> +
> +**curr1_label**
> +
> +**curr1_max**
> +
> +**curr1_max_alarm**
> +
> +The driver provides the following attributes for output current:
> +
> +**curr2_input**
> +
> +**curr2_label**
> +
> +The driver provides the following attributes for input power:
> +
> +**power1_input**
> +
> +**power1_label**
> +
> +The driver provides the following attributes for output power:
> +
> +**power2_input**
> +
> +**power2_label**
> +
> +The driver provides the following attributes for temperature:
> +
> +**temp1_input**
> +
> +**temp1_crit**
> +
> +**temp1_crit_alarm**
> +
> +**temp1_max**
> +
> +**temp1_max_alarm**
> diff --git a/MAINTAINERS b/MAINTAINERS
> index f47f3e13b004..d4600533a3ee 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -15265,6 +15265,13 @@ F: drivers/video/backlight/mp3309c.c
> +F: Documentation/hwmon/mp2993.rst
> +F: drivers/hwmon/pmbus/mp2993.c
>
> ++MPS MP9941 DRIVER
> ++M: Noah Wang <noahwang.wang@outlook.com>
> ++L: linux-hwmon@vger.kernel.org
> ++S: Maintained
> ++F: Documentation/hwmon/mp9941.rst
> ++F: drivers/hwmon/pmbus/mp9941.c
> +
> MR800 AVERMEDIA USB FM RADIO DRIVER
> M: Alexey Klimov <klimov.linux@gmail.com>
> L: linux-media@vger.kernel.org
> diff --git a/drivers/hwmon/pmbus/Kconfig b/drivers/hwmon/pmbus/Kconfig
> index d875d31ce84c..7d32cfc19820 100644
> --- a/drivers/hwmon/pmbus/Kconfig
> +++ b/drivers/hwmon/pmbus/Kconfig
> @@ -380,6 +380,15 @@ config SENSORS_MP5990
> This driver can also be built as a module. If so, the module will
> be called mp5990.
>
> +config SENSORS_MP9941
> + tristate "MPS MP9941"
> + help
> + If you say yes here you get hardware monitoring support for MPS
> + MP9941.
> +
> + This driver can also be built as a module. If so, the module will
> + be called mp9941.
> +
> config SENSORS_MPQ7932_REGULATOR
> bool "Regulator support for MPQ7932"
> depends on SENSORS_MPQ7932 && REGULATOR
> diff --git a/drivers/hwmon/pmbus/Makefile b/drivers/hwmon/pmbus/Makefile
> index 312d3f0c0540..6c7177fde355 100644
> --- a/drivers/hwmon/pmbus/Makefile
> +++ b/drivers/hwmon/pmbus/Makefile
> @@ -40,6 +40,7 @@ obj-$(CONFIG_SENSORS_MP2975) += mp2975.o
> obj-$(CONFIG_SENSORS_MP2993) += mp2993.o
> obj-$(CONFIG_SENSORS_MP5023) += mp5023.o
> obj-$(CONFIG_SENSORS_MP5990) += mp5990.o
> +obj-$(CONFIG_SENSORS_MP9941) += mp9941.o
> obj-$(CONFIG_SENSORS_MPQ7932) += mpq7932.o
> obj-$(CONFIG_SENSORS_MPQ8785) += mpq8785.o
> obj-$(CONFIG_SENSORS_PLI1209BC) += pli1209bc.o
> diff --git a/drivers/hwmon/pmbus/mp9941.c b/drivers/hwmon/pmbus/mp9941.c
> new file mode 100644
> index 000000000000..d24e98671e16
> --- /dev/null
> +++ b/drivers/hwmon/pmbus/mp9941.c
> @@ -0,0 +1,328 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Hardware monitoring driver for MPS Multi-phase Digital VR Controllers(MP9941)
> + */
> +
> +#include <linux/i2c.h>
> +#include <linux/module.h>
> +#include <linux/of_device.h>
> +#include "pmbus.h"
> +
> +/*
> + * Vender specific registers. The MFR_ICC_MAX(0x02) is used to
> + * config the iin scale. The MFR_RESO_SET(0xC7) is used to
> + * config the vout format. The MFR_VR_MULTI_CONFIG_R1(0x0D) is
> + * used to identify the vout vid step.
> + */
> +#define MFR_ICC_MAX 0x02
> +#define MFR_RESO_SET 0xC7
> +#define MFR_VR_MULTI_CONFIG_R1 0x0D
> +
> +#define MP9941_VIN_LIMIT_UINT 1
> +#define MP9941_VIN_LIMIT_DIV 8
> +#define MP9941_READ_VIN_UINT 1
> +#define MP9941_READ_VIN_DIV 32
> +
> +#define MP9941_PAGE_NUM 1
> +
> +#define MP9941_RAIL1_FUNC (PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT | \
> + PMBUS_HAVE_IOUT | PMBUS_HAVE_POUT | \
> + PMBUS_HAVE_TEMP | PMBUS_HAVE_PIN | \
> + PMBUS_HAVE_IIN | \
> + PMBUS_HAVE_STATUS_VOUT | \
> + PMBUS_HAVE_STATUS_IOUT | \
> + PMBUS_HAVE_STATUS_TEMP | \
> + PMBUS_HAVE_STATUS_INPUT)
> +
> +struct mp9941_data {
> + struct pmbus_driver_info info;
> + int vid_resolution;
> +};
> +
> +#define to_mp9941_data(x) container_of(x, struct mp9941_data, info)
> +
> +static int mp2993_set_vout_format(struct i2c_client *client)
> +{
> + int ret;
> +
> + ret = i2c_smbus_write_byte_data(client, PMBUS_PAGE, 0);
> + if (ret < 0)
> + return ret;
> +
> + ret = i2c_smbus_read_word_data(client, MFR_RESO_SET);
> + if (ret < 0)
> + return ret;
> +
> + /*
> + * page = 0, MFR_RESO_SET[7:6] defines the vout format
> + * 2'b11 set the vout format as direct
> + */
> + ret = (ret & ~GENMASK(7, 6)) | FIELD_PREP(GENMASK(7, 6), 3);
> +
> + ret = i2c_smbus_write_word_data(client, MFR_RESO_SET, ret);
> + if (ret < 0)
> + return ret;
> +
i2c_smbus_write_word_data() returns 0 or an error code. The above
is therefore not necessary.
return i2c_smbus_write_word_data(client, MFR_RESO_SET, ret);
is sufficient. Same everythere else where the same pattern is used.
Thanks,
Guenter
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 2/4] hwmon: add MP2993 driver
2024-06-07 9:05 ` [PATCH 2/4] hwmon: add MP2993 driver Noah Wang
@ 2024-06-10 16:21 ` Guenter Roeck
0 siblings, 0 replies; 8+ messages in thread
From: Guenter Roeck @ 2024-06-10 16:21 UTC (permalink / raw)
To: Noah Wang, robh, krzk+dt, conor+dt, jdelvare
Cc: corbet, Delphine_CC_Chiu, peteryin.openbmc, javier.carrasco.cruz,
patrick.rudolph, bhelgaas, lukas, devicetree, linux-kernel,
linux-hwmon, linux-doc, linux-i2c
On 6/7/24 02:05, Noah Wang wrote:
> Add support for MPS VR controller mp2993. This driver exposes
> telemetry and limit value readings and writtings.
>
> Signed-off-by: Noah Wang <noahwang.wang@outlook.com>
> ---
> Documentation/hwmon/index.rst | 1 +
> Documentation/hwmon/mp2993.rst | 150 ++++++++++++++++++
> MAINTAINERS | 7 +
> drivers/hwmon/pmbus/Kconfig | 9 ++
> drivers/hwmon/pmbus/Makefile | 1 +
> drivers/hwmon/pmbus/mp2993.c | 269 +++++++++++++++++++++++++++++++++
> 6 files changed, 437 insertions(+)
> create mode 100644 Documentation/hwmon/mp2993.rst
> create mode 100644 drivers/hwmon/pmbus/mp2993.c
>
> diff --git a/Documentation/hwmon/index.rst b/Documentation/hwmon/index.rst
> index 03d313af469a..9d9d55b889f2 100644
> --- a/Documentation/hwmon/index.rst
> +++ b/Documentation/hwmon/index.rst
> @@ -166,6 +166,7 @@ Hardware Monitoring Kernel Drivers
> mp2856
> mp2888
> mp2975
> + mp2993
> mp5023
> mp5990
> mpq8785
> diff --git a/Documentation/hwmon/mp2993.rst b/Documentation/hwmon/mp2993.rst
> new file mode 100644
> index 000000000000..a14bb30969f9
> --- /dev/null
> +++ b/Documentation/hwmon/mp2993.rst
> @@ -0,0 +1,150 @@
> +.. SPDX-License-Identifier: GPL-2.0
> +
> +Kernel driver mp2993
> +====================
> +
> +Supported chips:
> +
> + * MPS mp2993
> +
> + Prefix: 'mp2993'
> +
> + * Datasheet
> + https://scnbwymvp-my.sharepoint.com/:f:/g/personal/admin_scnbwy_com/Eth4kX1_J1hMsaASHiOYL4QBHU5a75r-tRfLKbHnJFdKLQ?e=vxj3DF
> +
> +Author:
> +
> + Noah Wang <noahwang.wang@outlook.com>
> +
> +Description
> +-----------
> +
> +This driver implements support for Monolithic Power Systems, Inc. (MPS)
> +MP2993 Dual Loop Digital Multi-phase Controller.
> +
> +Device compliant with:
> +
> +- PMBus rev 1.3 interface.
> +
> +The driver exports the following attributes via the 'sysfs' files
> +for input voltage:
> +
> +**in1_input**
> +
> +**in1_label**
> +
> +**in1_crit**
> +
> +**in1_crit_alarm**
> +
> +**in1_lcrit**
> +
> +**in1_lcrit_alarm**
> +
> +**in1_max**
> +
> +**in1_max_alarm**
> +
> +**in1_min**
> +
> +**in1_min_alarm**
> +
> +The driver provides the following attributes for output voltage:
> +
> +**in2_input**
> +
> +**in2_label**
> +
> +**in2_crit**
> +
> +**in2_crit_alarm**
> +
> +**in2_lcrit**
> +
> +**in2_lcrit_alarm**
> +
> +**in3_input**
> +
> +**in3_label**
> +
> +**in3_crit**
> +
> +**in3_crit_alarm**
> +
> +**in3_lcrit**
> +
> +**in3_lcrit_alarm**
> +
> +The driver provides the following attributes for input current:
> +
> +**curr1_input**
> +
> +**curr1_label**
> +
> +**curr1_max**
> +
> +**curr1_max_alarm**
> +
> +The driver provides the following attributes for output current:
> +
> +**curr2_input**
> +
> +**curr2_label**
> +
> +**curr2_crit**
> +
> +**curr2_crit_alarm**
> +
> +**curr2_max**
> +
> +**curr2_max_alarm**
> +
> +**curr3_input**
> +
> +**curr3_label**
> +
> +**curr3_crit**
> +
> +**curr3_crit_alarm**
> +
> +**curr3_max**
> +
> +**curr3_max_alarm**
> +
> +The driver provides the following attributes for input power:
> +
> +**power1_input**
> +
> +**power1_label**
> +
> +The driver provides the following attributes for output power:
> +
> +**power2_input**
> +
> +**power2_label**
> +
> +**power3_input**
> +
> +**power3_label**
> +
> +The driver provides the following attributes for temperature:
> +
> +**temp1_input**
> +
> +**temp1_crit**
> +
> +**temp1_crit_alarm**
> +
> +**temp1_max**
> +
> +**temp1_max_alarm**
> +
> +**temp2_input**
> +
> +**temp2_crit**
> +
> +**temp2_crit_alarm**
> +
> +**temp2_max**
> +
> +**temp2_max_alarm**
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 8754ac2c259d..f47f3e13b004 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -15258,6 +15258,13 @@ S: Maintained
> F: Documentation/devicetree/bindings/leds/backlight/mps,mp3309c.yaml
> F: drivers/video/backlight/mp3309c.c
>
> ++MPS MP2993 DRIVER
> ++M: Noah Wang <noahwang.wang@outlook.com>
> ++L: linux-hwmon@vger.kernel.org
> ++S: Maintained
> ++F: Documentation/hwmon/mp2993.rst
> ++F: drivers/hwmon/pmbus/mp2993.c
> +
> MR800 AVERMEDIA USB FM RADIO DRIVER
> M: Alexey Klimov <klimov.linux@gmail.com>
> L: linux-media@vger.kernel.org
> diff --git a/drivers/hwmon/pmbus/Kconfig b/drivers/hwmon/pmbus/Kconfig
> index 08e82c457356..d875d31ce84c 100644
> --- a/drivers/hwmon/pmbus/Kconfig
> +++ b/drivers/hwmon/pmbus/Kconfig
> @@ -346,6 +346,15 @@ config SENSORS_MP2975
> This driver can also be built as a module. If so, the module will
> be called mp2975.
>
> +config SENSORS_MP2993
> + tristate "MPS MP2993"
> + help
> + If you say yes here you get hardware monitoring support for MPS
> + MP2993 Dual Loop Digital Multi-Phase Controller.
> +
> + This driver can also be built as a module. If so, the module will
> + be called mp2993.
> +
> config SENSORS_MP2975_REGULATOR
> depends on SENSORS_MP2975 && REGULATOR
> bool "Regulator support for MPS MP2975"
> diff --git a/drivers/hwmon/pmbus/Makefile b/drivers/hwmon/pmbus/Makefile
> index 2279b3327bbf..312d3f0c0540 100644
> --- a/drivers/hwmon/pmbus/Makefile
> +++ b/drivers/hwmon/pmbus/Makefile
> @@ -37,6 +37,7 @@ obj-$(CONFIG_SENSORS_MAX8688) += max8688.o
> obj-$(CONFIG_SENSORS_MP2856) += mp2856.o
> obj-$(CONFIG_SENSORS_MP2888) += mp2888.o
> obj-$(CONFIG_SENSORS_MP2975) += mp2975.o
> +obj-$(CONFIG_SENSORS_MP2993) += mp2993.o
> obj-$(CONFIG_SENSORS_MP5023) += mp5023.o
> obj-$(CONFIG_SENSORS_MP5990) += mp5990.o
> obj-$(CONFIG_SENSORS_MPQ7932) += mpq7932.o
> diff --git a/drivers/hwmon/pmbus/mp2993.c b/drivers/hwmon/pmbus/mp2993.c
> new file mode 100644
> index 000000000000..43432b8d4faf
> --- /dev/null
> +++ b/drivers/hwmon/pmbus/mp2993.c
> @@ -0,0 +1,269 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Hardware monitoring driver for MPS Multi-phase Digital VR Controllers(MP2993)
> + */
> +
> +#include <linux/i2c.h>
> +#include <linux/module.h>
> +#include <linux/of_device.h>
> +#include "pmbus.h"
> +
> +#define MP2993_VOUT_OVUV_UINT 125
> +#define MP2993_VOUT_OVUV_DIV 64
> +#define MP2993_VIN_LIMIT_UINT 1
> +#define MP2993_VIN_LIMIT_DIV 8
> +#define MP2993_READ_VIN_UINT 1
> +#define MP2993_READ_VIN_DIV 32
> +
> +#define MP2993_PAGE_NUM 2
> +
> +#define MP2993_RAIL1_FUNC (PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT | \
> + PMBUS_HAVE_IOUT | PMBUS_HAVE_POUT | \
> + PMBUS_HAVE_TEMP | PMBUS_HAVE_PIN | \
> + PMBUS_HAVE_IIN | \
> + PMBUS_HAVE_STATUS_VOUT | \
> + PMBUS_HAVE_STATUS_IOUT | \
> + PMBUS_HAVE_STATUS_TEMP | \
> + PMBUS_HAVE_STATUS_INPUT)
> +
> +#define MP2993_RAIL2_FUNC (PMBUS_HAVE_VOUT | PMBUS_HAVE_IOUT | \
> + PMBUS_HAVE_POUT | PMBUS_HAVE_TEMP | \
> + PMBUS_HAVE_STATUS_VOUT | \
> + PMBUS_HAVE_STATUS_IOUT | \
> + PMBUS_HAVE_STATUS_TEMP | \
> + PMBUS_HAVE_STATUS_INPUT)
> +
> +/* Converts a linear11 data exponent to a specified value */
> +static u16 mp2993_linear11_exponent_transfer(u16 word, u16 expect_exponent)
> +{
> + s16 exponent, mantissa, target_exponent;
> +
> + exponent = ((s16)word) >> 11;
> + mantissa = ((s16)((word & 0x7ff) << 5)) >> 5;
> + target_exponent = (s16)((expect_exponent & 0x1f) << 11) >> 11;
> +
> + if (exponent > target_exponent)
> + mantissa = mantissa << (exponent - target_exponent);
> + else
> + mantissa = mantissa >> (target_exponent - exponent);
> +
> + return (mantissa & 0x7ff) | ((expect_exponent << 11) & 0xf800);
> +}
> +
> +static int
> +mp2993_set_vout_format(struct i2c_client *client, int page, int format)
> +{
> + int ret;
> +
> + ret = i2c_smbus_write_byte_data(client, PMBUS_PAGE, page);
> + if (ret < 0)
> + return ret;
> +
> + ret = i2c_smbus_write_byte_data(client, PMBUS_VOUT_MODE, format);
> + if (ret < 0)
> + return ret;
return i2c_smbus_write_byte_data(...);
> +
> + return 0;
> +}
> +
> +static int mp2993_identify(struct i2c_client *client, struct pmbus_driver_info *info)
> +{
> + int ret;
> +
> + /* Set vout to direct format for rail1. */
> + ret = mp2993_set_vout_format(client, 0, PB_VOUT_MODE_DIRECT);
> + if (ret < 0)
> + return ret;
> +
> + /* Set vout to direct format for rail2. */
> + ret = mp2993_set_vout_format(client, 1, PB_VOUT_MODE_DIRECT);
> + if (ret < 0)
> + return ret;
> +
> + return ret;
In other words,
if (ret < 0)
return ret;
else
return ret;
Please, don't do that.
return mp2993_set_vout_format(...);
> +}
> +
> +static int mp2993_read_word_data(struct i2c_client *client, int page, int phase,
> + int reg)
> +{
> + int ret;
> +
> + switch (reg) {
> + case PMBUS_VOUT_OV_FAULT_LIMIT:
> + case PMBUS_VOUT_UV_FAULT_LIMIT:
> + ret = pmbus_read_word_data(client, page, phase, reg);
> + if (ret < 0)
> + return ret;
> +
> + ret = DIV_ROUND_CLOSEST(ret * MP2993_VOUT_OVUV_UINT, MP2993_VOUT_OVUV_DIV);
> + break;
> + case PMBUS_OT_FAULT_LIMIT:
> + case PMBUS_OT_WARN_LIMIT:
> + /*
> + * The MP2993 ot fault limit value and ot warn limit value
> + * per rail are always the same, so only PMBUS_OT_FAULT_LIMIT
> + * and PMBUS_OT_WARN_LIMIT register in page 0 are defined to
> + * indicates the limit value.
> + */
> + ret = pmbus_read_word_data(client, 0, phase, reg);
> + break;
> + case PMBUS_READ_VIN:
> + /* The MP2993 vin scale is (1/32V)/Lsb */
> + ret = pmbus_read_word_data(client, page, phase, reg);
> + if (ret < 0)
> + return ret;
> +
> + ret = DIV_ROUND_CLOSEST((ret & GENMASK(9, 0)) * MP2993_READ_VIN_UINT,
> + MP2993_READ_VIN_DIV);
> + break;
> + case PMBUS_VIN_OV_FAULT_LIMIT:
> + case PMBUS_VIN_OV_WARN_LIMIT:
> + case PMBUS_VIN_UV_WARN_LIMIT:
> + case PMBUS_VIN_UV_FAULT_LIMIT:
> + /* The MP2993 vin limit scale is (1/8V)/Lsb */
> + ret = pmbus_read_word_data(client, page, phase, reg);
> + if (ret < 0)
> + return ret;
> +
> + ret = DIV_ROUND_CLOSEST((ret & GENMASK(7, 0)) * MP2993_VIN_LIMIT_UINT,
> + MP2993_VIN_LIMIT_DIV);
> + break;
> + case PMBUS_READ_IOUT:
> + case PMBUS_READ_IIN:
> + case PMBUS_IIN_OC_WARN_LIMIT:
> + case PMBUS_IOUT_OC_FAULT_LIMIT:
> + case PMBUS_IOUT_OC_WARN_LIMIT:
> + case PMBUS_READ_VOUT:
> + case PMBUS_READ_PIN:
> + case PMBUS_READ_POUT:
> + case PMBUS_READ_TEMPERATURE_1:
> + ret = -ENODATA;
> + break;
> + default:
> + ret = -EINVAL;
> + break;
> + }
> +
> + return ret;
> +}
> +
> +static int mp2993_write_word_data(struct i2c_client *client, int page, int reg,
> + u16 word)
> +{
> + int ret;
> +
> + switch (reg) {
> + case PMBUS_VOUT_OV_FAULT_LIMIT:
> + case PMBUS_VOUT_UV_FAULT_LIMIT:
> + ret = DIV_ROUND_CLOSEST(word * MP2993_VOUT_OVUV_DIV, MP2993_VOUT_OVUV_UINT);
> + ret = pmbus_write_word_data(client, 0, reg, ret);
> + break;
> + case PMBUS_OT_FAULT_LIMIT:
> + case PMBUS_OT_WARN_LIMIT:
> + /*
> + * The MP2993 ot fault limit value and ot warn limit value
> + * per rail are always the same, so only PMBUS_OT_FAULT_LIMIT
> + * and PMBUS_OT_WARN_LIMIT register in page 0 are defined to
> + * config the ot limit value.
> + */
> + ret = pmbus_write_word_data(client, 0, reg, word);
> + break;
> + case PMBUS_VIN_OV_FAULT_LIMIT:
> + case PMBUS_VIN_OV_WARN_LIMIT:
> + case PMBUS_VIN_UV_WARN_LIMIT:
> + case PMBUS_VIN_UV_FAULT_LIMIT:
> + /* The MP2993 vin limit scale is (1/8V)/Lsb */
> + ret = pmbus_write_word_data(client, 0, reg,
> + DIV_ROUND_CLOSEST(word * MP2993_VIN_LIMIT_DIV,
> + MP2993_VIN_LIMIT_UINT));
> + break;
> + case PMBUS_IIN_OC_WARN_LIMIT:
> + /*
> + * The PMBUS_IIN_OC_WARN_LIMIT of MP2993 is linear11 format,
> + * and the exponent is a constant value(5'b00000), so the
> + * exponent of word parameter should be converted to 5'b00000.
> + */
> + ret = pmbus_write_word_data(client, page, reg,
> + mp2993_linear11_exponent_transfer(word, 0x00));
> + break;
> + //
> + case PMBUS_IOUT_OC_FAULT_LIMIT:
> + case PMBUS_IOUT_OC_WARN_LIMIT:
> + /*
> + * The PMBUS_IOUT_OC_FAULT_LIMIT and PMBUS_IOUT_OC_WARN_LIMIT
> + * of MP2993 can be regarded as linear11 format, and the
> + * exponent is a 5'b00001 or 5'b00000. To ensure a larger
> + * range of limit value, so the exponent of word parameter
> + * should be converted to 5'b00001.
> + */
> + ret = pmbus_write_word_data(client, page, reg,
> + mp2993_linear11_exponent_transfer(word, 0x01));
> + break;
> + default:
> + ret = -EINVAL;
> + break;
> + }
> +
> + return ret;
> +}
> +
> +static struct pmbus_driver_info mp2993_info = {
> + .pages = MP2993_PAGE_NUM,
> + .format[PSC_VOLTAGE_IN] = direct,
> + .format[PSC_CURRENT_IN] = linear,
> + .format[PSC_CURRENT_OUT] = linear,
> + .format[PSC_TEMPERATURE] = direct,
> + .format[PSC_POWER] = linear,
> + .format[PSC_VOLTAGE_OUT] = direct,
> +
> + .m[PSC_VOLTAGE_OUT] = 1,
> + .R[PSC_VOLTAGE_OUT] = 3,
> + .b[PSC_VOLTAGE_OUT] = 0,
> +
> + .m[PSC_VOLTAGE_IN] = 1,
> + .R[PSC_VOLTAGE_IN] = 0,
> + .b[PSC_VOLTAGE_IN] = 0,
> +
> + .m[PSC_TEMPERATURE] = 1,
> + .R[PSC_TEMPERATURE] = 0,
> + .b[PSC_TEMPERATURE] = 0,
> +
> + .func[0] = MP2993_RAIL1_FUNC,
> + .func[1] = MP2993_RAIL2_FUNC,
> + .read_word_data = mp2993_read_word_data,
> + .write_word_data = mp2993_write_word_data,
> + .identify = mp2993_identify,
> +};
> +
> +static int mp2993_probe(struct i2c_client *client)
> +{
> + return pmbus_do_probe(client, &mp2993_info);
> +}
> +
> +static const struct i2c_device_id mp2993_id[] = {
> + {"mp2993", 0},
> + {}
> +};
> +MODULE_DEVICE_TABLE(i2c, mp2993_id);
> +
> +static const struct of_device_id __maybe_unused mp2993_of_match[] = {
> + {.compatible = "mps,mp2993"},
> + {}
> +};
> +MODULE_DEVICE_TABLE(of, mp2993_of_match);
> +
> +static struct i2c_driver mp2993_driver = {
> + .driver = {
> + .name = "mp2993",
> + .of_match_table = mp2993_of_match,
> + },
> + .probe = mp2993_probe,
> + .id_table = mp2993_id,
> +};
> +
> +module_i2c_driver(mp2993_driver);
> +
> +MODULE_AUTHOR("Noah Wang <noahwang.wang@outlook.com>");
> +MODULE_DESCRIPTION("PMBus driver for MPS MP2993");
> +MODULE_LICENSE("GPL");
> +MODULE_IMPORT_NS(PMBUS);
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2024-06-10 16:21 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20240607090544.466833-1-noahwang.wang@outlook.com>
2024-06-07 9:05 ` [PATCH 1/4] dt-bindings: hwmon: Add MPS mp2993 Noah Wang
2024-06-07 9:27 ` Krzysztof Kozlowski
2024-06-07 9:05 ` [PATCH 2/4] hwmon: add MP2993 driver Noah Wang
2024-06-10 16:21 ` Guenter Roeck
2024-06-07 9:05 ` [PATCH 3/4] dt-bindings: hwmon: Add MPS mp9941 Noah Wang
2024-06-07 9:28 ` Krzysztof Kozlowski
2024-06-07 9:05 ` [PATCH 4/4] hwmon: add MP9941 driver Noah Wang
2024-06-10 16:18 ` Guenter Roeck
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).