From 30f6cb0eb86dbc9e08f20fc41080a772b118c3e3 Mon Sep 17 00:00:00 2001
From: Michael Jones <Michael-A1.Jones@analog.com>
Date: Mon, 11 Nov 2024 13:41:12 -0700
Subject: [PATCH] Add devices LTC2971, LTC2980_24, LTC3888, LTC7841, LTC7883,
 LTM4673, LTM4681, LTM4683, LTC7131, LTC7132, LT7182S, LT7170, LT7171

---
 Documentation/hwmon/ltc2978.rst | 128 ++++++++--
 drivers/hwmon/pmbus/Kconfig     |  21 +-
 drivers/hwmon/pmbus/ltc2978.c   | 429 +++++++++++++++++++++++++++++++-
 3 files changed, 536 insertions(+), 42 deletions(-)

diff --git a/Documentation/hwmon/ltc2978.rst b/Documentation/hwmon/ltc2978.rst
index edf24e5e1e11..3ce5fd5ceacb 100644
--- a/Documentation/hwmon/ltc2978.rst
+++ b/Documentation/hwmon/ltc2978.rst
@@ -3,13 +3,21 @@ Kernel driver ltc2978
 
 Supported chips:
 
+  * Linear Technology LTC2971
+
+    Prefix: 'ltc2971'
+
+    Addresses scanned: -
+
+    Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/ltc2971.pdf
+
   * Linear Technology LTC2972
 
     Prefix: 'ltc2972'
 
     Addresses scanned: -
 
-    Datasheet: https://www.analog.com/en/products/ltc2972.html
+    Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/ltc2972.pdf
 
   * Linear Technology LTC2974
 
@@ -17,7 +25,7 @@ Supported chips:
 
     Addresses scanned: -
 
-    Datasheet: https://www.analog.com/en/products/ltc2974
+    Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/ltc2974.pdf
 
   * Linear Technology LTC2975
 
@@ -25,7 +33,7 @@ Supported chips:
 
     Addresses scanned: -
 
-    Datasheet: https://www.analog.com/en/products/ltc2975
+    Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/ltc2975.pdf
 
   * Linear Technology LTC2977
 
@@ -33,7 +41,7 @@ Supported chips:
 
     Addresses scanned: -
 
-    Datasheet: https://www.analog.com/en/products/ltc2977
+    Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/ltc2977.pdf
 
   * Linear Technology LTC2978, LTC2978A
 
@@ -41,9 +49,9 @@ Supported chips:
 
     Addresses scanned: -
 
-    Datasheet: https://www.analog.com/en/products/ltc2978
+    Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/2978fd.pdf
 
-	       https://www.analog.com/en/products/ltc2978a
+	       https://www.analog.com/media/en/technical-documentation/data-sheets/2978afb.pdf
 
   * Linear Technology LTC2979
 
@@ -51,7 +59,7 @@ Supported chips:
 
     Addresses scanned: -
 
-    Datasheet: https://www.analog.com/en/products/ltc2979
+    Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/ltc2979.pdf
 
   * Linear Technology LTC2980
 
@@ -59,7 +67,15 @@ Supported chips:
 
     Addresses scanned: -
 
-    Datasheet: https://www.analog.com/en/products/ltc2980
+    Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/ltc2980.pdf
+
+  * Linear Technology LTC2980_24
+
+    Prefix: 'ltc2980_24'
+
+    Addresses scanned: -
+
+    Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/ltc2980-24.pdf
 
   * Linear Technology LTC3880
 
@@ -67,7 +83,7 @@ Supported chips:
 
     Addresses scanned: -
 
-    Datasheet: https://www.analog.com/en/products/ltc3880
+    Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/LTC3880-3880-1.pdf
 
   * Linear Technology LTC3882
 
@@ -75,7 +91,7 @@ Supported chips:
 
     Addresses scanned: -
 
-    Datasheet: https://www.analog.com/en/products/ltc3882
+    Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/LTC3882.pdf
 
   * Linear Technology LTC3883
 
@@ -83,7 +99,7 @@ Supported chips:
 
     Addresses scanned: -
 
-    Datasheet: https://www.analog.com/en/products/ltc3883
+    Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/LTC3883-3883-1.pdf
 
   * Linear Technology LTC3884
 
@@ -91,7 +107,7 @@ Supported chips:
 
     Addresses scanned: -
 
-    Datasheet: https://www.analog.com/en/products/ltc3884
+    Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/ltc3884-3884-1.pdf
 
   * Linear Technology LTC3886
 
@@ -99,7 +115,7 @@ Supported chips:
 
     Addresses scanned: -
 
-    Datasheet: https://www.analog.com/en/products/ltc3886
+    Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/ltc3886-3886-1.pdf
 
   * Linear Technology LTC3887
 
@@ -107,7 +123,15 @@ Supported chips:
 
     Addresses scanned: -
 
-    Datasheet: https://www.analog.com/en/products/ltc3887
+    Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/LTC3887-3887-1-3887-2.pdf
+
+  * Linear Technology LTC3888
+
+    Prefix: 'ltc3888'
+
+    Addresses scanned: -
+
+    Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/ltc3888-3888-1-3888-2.pdf
 
   * Linear Technology LTC3889
 
@@ -115,7 +139,15 @@ Supported chips:
 
     Addresses scanned: -
 
-    Datasheet: https://www.analog.com/en/products/ltc3889
+    Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/ltc3889.pdf
+
+  * Linear Technology LTC7841
+
+    Prefix: 'ltc7841'
+
+    Addresses scanned: -
+
+    Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/ltc7841.pdf
 
   * Linear Technology LTC7880
 
@@ -123,7 +155,15 @@ Supported chips:
 
     Addresses scanned: -
 
-    Datasheet: https://www.analog.com/en/products/ltc7880
+    Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/LTC7880.pdf
+
+  * Linear Technology LTC7883
+
+    Prefix: 'ltc7883'
+
+    Addresses scanned: -
+
+    Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/ltc7883.pdf
 
   * Linear Technology LTM2987
 
@@ -131,7 +171,7 @@ Supported chips:
 
     Addresses scanned: -
 
-    Datasheet: https://www.analog.com/en/products/ltm2987
+    Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/ltm2987.pdf
 
   * Linear Technology LTM4644
 
@@ -139,7 +179,15 @@ Supported chips:
 
     Addresses scanned: -
 
-    Datasheet: https://www.analog.com/en/products/ltm4644
+    Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/LTM4644-4644-1.pdf
+
+   * Linear Technology LTM4673
+
+    Prefix: 'ltm4673'
+
+    Addresses scanned: -
+
+    Datasheet: hhttps://www.analog.com/media/en/technical-documentation/data-sheets/ltm4673.pdf
 
    * Linear Technology LTM4675
 
@@ -147,7 +195,7 @@ Supported chips:
 
     Addresses scanned: -
 
-    Datasheet: https://www.analog.com/en/products/ltm4675
+    Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/ltm4675.pdf
 
   * Linear Technology LTM4676
 
@@ -155,7 +203,7 @@ Supported chips:
 
     Addresses scanned: -
 
-    Datasheet: https://www.analog.com/en/products/ltm4676
+    Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/4676fd.pdf
 
   * Linear Technology LTM4677
 
@@ -163,7 +211,7 @@ Supported chips:
 
     Addresses scanned: -
 
-    Datasheet: https://www.analog.com/en/products/ltm4677
+    Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/ltm4677.pdf
 
   * Linear Technology LTM4678
 
@@ -171,7 +219,7 @@ Supported chips:
 
     Addresses scanned: -
 
-    Datasheet: https://www.analog.com/en/products/ltm4678
+    Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/ltm4678.pdf
 
   * Analog Devices LTM4680
 
@@ -179,7 +227,23 @@ Supported chips:
 
     Addresses scanned: -
 
-    Datasheet: https://www.analog.com/ltm4680
+    Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/ltm4680.pdf
+
+  * Analog Devices LTM4681
+
+    Prefix: 'ltm4681'
+
+    Addresses scanned: -
+
+    Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/ltm4681.pdf
+
+  * Analog Devices LTM4683
+
+    Prefix: 'ltm4683'
+
+    Addresses scanned: -
+
+    Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/ltm4683.pdf
 
   * Analog Devices LTM4686
 
@@ -187,7 +251,7 @@ Supported chips:
 
     Addresses scanned: -
 
-    Datasheet: https://www.analog.com/ltm4686
+    Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/ltm4686-4686-1.pdf
 
   * Analog Devices LTM4700
 
@@ -195,9 +259,23 @@ Supported chips:
 
     Addresses scanned: -
 
-    Datasheet: https://www.analog.com/ltm4700
+    Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/ltm4700.pdf
+
+  * Analog Devices LTC7131
+
+    Prefix: 'ltc7131'
+
+    Addresses scanned: -
+
+    Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/ltc7131-1.pdf
 
+  * Analog Devices LTC7132
+
+    Prefix: 'ltc7132'
+
+    Addresses scanned: -
 
+    Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/ltc7132.pdf
 
 Author: Guenter Roeck <linux@roeck-us.net>
 
diff --git a/drivers/hwmon/pmbus/Kconfig b/drivers/hwmon/pmbus/Kconfig
index 294808f5240a..b7225d793b55 100644
--- a/drivers/hwmon/pmbus/Kconfig
+++ b/drivers/hwmon/pmbus/Kconfig
@@ -202,9 +202,16 @@ config SENSORS_LT7182S
 config SENSORS_LTC2978
 	tristate "Linear Technologies LTC2978 and compatibles"
 	help
-	  If you say yes here you get hardware monitoring support for Linear
-	  Technology LTC2972, LTC2974, LTC2975, LTC2977, LTC2978, LTC2979,
-	  LTC2980, and LTM2987.
+	  If you say yes here you get hardware monitoring support for Analog
+	  Devices LTC2971, LTC2972, LTC2974, LTC2975, LTC2977, LTC2978, LTC2979,
+	  LTC2980, LTC2980_24, LTM2987,
+	  LTC3880, LTC3882, LTC3883, LTC3884, 
+	  LTC3886, LTC3887, LTC3888, LTC3889,
+	  LTC7841, LTC7880, LTC7883, LTM4664, 
+	  LTM4673, LTM4675, LTM4676, LTM5677, 
+	  LTM4678, LTM4680, LTM4681, LTM4683, 
+	  LTM4686, LTM4700,
+	  LTC7131m LTC7132, LT7170, LT7171
 
 	  This driver can also be built as a module. If so, the module will
 	  be called ltc2978.
@@ -214,8 +221,12 @@ config SENSORS_LTC2978_REGULATOR
 	depends on SENSORS_LTC2978 && REGULATOR
 	help
 	  If you say yes here you get regulator support for Linear Technology
-	  LTC3880, LTC3883, LTC3884, LTC3886, LTC3887, LTC3889, LTC7880,
-	  LTM4644, LTM4675, LTM4676, LTM4677, LTM4678, LTM4680, LTM4686,
+	  LTC3880, LTC3882, LTC3883, LTC3884, 
+	  LTC3886, LTC3887, LTC3888, LTC3889, 
+	  LTC7841, LTC7880, LTC7883,
+	  LTM4644, LTM4673, LTM4675, LTM4676, 
+	  LTM4677, LTM4678, LTM4680, LTM4681,
+	  LTM4683, LTM4686, LTM4700
 	  and LTM4700.
 
 config SENSORS_LTC3815
diff --git a/drivers/hwmon/pmbus/ltc2978.c b/drivers/hwmon/pmbus/ltc2978.c
index 73a86f4d6472..02d1516d50bd 100644
--- a/drivers/hwmon/pmbus/ltc2978.c
+++ b/drivers/hwmon/pmbus/ltc2978.c
@@ -5,7 +5,7 @@
  * Copyright (c) 2011 Ericsson AB.
  * Copyright (c) 2013, 2014, 2015 Guenter Roeck
  * Copyright (c) 2015 Linear Technology
- * Copyright (c) 2018 Analog Devices Inc.
+ * Copyright (c) 2018-2024 Analog Devices Inc.
  */
 
 #include <linux/delay.h>
@@ -16,17 +16,22 @@
 #include <linux/err.h>
 #include <linux/slab.h>
 #include <linux/i2c.h>
+#include <linux/pmbus.h>
 #include <linux/regulator/driver.h>
 #include "pmbus.h"
 
-enum chips {
+enum chips : u64 {
 	/* Managers */
-	ltc2972, ltc2974, ltc2975, ltc2977, ltc2978, ltc2979, ltc2980,
+	ltc2971, ltc2972, ltc2974, ltc2975, ltc2977, ltc2978, ltc2979, ltc2980,
 	/* Controllers */
-	ltc3880, ltc3882, ltc3883, ltc3884, ltc3886, ltc3887, ltc3889, ltc7132, ltc7880,
+	ltc3880, ltc3882, ltc3883, ltc3884, ltc3886, ltc3887, ltc3888, ltc3889, ltc7841, ltc7880, ltc7883,
 	/* Modules */
-	ltm2987, ltm4664, ltm4675, ltm4676, ltm4677, ltm4678, ltm4680, ltm4686,
+	ltm2987, ltm4664, ltm4673, ltm4675, ltm4676, ltm4677, ltm4678, ltm4680, ltm4681, ltm4683, ltm4686,
 	ltm4700,
+	/* Monolithics */
+	ltc7131, ltc7132,
+	/* ID 0xC1D1 devices */
+	lt7182s, lt7170, lt7171,
 };
 
 /* Common for all chips */
@@ -61,6 +66,14 @@ enum chips {
 
 #define LTC2978_ID_MASK			0xfff0
 
+#define LTC7131_MFR_IIN_PEAK		0x89
+#define LTC7131_MFR_IOUT_PEAK		0x8c
+
+#define LTC7841_MFR_CONFIG		0xe9
+#define LTC7841_TEMP_MODE		0x04
+
+
+#define LTC2971_ID			0x0320
 #define LTC2972_ID			0x0310
 #define LTC2974_ID			0x0210
 #define LTC2975_ID			0x0220
@@ -71,6 +84,9 @@ enum chips {
 #define LTC2979_ID_B			0x8070
 #define LTC2980_ID_A			0x8030	/* A/B for two die IDs */
 #define LTC2980_ID_B			0x8040
+#define LTC2980_24_ID_A 		0x80A0  /* A/B/C for two die IDs */
+#define LTC2980_24_ID_B 		0x80B0
+#define LTC2980_24_ID_C 		0x80C0
 #define LTC3880_ID			0x4020
 #define LTC3882_ID			0x4200
 #define LTC3882_ID_D1			0x4240	/* Dash 1 */
@@ -78,12 +94,16 @@ enum chips {
 #define LTC3884_ID			0x4C00
 #define LTC3886_ID			0x4600
 #define LTC3887_ID			0x4700
+#define LTC3888_ID			0x4800
 #define LTC3889_ID			0x4900
-#define LTC7132_ID			0x4CE0
+#define LTC7841_ID			0x40D0
 #define LTC7880_ID			0x49E0
+#define LTC7883_ID_A			0x4500
+#define LTC7883_ID_B			0x4510
 #define LTM2987_ID_A			0x8010	/* A/B for two die IDs */
 #define LTM2987_ID_B			0x8020
 #define LTM4664_ID			0x4120
+#define LTM4673_ID 			0x0230
 #define LTM4675_ID			0x47a0
 #define LTM4676_ID_REV1			0x4400
 #define LTM4676_ID_REV2			0x4480
@@ -92,9 +112,21 @@ enum chips {
 #define LTM4677_ID_REV2			0x47D0
 #define LTM4678_ID_REV1			0x4100
 #define LTM4678_ID_REV2			0x4110
+#define LTM4681_ID			0x4150
+#define LTM4683_ID_REV1			0x4740
+#define LTM4683_ID_REV2			0x4190
 #define LTM4680_ID			0x4140
 #define LTM4686_ID			0x4770
 #define LTM4700_ID			0x4130
+#define LTC7131_ID 			0x40E0
+#define LTC7132_ID			0x4CE0
+#define LTC_UNIVERSAL_ID		0x1C1D
+
+#define LT7182S_ID			"LT7182S"
+#define LT7170_ID			"LT7170"
+#define LT7170_1_ID			"LT7170-1"
+#define LT7171_ID			"LT7171"
+#define LT7171_1_ID			"LT7171-1"
 
 #define LTC2972_NUM_PAGES		2
 #define LTC2974_NUM_PAGES		4
@@ -218,6 +250,28 @@ static int ltc_write_byte(struct i2c_client *client, int page, u8 byte)
 	return pmbus_write_byte(client, page, byte);
 }
 
+static int ltc_read_word_data_ltc7841(struct i2c_client *client, int page, int phase,
+                             int reg)
+{
+       return pmbus_read_word_data(client, -1, 0xff, reg);
+}
+
+static int ltc_read_byte_data_ltc7841(struct i2c_client *client, int page, int reg)
+{
+       return pmbus_read_byte_data(client, -1, reg);
+}
+
+static int ltc_write_byte_data_ltc7841(struct i2c_client *client, int page, int reg, u8 value)
+{
+       return pmbus_write_byte_data(client, -1, reg, value);
+}
+
+static int ltc_write_byte_ltc7841(struct i2c_client *client, int page, u8 byte)
+{
+       return pmbus_write_byte(client, -1, byte);
+}
+
+
 static inline int lin11_to_val(int data)
 {
 	s16 e = ((s16)data) >> 11;
@@ -532,7 +586,86 @@ static int ltc2978_write_word_data(struct i2c_client *client, int page,
 	return ret;
 }
 
+static int ltc7131_write_byte(struct i2c_client *client, int page, u8 value)
+{
+	if (value == PMBUS_CLEAR_FAULTS)
+		return pmbus_write_word_data(client, page, PMBUS_STATUS_WORD, 0xFFFF);
+	return pmbus_write_byte(client, page, value);
+}
+
+static int ltc7131_read_byte_data(struct i2c_client *client, int page, int reg)
+{
+	if (reg == PMBUS_VOUT_MODE)
+		/* Force direct. Actual value is vid, but READ_VOUT is direct. */
+		return 0x40; 
+	return pmbus_read_byte_data(client, page, reg);
+}
+
+static int ltc7131_read_word_data(struct i2c_client *client, int page, int phase, int reg)
+{
+	int ret;
+
+	switch (reg) {
+	case PMBUS_VIRT_READ_VIN_MAX:
+		ret = pmbus_read_word_data(client, page,
+					   LTC2978_MFR_VIN_PEAK, 0);
+		break;
+	case PMBUS_VIRT_READ_VOUT_MAX:
+		ret = pmbus_read_word_data(client, page,
+					   LTC2978_MFR_VOUT_PEAK, 0);
+		break;
+	case PMBUS_VIRT_READ_IIN_MAX:
+		ret = pmbus_read_word_data(client, page,
+					   LTC7131_MFR_IIN_PEAK, 0);
+		break;
+	case PMBUS_VIRT_READ_IOUT_MAX:
+		ret = pmbus_read_word_data(client, page,
+					   LTC7131_MFR_IOUT_PEAK, 0);
+		break;
+	case PMBUS_VIRT_RESET_VIN_HISTORY:
+	case PMBUS_VIRT_RESET_VOUT_HISTORY:
+	case PMBUS_VIRT_RESET_IIN_HISTORY:
+	case PMBUS_VIRT_RESET_IOUT_HISTORY:
+		ret = 0;
+		break;
+	default:
+		ret = -ENODATA;
+		break;
+	}
+	return ret;
+}
+
+static int ltc7131_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_data(client, page,
+					    LTC3880_MFR_CLEAR_PEAKS, 0);
+		break;
+	case PMBUS_VIRT_RESET_VOUT_HISTORY:
+		ret = pmbus_write_byte_data(client, page,
+					    LTC3880_MFR_CLEAR_PEAKS, 0);
+		break;
+	case PMBUS_VIRT_RESET_IIN_HISTORY:
+		ret = pmbus_write_byte_data(client, page,
+					    LTC3880_MFR_CLEAR_PEAKS, 0);
+		break;
+	case PMBUS_VIRT_RESET_IOUT_HISTORY:
+		ret = pmbus_write_byte_data(client, page,
+					    LTC3880_MFR_CLEAR_PEAKS, 0);
+		break;
+	default:
+		ret = -ENODATA;
+		break;
+	}
+	return ret;
+}
+
 static const struct i2c_device_id ltc2978_id[] = {
+	{"ltc2971", ltc2971},
 	{"ltc2972", ltc2972},
 	{"ltc2974", ltc2974},
 	{"ltc2975", ltc2975},
@@ -540,24 +673,35 @@ static const struct i2c_device_id ltc2978_id[] = {
 	{"ltc2978", ltc2978},
 	{"ltc2979", ltc2979},
 	{"ltc2980", ltc2980},
+	{"ltc2980_24", ltc2980},
 	{"ltc3880", ltc3880},
 	{"ltc3882", ltc3882},
 	{"ltc3883", ltc3883},
 	{"ltc3884", ltc3884},
 	{"ltc3886", ltc3886},
 	{"ltc3887", ltc3887},
+	{"ltc3888", ltc3888},
 	{"ltc3889", ltc3889},
-	{"ltc7132", ltc7132},
+	{"ltc7841", ltc7841},
 	{"ltc7880", ltc7880},
+	{"ltc7883", ltc7883},
 	{"ltm2987", ltm2987},
 	{"ltm4664", ltm4664},
+	{"ltm4673", ltm4673},
 	{"ltm4675", ltm4675},
 	{"ltm4676", ltm4676},
 	{"ltm4677", ltm4677},
 	{"ltm4678", ltm4678},
 	{"ltm4680", ltm4680},
+	{"ltm4681", ltm4681},
+	{"ltm4683", ltm4683},
 	{"ltm4686", ltm4686},
 	{"ltm4700", ltm4700},
+	{"ltc7131", ltc7131},
+	{"ltc7132", ltc7132},
+	{"lt7182S", lt7182s},
+	{"lt7170",  lt7170},
+	{"lt7171",  lt7171},
 	{}
 };
 MODULE_DEVICE_TABLE(i2c, ltc2978_id);
@@ -621,10 +765,58 @@ static int ltc2978_get_id(struct i2c_client *client)
 		}
 		return -ENODEV;
 	}
+	else if (chip_id == LTC_UNIVERSAL_ID) {
+		u8 buf[I2C_SMBUS_BLOCK_MAX];
+		int ret;
+
+		if (!i2c_check_functionality(client->adapter,
+					     I2C_FUNC_SMBUS_READ_BLOCK_DATA))
+			return -ENODEV;
+
+		ret = i2c_smbus_read_block_data(client, PMBUS_MFR_ID, buf);
+		if (ret < 0)
+			return ret;
+		if (ret < 3 || strncmp(buf, "ADI", 3))
+			return -ENODEV;
+
+		ret = i2c_smbus_read_block_data(client, PMBUS_MFR_MODEL, buf);
+		if (ret >= 0) {
+			if (strlen(buf) >= strlen(LT7182S_ID))
+				if (!strncasecmp(LT7182S_ID, buf, strlen(LT7182S_ID)))
+				return lt7182s;
+			dev_err(&client->dev, "Unsupported chip ID 0x%x\n", chip_id);
+			return -ENODEV;
+		}
+		else {
+			ret = i2c_smbus_read_block_data(client, PMBUS_IC_DEVICE_ID, buf);
+			if (ret < 0)
+				return ret;
+			if (strlen(buf) >= strlen(LT7170_ID)) {
+				if (!strncasecmp(LT7170_ID, buf, strlen(LT7170_ID)))
+					return lt7170;
+			}
+			if (strlen(buf) >= strlen(LT7170_1_ID)) {
+				if (!strncasecmp(LT7170_1_ID, buf, strlen(LT7170_1_ID)))
+					return lt7170;
+			}
+			if (strlen(buf) >= strlen(LT7171_ID)) {
+				if (!strncasecmp(LT7171_ID, buf, strlen(LT7171_ID)))
+					return lt7171;
+			}
+			if (strlen(buf) >= strlen(LT7171_1_ID)) {
+				if (!strncasecmp(LT7171_1_ID, buf, strlen(LT7171_1_ID)))
+					return lt7171;
+			}
+			dev_err(&client->dev, "Unsupported chip ID 0x%x\n", chip_id);
+			return -ENODEV;
+		}
+	}
 
 	chip_id &= LTC2978_ID_MASK;
 
-	if (chip_id == LTC2972_ID)
+	if (chip_id == LTC2971_ID)
+		return ltc2971;
+	else if (chip_id == LTC2972_ID)
 		return ltc2972;
 	else if (chip_id == LTC2974_ID)
 		return ltc2974;
@@ -636,7 +828,8 @@ static int ltc2978_get_id(struct i2c_client *client)
 		return ltc2978;
 	else if (chip_id == LTC2979_ID_A || chip_id == LTC2979_ID_B)
 		return ltc2979;
-	else if (chip_id == LTC2980_ID_A || chip_id == LTC2980_ID_B)
+	else if (chip_id == LTC2980_ID_A || chip_id == LTC2980_ID_B || 
+		chip_id == LTC2980_24_ID_A || chip_id == LTC2980_24_ID_B || chip_id == LTC2980_24_ID_C)
 		return ltc2980;
 	else if (chip_id == LTC3880_ID)
 		return ltc3880;
@@ -650,16 +843,24 @@ static int ltc2978_get_id(struct i2c_client *client)
 		return ltc3886;
 	else if (chip_id == LTC3887_ID)
 		return ltc3887;
+	else if (chip_id == LTC3888_ID)
+		return ltc3888;
 	else if (chip_id == LTC3889_ID)
 		return ltc3889;
 	else if (chip_id == LTC7132_ID)
 		return ltc7132;
+	else if (chip_id == LTC7841_ID)
+		return ltc7841;
 	else if (chip_id == LTC7880_ID)
 		return ltc7880;
+	else if (chip_id == LTC7883_ID_A || chip_id == LTC7883_ID_B)
+		return ltc7883;
 	else if (chip_id == LTM2987_ID_A || chip_id == LTM2987_ID_B)
 		return ltm2987;
 	else if (chip_id == LTM4664_ID)
 		return ltm4664;
+	else if (chip_id == LTM4673_ID)
+		return ltm4673;
 	else if (chip_id == LTM4675_ID)
 		return ltm4675;
 	else if (chip_id == LTM4676_ID_REV1 || chip_id == LTM4676_ID_REV2 ||
@@ -671,10 +872,16 @@ static int ltc2978_get_id(struct i2c_client *client)
 		return ltm4678;
 	else if (chip_id == LTM4680_ID)
 		return ltm4680;
+	else if (chip_id == LTM4681_ID)
+		return ltm4681;
+	else if (chip_id == LTM4683_ID_REV1 || chip_id == LTM4683_ID_REV2)
+		return ltm4683;
 	else if (chip_id == LTM4686_ID)
 		return ltm4686;
 	else if (chip_id == LTM4700_ID)
 		return ltm4700;
+	else if (chip_id == LTC7131_ID)
+		return ltc7131;
 
 	dev_err(&client->dev, "Unsupported chip ID 0x%x\n", chip_id);
 	return -ENODEV;
@@ -682,10 +889,13 @@ static int ltc2978_get_id(struct i2c_client *client)
 
 static int ltc2978_probe(struct i2c_client *client)
 {
-	int i, chip_id;
+	int i, chip_id, ret;
+	bool external_temperature = 0;
 	struct ltc2978_data *data;
 	struct pmbus_driver_info *info;
 	const struct i2c_device_id *id;
+	struct pmbus_platform_data *pdata;
+	struct device *dev = &client->dev;
 
 	if (!i2c_check_functionality(client->adapter,
 				     I2C_FUNC_SMBUS_READ_WORD_DATA))
@@ -730,7 +940,36 @@ static int ltc2978_probe(struct i2c_client *client)
 		data->temp_max[i] = 0x7c00;
 	data->temp2_max = 0x7c00;
 
+	if (!strncmp(client->name, "ltc7841", 7))
+	{
+		pdata = devm_kzalloc(dev, sizeof(struct pmbus_platform_data),
+			     GFP_KERNEL);
+		if (!pdata)
+			return -ENOMEM;
+		dev->platform_data = pdata;
+		pdata->flags = PMBUS_NO_CAPABILITY | PMBUS_NO_WRITE_PROTECT;
+
+		ret = ltc_read_byte_data_ltc7841(client, 0, LTC7841_MFR_CONFIG);
+		if (ret < 0)
+			return ret;
+
+		external_temperature = (ret & LTC7841_TEMP_MODE) > 0;
+	}
+
 	switch (data->id) {
+	case ltc2971:
+		info->read_word_data = ltc2975_read_word_data;
+		info->pages = LTC2972_NUM_PAGES;
+		info->func[0] = PMBUS_HAVE_IIN | PMBUS_HAVE_PIN
+		  | PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT
+		  | PMBUS_HAVE_TEMP2;
+		for (i = 0; i < info->pages; i++) {
+			info->func[i] |= PMBUS_HAVE_VOUT
+			  | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_POUT
+			  | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP
+			  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT;
+		}
+		break;
 	case ltc2972:
 		info->read_word_data = ltc2975_read_word_data;
 		info->pages = LTC2972_NUM_PAGES;
@@ -757,6 +996,7 @@ static int ltc2978_probe(struct i2c_client *client)
 		}
 		break;
 	case ltc2975:
+	case ltm4673:
 		info->read_word_data = ltc2975_read_word_data;
 		info->pages = LTC2974_NUM_PAGES;
 		info->func[0] = PMBUS_HAVE_IIN | PMBUS_HAVE_PIN
@@ -769,7 +1009,6 @@ static int ltc2978_probe(struct i2c_client *client)
 			  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT;
 		}
 		break;
-
 	case ltc2977:
 	case ltc2978:
 	case ltc2979:
@@ -820,6 +1059,21 @@ static int ltc2978_probe(struct i2c_client *client)
 		  | PMBUS_HAVE_POUT
 		  | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP;
 		break;
+	case ltc7883:
+		data->features |= FEAT_CLEAR_PEAKS | FEAT_NEEDS_POLLING;
+		info->read_word_data = ltc3880_read_word_data;
+		info->pages = LTC3880_NUM_PAGES;
+		info->func[0] = PMBUS_HAVE_VIN
+		  | PMBUS_HAVE_STATUS_INPUT
+		  | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
+		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT
+		  | PMBUS_HAVE_POUT | PMBUS_HAVE_TEMP
+		  | PMBUS_HAVE_TEMP2 | PMBUS_HAVE_STATUS_TEMP;
+		info->func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
+		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT
+		  | PMBUS_HAVE_POUT
+		  | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP;
+		break;
 	case ltc3883:
 		data->features |= FEAT_CLEAR_PEAKS | FEAT_NEEDS_POLLING;
 		info->read_word_data = ltc3883_read_word_data;
@@ -831,6 +1085,20 @@ static int ltc2978_probe(struct i2c_client *client)
 		  | PMBUS_HAVE_PIN | PMBUS_HAVE_POUT | PMBUS_HAVE_TEMP
 		  | PMBUS_HAVE_TEMP2 | PMBUS_HAVE_STATUS_TEMP;
 		break;
+	case ltc3888:
+		data->features |= FEAT_CLEAR_PEAKS | FEAT_NEEDS_POLLING;
+		info->read_word_data = ltc3880_read_word_data;
+		info->pages = LTC3880_NUM_PAGES;
+		info->func[0] = PMBUS_HAVE_VIN
+		  | PMBUS_HAVE_STATUS_INPUT
+		  | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
+		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT
+		  | PMBUS_HAVE_TEMP
+		  | PMBUS_HAVE_TEMP2 | PMBUS_HAVE_STATUS_TEMP;
+		info->func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
+		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT
+		  | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP;
+		break;
 	case ltc3884:
 	case ltc3886:
 	case ltc3889:
@@ -854,13 +1122,138 @@ static int ltc2978_probe(struct i2c_client *client)
 		  | PMBUS_HAVE_POUT
 		  | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP;
 		break;
+	case ltm4681:
+		data->features |= FEAT_CLEAR_PEAKS | FEAT_NEEDS_POLLING;
+		info->read_word_data = ltc3883_read_word_data;
+		info->pages = LTC3880_NUM_PAGES;
+		info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_IIN
+		  | PMBUS_HAVE_STATUS_INPUT
+		  | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
+		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT
+		  | PMBUS_HAVE_PIN | PMBUS_HAVE_POUT | PMBUS_HAVE_TEMP
+		  | PMBUS_HAVE_TEMP2 | PMBUS_HAVE_STATUS_TEMP;
+		info->func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
+		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT
+		  | PMBUS_HAVE_POUT
+		  | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP;
+		break;
+	case ltm4683:
+		data->features |= FEAT_CLEAR_PEAKS | FEAT_NEEDS_POLLING;
+		info->read_word_data = ltc3883_read_word_data;
+		info->pages = LTC3880_NUM_PAGES;
+		info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_IIN
+		  | PMBUS_HAVE_STATUS_INPUT
+		  | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
+		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT
+		  | PMBUS_HAVE_TEMP
+		  | PMBUS_HAVE_TEMP2 | PMBUS_HAVE_STATUS_TEMP;
+		info->func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
+		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT
+		  | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP;
+		break;
+	case lt7182s:
+		data->features |= FEAT_CLEAR_PEAKS | FEAT_NEEDS_POLLING;
+		info->read_word_data = ltc3883_read_word_data;
+		info->pages = LTC3880_NUM_PAGES;
+		info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_IIN
+		  | PMBUS_HAVE_STATUS_INPUT
+		  | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
+		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT
+		  | PMBUS_HAVE_POUT 
+		  | PMBUS_HAVE_TEMP
+		  | PMBUS_HAVE_STATUS_TEMP;
+		info->func[1] = PMBUS_HAVE_VIN | PMBUS_HAVE_IIN
+		  | PMBUS_HAVE_STATUS_INPUT
+		  | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
+		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT
+		  | PMBUS_HAVE_POUT;
+		break;
+	case lt7170:
+	case lt7171:
+		data->features |= FEAT_CLEAR_PEAKS | FEAT_NEEDS_POLLING;
+		info->read_word_data = ltc3883_read_word_data;
+		info->pages = LTC3883_NUM_PAGES;
+		info->format[PSC_VOLTAGE_IN] = ieee754;
+		info->format[PSC_VOLTAGE_OUT] = ieee754;
+		info->format[PSC_CURRENT_OUT] = ieee754;
+		info->format[PSC_TEMPERATURE] = ieee754;
+		info->func[0] = PMBUS_HAVE_VIN
+		  | PMBUS_HAVE_STATUS_INPUT
+		  | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
+		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT
+		  | PMBUS_HAVE_TEMP
+		  | PMBUS_HAVE_STATUS_TEMP;
+		break;
+	case ltc7841:
+		data->features |= FEAT_CLEAR_PEAKS | FEAT_NEEDS_POLLING;
+		info->read_byte_data = ltc_read_byte_data_ltc7841;
+		info->read_word_data = ltc_read_word_data_ltc7841;
+		info->write_byte_data = ltc_write_byte_data_ltc7841;
+		info->write_byte = ltc_write_byte_ltc7841;
+		info->pages = LTC3883_NUM_PAGES;
+		info->format[PSC_VOLTAGE_IN] = direct;
+		info->format[PSC_VOLTAGE_OUT] = direct;
+		info->format[PSC_CURRENT_IN] = direct;
+		info->format[PSC_CURRENT_OUT] = direct;
+		info->format[PSC_TEMPERATURE] = direct;
+		info->m[PSC_VOLTAGE_IN] = 100;
+		info->b[PSC_VOLTAGE_IN] = 0;
+		info->R[PSC_VOLTAGE_IN] = 0;
+		info->m[PSC_VOLTAGE_OUT] = 100;
+		info->b[PSC_VOLTAGE_OUT] = 0;
+		info->R[PSC_VOLTAGE_OUT] = 0;
+		info->m[PSC_CURRENT_IN] = 20000;
+		info->b[PSC_CURRENT_IN] = 0;
+		info->R[PSC_CURRENT_IN] = 0;
+		info->m[PSC_CURRENT_OUT] = 20000;
+		info->b[PSC_CURRENT_OUT] = 0;
+		info->R[PSC_CURRENT_OUT] = 0;
+		if (external_temperature)
+			info->m[PSC_TEMPERATURE] = 2;
+		else
+			info->m[PSC_TEMPERATURE] = 1;
+		info->b[PSC_TEMPERATURE] = 0;
+		info->R[PSC_TEMPERATURE] = 0;
+		info->func[0] = PMBUS_HAVE_VIN
+		  | PMBUS_HAVE_VOUT
+		  | PMBUS_HAVE_IOUT
+		  | PMBUS_HAVE_TEMP;
+		break;
+	case ltc7131:
+		data->features = 0;
+		info->pages = LTC3883_NUM_PAGES;
+		info->format[PSC_VOLTAGE_IN] = direct;
+		info->format[PSC_VOLTAGE_OUT] = direct;
+		info->format[PSC_CURRENT_IN] = direct;
+		info->format[PSC_CURRENT_OUT] = direct;
+		info->m[PSC_VOLTAGE_IN] = 250;
+		info->b[PSC_VOLTAGE_IN] = 0;
+		info->R[PSC_VOLTAGE_IN] = 0;
+		info->m[PSC_VOLTAGE_OUT] = 2000;
+		info->b[PSC_VOLTAGE_OUT] = 0;
+		info->R[PSC_VOLTAGE_OUT] = 0;
+		info->m[PSC_CURRENT_IN] = 100;
+		info->b[PSC_CURRENT_IN] = 0;
+		info->R[PSC_CURRENT_IN] = 0;
+		info->m[PSC_CURRENT_OUT] = 100;
+		info->b[PSC_CURRENT_OUT] = 0;
+		info->R[PSC_CURRENT_OUT] = 0;
+		info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT 
+		    | PMBUS_HAVE_IIN | PMBUS_HAVE_IOUT;
+		info->write_byte = ltc7131_write_byte;
+		info->read_byte_data = ltc7131_read_byte_data;
+		info->read_word_data = ltc7131_read_word_data;
+		info->write_word_data = ltc7131_write_word_data;
+		break;	
 	default:
 		return -ENODEV;
 	}
 
+
 #if IS_ENABLED(CONFIG_SENSORS_LTC2978_REGULATOR)
 	info->num_regulators = info->pages;
 	switch (data->id) {
+	case ltc2971:
 	case ltc2972:
 	case ltc2974:
 	case ltc2975:
@@ -892,6 +1285,7 @@ static int ltc2978_probe(struct i2c_client *client)
 
 #ifdef CONFIG_OF
 static const struct of_device_id ltc2978_of_match[] = {
+	{ .compatible = "lltc,ltc2971" },
 	{ .compatible = "lltc,ltc2972" },
 	{ .compatible = "lltc,ltc2974" },
 	{ .compatible = "lltc,ltc2975" },
@@ -899,24 +1293,35 @@ static const struct of_device_id ltc2978_of_match[] = {
 	{ .compatible = "lltc,ltc2978" },
 	{ .compatible = "lltc,ltc2979" },
 	{ .compatible = "lltc,ltc2980" },
+	{ .compatible = "lltc,ltc2980_24" },
 	{ .compatible = "lltc,ltc3880" },
 	{ .compatible = "lltc,ltc3882" },
 	{ .compatible = "lltc,ltc3883" },
 	{ .compatible = "lltc,ltc3884" },
 	{ .compatible = "lltc,ltc3886" },
 	{ .compatible = "lltc,ltc3887" },
+	{ .compatible = "lltc,ltc3888" },
 	{ .compatible = "lltc,ltc3889" },
-	{ .compatible = "lltc,ltc7132" },
+	{ .compatible = "lltc,ltc7841" },
 	{ .compatible = "lltc,ltc7880" },
+	{ .compatible = "lltc,ltc7883" },
 	{ .compatible = "lltc,ltm2987" },
 	{ .compatible = "lltc,ltm4664" },
+	{ .compatible = "lltc,ltm4673" },
 	{ .compatible = "lltc,ltm4675" },
 	{ .compatible = "lltc,ltm4676" },
 	{ .compatible = "lltc,ltm4677" },
 	{ .compatible = "lltc,ltm4678" },
 	{ .compatible = "lltc,ltm4680" },
+	{ .compatible = "lltc,ltm4681" },
+	{ .compatible = "lltc,ltm4683" },
 	{ .compatible = "lltc,ltm4686" },
 	{ .compatible = "lltc,ltm4700" },
+	{ .compatible = "lltc,ltc7131" },
+	{ .compatible = "lltc,ltc7132" },
+	{ .compatible = "lltc,lt7182s" },
+	{ .compatible = "lltc,lt7170" },
+	{ .compatible = "lltc,lt7171" },
 	{ }
 };
 MODULE_DEVICE_TABLE(of, ltc2978_of_match);
-- 
2.43.0

