ina2xx.c (75bf465f0bc33e9b776a46d6a1b9b990f5fb7c37) ina2xx.c (5a56a39be7ffb416dd5ec5e1489d5a3a8b6a63f2)
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Driver for Texas Instruments INA219, INA226 power monitor chips
4 *
5 * INA219:
6 * Zero Drift Bi-Directional Current/Power Monitor with I2C Interface
7 * Datasheet: http://www.ti.com/product/ina219
8 *

--- 60 unchanged lines hidden (view full) ---

69#define INA2XX_RSHUNT_DEFAULT 10000
70
71/* bit mask for reading the averaging setting in the configuration register */
72#define INA226_AVG_RD_MASK 0x0E00
73
74#define INA226_READ_AVG(reg) (((reg) & INA226_AVG_RD_MASK) >> 9)
75#define INA226_SHIFT_AVG(val) ((val) << 9)
76
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Driver for Texas Instruments INA219, INA226 power monitor chips
4 *
5 * INA219:
6 * Zero Drift Bi-Directional Current/Power Monitor with I2C Interface
7 * Datasheet: http://www.ti.com/product/ina219
8 *

--- 60 unchanged lines hidden (view full) ---

69#define INA2XX_RSHUNT_DEFAULT 10000
70
71/* bit mask for reading the averaging setting in the configuration register */
72#define INA226_AVG_RD_MASK 0x0E00
73
74#define INA226_READ_AVG(reg) (((reg) & INA226_AVG_RD_MASK) >> 9)
75#define INA226_SHIFT_AVG(val) ((val) << 9)
76
77/* bit number of alert functions in Mask/Enable Register */
78#define INA226_SHUNT_OVER_VOLTAGE_BIT 15
79#define INA226_SHUNT_UNDER_VOLTAGE_BIT 14
80#define INA226_BUS_OVER_VOLTAGE_BIT 13
81#define INA226_BUS_UNDER_VOLTAGE_BIT 12
82#define INA226_POWER_OVER_LIMIT_BIT 11
83
84/* bit mask for alert config bits of Mask/Enable Register */
85#define INA226_ALERT_CONFIG_MASK 0xFC00
86#define INA226_ALERT_FUNCTION_FLAG BIT(4)
87
77/* common attrs, ina226 attrs and NULL */
78#define INA2XX_MAX_ATTRIBUTE_GROUPS 3
79
80/*
81 * Both bus voltage and shunt voltage conversion times for ina226 are set
82 * to 0b0100 on POR, which translates to 2200 microseconds in total.
83 */
84#define INA226_TOTAL_CONV_TIME_DEFAULT 2200

--- 213 unchanged lines hidden (view full) ---

298
299 if (err < 0)
300 return err;
301
302 return snprintf(buf, PAGE_SIZE, "%d\n",
303 ina2xx_get_value(data, attr->index, regval));
304}
305
88/* common attrs, ina226 attrs and NULL */
89#define INA2XX_MAX_ATTRIBUTE_GROUPS 3
90
91/*
92 * Both bus voltage and shunt voltage conversion times for ina226 are set
93 * to 0b0100 on POR, which translates to 2200 microseconds in total.
94 */
95#define INA226_TOTAL_CONV_TIME_DEFAULT 2200

--- 213 unchanged lines hidden (view full) ---

309
310 if (err < 0)
311 return err;
312
313 return snprintf(buf, PAGE_SIZE, "%d\n",
314 ina2xx_get_value(data, attr->index, regval));
315}
316
317static int ina226_reg_to_alert(struct ina2xx_data *data, u8 bit, u16 regval)
318{
319 int reg;
320
321 switch (bit) {
322 case INA226_SHUNT_OVER_VOLTAGE_BIT:
323 case INA226_SHUNT_UNDER_VOLTAGE_BIT:
324 reg = INA2XX_SHUNT_VOLTAGE;
325 break;
326 case INA226_BUS_OVER_VOLTAGE_BIT:
327 case INA226_BUS_UNDER_VOLTAGE_BIT:
328 reg = INA2XX_BUS_VOLTAGE;
329 break;
330 case INA226_POWER_OVER_LIMIT_BIT:
331 reg = INA2XX_POWER;
332 break;
333 default:
334 /* programmer goofed */
335 WARN_ON_ONCE(1);
336 return 0;
337 }
338
339 return ina2xx_get_value(data, reg, regval);
340}
341
306/*
342/*
343 * Turns alert limit values into register values.
344 * Opposite of the formula in ina2xx_get_value().
345 */
346static s16 ina226_alert_to_reg(struct ina2xx_data *data, u8 bit, int val)
347{
348 switch (bit) {
349 case INA226_SHUNT_OVER_VOLTAGE_BIT:
350 case INA226_SHUNT_UNDER_VOLTAGE_BIT:
351 val *= data->config->shunt_div;
352 return clamp_val(val, SHRT_MIN, SHRT_MAX);
353 case INA226_BUS_OVER_VOLTAGE_BIT:
354 case INA226_BUS_UNDER_VOLTAGE_BIT:
355 val = (val * 1000) << data->config->bus_voltage_shift;
356 val = DIV_ROUND_CLOSEST(val, data->config->bus_voltage_lsb);
357 return clamp_val(val, 0, SHRT_MAX);
358 case INA226_POWER_OVER_LIMIT_BIT:
359 val = DIV_ROUND_CLOSEST(val, data->power_lsb_uW);
360 return clamp_val(val, 0, USHRT_MAX);
361 default:
362 /* programmer goofed */
363 WARN_ON_ONCE(1);
364 return 0;
365 }
366}
367
368static ssize_t ina226_alert_show(struct device *dev,
369 struct device_attribute *da, char *buf)
370{
371 struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
372 struct ina2xx_data *data = dev_get_drvdata(dev);
373 int regval;
374 int val = 0;
375 int ret;
376
377 mutex_lock(&data->config_lock);
378 ret = regmap_read(data->regmap, INA226_MASK_ENABLE, &regval);
379 if (ret)
380 goto abort;
381
382 if (regval & BIT(attr->index)) {
383 ret = regmap_read(data->regmap, INA226_ALERT_LIMIT, &regval);
384 if (ret)
385 goto abort;
386 val = ina226_reg_to_alert(data, attr->index, regval);
387 }
388
389 ret = snprintf(buf, PAGE_SIZE, "%d\n", val);
390abort:
391 mutex_unlock(&data->config_lock);
392 return ret;
393}
394
395static ssize_t ina226_alert_store(struct device *dev,
396 struct device_attribute *da,
397 const char *buf, size_t count)
398{
399 struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
400 struct ina2xx_data *data = dev_get_drvdata(dev);
401 unsigned long val;
402 int ret;
403
404 ret = kstrtoul(buf, 10, &val);
405 if (ret < 0)
406 return ret;
407
408 /*
409 * Clear all alerts first to avoid accidentally triggering ALERT pin
410 * due to register write sequence. Then, only enable the alert
411 * if the value is non-zero.
412 */
413 mutex_lock(&data->config_lock);
414 ret = regmap_update_bits(data->regmap, INA226_MASK_ENABLE,
415 INA226_ALERT_CONFIG_MASK, 0);
416 if (ret < 0)
417 goto abort;
418
419 ret = regmap_write(data->regmap, INA226_ALERT_LIMIT,
420 ina226_alert_to_reg(data, attr->index, val));
421 if (ret < 0)
422 goto abort;
423
424 if (val != 0) {
425 ret = regmap_update_bits(data->regmap, INA226_MASK_ENABLE,
426 INA226_ALERT_CONFIG_MASK,
427 BIT(attr->index));
428 if (ret < 0)
429 goto abort;
430 }
431
432 ret = count;
433abort:
434 mutex_unlock(&data->config_lock);
435 return ret;
436}
437
438static ssize_t ina226_alarm_show(struct device *dev,
439 struct device_attribute *da, char *buf)
440{
441 struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
442 struct ina2xx_data *data = dev_get_drvdata(dev);
443 int regval;
444 int alarm = 0;
445 int ret;
446
447 ret = regmap_read(data->regmap, INA226_MASK_ENABLE, &regval);
448 if (ret)
449 return ret;
450
451 alarm = (regval & BIT(attr->index)) &&
452 (regval & INA226_ALERT_FUNCTION_FLAG);
453 return snprintf(buf, PAGE_SIZE, "%d\n", alarm);
454}
455
456/*
307 * In order to keep calibration register value fixed, the product
308 * of current_lsb and shunt_resistor should also be fixed and equal
309 * to shunt_voltage_lsb = 1 / shunt_div multiplied by 10^9 in order
310 * to keep the scale.
311 */
312static int ina2xx_set_shunt(struct ina2xx_data *data, long val)
313{
314 unsigned int dividend = DIV_ROUND_CLOSEST(1000000000,

--- 72 unchanged lines hidden (view full) ---

387 if (status)
388 return status;
389
390 return snprintf(buf, PAGE_SIZE, "%d\n", ina226_reg_to_interval(regval));
391}
392
393/* shunt voltage */
394static SENSOR_DEVICE_ATTR_RO(in0_input, ina2xx_value, INA2XX_SHUNT_VOLTAGE);
457 * In order to keep calibration register value fixed, the product
458 * of current_lsb and shunt_resistor should also be fixed and equal
459 * to shunt_voltage_lsb = 1 / shunt_div multiplied by 10^9 in order
460 * to keep the scale.
461 */
462static int ina2xx_set_shunt(struct ina2xx_data *data, long val)
463{
464 unsigned int dividend = DIV_ROUND_CLOSEST(1000000000,

--- 72 unchanged lines hidden (view full) ---

537 if (status)
538 return status;
539
540 return snprintf(buf, PAGE_SIZE, "%d\n", ina226_reg_to_interval(regval));
541}
542
543/* shunt voltage */
544static SENSOR_DEVICE_ATTR_RO(in0_input, ina2xx_value, INA2XX_SHUNT_VOLTAGE);
545/* shunt voltage over/under voltage alert setting and alarm */
546static SENSOR_DEVICE_ATTR_RW(in0_crit, ina226_alert,
547 INA226_SHUNT_OVER_VOLTAGE_BIT);
548static SENSOR_DEVICE_ATTR_RW(in0_lcrit, ina226_alert,
549 INA226_SHUNT_UNDER_VOLTAGE_BIT);
550static SENSOR_DEVICE_ATTR_RO(in0_crit_alarm, ina226_alarm,
551 INA226_SHUNT_OVER_VOLTAGE_BIT);
552static SENSOR_DEVICE_ATTR_RO(in0_lcrit_alarm, ina226_alarm,
553 INA226_SHUNT_UNDER_VOLTAGE_BIT);
395
396/* bus voltage */
397static SENSOR_DEVICE_ATTR_RO(in1_input, ina2xx_value, INA2XX_BUS_VOLTAGE);
554
555/* bus voltage */
556static SENSOR_DEVICE_ATTR_RO(in1_input, ina2xx_value, INA2XX_BUS_VOLTAGE);
557/* bus voltage over/under voltage alert setting and alarm */
558static SENSOR_DEVICE_ATTR_RW(in1_crit, ina226_alert,
559 INA226_BUS_OVER_VOLTAGE_BIT);
560static SENSOR_DEVICE_ATTR_RW(in1_lcrit, ina226_alert,
561 INA226_BUS_UNDER_VOLTAGE_BIT);
562static SENSOR_DEVICE_ATTR_RO(in1_crit_alarm, ina226_alarm,
563 INA226_BUS_OVER_VOLTAGE_BIT);
564static SENSOR_DEVICE_ATTR_RO(in1_lcrit_alarm, ina226_alarm,
565 INA226_BUS_UNDER_VOLTAGE_BIT);
398
399/* calculated current */
400static SENSOR_DEVICE_ATTR_RO(curr1_input, ina2xx_value, INA2XX_CURRENT);
401
402/* calculated power */
403static SENSOR_DEVICE_ATTR_RO(power1_input, ina2xx_value, INA2XX_POWER);
566
567/* calculated current */
568static SENSOR_DEVICE_ATTR_RO(curr1_input, ina2xx_value, INA2XX_CURRENT);
569
570/* calculated power */
571static SENSOR_DEVICE_ATTR_RO(power1_input, ina2xx_value, INA2XX_POWER);
572/* over-limit power alert setting and alarm */
573static SENSOR_DEVICE_ATTR_RW(power1_crit, ina226_alert,
574 INA226_POWER_OVER_LIMIT_BIT);
575static SENSOR_DEVICE_ATTR_RO(power1_crit_alarm, ina226_alarm,
576 INA226_POWER_OVER_LIMIT_BIT);
404
405/* shunt resistance */
406static SENSOR_DEVICE_ATTR_RW(shunt_resistor, ina2xx_shunt, INA2XX_CALIBRATION);
407
408/* update interval (ina226 only) */
409static SENSOR_DEVICE_ATTR_RW(update_interval, ina226_interval, 0);
410
411/* pointers to created device attributes */

--- 6 unchanged lines hidden (view full) ---

418 NULL,
419};
420
421static const struct attribute_group ina2xx_group = {
422 .attrs = ina2xx_attrs,
423};
424
425static struct attribute *ina226_attrs[] = {
577
578/* shunt resistance */
579static SENSOR_DEVICE_ATTR_RW(shunt_resistor, ina2xx_shunt, INA2XX_CALIBRATION);
580
581/* update interval (ina226 only) */
582static SENSOR_DEVICE_ATTR_RW(update_interval, ina226_interval, 0);
583
584/* pointers to created device attributes */

--- 6 unchanged lines hidden (view full) ---

591 NULL,
592};
593
594static const struct attribute_group ina2xx_group = {
595 .attrs = ina2xx_attrs,
596};
597
598static struct attribute *ina226_attrs[] = {
599 &sensor_dev_attr_in0_crit.dev_attr.attr,
600 &sensor_dev_attr_in0_lcrit.dev_attr.attr,
601 &sensor_dev_attr_in0_crit_alarm.dev_attr.attr,
602 &sensor_dev_attr_in0_lcrit_alarm.dev_attr.attr,
603 &sensor_dev_attr_in1_crit.dev_attr.attr,
604 &sensor_dev_attr_in1_lcrit.dev_attr.attr,
605 &sensor_dev_attr_in1_crit_alarm.dev_attr.attr,
606 &sensor_dev_attr_in1_lcrit_alarm.dev_attr.attr,
607 &sensor_dev_attr_power1_crit.dev_attr.attr,
608 &sensor_dev_attr_power1_crit_alarm.dev_attr.attr,
426 &sensor_dev_attr_update_interval.dev_attr.attr,
427 NULL,
428};
429
430static const struct attribute_group ina226_group = {
431 .attrs = ina226_attrs,
432};
433

--- 112 unchanged lines hidden ---
609 &sensor_dev_attr_update_interval.dev_attr.attr,
610 NULL,
611};
612
613static const struct attribute_group ina226_group = {
614 .attrs = ina226_attrs,
615};
616

--- 112 unchanged lines hidden ---