@@ -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>
@@ -104,6 +105,7 @@ struct ina3221_input {
const char *label;
int shunt_resistor;
bool disconnected;
+ bool summation_disable;
};
/**
@@ -123,8 +125,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 +158,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 +791,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 +835,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 +882,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 +913,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 +940,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 +1002,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;