aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/hwmon/ina2xx5
-rw-r--r--drivers/hwmon/ina2xx.c48
2 files changed, 49 insertions, 4 deletions
diff --git a/Documentation/hwmon/ina2xx b/Documentation/hwmon/ina2xx
index 4223c2d3b508..320dd69fb5e6 100644
--- a/Documentation/hwmon/ina2xx
+++ b/Documentation/hwmon/ina2xx
@@ -44,6 +44,7 @@ The INA226 monitors both a shunt voltage drop and bus supply voltage.
44The INA230 is a high or low side current shunt and power monitor with an I2C 44The INA230 is a high or low side current shunt and power monitor with an I2C
45interface. The INA230 monitors both a shunt voltage drop and bus supply voltage. 45interface. The INA230 monitors both a shunt voltage drop and bus supply voltage.
46 46
47The shunt value in micro-ohms can be set via platform data or device tree. 47The shunt value in micro-ohms can be set via platform data or device tree at
48Please refer to the Documentation/devicetree/bindings/i2c/ina2xx.txt for bindings 48compile-time or via the shunt_resistor attribute in sysfs at run-time. Please
49refer to the Documentation/devicetree/bindings/i2c/ina2xx.txt for bindings
49if the device tree is used. 50if the device tree is used.
diff --git a/drivers/hwmon/ina2xx.c b/drivers/hwmon/ina2xx.c
index 3234e571805c..49537ea80748 100644
--- a/drivers/hwmon/ina2xx.c
+++ b/drivers/hwmon/ina2xx.c
@@ -115,6 +115,12 @@ static const struct ina2xx_config ina2xx_config[] = {
115 }, 115 },
116}; 116};
117 117
118static int ina2xx_calibrate(struct ina2xx_data *data)
119{
120 return i2c_smbus_write_word_swapped(data->client, INA2XX_CALIBRATION,
121 data->config->calibration_factor / data->rshunt);
122}
123
118/* 124/*
119 * Initialize the configuration and calibration registers. 125 * Initialize the configuration and calibration registers.
120 */ 126 */
@@ -133,8 +139,7 @@ static int ina2xx_init(struct ina2xx_data *data)
133 * Set current LSB to 1mA, shunt is in uOhms 139 * Set current LSB to 1mA, shunt is in uOhms
134 * (equation 13 in datasheet). 140 * (equation 13 in datasheet).
135 */ 141 */
136 return i2c_smbus_write_word_swapped(client, INA2XX_CALIBRATION, 142 return ina2xx_calibrate(data);
137 data->config->calibration_factor / data->rshunt);
138} 143}
139 144
140static int ina2xx_do_update(struct device *dev) 145static int ina2xx_do_update(struct device *dev)
@@ -231,6 +236,9 @@ static int ina2xx_get_value(struct ina2xx_data *data, u8 reg)
231 /* signed register, LSB=1mA (selected), in mA */ 236 /* signed register, LSB=1mA (selected), in mA */
232 val = (s16)data->regs[reg]; 237 val = (s16)data->regs[reg];
233 break; 238 break;
239 case INA2XX_CALIBRATION:
240 val = data->config->calibration_factor / data->regs[reg];
241 break;
234 default: 242 default:
235 /* programmer goofed */ 243 /* programmer goofed */
236 WARN_ON_ONCE(1); 244 WARN_ON_ONCE(1);
@@ -254,6 +262,36 @@ static ssize_t ina2xx_show_value(struct device *dev,
254 ina2xx_get_value(data, attr->index)); 262 ina2xx_get_value(data, attr->index));
255} 263}
256 264
265static ssize_t ina2xx_set_shunt(struct device *dev,
266 struct device_attribute *da,
267 const char *buf, size_t count)
268{
269 struct ina2xx_data *data = ina2xx_update_device(dev);
270 unsigned long val;
271 int status;
272
273 if (IS_ERR(data))
274 return PTR_ERR(data);
275
276 status = kstrtoul(buf, 10, &val);
277 if (status < 0)
278 return status;
279
280 if (val == 0 ||
281 /* Values greater than the calibration factor make no sense. */
282 val > data->config->calibration_factor)
283 return -EINVAL;
284
285 mutex_lock(&data->update_lock);
286 data->rshunt = val;
287 status = ina2xx_calibrate(data);
288 mutex_unlock(&data->update_lock);
289 if (status < 0)
290 return status;
291
292 return count;
293}
294
257/* shunt voltage */ 295/* shunt voltage */
258static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, ina2xx_show_value, NULL, 296static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, ina2xx_show_value, NULL,
259 INA2XX_SHUNT_VOLTAGE); 297 INA2XX_SHUNT_VOLTAGE);
@@ -270,12 +308,18 @@ static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, ina2xx_show_value, NULL,
270static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO, ina2xx_show_value, NULL, 308static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO, ina2xx_show_value, NULL,
271 INA2XX_POWER); 309 INA2XX_POWER);
272 310
311/* shunt resistance */
312static SENSOR_DEVICE_ATTR(shunt_resistor, S_IRUGO | S_IWUSR,
313 ina2xx_show_value, ina2xx_set_shunt,
314 INA2XX_CALIBRATION);
315
273/* pointers to created device attributes */ 316/* pointers to created device attributes */
274static struct attribute *ina2xx_attrs[] = { 317static struct attribute *ina2xx_attrs[] = {
275 &sensor_dev_attr_in0_input.dev_attr.attr, 318 &sensor_dev_attr_in0_input.dev_attr.attr,
276 &sensor_dev_attr_in1_input.dev_attr.attr, 319 &sensor_dev_attr_in1_input.dev_attr.attr,
277 &sensor_dev_attr_curr1_input.dev_attr.attr, 320 &sensor_dev_attr_curr1_input.dev_attr.attr,
278 &sensor_dev_attr_power1_input.dev_attr.attr, 321 &sensor_dev_attr_power1_input.dev_attr.attr,
322 &sensor_dev_attr_shunt_resistor.dev_attr.attr,
279 NULL, 323 NULL,
280}; 324};
281ATTRIBUTE_GROUPS(ina2xx); 325ATTRIBUTE_GROUPS(ina2xx);