summaryrefslogtreecommitdiff
path: root/drivers/hwmon/pmbus
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon/pmbus')
-rw-r--r--drivers/hwmon/pmbus/Kconfig36
-rw-r--r--drivers/hwmon/pmbus/Makefile2
-rw-r--r--drivers/hwmon/pmbus/ltc2978.c16
-rw-r--r--drivers/hwmon/pmbus/max16601.c14
-rw-r--r--drivers/hwmon/pmbus/mpq7932.c156
-rw-r--r--drivers/hwmon/pmbus/pmbus.h5
-rw-r--r--drivers/hwmon/pmbus/tda38640.c74
7 files changed, 286 insertions, 17 deletions
diff --git a/drivers/hwmon/pmbus/Kconfig b/drivers/hwmon/pmbus/Kconfig
index 89668af67206..59d9a7430499 100644
--- a/drivers/hwmon/pmbus/Kconfig
+++ b/drivers/hwmon/pmbus/Kconfig
@@ -237,10 +237,10 @@ config SENSORS_MAX16064
be called max16064.
config SENSORS_MAX16601
- tristate "Maxim MAX16508, MAX16601, MAX16602"
+ tristate "Maxim MAX16508, MAX16600, MAX16601, and MAX16602"
help
If you say yes here you get hardware monitoring support for Maxim
- MAX16508, MAX16601 and MAX16602.
+ MAX16508, MAX16600, MAX16601, and MAX16602.
This driver can also be built as a module. If so, the module will
be called max16601.
@@ -317,6 +317,22 @@ config SENSORS_MP5023
This driver can also be built as a module. If so, the module will
be called mp5023.
+config SENSORS_MPQ7932_REGULATOR
+ bool "Regulator support for MPQ7932"
+ depends on SENSORS_MPQ7932 && REGULATOR
+ help
+ If you say yes here you get six integrated buck converter regulator
+ support for power management IC MPS MPQ7932.
+
+config SENSORS_MPQ7932
+ tristate "MPS MPQ7932"
+ help
+ If you say yes here you get hardware monitoring functionality support
+ for power management IC MPS MPQ7932.
+
+ This driver can also be built as a module. If so, the module will
+ be called mpq7932.
+
config SENSORS_PIM4328
tristate "Flex PIM4328 and compatibles"
help
@@ -379,6 +395,22 @@ config SENSORS_STPDDC60
This driver can also be built as a module. If so, the module will
be called stpddc60.
+config SENSORS_TDA38640
+ tristate "Infineon TDA38640"
+ help
+ If you say yes here you get hardware monitoring support for Infineon
+ TDA38640.
+
+ This driver can also be built as a module. If so, the module will
+ be called tda38640.
+
+config SENSORS_TDA38640_REGULATOR
+ bool "Regulator support for TDA38640 and compatibles"
+ depends on SENSORS_TDA38640 && REGULATOR
+ help
+ If you say yes here you get regulator support for Infineon
+ TDA38640 as regulator.
+
config SENSORS_TPS40422
tristate "TI TPS40422"
help
diff --git a/drivers/hwmon/pmbus/Makefile b/drivers/hwmon/pmbus/Makefile
index 0002dbe22d52..3ae019916267 100644
--- a/drivers/hwmon/pmbus/Makefile
+++ b/drivers/hwmon/pmbus/Makefile
@@ -34,11 +34,13 @@ obj-$(CONFIG_SENSORS_MAX8688) += max8688.o
obj-$(CONFIG_SENSORS_MP2888) += mp2888.o
obj-$(CONFIG_SENSORS_MP2975) += mp2975.o
obj-$(CONFIG_SENSORS_MP5023) += mp5023.o
+obj-$(CONFIG_SENSORS_MPQ7932) += mpq7932.o
obj-$(CONFIG_SENSORS_PLI1209BC) += pli1209bc.o
obj-$(CONFIG_SENSORS_PM6764TR) += pm6764tr.o
obj-$(CONFIG_SENSORS_PXE1610) += pxe1610.o
obj-$(CONFIG_SENSORS_Q54SJ108A2) += q54sj108a2.o
obj-$(CONFIG_SENSORS_STPDDC60) += stpddc60.o
+obj-$(CONFIG_SENSORS_TDA38640) += tda38640.o
obj-$(CONFIG_SENSORS_TPS40422) += tps40422.o
obj-$(CONFIG_SENSORS_TPS53679) += tps53679.o
obj-$(CONFIG_SENSORS_TPS546D24) += tps546d24.o
diff --git a/drivers/hwmon/pmbus/ltc2978.c b/drivers/hwmon/pmbus/ltc2978.c
index 79f480b4425d..91df8e895147 100644
--- a/drivers/hwmon/pmbus/ltc2978.c
+++ b/drivers/hwmon/pmbus/ltc2978.c
@@ -570,14 +570,14 @@ MODULE_DEVICE_TABLE(i2c, ltc2978_id);
#define LTC2978_N_VOLTAGES ((LTC2978_MAX_UV / LTC2978_UV_STEP) + 1)
static const struct regulator_desc ltc2978_reg_desc[] = {
- PMBUS_REGULATOR_STEP("vout", 0, LTC2978_N_VOLTAGES, LTC2978_UV_STEP),
- PMBUS_REGULATOR_STEP("vout", 1, LTC2978_N_VOLTAGES, LTC2978_UV_STEP),
- PMBUS_REGULATOR_STEP("vout", 2, LTC2978_N_VOLTAGES, LTC2978_UV_STEP),
- PMBUS_REGULATOR_STEP("vout", 3, LTC2978_N_VOLTAGES, LTC2978_UV_STEP),
- PMBUS_REGULATOR_STEP("vout", 4, LTC2978_N_VOLTAGES, LTC2978_UV_STEP),
- PMBUS_REGULATOR_STEP("vout", 5, LTC2978_N_VOLTAGES, LTC2978_UV_STEP),
- PMBUS_REGULATOR_STEP("vout", 6, LTC2978_N_VOLTAGES, LTC2978_UV_STEP),
- PMBUS_REGULATOR_STEP("vout", 7, LTC2978_N_VOLTAGES, LTC2978_UV_STEP),
+ PMBUS_REGULATOR_STEP("vout", 0, LTC2978_N_VOLTAGES, LTC2978_UV_STEP, 0),
+ PMBUS_REGULATOR_STEP("vout", 1, LTC2978_N_VOLTAGES, LTC2978_UV_STEP, 0),
+ PMBUS_REGULATOR_STEP("vout", 2, LTC2978_N_VOLTAGES, LTC2978_UV_STEP, 0),
+ PMBUS_REGULATOR_STEP("vout", 3, LTC2978_N_VOLTAGES, LTC2978_UV_STEP, 0),
+ PMBUS_REGULATOR_STEP("vout", 4, LTC2978_N_VOLTAGES, LTC2978_UV_STEP, 0),
+ PMBUS_REGULATOR_STEP("vout", 5, LTC2978_N_VOLTAGES, LTC2978_UV_STEP, 0),
+ PMBUS_REGULATOR_STEP("vout", 6, LTC2978_N_VOLTAGES, LTC2978_UV_STEP, 0),
+ PMBUS_REGULATOR_STEP("vout", 7, LTC2978_N_VOLTAGES, LTC2978_UV_STEP, 0),
};
static const struct regulator_desc ltc2978_reg_desc_default[] = {
diff --git a/drivers/hwmon/pmbus/max16601.c b/drivers/hwmon/pmbus/max16601.c
index b628405e6586..6724f723f74c 100644
--- a/drivers/hwmon/pmbus/max16601.c
+++ b/drivers/hwmon/pmbus/max16601.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
/*
- * Hardware monitoring driver for Maxim MAX16508, MAX16601 and MAX16602.
+ * Hardware monitoring driver for Maxim MAX16508, MAX16600, MAX16601,
+ * and MAX16602.
*
* Implementation notes:
*
@@ -31,7 +32,7 @@
#include "pmbus.h"
-enum chips { max16508, max16601, max16602 };
+enum chips { max16508, max16600, max16601, max16602 };
#define REG_DEFAULT_NUM_POP 0xc4
#define REG_SETPT_DVID 0xd1
@@ -202,7 +203,7 @@ static int max16601_identify(struct i2c_client *client,
else
info->vrm_version[0] = vr12;
- if (data->id != max16601 && data->id != max16602)
+ if (data->id != max16600 && data->id != max16601 && data->id != max16602)
return 0;
reg = i2c_smbus_read_byte_data(client, REG_DEFAULT_NUM_POP);
@@ -263,6 +264,7 @@ static void max16601_remove(void *_data)
static const struct i2c_device_id max16601_id[] = {
{"max16508", max16508},
+ {"max16600", max16600},
{"max16601", max16601},
{"max16602", max16602},
{}
@@ -281,11 +283,13 @@ static int max16601_get_id(struct i2c_client *client)
return -ENODEV;
/*
- * PMBUS_IC_DEVICE_ID is expected to return "MAX16601y.xx" or
- * MAX16602y.xx or "MAX16500y.xx".cdxxcccccccccc
+ * PMBUS_IC_DEVICE_ID is expected to return MAX1660[012]y.xx" or
+ * "MAX16500y.xx".cdxxcccccccccc
*/
if (!strncmp(buf, "MAX16500", 8)) {
id = max16508;
+ } else if (!strncmp(buf, "MAX16600", 8)) {
+ id = max16600;
} else if (!strncmp(buf, "MAX16601", 8)) {
id = max16601;
} else if (!strncmp(buf, "MAX16602", 8)) {
diff --git a/drivers/hwmon/pmbus/mpq7932.c b/drivers/hwmon/pmbus/mpq7932.c
new file mode 100644
index 000000000000..ff939881dc3b
--- /dev/null
+++ b/drivers/hwmon/pmbus/mpq7932.c
@@ -0,0 +1,156 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * mpq7932.c - hwmon with optional regulator driver for mps mpq7932
+ * Copyright 2022 Monolithic Power Systems, Inc
+ *
+ * Author: Saravanan Sekar <saravanan@linumiz.com>
+ */
+
+#include <linux/bits.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/pmbus.h>
+#include "pmbus.h"
+
+#define MPQ7932_BUCK_UV_MIN 206250
+#define MPQ7932_UV_STEP 6250
+#define MPQ7932_N_VOLTAGES 256
+#define MPQ7932_VOUT_MAX 0xFF
+#define MPQ7932_NUM_PAGES 6
+
+#define MPQ7932_TON_DELAY 0x60
+#define MPQ7932_VOUT_STARTUP_SLEW 0xA3
+#define MPQ7932_VOUT_SHUTDOWN_SLEW 0xA5
+#define MPQ7932_VOUT_SLEW_MASK GENMASK(1, 0)
+#define MPQ7932_TON_DELAY_MASK GENMASK(4, 0)
+
+struct mpq7932_data {
+ struct pmbus_driver_info info;
+ struct pmbus_platform_data pdata;
+};
+
+#if IS_ENABLED(CONFIG_SENSORS_MPQ7932_REGULATOR)
+static struct regulator_desc mpq7932_regulators_desc[] = {
+ PMBUS_REGULATOR_STEP("buck", 0, MPQ7932_N_VOLTAGES,
+ MPQ7932_UV_STEP, MPQ7932_BUCK_UV_MIN),
+ PMBUS_REGULATOR_STEP("buck", 1, MPQ7932_N_VOLTAGES,
+ MPQ7932_UV_STEP, MPQ7932_BUCK_UV_MIN),
+ PMBUS_REGULATOR_STEP("buck", 2, MPQ7932_N_VOLTAGES,
+ MPQ7932_UV_STEP, MPQ7932_BUCK_UV_MIN),
+ PMBUS_REGULATOR_STEP("buck", 3, MPQ7932_N_VOLTAGES,
+ MPQ7932_UV_STEP, MPQ7932_BUCK_UV_MIN),
+ PMBUS_REGULATOR_STEP("buck", 4, MPQ7932_N_VOLTAGES,
+ MPQ7932_UV_STEP, MPQ7932_BUCK_UV_MIN),
+ PMBUS_REGULATOR_STEP("buck", 5, MPQ7932_N_VOLTAGES,
+ MPQ7932_UV_STEP, MPQ7932_BUCK_UV_MIN),
+};
+#endif
+
+static int mpq7932_write_word_data(struct i2c_client *client, int page, int reg,
+ u16 word)
+{
+ switch (reg) {
+ /*
+ * chip supports only byte access for VOUT_COMMAND otherwise
+ * access results -EREMOTEIO
+ */
+ case PMBUS_VOUT_COMMAND:
+ return pmbus_write_byte_data(client, page, reg, word & 0xFF);
+
+ default:
+ return -ENODATA;
+ }
+}
+
+static int mpq7932_read_word_data(struct i2c_client *client, int page,
+ int phase, int reg)
+{
+ switch (reg) {
+ /*
+ * chip supports neither (PMBUS_VOUT_MARGIN_HIGH, PMBUS_VOUT_MARGIN_LOW)
+ * nor (PMBUS_MFR_VOUT_MIN, PMBUS_MFR_VOUT_MAX). As a result set voltage
+ * fails due to error in pmbus_regulator_get_low_margin, so faked.
+ */
+ case PMBUS_MFR_VOUT_MIN:
+ return 0;
+
+ case PMBUS_MFR_VOUT_MAX:
+ return MPQ7932_VOUT_MAX;
+
+ /*
+ * chip supports only byte access for VOUT_COMMAND otherwise
+ * access results in -EREMOTEIO
+ */
+ case PMBUS_READ_VOUT:
+ return pmbus_read_byte_data(client, page, PMBUS_VOUT_COMMAND);
+
+ default:
+ return -ENODATA;
+ }
+}
+
+static int mpq7932_probe(struct i2c_client *client)
+{
+ struct mpq7932_data *data;
+ struct pmbus_driver_info *info;
+ struct device *dev = &client->dev;
+ int i;
+
+ data = devm_kzalloc(dev, sizeof(struct mpq7932_data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ info = &data->info;
+ info->pages = MPQ7932_NUM_PAGES;
+ info->format[PSC_VOLTAGE_OUT] = direct;
+ info->m[PSC_VOLTAGE_OUT] = 160;
+ info->b[PSC_VOLTAGE_OUT] = -33;
+ for (i = 0; i < info->pages; i++) {
+ info->func[i] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
+ | PMBUS_HAVE_STATUS_TEMP;
+ }
+
+#if IS_ENABLED(CONFIG_SENSORS_MPQ7932_REGULATOR)
+ info->num_regulators = ARRAY_SIZE(mpq7932_regulators_desc);
+ info->reg_desc = mpq7932_regulators_desc;
+#endif
+
+ info->read_word_data = mpq7932_read_word_data;
+ info->write_word_data = mpq7932_write_word_data;
+
+ data->pdata.flags = PMBUS_NO_CAPABILITY;
+ dev->platform_data = &data->pdata;
+
+ return pmbus_do_probe(client, info);
+}
+
+static const struct of_device_id mpq7932_of_match[] = {
+ { .compatible = "mps,mpq7932"},
+ {},
+};
+MODULE_DEVICE_TABLE(of, mpq7932_of_match);
+
+static const struct i2c_device_id mpq7932_id[] = {
+ { "mpq7932", },
+ { },
+};
+MODULE_DEVICE_TABLE(i2c, mpq7932_id);
+
+static struct i2c_driver mpq7932_regulator_driver = {
+ .driver = {
+ .name = "mpq7932",
+ .of_match_table = mpq7932_of_match,
+ },
+ .probe_new = mpq7932_probe,
+ .id_table = mpq7932_id,
+};
+module_i2c_driver(mpq7932_regulator_driver);
+
+MODULE_AUTHOR("Saravanan Sekar <saravanan@linumiz.com>");
+MODULE_DESCRIPTION("MPQ7932 PMIC regulator driver");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS(PMBUS);
diff --git a/drivers/hwmon/pmbus/pmbus.h b/drivers/hwmon/pmbus/pmbus.h
index 10fb17879f8e..713ea7915425 100644
--- a/drivers/hwmon/pmbus/pmbus.h
+++ b/drivers/hwmon/pmbus/pmbus.h
@@ -464,7 +464,7 @@ struct pmbus_driver_info {
extern const struct regulator_ops pmbus_regulator_ops;
/* Macros for filling in array of struct regulator_desc */
-#define PMBUS_REGULATOR_STEP(_name, _id, _voltages, _step) \
+#define PMBUS_REGULATOR_STEP(_name, _id, _voltages, _step, _min_uV) \
[_id] = { \
.name = (_name # _id), \
.id = (_id), \
@@ -475,9 +475,10 @@ extern const struct regulator_ops pmbus_regulator_ops;
.owner = THIS_MODULE, \
.n_voltages = _voltages, \
.uV_step = _step, \
+ .min_uV = _min_uV, \
}
-#define PMBUS_REGULATOR(_name, _id) PMBUS_REGULATOR_STEP(_name, _id, 0, 0)
+#define PMBUS_REGULATOR(_name, _id) PMBUS_REGULATOR_STEP(_name, _id, 0, 0, 0)
/* Function declarations */
diff --git a/drivers/hwmon/pmbus/tda38640.c b/drivers/hwmon/pmbus/tda38640.c
new file mode 100644
index 000000000000..c3e781319cd1
--- /dev/null
+++ b/drivers/hwmon/pmbus/tda38640.c
@@ -0,0 +1,74 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Hardware monitoring driver for Infineon TDA38640
+ *
+ * Copyright (c) 2023 9elements GmbH
+ *
+ */
+
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/regulator/driver.h>
+#include "pmbus.h"
+
+static const struct regulator_desc __maybe_unused tda38640_reg_desc[] = {
+ PMBUS_REGULATOR("vout", 0),
+};
+
+static struct pmbus_driver_info tda38640_info = {
+ .pages = 1,
+ .format[PSC_VOLTAGE_IN] = linear,
+ .format[PSC_VOLTAGE_OUT] = linear,
+ .format[PSC_CURRENT_OUT] = linear,
+ .format[PSC_CURRENT_IN] = linear,
+ .format[PSC_POWER] = linear,
+ .format[PSC_TEMPERATURE] = linear,
+
+ .func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT
+ | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP
+ | PMBUS_HAVE_IIN
+ | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
+ | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT
+ | PMBUS_HAVE_POUT | PMBUS_HAVE_PIN,
+#if IS_ENABLED(CONFIG_SENSORS_TDA38640_REGULATOR)
+ .num_regulators = 1,
+ .reg_desc = tda38640_reg_desc,
+#endif
+};
+
+static int tda38640_probe(struct i2c_client *client)
+{
+ return pmbus_do_probe(client, &tda38640_info);
+}
+
+static const struct i2c_device_id tda38640_id[] = {
+ {"tda38640", 0},
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, tda38640_id);
+
+static const struct of_device_id __maybe_unused tda38640_of_match[] = {
+ { .compatible = "infineon,tda38640"},
+ { },
+};
+MODULE_DEVICE_TABLE(of, tda38640_of_match);
+
+/* This is the driver that will be inserted */
+static struct i2c_driver tda38640_driver = {
+ .driver = {
+ .name = "tda38640",
+ .of_match_table = of_match_ptr(tda38640_of_match),
+ },
+ .probe_new = tda38640_probe,
+ .id_table = tda38640_id,
+};
+
+module_i2c_driver(tda38640_driver);
+
+MODULE_AUTHOR("Patrick Rudolph <patrick.rudolph@9elements.com>");
+MODULE_DESCRIPTION("PMBus driver for Infineon TDA38640");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS(PMBUS);