From: Guenter Roeck <linux@roeck-us.net>
To: linux-hwmon@vger.kernel.org
Cc: Jean Delvare <jdelvare@suse.com>,
devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-doc@vger.kernel.org, Rob Herring <robh+dt@kernel.org>,
Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>,
Guenter Roeck <linux@roeck-us.net>
Subject: [PATCH v2 3/3] hwmon: (pmbus) Add support for Analog Devices LT7182S
Date: Tue, 24 May 2022 18:07:17 -0700 [thread overview]
Message-ID: <20220525010717.4000736-3-linux@roeck-us.net> (raw)
In-Reply-To: <20220525010717.4000736-1-linux@roeck-us.net>
Add support for Analog Devices LT7182S Dual Channel 6A, 20V PolyPhase
Step-Down Silent Switcher with Digital Power System Management.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
v2: New patch
Documentation/hwmon/index.rst | 1 +
Documentation/hwmon/lt7182s.rst | 91 +++++++++++++++
drivers/hwmon/pmbus/Kconfig | 9 ++
drivers/hwmon/pmbus/Makefile | 1 +
drivers/hwmon/pmbus/lt7182s.c | 195 ++++++++++++++++++++++++++++++++
5 files changed, 297 insertions(+)
create mode 100644 Documentation/hwmon/lt7182s.rst
create mode 100644 drivers/hwmon/pmbus/lt7182s.c
diff --git a/Documentation/hwmon/index.rst b/Documentation/hwmon/index.rst
index a72c16872ec2..f7113b0f8b2a 100644
--- a/Documentation/hwmon/index.rst
+++ b/Documentation/hwmon/index.rst
@@ -109,6 +109,7 @@ Hardware Monitoring Kernel Drivers
lm95234
lm95245
lochnagar
+ lt7182s
ltc2992
ltc2945
ltc2947
diff --git a/Documentation/hwmon/lt7182s.rst b/Documentation/hwmon/lt7182s.rst
new file mode 100644
index 000000000000..aac7789d807b
--- /dev/null
+++ b/Documentation/hwmon/lt7182s.rst
@@ -0,0 +1,91 @@
+.. SPDX-License-Identifier: GPL-2.0
+Kernel driver lt7182s
+=====================
+
+Supported chips:
+
+ * ADI LT7182S
+
+ Prefix: 'lt7182s'
+
+ Addresses scanned: -
+
+ Datasheet: https://www.analog.com/en/products/lt7182s.html
+
+Author: Guenter Roeck <linux@roeck-us.net>
+
+
+Description
+-----------
+
+LT7182S is a Dual Channel 6A, 20V PolyPhase Step-Down Silent Switcher with
+Digital Power System Management support.
+
+
+Usage Notes
+-----------
+
+This driver does not probe for PMBus devices. You will have to instantiate
+devices explicitly.
+
+Example: the following commands will load the driver for a LT7182S
+at address 0x4f on I2C bus #4::
+
+ # modprobe lt7182s
+ # echo lt7182s 0x4f > /sys/bus/i2c/devices/i2c-4/new_device
+
+It can also be instantiated by declaring an entry in device tree.
+
+
+Sysfs attributes
+----------------
+
+====================== ====================================
+curr[1-2]_label "iin[12]"
+curr[1-2]_input Measured input current
+curr[1-2]_max Maximum input current
+curr[1-2]_max_alarm Current high alarm
+
+curr[3-4]_label "iout[1-2]"
+curr[3-4]_input Measured output current
+curr[3-4]_highest Highest measured output current
+curr[3-4]_max Maximum output current
+curr[3-4]_max_alarm Output current high alarm
+
+in[1-2]_label "vin[12]"
+in[1-2]_input Measured input voltage
+in[1-2]_highest Highest measured input voltage
+in[1-2]_crit Critical maximum input voltage
+in[1-2]_crit_alarm Input voltage critical high alarm
+in[1-2]_min Minimum input voltage
+in[1-2]_min_alarm Input voltage low alarm
+in[1-2]_rated_min Rated minimum input voltage
+in[1-2]_rated_max Rated maximum input voltage
+in1_reset_history Write to reset history for all attributes
+
+in[3-5]_label "vmon[1-3]"
+in[3-5]_input Measured voltage on ITH1/ITH2/EXTVCC pins
+ Only available if enabled with MFR_ADC_CONTROL_LT7182S
+ command.
+
+in[3-4|6-7]_label "vout[1-2]"
+in[3-4|6-7]_input Measured output voltage
+in[3-4|6-7]_highest Highest measured output voltage
+in[3-4|6-7]_lcrit Critical minimum output voltage
+in[3-4|6-7]_lcrit_alarm Output voltage critical low alarm
+in[3-4|6-7]_min Minimum output voltage
+in[3-4|6-7]_max_alarm Output voltage low alarm
+in[3-4|6-7]_max Maximum output voltage
+in[3-4|6-7]_max_alarm Output voltage high alarm
+in[3-4|6-7]_crit Critical maximum output voltage
+in[3-4|6-7]_crit_alarm Output voltage critical high alarm
+
+power[1-2]_label "pout[1-2]"
+power[1-2]_input Measured output power
+
+temp1_input Measured temperature
+temp1_crit Critical high temperature
+temp1_crit_alarm Chip temperature critical high alarm
+temp1_max Maximum temperature
+temp1_max_alarm Chip temperature high alarm
+====================== ====================================
diff --git a/drivers/hwmon/pmbus/Kconfig b/drivers/hwmon/pmbus/Kconfig
index dfae76db65ae..951e4a9ff2d6 100644
--- a/drivers/hwmon/pmbus/Kconfig
+++ b/drivers/hwmon/pmbus/Kconfig
@@ -181,6 +181,15 @@ config SENSORS_LM25066_REGULATOR
If you say yes here you get regulator support for National
Semiconductor LM25066, LM5064, and LM5066.
+config SENSORS_LT7182S
+ tristate "Analog Devices LT7182S"
+ help
+ If you say yes here you get hardware monitoring support for Analog
+ Devices LT7182S.
+
+ This driver can also be built as a module. If so, the module will
+ be called lt7182s.
+
config SENSORS_LTC2978
tristate "Linear Technologies LTC2978 and compatibles"
help
diff --git a/drivers/hwmon/pmbus/Makefile b/drivers/hwmon/pmbus/Makefile
index 4678fba5012c..e2fe86f98965 100644
--- a/drivers/hwmon/pmbus/Makefile
+++ b/drivers/hwmon/pmbus/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_SENSORS_IR38064) += ir38064.o
obj-$(CONFIG_SENSORS_IRPS5401) += irps5401.o
obj-$(CONFIG_SENSORS_ISL68137) += isl68137.o
obj-$(CONFIG_SENSORS_LM25066) += lm25066.o
+obj-$(CONFIG_SENSORS_LT7182S) += lt7182s.o
obj-$(CONFIG_SENSORS_LTC2978) += ltc2978.o
obj-$(CONFIG_SENSORS_LTC3815) += ltc3815.o
obj-$(CONFIG_SENSORS_MAX15301) += max15301.o
diff --git a/drivers/hwmon/pmbus/lt7182s.c b/drivers/hwmon/pmbus/lt7182s.c
new file mode 100644
index 000000000000..4cfe476fc92d
--- /dev/null
+++ b/drivers/hwmon/pmbus/lt7182s.c
@@ -0,0 +1,195 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Hardware monitoring driver for Analog Devices LT7182S
+ *
+ * Copyright (c) 2022 Guenter Roeck
+ *
+ */
+
+#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.h>
+#include "pmbus.h"
+
+#define LT7182S_NUM_PAGES 2
+
+#define MFR_READ_EXTVCC 0xcd
+#define MFR_READ_ITH 0xce
+#define MFR_CONFIG_ALL_LT7182S 0xd1
+#define MFR_IOUT_PEAK 0xd7
+#define MFR_ADC_CONTROL_LT7182S 0xd8
+
+#define MFR_DEBUG_TELEMETRY BIT(0)
+
+#define MFR_VOUT_PEAK 0xdd
+#define MFR_VIN_PEAK 0xde
+#define MFR_TEMPERATURE_1_PEAK 0xdf
+#define MFR_CLEAR_PEAKS 0xe3
+
+#define MFR_CONFIG_IEEE BIT(8)
+
+static int lt7182s_read_word_data(struct i2c_client *client, int page, int phase, int reg)
+{
+ int ret;
+
+ switch (reg) {
+ case PMBUS_VIRT_READ_VMON:
+ if (page == 0 || page == 1)
+ ret = pmbus_read_word_data(client, page, phase, MFR_READ_ITH);
+ else
+ ret = pmbus_read_word_data(client, 0, phase, MFR_READ_EXTVCC);
+ break;
+ case PMBUS_VIRT_READ_IOUT_MAX:
+ ret = pmbus_read_word_data(client, page, phase, MFR_IOUT_PEAK);
+ break;
+ case PMBUS_VIRT_READ_VOUT_MAX:
+ ret = pmbus_read_word_data(client, page, phase, MFR_VOUT_PEAK);
+ break;
+ case PMBUS_VIRT_READ_VIN_MAX:
+ ret = pmbus_read_word_data(client, page, phase, MFR_VIN_PEAK);
+ break;
+ case PMBUS_VIRT_READ_TEMP_MAX:
+ ret = pmbus_read_word_data(client, page, phase, MFR_TEMPERATURE_1_PEAK);
+ break;
+ case PMBUS_VIRT_RESET_VIN_HISTORY:
+ ret = (page == 0) ? 0 : -ENODATA;
+ break;
+ default:
+ ret = -ENODATA;
+ break;
+ }
+ return ret;
+}
+
+static int lt7182s_write_word_data(struct i2c_client *client, int page, int reg, u16 word)
+{
+ int ret;
+
+ switch (reg) {
+ case PMBUS_VIRT_RESET_VIN_HISTORY:
+ ret = pmbus_write_byte(client, 0, MFR_CLEAR_PEAKS);
+ break;
+ default:
+ ret = -ENODATA;
+ break;
+ }
+ return ret;
+}
+
+static struct pmbus_driver_info lt7182s_info = {
+ .pages = LT7182S_NUM_PAGES,
+ .format[PSC_VOLTAGE_IN] = linear,
+ .format[PSC_VOLTAGE_OUT] = linear,
+ .format[PSC_CURRENT_IN] = linear,
+ .format[PSC_CURRENT_OUT] = linear,
+ .format[PSC_TEMPERATURE] = linear,
+ .format[PSC_POWER] = linear,
+ .func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT |
+ PMBUS_HAVE_IIN | PMBUS_HAVE_IOUT | PMBUS_HAVE_POUT |
+ PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_STATUS_IOUT |
+ PMBUS_HAVE_STATUS_INPUT | PMBUS_HAVE_STATUS_TEMP,
+ .func[1] = PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT |
+ PMBUS_HAVE_IIN | PMBUS_HAVE_IOUT | PMBUS_HAVE_POUT |
+ PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_STATUS_IOUT |
+ PMBUS_HAVE_STATUS_INPUT,
+ .read_word_data = lt7182s_read_word_data,
+ .write_word_data = lt7182s_write_word_data,
+};
+
+static int lt7182s_probe(struct i2c_client *client)
+{
+ struct device *dev = &client->dev;
+ struct pmbus_driver_info *info;
+ u8 buf[I2C_SMBUS_BLOCK_MAX + 1];
+ int ret;
+
+ if (!i2c_check_functionality(client->adapter,
+ I2C_FUNC_SMBUS_READ_BYTE_DATA |
+ I2C_FUNC_SMBUS_READ_WORD_DATA |
+ I2C_FUNC_SMBUS_READ_BLOCK_DATA))
+ return -ENODEV;
+
+ ret = i2c_smbus_read_block_data(client, PMBUS_MFR_ID, buf);
+ if (ret < 0) {
+ dev_err(dev, "Failed to read PMBUS_MFR_ID\n");
+ return ret;
+ }
+ if (ret != 3 || strncmp(buf, "ADI", 3)) {
+ buf[ret] = '\0';
+ dev_err(dev, "Manufacturer '%s' not supported\n", buf);
+ return -ENODEV;
+ }
+
+ ret = i2c_smbus_read_block_data(client, PMBUS_MFR_MODEL, buf);
+ if (ret < 0) {
+ dev_err(dev, "Failed to read PMBUS_MFR_MODEL\n");
+ return ret;
+ }
+ if (ret != 7 || strncmp(buf, "LT7182S", 7)) {
+ buf[ret] = '\0';
+ dev_err(dev, "Model '%s' not supported\n", buf);
+ return -ENODEV;
+ }
+
+ info = devm_kmemdup(dev, <7182s_info,
+ sizeof(struct pmbus_driver_info), GFP_KERNEL);
+ if (!info)
+ return -ENOMEM;
+
+ /* Set data format to IEEE754 if configured */
+ ret = i2c_smbus_read_word_data(client, MFR_CONFIG_ALL_LT7182S);
+ if (ret < 0)
+ return ret;
+ if (ret & MFR_CONFIG_IEEE) {
+ info->format[PSC_VOLTAGE_IN] = ieee754;
+ info->format[PSC_VOLTAGE_OUT] = ieee754;
+ info->format[PSC_CURRENT_IN] = ieee754;
+ info->format[PSC_CURRENT_OUT] = ieee754;
+ info->format[PSC_TEMPERATURE] = ieee754;
+ info->format[PSC_POWER] = ieee754;
+ }
+
+ /* Enable VMON output if configured */
+ ret = i2c_smbus_read_byte_data(client, MFR_ADC_CONTROL_LT7182S);
+ if (ret < 0)
+ return ret;
+ if (ret & MFR_DEBUG_TELEMETRY) {
+ info->pages = 3;
+ info->func[0] |= PMBUS_HAVE_VMON;
+ info->func[1] |= PMBUS_HAVE_VMON;
+ info->func[2] = PMBUS_HAVE_VMON;
+ }
+
+ return pmbus_do_probe(client, info);
+}
+
+static const struct i2c_device_id lt7182s_id[] = {
+ { "lt7182s", 0 },
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, lt7182s_id);
+
+static const struct of_device_id __maybe_unused lt7182s_of_match[] = {
+ { .compatible = "adi,lt7182s" },
+ {}
+};
+
+static struct i2c_driver lt7182s_driver = {
+ .driver = {
+ .name = "lt7182s",
+ .of_match_table = of_match_ptr(lt7182s_of_match),
+ },
+ .probe_new = lt7182s_probe,
+ .id_table = lt7182s_id,
+};
+
+module_i2c_driver(lt7182s_driver);
+
+MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>");
+MODULE_DESCRIPTION("PMBus driver for Analog Devices LT7182S");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS(PMBUS);
--
2.35.1
prev parent reply other threads:[~2022-05-25 1:07 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-05-25 1:07 [PATCH v2 1/3] hwmon: (pmbus) Add IEEE 754 half precision support to PMBus core Guenter Roeck
2022-05-25 1:07 ` [PATCH v2 2/3] dt-bindings: trivial-devices: Add lt7182s Guenter Roeck
2022-05-26 12:40 ` Krzysztof Kozlowski
2022-05-25 1:07 ` Guenter Roeck [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220525010717.4000736-3-linux@roeck-us.net \
--to=linux@roeck-us.net \
--cc=devicetree@vger.kernel.org \
--cc=jdelvare@suse.com \
--cc=krzysztof.kozlowski+dt@linaro.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-hwmon@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=robh+dt@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.