diff mbox series

[V5,3/4] hwmon: ina3221: Add support for channel summation disable

Message ID 20230929103650.86074-4-jonathanh@nvidia.com (mailing list archive)
State Accepted
Headers show
Series hwmon: ina3221: Add selective summation support | expand

Commit Message

Jon Hunter Sept. 29, 2023, 10:36 a.m. UTC
From: Ninad Malwade <nmalwade@nvidia.com>

The INA3221 allows the Critical alert pin to be controlled by the
summation control function. This function adds the single
shunt-voltage conversions for the desired channels in order to compare
the combined sum to the programmed limit. The Shunt-Voltage Sum Limit
register contains the programmed value that is compared to the value in
the Shunt-Voltage Sum register in order to determine if the total summed
limit is exceeded. If the shunt-voltage sum limit value is exceeded, the
Critical alert pin pulls low.

For the summation limit to have a meaningful value, we have to use the
same shunt-resistor value on all included channels. Unless equal
shunt-resistor values are used for each channel, the summation control
function cannot be used and it is not enabled by the driver.

To address this, add support to disable the summation of specific
channels via device tree property "ti,summation-disable". The channel
which has this property would be excluded from the calculation of
summation control function.

For example, summation control function calculates Shunt-Voltage Sum as:

- input_shunt_voltage_summation = input_shunt_voltage_channel1
                                + input_shunt_voltage_channel2
                                + input_shunt_voltage_channel3

If we want the summation to only use channel1 and channel3, we can add
'ti,summation-disable' property in device tree node for channel2. Then
the calculation will skip channel2.

- input_shunt_voltage_summation = input_shunt_voltage_channel1
                                + input_shunt_voltage_channel3

Note that we only want the channel to be skipped for summation control
function rather than completely disabled. Therefore, even if we add the
property 'ti,summation-disable', the channel is still enabled and
functional.

Finally, create debugfs entries that display if summation is disabled
for each of the channels.

Signed-off-by: Rajkumar Kasirajan <rkasirajan@nvidia.com>
Signed-off-by: Ninad Malwade <nmalwade@nvidia.com>
Co-developed-by: Jon Hunter <jonathanh@nvidia.com>
Signed-off-by: Jon Hunter <jonathanh@nvidia.com>
---
 drivers/hwmon/ina3221.c | 33 ++++++++++++++++++++++++++++++---
 1 file changed, 30 insertions(+), 3 deletions(-)

Comments

Jon Hunter Oct. 11, 2023, 8:15 a.m. UTC | #1
Hi Jean, Guenter,

On 29/09/2023 11:36, Jon Hunter wrote:
> From: Ninad Malwade <nmalwade@nvidia.com>
> 
> The INA3221 allows the Critical alert pin to be controlled by the
> summation control function. This function adds the single
> shunt-voltage conversions for the desired channels in order to compare
> the combined sum to the programmed limit. The Shunt-Voltage Sum Limit
> register contains the programmed value that is compared to the value in
> the Shunt-Voltage Sum register in order to determine if the total summed
> limit is exceeded. If the shunt-voltage sum limit value is exceeded, the
> Critical alert pin pulls low.
> 
> For the summation limit to have a meaningful value, we have to use the
> same shunt-resistor value on all included channels. Unless equal
> shunt-resistor values are used for each channel, the summation control
> function cannot be used and it is not enabled by the driver.
> 
> To address this, add support to disable the summation of specific
> channels via device tree property "ti,summation-disable". The channel
> which has this property would be excluded from the calculation of
> summation control function.
> 
> For example, summation control function calculates Shunt-Voltage Sum as:
> 
> - input_shunt_voltage_summation = input_shunt_voltage_channel1
>                                  + input_shunt_voltage_channel2
>                                  + input_shunt_voltage_channel3
> 
> If we want the summation to only use channel1 and channel3, we can add
> 'ti,summation-disable' property in device tree node for channel2. Then
> the calculation will skip channel2.
> 
> - input_shunt_voltage_summation = input_shunt_voltage_channel1
>                                  + input_shunt_voltage_channel3
> 
> Note that we only want the channel to be skipped for summation control
> function rather than completely disabled. Therefore, even if we add the
> property 'ti,summation-disable', the channel is still enabled and
> functional.
> 
> Finally, create debugfs entries that display if summation is disabled
> for each of the channels.
> 
> Signed-off-by: Rajkumar Kasirajan <rkasirajan@nvidia.com>
> Signed-off-by: Ninad Malwade <nmalwade@nvidia.com>
> Co-developed-by: Jon Hunter <jonathanh@nvidia.com>
> Signed-off-by: Jon Hunter <jonathanh@nvidia.com>


Any feedback on this?

Thanks
Jon
Guenter Roeck Oct. 26, 2023, 12:59 a.m. UTC | #2
On Fri, Sep 29, 2023 at 11:36:49AM +0100, Jon Hunter wrote:
> From: Ninad Malwade <nmalwade@nvidia.com>
> 
> The INA3221 allows the Critical alert pin to be controlled by the
> summation control function. This function adds the single
> shunt-voltage conversions for the desired channels in order to compare
> the combined sum to the programmed limit. The Shunt-Voltage Sum Limit
> register contains the programmed value that is compared to the value in
> the Shunt-Voltage Sum register in order to determine if the total summed
> limit is exceeded. If the shunt-voltage sum limit value is exceeded, the
> Critical alert pin pulls low.
> 
> For the summation limit to have a meaningful value, we have to use the
> same shunt-resistor value on all included channels. Unless equal
> shunt-resistor values are used for each channel, the summation control
> function cannot be used and it is not enabled by the driver.
> 
> To address this, add support to disable the summation of specific
> channels via device tree property "ti,summation-disable". The channel
> which has this property would be excluded from the calculation of
> summation control function.
> 
> For example, summation control function calculates Shunt-Voltage Sum as:
> 
> - input_shunt_voltage_summation = input_shunt_voltage_channel1
>                                 + input_shunt_voltage_channel2
>                                 + input_shunt_voltage_channel3
> 
> If we want the summation to only use channel1 and channel3, we can add
> 'ti,summation-disable' property in device tree node for channel2. Then
> the calculation will skip channel2.
> 
> - input_shunt_voltage_summation = input_shunt_voltage_channel1
>                                 + input_shunt_voltage_channel3
> 
> Note that we only want the channel to be skipped for summation control
> function rather than completely disabled. Therefore, even if we add the
> property 'ti,summation-disable', the channel is still enabled and
> functional.
> 
> Finally, create debugfs entries that display if summation is disabled
> for each of the channels.
> 
> Signed-off-by: Rajkumar Kasirajan <rkasirajan@nvidia.com>
> Signed-off-by: Ninad Malwade <nmalwade@nvidia.com>
> Co-developed-by: Jon Hunter <jonathanh@nvidia.com>
> Signed-off-by: Jon Hunter <jonathanh@nvidia.com>

Applied.

Thanks,
Guenter
diff mbox series

Patch

diff --git a/drivers/hwmon/ina3221.c b/drivers/hwmon/ina3221.c
index 5ab944056ec0..5ffdc94db436 100644
--- a/drivers/hwmon/ina3221.c
+++ b/drivers/hwmon/ina3221.c
@@ -6,6 +6,7 @@ 
  *	Andrew F. Davis <afd@ti.com>
  */
 
+#include <linux/debugfs.h>
 #include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
 #include <linux/i2c.h>
@@ -99,11 +100,13 @@  enum ina3221_channels {
  * @label: label of channel input source
  * @shunt_resistor: shunt resistor value of channel input source
  * @disconnected: connection status of channel input source
+ * @summation_disable: channel summation status of input source
  */
 struct ina3221_input {
 	const char *label;
 	int shunt_resistor;
 	bool disconnected;
+	bool summation_disable;
 };
 
 /**
@@ -113,8 +116,10 @@  struct ina3221_input {
  * @fields: Register fields of the device
  * @inputs: Array of channel input source specific structures
  * @lock: mutex lock to serialize sysfs attribute accesses
+ * @debugfs: Pointer to debugfs entry for device
  * @reg_config: Register value of INA3221_CONFIG
  * @summation_shunt_resistor: equivalent shunt resistor value for summation
+ * @summation_channel_control: Value written to SCC field in INA3221_MASK_ENABLE
  * @single_shot: running in single-shot operating mode
  */
 struct ina3221_data {
@@ -123,8 +128,10 @@  struct ina3221_data {
 	struct regmap_field *fields[F_MAX_FIELDS];
 	struct ina3221_input inputs[INA3221_NUM_CHANNELS];
 	struct mutex lock;
+	struct dentry *debugfs;
 	u32 reg_config;
 	int summation_shunt_resistor;
+	u32 summation_channel_control;
 
 	bool single_shot;
 };
@@ -154,7 +161,8 @@  static inline int ina3221_summation_shunt_resistor(struct ina3221_data *ina)
 	int i, shunt_resistor = 0;
 
 	for (i = 0; i < INA3221_NUM_CHANNELS; i++) {
-		if (input[i].disconnected || !input[i].shunt_resistor)
+		if (input[i].disconnected || !input[i].shunt_resistor ||
+		    input[i].summation_disable)
 			continue;
 		if (!shunt_resistor) {
 			/* Found the reference shunt resistor value */
@@ -786,6 +794,9 @@  static int ina3221_probe_child_from_dt(struct device *dev,
 	/* Save the connected input label if available */
 	of_property_read_string(child, "label", &input->label);
 
+	/* summation channel control */
+	input->summation_disable = of_property_read_bool(child, "ti,summation-disable");
+
 	/* Overwrite default shunt resistor value optionally */
 	if (!of_property_read_u32(child, "shunt-resistor-micro-ohms", &val)) {
 		if (val < 1 || val > INT_MAX) {
@@ -827,6 +838,7 @@  static int ina3221_probe(struct i2c_client *client)
 	struct device *dev = &client->dev;
 	struct ina3221_data *ina;
 	struct device *hwmon_dev;
+	char name[32];
 	int i, ret;
 
 	ina = devm_kzalloc(dev, sizeof(*ina), GFP_KERNEL);
@@ -873,6 +885,10 @@  static int ina3221_probe(struct i2c_client *client)
 
 	/* Initialize summation_shunt_resistor for summation channel control */
 	ina->summation_shunt_resistor = ina3221_summation_shunt_resistor(ina);
+	for (i = 0; i < INA3221_NUM_CHANNELS; i++) {
+		if (!ina->inputs[i].summation_disable)
+			ina->summation_channel_control |= BIT(14 - i);
+	}
 
 	ina->pm_dev = dev;
 	mutex_init(&ina->lock);
@@ -900,6 +916,15 @@  static int ina3221_probe(struct i2c_client *client)
 		goto fail;
 	}
 
+	scnprintf(name, sizeof(name), "%s-%s", INA3221_DRIVER_NAME, dev_name(dev));
+	ina->debugfs = debugfs_create_dir(name, NULL);
+
+	for (i = 0; i < INA3221_NUM_CHANNELS; i++) {
+		scnprintf(name, sizeof(name), "in%d_summation_disable", i);
+		debugfs_create_bool(name, 0400, ina->debugfs,
+				    &ina->inputs[i].summation_disable);
+	}
+
 	return 0;
 
 fail:
@@ -918,6 +943,8 @@  static void ina3221_remove(struct i2c_client *client)
 	struct ina3221_data *ina = dev_get_drvdata(&client->dev);
 	int i;
 
+	debugfs_remove_recursive(ina->debugfs);
+
 	pm_runtime_disable(ina->pm_dev);
 	pm_runtime_set_suspended(ina->pm_dev);
 
@@ -978,13 +1005,13 @@  static int ina3221_resume(struct device *dev)
 	/* Initialize summation channel control */
 	if (ina->summation_shunt_resistor) {
 		/*
-		 * Take all three channels into summation by default
+		 * Sum only channels that are not disabled for summation.
 		 * Shunt measurements of disconnected channels should
 		 * be 0, so it does not matter for summation.
 		 */
 		ret = regmap_update_bits(ina->regmap, INA3221_MASK_ENABLE,
 					 INA3221_MASK_ENABLE_SCC_MASK,
-					 INA3221_MASK_ENABLE_SCC_MASK);
+					 ina->summation_channel_control);
 		if (ret) {
 			dev_err(dev, "Unable to control summation channel\n");
 			return ret;