Commit cd228e7b authored by Alex Vdovydchenko's avatar Alex Vdovydchenko Committed by Guenter Roeck
Browse files

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: default avatarAlex Vdovydchenko <xzeol@yahoo.com>
Reviewed-by: default avatarThomas 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: default avatarGuenter Roeck <linux@roeck-us.net>
parent a50fbf8a
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -169,6 +169,7 @@ Hardware Monitoring Kernel Drivers
   mp2975
   mp2993
   mp5023
   mp5920
   mp5990
   mp9941
   mpq8785
+91 −0
Original line number Diff line number Diff line
.. 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**
+9 −0
Original line number Diff line number Diff line
@@ -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
+1 −0
Original line number Diff line number Diff line
@@ -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
+90 −0
Original line number Diff line number Diff line
// 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);