devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/2] dt-bindings: hwmon: ti,ina780a: Add INA780 device
@ 2025-08-06  0:51 Chris Packham
  2025-08-06  0:51 ` [PATCH 2/2] hwmon: (ina780) Add driver for TI INA780 Chris Packham
  2025-08-06  6:32 ` [PATCH 1/2] dt-bindings: hwmon: ti,ina780a: Add INA780 device Krzysztof Kozlowski
  0 siblings, 2 replies; 9+ messages in thread
From: Chris Packham @ 2025-08-06  0:51 UTC (permalink / raw)
  To: jdelvare, linux, robh, krzk+dt, conor+dt
  Cc: linux-hwmon, devicetree, linux-kernel, Chris Packham

Add dtschema for TI INA780 Digital Power Monitor

Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
---
 .../devicetree/bindings/hwmon/ti,ina780a.yaml | 47 +++++++++++++++++++
 1 file changed, 47 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/hwmon/ti,ina780a.yaml

diff --git a/Documentation/devicetree/bindings/hwmon/ti,ina780a.yaml b/Documentation/devicetree/bindings/hwmon/ti,ina780a.yaml
new file mode 100644
index 000000000000..fa19d621b27b
--- /dev/null
+++ b/Documentation/devicetree/bindings/hwmon/ti,ina780a.yaml
@@ -0,0 +1,47 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/hwmon/ti,ina780a.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Texas Instruments INA780 Digital Power Monitor
+
+maintainers:
+  - Chris Packham <chris.packham@alliedtelesis.co.nz>
+
+description: |
+  The INA780x is a digital power monitor with an integrated current sensing
+  element.
+
+  Datasheets:
+    https://www.ti.com/lit/gpn/ina780a
+
+properties:
+  compatible:
+    enum:
+      - ti,ina780a
+      - ti,ina780b
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+
+allOf:
+  - $ref: hwmon-common.yaml#
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    i2c {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        hwmon@40 {
+          compatible = "ti,ina780a";
+          reg = <0x40>;
+        };
+    };
-- 
2.50.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 2/2] hwmon: (ina780) Add driver for TI INA780
  2025-08-06  0:51 [PATCH 1/2] dt-bindings: hwmon: ti,ina780a: Add INA780 device Chris Packham
@ 2025-08-06  0:51 ` Chris Packham
  2025-08-06  3:14   ` Guenter Roeck
  2025-08-06 19:21   ` kernel test robot
  2025-08-06  6:32 ` [PATCH 1/2] dt-bindings: hwmon: ti,ina780a: Add INA780 device Krzysztof Kozlowski
  1 sibling, 2 replies; 9+ messages in thread
From: Chris Packham @ 2025-08-06  0:51 UTC (permalink / raw)
  To: jdelvare, linux, robh, krzk+dt, conor+dt
  Cc: linux-hwmon, devicetree, linux-kernel, Chris Packham

Add support for the TI INA780 Digital Power Monitor.

Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
---
 drivers/hwmon/Kconfig  |  11 +
 drivers/hwmon/Makefile |   1 +
 drivers/hwmon/ina780.c | 566 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 578 insertions(+)
 create mode 100644 drivers/hwmon/ina780.c

diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 079620dd4286..d11aebb6a1c1 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -2264,6 +2264,17 @@ config SENSORS_INA3221
 	  This driver can also be built as a module. If so, the module
 	  will be called ina3221.
 
+config SENSORS_INA780
+	tristate "Texas Instruments INA780 Power Monitor"
+	depends on I2C
+	select REGMAP_I2C
+	help
+	  If you say yes here you get support for  the TI INA780 Digital
+	  Power Monitor.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called ina780.
+
 config SENSORS_SPD5118
 	tristate "SPD5118 Compliant Temperature Sensors"
 	depends on I2C
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 48e5866c0c9a..e4acef261f14 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -104,6 +104,7 @@ obj-$(CONFIG_SENSORS_INA209)	+= ina209.o
 obj-$(CONFIG_SENSORS_INA2XX)	+= ina2xx.o
 obj-$(CONFIG_SENSORS_INA238)	+= ina238.o
 obj-$(CONFIG_SENSORS_INA3221)	+= ina3221.o
+obj-$(CONFIG_SENSORS_INA780)	+= ina780.o
 obj-$(CONFIG_SENSORS_INTEL_M10_BMC_HWMON) += intel-m10-bmc-hwmon.o
 obj-$(CONFIG_SENSORS_ISL28022)	+= isl28022.o
 obj-$(CONFIG_SENSORS_IT87)	+= it87.o
diff --git a/drivers/hwmon/ina780.c b/drivers/hwmon/ina780.c
new file mode 100644
index 000000000000..b6a31fca400a
--- /dev/null
+++ b/drivers/hwmon/ina780.c
@@ -0,0 +1,566 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Driver for the Texas Instruments INA780 Digital Power Monitor
+ *
+ * Datasheet:
+ * https://www.ti.com/lit/gpn/ina780a
+ */
+
+#include <linux/bits.h>
+#include <linux/cleanup.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/hwmon.h>
+#include <linux/i2c.h>
+#include <linux/kernel.h>
+#include <linux/math64.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+
+#define INA780_CONFIG		0x0
+#define INA780_ADC_CONFIG	0x1
+#define INA780_VBUS		0x5
+#define INA780_DIETEMP		0x6
+#define INA780_CURRENT		0x7
+#define INA780_POWER		0x8
+#define INA780_ENERGY		0x9
+#define INA780_CHARGE		0xa
+#define INA780_DIAG_ALRT	0xb
+#define INA780_COL		0xc
+#define INA780_CUL		0xd
+#define INA780_BOVL		0xe
+#define INA780_BUVL		0xf
+#define INA780_TEMP_LIMIT	0x10
+#define INA780_PWR_LIMIT	0x11
+#define INA780_MANUFACTURER_ID	0x3e
+
+#define INA780_DIAG_ALRT_TMPOL		BIT(7)
+#define INA780_DIAG_ALRT_CURRENTOL	BIT(6)
+#define INA780_DIAG_ALRT_CURRENTUL	BIT(5)
+#define INA780_DIAG_ALRT_BUSOL		BIT(4)
+#define INA780_DIAG_ALRT_BUSUL		BIT(3)
+#define INA780_DIAG_ALRT_POL		BIT(2)
+
+#define INA780_BUS_VOLTAGE_LSB		3125	/* 3.125 mV/lsb */
+#define INA780_CURRENT_LSB		2400	/* 2.4 mA/lsb  */
+#define INA780_TEMP_LSB			125000	/* 125 mC/lsb */
+#define INA780_ENERGY_LSB		7680	/* 7.68 mJ/lsb */
+#define INA780_POWER_LSB		480000	/* 480 uW/lsb */
+#define INA780_PWR_LIMIT_LSB		(256 * INA780_POWER_LSB)  /* 122.88 mW/lsb */
+
+#define INA780_ID			0x5449
+
+static const struct regmap_config ina780_regmap_config = {
+	.max_register = INA780_MANUFACTURER_ID,
+	.reg_bits = 8,
+	.val_bits = 16,
+};
+
+struct ina780_data {
+	struct mutex lock;
+	struct i2c_client *client;
+	struct regmap *regmap;
+};
+
+static int ina780_read_reg24(const struct i2c_client *client, u8 reg, u32 *val)
+{
+	u8 data[3];
+	int err;
+
+	err = i2c_smbus_read_i2c_block_data(client, reg, 3, data);
+	if (err < 0)
+		return err;
+	if (err != 3)
+		return -EIO;
+	*val = (data[0] << 16) | (data[1] << 8) | data[2];
+
+	return 0;
+}
+
+static int ina780_read_reg40(struct i2c_client *client, int reg, u64 *val)
+{
+	u8 data[5];
+	u32 low;
+	int err;
+
+	err = i2c_smbus_read_i2c_block_data(client, reg, 5, data);
+	if (err < 0)
+		return err;
+	if (err != 5)
+		return -EIO;
+
+	low = (data[1] << 24) | (data[2] << 16) | (data[3] << 8) | data[4];
+	*val = ((long long)data[0] << 32) | low;
+
+	return 0;
+}
+
+static int ina780_read_in(struct device *dev, u32 attr, long *val)
+{
+	struct ina780_data *data = dev_get_drvdata(dev);
+	unsigned int regval;
+	int reg, mask;
+	int err;
+
+	switch (attr) {
+	case hwmon_in_input:
+		reg = INA780_VBUS;
+		break;
+	case hwmon_in_max:
+		reg = INA780_BOVL;
+		break;
+	case hwmon_in_min:
+		reg = INA780_BUVL;
+		break;
+	case hwmon_in_max_alarm:
+		reg = INA780_DIAG_ALRT;
+		mask = INA780_DIAG_ALRT_BUSOL;
+		break;
+	case hwmon_in_min_alarm:
+		reg = INA780_DIAG_ALRT;
+		mask = INA780_DIAG_ALRT_BUSUL;
+		break;
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	switch (attr) {
+	case hwmon_in_input:
+	case hwmon_in_max:
+	case hwmon_in_min:
+		err = regmap_read(data->regmap, reg, &regval);
+		if (err)
+			return err;
+
+		*val = (regval * INA780_BUS_VOLTAGE_LSB) / 1000;
+		break;
+	case hwmon_in_max_alarm:
+	case hwmon_in_min_alarm:
+		err = regmap_read(data->regmap, reg, &regval);
+		if (err)
+			return err;
+		*val = !!(regval & mask);
+		break;
+	}
+
+	return 0;
+}
+
+static int ina780_write_in(struct device *dev, u32 attr, long val)
+{
+	struct ina780_data *data = dev_get_drvdata(dev);
+	unsigned int regval;
+	int reg;
+
+	switch (attr) {
+	case hwmon_in_max:
+		reg = INA780_BOVL;
+		break;
+	case hwmon_in_min:
+		reg = INA780_BUVL;
+		break;
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	val = clamp_val(val, 0, 102396);
+	regval = div_u64(val * 1000ULL, INA780_BUS_VOLTAGE_LSB);
+
+	return regmap_write(data->regmap, reg, regval);
+}
+
+static int ina780_read_curr(struct device *dev, u32 attr, long *val)
+{
+	struct ina780_data *data = dev_get_drvdata(dev);
+	unsigned int regval;
+	int reg, mask;
+	int err;
+
+	switch (attr) {
+	case hwmon_curr_input:
+		reg = INA780_CURRENT;
+		break;
+	case hwmon_curr_max:
+		reg = INA780_COL;
+		break;
+	case hwmon_curr_min:
+		reg = INA780_CUL;
+		break;
+	case hwmon_curr_max_alarm:
+		reg = INA780_DIAG_ALRT;
+		mask = INA780_DIAG_ALRT_CURRENTOL;
+		break;
+	case hwmon_curr_min_alarm:
+		reg = INA780_DIAG_ALRT;
+		mask = INA780_DIAG_ALRT_CURRENTUL;
+		break;
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	switch (attr) {
+	case hwmon_curr_input:
+	case hwmon_curr_max:
+	case hwmon_curr_min:
+		err = regmap_read(data->regmap, reg, &regval);
+		if (err)
+			return err;
+		*val = div_s64((s16)regval * INA780_CURRENT_LSB, 1000);
+		break;
+	case hwmon_curr_max_alarm:
+	case hwmon_curr_min_alarm:
+		err = regmap_read(data->regmap, reg, &regval);
+		if (err)
+			return err;
+		*val = !!(regval & mask);
+		break;
+	}
+
+	return 0;
+}
+
+static int ina780_write_curr(struct device *dev, u32 attr, long val)
+{
+	struct ina780_data *data = dev_get_drvdata(dev);
+	unsigned int regval;
+	int reg;
+
+	switch (attr) {
+	case hwmon_curr_max:
+		reg = INA780_COL;
+		break;
+	case hwmon_curr_min:
+		reg = INA780_CUL;
+		break;
+	default:
+		return -EOPNOTSUPP;
+	}
+	clamp_val(val, -78643, 78640);
+	regval = div_s64(val * 1000ULL, INA780_CURRENT_LSB);
+
+	return regmap_write(data->regmap, reg, regval);
+}
+
+static int ina780_read_power(struct device *dev, u32 attr, long *val)
+{
+	struct ina780_data *data = dev_get_drvdata(dev);
+	unsigned int regval;
+	int err;
+
+	switch (attr) {
+	case hwmon_power_input:
+		err = ina780_read_reg24(data->client, INA780_POWER, &regval);
+		if (err)
+			return err;
+		*val = div_u64((u64)regval * INA780_POWER_LSB, 1000);
+		break;
+	case hwmon_power_max:
+		err = regmap_read(data->regmap, INA780_PWR_LIMIT, &regval);
+		if (err)
+			return err;
+		*val = div_u64((u64)regval * INA780_PWR_LIMIT_LSB, 1000);
+		break;
+	case hwmon_power_max_alarm:
+		err = regmap_read(data->regmap, INA780_DIAG_ALRT, &regval);
+		if (err)
+			return err;
+		*val = !!(regval & INA780_DIAG_ALRT_POL);
+		break;
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	return 0;
+}
+
+static int ina780_write_power(struct device *dev, u32 attr, long val)
+{
+	struct ina780_data *data = dev_get_drvdata(dev);
+	int regval;
+
+	switch (attr) {
+	case hwmon_power_max:
+		val = clamp_val(val, 0, 8052940800);
+		regval = div_u64(val * 1000ULL, INA780_PWR_LIMIT_LSB);
+		return regmap_write(data->regmap, INA780_PWR_LIMIT, regval);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+static int ina780_read_temp(struct device *dev, u32 attr, long *val)
+{
+	struct ina780_data *data = dev_get_drvdata(dev);
+	int reg, mask;
+	int regval;
+	int err;
+
+	switch (attr) {
+	case hwmon_temp_input:
+		reg = INA780_DIETEMP;
+		break;
+	case hwmon_temp_max:
+		reg = INA780_TEMP_LIMIT;
+		break;
+	case hwmon_temp_max_alarm:
+		reg = INA780_DIAG_ALRT;
+		mask = INA780_DIAG_ALRT_TMPOL;
+		break;
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	switch (attr) {
+	case hwmon_temp_input:
+	case hwmon_temp_max:
+		err = regmap_read(data->regmap, reg, &regval);
+		if (err)
+			return err;
+		*val = div_s64(((s64)((s16)regval) >> 4) * INA780_TEMP_LSB, 1000);
+		break;
+	case hwmon_temp_max_alarm:
+		err = regmap_read(data->regmap, INA780_DIAG_ALRT, &regval);
+		*val = !!(regval & INA780_DIAG_ALRT_TMPOL);
+		break;
+	}
+
+	return 0;
+}
+
+static int ina780_write_temp(struct device *dev, u32 attr, long val)
+{
+	struct ina780_data *data = dev_get_drvdata(dev);
+	int regval;
+
+	if (attr != hwmon_temp_max)
+		return -EOPNOTSUPP;
+
+	val = clamp_val(val, -40000, 150000);
+	regval = div_s64(val * 1000, INA780_TEMP_LSB) << 4;
+
+	return regmap_write(data->regmap, INA780_TEMP_LIMIT, regval);
+}
+
+static int ina780_read_energy(struct device *dev, u32 attr, long *val)
+{
+	struct ina780_data *data = dev_get_drvdata(dev);
+	u64 regval;
+	int err;
+
+	if (attr != hwmon_energy_input)
+		return -EOPNOTSUPP;
+
+	err = ina780_read_reg40(data->client, INA780_ENERGY, &regval);
+	if (err)
+		return err;
+
+	*val = div_u64(regval * INA780_ENERGY_LSB, 1000);
+
+	return 0;
+}
+
+static int ina780_read(struct device *dev, enum hwmon_sensor_types type,
+		       u32 attr, int channel, long *val)
+{
+	struct ina780_data *data = dev_get_drvdata(dev);
+
+	guard(mutex)(&data->lock);
+
+	switch (type) {
+	case hwmon_in:
+		return ina780_read_in(dev, attr, val);
+	case hwmon_curr:
+		return ina780_read_curr(dev, attr, val);
+	case hwmon_power:
+		return ina780_read_power(dev, attr, val);
+	case hwmon_temp:
+		return ina780_read_temp(dev, attr, val);
+	case hwmon_energy:
+		return ina780_read_energy(dev, attr, val);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+static int ina780_write(struct device *dev, enum hwmon_sensor_types type,
+			u32 attr, int channel, long val)
+{
+	struct ina780_data *data = dev_get_drvdata(dev);
+
+	guard(mutex)(&data->lock);
+
+	switch (type) {
+	case hwmon_in:
+		return ina780_write_in(dev, attr, val);
+	case hwmon_curr:
+		return ina780_write_curr(dev, attr, val);
+	case hwmon_power:
+		return ina780_write_power(dev, attr, val);
+	case hwmon_temp:
+		return ina780_write_temp(dev, attr, val);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+static umode_t ina780_is_visible(const void *drvdata,
+				 enum hwmon_sensor_types type,
+				 u32 attr, int channel)
+{
+	switch (type) {
+	case hwmon_in:
+		switch (attr) {
+		case hwmon_in_input:
+		case hwmon_in_max_alarm:
+		case hwmon_in_min_alarm:
+			return 0444;
+		case hwmon_in_max:
+		case hwmon_in_min:
+			return 0644;
+		default:
+			return 0;
+		}
+	case hwmon_curr:
+		switch (attr) {
+		case hwmon_curr_input:
+		case hwmon_curr_max_alarm:
+		case hwmon_curr_min_alarm:
+			return 0444;
+		case hwmon_curr_max:
+		case hwmon_curr_min:
+			return 0644;
+		default:
+			return 0;
+		}
+	case hwmon_power:
+		switch (attr) {
+		case hwmon_power_input:
+		case hwmon_power_max_alarm:
+			return 0444;
+		case hwmon_power_max:
+			return 0644;
+		default:
+			return 0;
+		}
+	case hwmon_temp:
+		switch (attr) {
+		case hwmon_temp_input:
+		case hwmon_temp_max_alarm:
+			return 0444;
+		case hwmon_temp_max:
+			return 0644;
+		default:
+			return 0;
+		}
+	case hwmon_energy:
+		switch (attr) {
+		case hwmon_energy_input:
+			return 0444;
+		default:
+			return 0;
+		}
+	default:
+		return 0;
+	}
+}
+
+static const struct hwmon_channel_info * const ina238_info[] = {
+	HWMON_CHANNEL_INFO(in,
+			   HWMON_I_INPUT |
+			   HWMON_I_MAX | HWMON_I_MAX_ALARM |
+			   HWMON_I_MIN | HWMON_I_MIN_ALARM),
+	HWMON_CHANNEL_INFO(curr,
+			   HWMON_C_INPUT |
+			   HWMON_C_MAX | HWMON_C_MAX_ALARM |
+			   HWMON_C_MIN | HWMON_C_MIN_ALARM),
+	HWMON_CHANNEL_INFO(power,
+			   HWMON_P_INPUT | HWMON_P_MAX | HWMON_P_MAX_ALARM),
+	HWMON_CHANNEL_INFO(temp,
+			   HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_ALARM),
+	HWMON_CHANNEL_INFO(energy,
+			   HWMON_E_INPUT),
+	NULL
+};
+
+static const struct hwmon_ops ina780_hwmon_ops = {
+	.is_visible = ina780_is_visible,
+	.read = ina780_read,
+	.write = ina780_write,
+};
+
+static const struct hwmon_chip_info ina780_chip_info = {
+	.ops = &ina780_hwmon_ops,
+	.info = ina238_info,
+};
+
+static int ina780_probe(struct i2c_client *client)
+{
+	struct device *dev = &client->dev;
+	struct ina780_data *data;
+	struct device *hwmon_dev;
+	unsigned int val;
+	int err;
+
+	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	data->client = client;
+	data->regmap = devm_regmap_init_i2c(client, &ina780_regmap_config);
+	if (IS_ERR(data->regmap)) {
+		dev_err(dev, "Failed to allocate register map\n");
+		return PTR_ERR(data->regmap);
+	}
+
+	err = regmap_read(data->regmap, INA780_MANUFACTURER_ID, &val);
+	if (err) {
+		dev_err(dev, "Error reading device ID\n");
+		return err;
+	}
+
+	if (val != INA780_ID)
+		dev_warn(dev, "Unexpected device ID %04x\n", val);
+
+	mutex_init(&data->lock);
+
+	hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, data,
+							 &ina780_chip_info,
+							 NULL);
+	if (IS_ERR(hwmon_dev))
+		return PTR_ERR(hwmon_dev);
+
+	/* Temp limit register can go to 255 C but actual max is 150 C*/
+	err = ina780_write_temp(hwmon_dev, hwmon_temp_max, 150000);
+	if (err)
+		return err;
+
+	return 0;
+}
+
+static const struct i2c_device_id ina780_id[] = {
+	{ "ina780a" },
+	{ "ina780b" },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, ina780_id);
+
+static const struct of_device_id ina780_of_match[] = {
+	{ .compatible = "ti,ina780a" },
+	{ .compatible = "ti,ina780b" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, ina780_of_match);
+
+static struct i2c_driver ina780_driver = {
+	.driver = {
+		.name = "ina780",
+		.of_match_table = ina780_of_match,
+	},
+	.probe = ina780_probe,
+	.id_table = ina780_id,
+};
+
+module_i2c_driver(ina780_driver);
+
+MODULE_AUTHOR("Chris Packham <chris.packham@alliedtelesis.co.nz>");
+MODULE_DESCRIPTION("INA780 driver");
+MODULE_LICENSE("GPL");
-- 
2.50.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH 2/2] hwmon: (ina780) Add driver for TI INA780
  2025-08-06  0:51 ` [PATCH 2/2] hwmon: (ina780) Add driver for TI INA780 Chris Packham
@ 2025-08-06  3:14   ` Guenter Roeck
  2025-08-06  3:41     ` Chris Packham
  2025-08-06 19:21   ` kernel test robot
  1 sibling, 1 reply; 9+ messages in thread
From: Guenter Roeck @ 2025-08-06  3:14 UTC (permalink / raw)
  To: Chris Packham, jdelvare, robh, krzk+dt, conor+dt
  Cc: linux-hwmon, devicetree, linux-kernel

On 8/5/25 17:51, Chris Packham wrote:
> Add support for the TI INA780 Digital Power Monitor.
> 
> Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>

Looking at the registers, the chip seems to be almost identical to INA237/238.
Why a new driver ?

Guenter


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 2/2] hwmon: (ina780) Add driver for TI INA780
  2025-08-06  3:14   ` Guenter Roeck
@ 2025-08-06  3:41     ` Chris Packham
  2025-08-06 20:22       ` Guenter Roeck
  0 siblings, 1 reply; 9+ messages in thread
From: Chris Packham @ 2025-08-06  3:41 UTC (permalink / raw)
  To: Guenter Roeck, jdelvare@suse.com, robh@kernel.org,
	krzk+dt@kernel.org, conor+dt@kernel.org
  Cc: linux-hwmon@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org

Hi Guenter,

On 06/08/2025 15:14, Guenter Roeck wrote:
> On 8/5/25 17:51, Chris Packham wrote:
>> Add support for the TI INA780 Digital Power Monitor.
>>
>> Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
>
> Looking at the registers, the chip seems to be almost identical to 
> INA237/238.
> Why a new driver ?

Yes I'd noticed the same thing as I went along. The INA780 has the 
ezshunt thing (not sure if that's the same as the internal shunt on the 
INA260) which means that a lot of the places where things are calculated 
by the shunt resistor value aren't applicable and there's one less 
voltage sensor. I did consider adding it to the ina2xx.c but it seemed 
different enough to those chips to warrant a separate driver.

I think I can kind of squint and see how I might fold the ina780 support 
into the ina238 driver although that may make things a bit messier. If 
that's the direction you'd like to head I can give it a go.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 1/2] dt-bindings: hwmon: ti,ina780a: Add INA780 device
  2025-08-06  0:51 [PATCH 1/2] dt-bindings: hwmon: ti,ina780a: Add INA780 device Chris Packham
  2025-08-06  0:51 ` [PATCH 2/2] hwmon: (ina780) Add driver for TI INA780 Chris Packham
@ 2025-08-06  6:32 ` Krzysztof Kozlowski
  2025-08-07 20:46   ` Chris Packham
  1 sibling, 1 reply; 9+ messages in thread
From: Krzysztof Kozlowski @ 2025-08-06  6:32 UTC (permalink / raw)
  To: Chris Packham, jdelvare, linux, robh, krzk+dt, conor+dt
  Cc: linux-hwmon, devicetree, linux-kernel

On 06/08/2025 02:51, Chris Packham wrote:
> +
> +properties:
> +  compatible:
> +    enum:
> +      - ti,ina780a
> +      - ti,ina780b
> +
> +  reg:
> +    maxItems: 1


This looks a bit incomplete. Where is a supply? No shunt resistor
choice? No other properties from ina2xx apply?



Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 2/2] hwmon: (ina780) Add driver for TI INA780
  2025-08-06  0:51 ` [PATCH 2/2] hwmon: (ina780) Add driver for TI INA780 Chris Packham
  2025-08-06  3:14   ` Guenter Roeck
@ 2025-08-06 19:21   ` kernel test robot
  1 sibling, 0 replies; 9+ messages in thread
From: kernel test robot @ 2025-08-06 19:21 UTC (permalink / raw)
  To: Chris Packham, jdelvare, linux, robh, krzk+dt, conor+dt
  Cc: oe-kbuild-all, linux-hwmon, devicetree, linux-kernel,
	Chris Packham

Hi Chris,

kernel test robot noticed the following build warnings:

[auto build test WARNING on groeck-staging/hwmon-next]
[also build test WARNING on linus/master v6.16 next-20250806]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Chris-Packham/hwmon-ina780-Add-driver-for-TI-INA780/20250806-115131
base:   https://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git hwmon-next
patch link:    https://lore.kernel.org/r/20250806005127.542298-2-chris.packham%40alliedtelesis.co.nz
patch subject: [PATCH 2/2] hwmon: (ina780) Add driver for TI INA780
config: x86_64-randconfig-072-20250807 (https://download.01.org/0day-ci/archive/20250807/202508070319.QMV6021c-lkp@intel.com/config)
compiler: gcc-12 (Debian 12.2.0-14+deb12u1) 12.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250807/202508070319.QMV6021c-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202508070319.QMV6021c-lkp@intel.com/

All warnings (new ones prefixed by >>):

   drivers/hwmon/ina780.c: In function 'ina780_read_temp':
>> drivers/hwmon/ina780.c:293:18: warning: variable 'mask' set but not used [-Wunused-but-set-variable]
     293 |         int reg, mask;
         |                  ^~~~


vim +/mask +293 drivers/hwmon/ina780.c

   289	
   290	static int ina780_read_temp(struct device *dev, u32 attr, long *val)
   291	{
   292		struct ina780_data *data = dev_get_drvdata(dev);
 > 293		int reg, mask;
   294		int regval;
   295		int err;
   296	
   297		switch (attr) {
   298		case hwmon_temp_input:
   299			reg = INA780_DIETEMP;
   300			break;
   301		case hwmon_temp_max:
   302			reg = INA780_TEMP_LIMIT;
   303			break;
   304		case hwmon_temp_max_alarm:
   305			reg = INA780_DIAG_ALRT;
   306			mask = INA780_DIAG_ALRT_TMPOL;
   307			break;
   308		default:
   309			return -EOPNOTSUPP;
   310		}
   311	
   312		switch (attr) {
   313		case hwmon_temp_input:
   314		case hwmon_temp_max:
   315			err = regmap_read(data->regmap, reg, &regval);
   316			if (err)
   317				return err;
   318			*val = div_s64(((s64)((s16)regval) >> 4) * INA780_TEMP_LSB, 1000);
   319			break;
   320		case hwmon_temp_max_alarm:
   321			err = regmap_read(data->regmap, INA780_DIAG_ALRT, &regval);
   322			*val = !!(regval & INA780_DIAG_ALRT_TMPOL);
   323			break;
   324		}
   325	
   326		return 0;
   327	}
   328	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 2/2] hwmon: (ina780) Add driver for TI INA780
  2025-08-06  3:41     ` Chris Packham
@ 2025-08-06 20:22       ` Guenter Roeck
  0 siblings, 0 replies; 9+ messages in thread
From: Guenter Roeck @ 2025-08-06 20:22 UTC (permalink / raw)
  To: Chris Packham, jdelvare@suse.com, robh@kernel.org,
	krzk+dt@kernel.org, conor+dt@kernel.org
  Cc: linux-hwmon@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org

On 8/5/25 20:41, Chris Packham wrote:
> Hi Guenter,
> 
> On 06/08/2025 15:14, Guenter Roeck wrote:
>> On 8/5/25 17:51, Chris Packham wrote:
>>> Add support for the TI INA780 Digital Power Monitor.
>>>
>>> Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
>>
>> Looking at the registers, the chip seems to be almost identical to
>> INA237/238.
>> Why a new driver ?
> 
> Yes I'd noticed the same thing as I went along. The INA780 has the
> ezshunt thing (not sure if that's the same as the internal shunt on the
> INA260) which means that a lot of the places where things are calculated
> by the shunt resistor value aren't applicable and there's one less
> voltage sensor. I did consider adding it to the ina2xx.c but it seemed
> different enough to those chips to warrant a separate driver.
> 
> I think I can kind of squint and see how I might fold the ina780 support
> into the ina238 driver although that may make things a bit messier. If
> that's the direction you'd like to head I can give it a go.

Compare against INA280. The only difference I can see is that there is no
shunt resistor register, and current/power/energy LSBs are constant instead
of being configurable. That should be quite straightforward to figure out.

Guenter


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 1/2] dt-bindings: hwmon: ti,ina780a: Add INA780 device
  2025-08-06  6:32 ` [PATCH 1/2] dt-bindings: hwmon: ti,ina780a: Add INA780 device Krzysztof Kozlowski
@ 2025-08-07 20:46   ` Chris Packham
  2025-08-08  7:16     ` Krzysztof Kozlowski
  0 siblings, 1 reply; 9+ messages in thread
From: Chris Packham @ 2025-08-07 20:46 UTC (permalink / raw)
  To: Krzysztof Kozlowski, jdelvare@suse.com, linux@roeck-us.net,
	robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org
  Cc: linux-hwmon@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org


On 06/08/2025 18:32, Krzysztof Kozlowski wrote:
> On 06/08/2025 02:51, Chris Packham wrote:
>> +
>> +properties:
>> +  compatible:
>> +    enum:
>> +      - ti,ina780a
>> +      - ti,ina780b
>> +
>> +  reg:
>> +    maxItems: 1
>
> This looks a bit incomplete. Where is a supply? No shunt resistor
> choice? No other properties from ina2xx apply?
This chip doesn't need a shunt so pretty much all that is required is 
compatible + reg. Guenter did mention rolling this into the existing 
ina238 driver (and ina2xx binding) so I'm looking at that right now. I'm 
also thinking about dropping the A vs B distinction. They are ordering 
options that do impact the accuracy of the ADC but driver wise they 
behave the same.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 1/2] dt-bindings: hwmon: ti,ina780a: Add INA780 device
  2025-08-07 20:46   ` Chris Packham
@ 2025-08-08  7:16     ` Krzysztof Kozlowski
  0 siblings, 0 replies; 9+ messages in thread
From: Krzysztof Kozlowski @ 2025-08-08  7:16 UTC (permalink / raw)
  To: Chris Packham
  Cc: jdelvare@suse.com, linux@roeck-us.net, robh@kernel.org,
	krzk+dt@kernel.org, conor+dt@kernel.org,
	linux-hwmon@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org

On Thu, Aug 07, 2025 at 08:46:46PM +0000, Chris Packham wrote:
> 
> On 06/08/2025 18:32, Krzysztof Kozlowski wrote:
> > On 06/08/2025 02:51, Chris Packham wrote:
> >> +
> >> +properties:
> >> +  compatible:
> >> +    enum:
> >> +      - ti,ina780a
> >> +      - ti,ina780b
> >> +
> >> +  reg:
> >> +    maxItems: 1
> >
> > This looks a bit incomplete. Where is a supply? No shunt resistor
> > choice? No other properties from ina2xx apply?
> This chip doesn't need a shunt so pretty much all that is required is 
> compatible + reg. Guenter did mention rolling this into the existing 
> ina238 driver (and ina2xx binding) so I'm looking at that right now. I'm 
> also thinking about dropping the A vs B distinction. They are ordering 
> options that do impact the accuracy of the ADC but driver wise they 
> behave the same.

Then I suggest to skip a/b. Usually we do not have compatibles for
packaging differences or even consumer/industrial thermal choices.

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2025-08-08  7:16 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-08-06  0:51 [PATCH 1/2] dt-bindings: hwmon: ti,ina780a: Add INA780 device Chris Packham
2025-08-06  0:51 ` [PATCH 2/2] hwmon: (ina780) Add driver for TI INA780 Chris Packham
2025-08-06  3:14   ` Guenter Roeck
2025-08-06  3:41     ` Chris Packham
2025-08-06 20:22       ` Guenter Roeck
2025-08-06 19:21   ` kernel test robot
2025-08-06  6:32 ` [PATCH 1/2] dt-bindings: hwmon: ti,ina780a: Add INA780 device Krzysztof Kozlowski
2025-08-07 20:46   ` Chris Packham
2025-08-08  7:16     ` Krzysztof Kozlowski

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).