hwmon: add MP5920 driver

Add support for MPS Hot-Swap controller mp5920. This driver exposes
telemetry and limit value readings and writings.

Signed-off-by: Alex Vdovydchenko <xzeol@yahoo.com>
Reviewed-by: Thomas Weißschuh <linux@weissschuh.net>
Link: https://lore.kernel.org/r/20240702115252.981416-3-xzeol@yahoo.com
[groeck: Use min_t() to limit length of displayed model string]
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
This commit is contained in:
Alex Vdovydchenko 2024-07-02 14:52:51 +03:00 committed by Guenter Roeck
parent a50fbf8a52
commit cd228e7b65
5 changed files with 192 additions and 0 deletions

View File

@ -169,6 +169,7 @@ Hardware Monitoring Kernel Drivers
mp2975
mp2993
mp5023
mp5920
mp5990
mp9941
mpq8785

View File

@ -0,0 +1,91 @@
.. SPDX-License-Identifier: GPL-2.0
Kernel driver mp5920
====================
Supported chips:
* MPS MP5920
Prefix: 'mp5920'
* Datasheet
Publicly available at the MPS website : https://www.monolithicpower.com/en/mp5920.html
Authors:
Tony Ao <tony_ao@wiwynn.com>
Alex Vdovydchenko <xzeol@yahoo.com>
Description
-----------
This driver implements support for Monolithic Power Systems, Inc. (MPS)
MP5920 Hot-Swap Controller.
Device compliant with:
- PMBus rev 1.3 interface.
Device supports direct and linear format for reading input voltage,
output voltage, output current, input power and temperature.
The driver exports the following attributes via the 'sysfs' files
for input voltage:
**in1_input**
**in1_label**
**in1_rated_max**
**in1_rated_min**
**in1_crit**
**in1_alarm**
The driver provides the following attributes for output voltage:
**in2_input**
**in2_label**
**in2_rated_max**
**in2_rated_min**
**in2_alarm**
The driver provides the following attributes for output current:
**curr1_input**
**curr1_label**
**curr1_crit**
**curr1_alarm**
**curr1_rated_max**
The driver provides the following attributes for input power:
**power1_input**
**power1_label**
**power1_max**
**power1_rated_max**
The driver provides the following attributes for temperature:
**temp1_input**
**temp1_max**
**temp1_crit**
**temp1_alarm**

View File

@ -380,6 +380,15 @@ config SENSORS_MP5023
This driver can also be built as a module. If so, the module will
be called mp5023.
config SENSORS_MP5920
tristate "MPS MP5920"
help
If you say yes here you get hardware monitoring support for Monolithic
MP5920.
This driver can also be built as a module. If so, the module will
be called mp5920.
config SENSORS_MP5990
tristate "MPS MP5990"
help

View File

@ -40,6 +40,7 @@ obj-$(CONFIG_SENSORS_MP2891) += mp2891.o
obj-$(CONFIG_SENSORS_MP2975) += mp2975.o
obj-$(CONFIG_SENSORS_MP2993) += mp2993.o
obj-$(CONFIG_SENSORS_MP5023) += mp5023.o
obj-$(CONFIG_SENSORS_MP5920) += mp5920.o
obj-$(CONFIG_SENSORS_MP5990) += mp5990.o
obj-$(CONFIG_SENSORS_MP9941) += mp9941.o
obj-$(CONFIG_SENSORS_MPQ7932) += mpq7932.o

View File

@ -0,0 +1,90 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Hardware monitoring driver for MP5920 and compatible chips.
*/
#include <linux/i2c.h>
#include <linux/minmax.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include "pmbus.h"
static struct pmbus_driver_info mp5920_info = {
.pages = 1,
.format[PSC_VOLTAGE_IN] = direct,
.format[PSC_VOLTAGE_OUT] = direct,
.format[PSC_CURRENT_OUT] = direct,
.format[PSC_POWER] = direct,
.format[PSC_TEMPERATURE] = direct,
.m[PSC_VOLTAGE_IN] = 2266,
.b[PSC_VOLTAGE_IN] = 0,
.R[PSC_VOLTAGE_IN] = -1,
.m[PSC_VOLTAGE_OUT] = 2266,
.b[PSC_VOLTAGE_OUT] = 0,
.R[PSC_VOLTAGE_OUT] = -1,
.m[PSC_CURRENT_OUT] = 546,
.b[PSC_CURRENT_OUT] = 0,
.R[PSC_CURRENT_OUT] = -2,
.m[PSC_POWER] = 5840,
.b[PSC_POWER] = 0,
.R[PSC_POWER] = -3,
.m[PSC_TEMPERATURE] = 1067,
.b[PSC_TEMPERATURE] = 20500,
.R[PSC_TEMPERATURE] = -2,
.func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT |
PMBUS_HAVE_IOUT | PMBUS_HAVE_POUT |
PMBUS_HAVE_TEMP,
};
static int mp5920_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
int ret;
u8 buf[I2C_SMBUS_BLOCK_MAX];
if (!i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_READ_WORD_DATA))
return -ENODEV;
ret = i2c_smbus_read_block_data(client, PMBUS_MFR_MODEL, buf);
if (ret < 0)
return dev_err_probe(dev, ret, "Failed to read PMBUS_MFR_MODEL\n");
if (ret != 6 || strncmp(buf, "MP5920", 6)) {
return dev_err_probe(dev, -ENODEV, "Model '%.*s' not supported\n",
min_t(int, ret, sizeof(buf)), buf);
}
return pmbus_do_probe(client, &mp5920_info);
}
static const struct of_device_id mp5920_of_match[] = {
{ .compatible = "mps,mp5920" },
{ }
};
MODULE_DEVICE_TABLE(of, mp5920_of_match);
static const struct i2c_device_id mp5920_id[] = {
{ "mp5920" },
{ }
};
MODULE_DEVICE_TABLE(i2c, mp5920_id);
static struct i2c_driver mp5920_driver = {
.driver = {
.name = "mp5920",
.of_match_table = mp5920_of_match,
},
.probe = mp5920_probe,
.id_table = mp5920_id,
};
module_i2c_driver(mp5920_driver);
MODULE_AUTHOR("Tony Ao <tony_ao@wiwynn.com>");
MODULE_AUTHOR("Alex Vdovydchenko <xzeol@yahoo.com>");
MODULE_DESCRIPTION("PMBus driver for MP5920 HSC");
MODULE_LICENSE("GPL");
MODULE_IMPORT_NS(PMBUS);