ina2xx.c (9965ebd1836fb75c7a80f20ca65469f5df0d6063) ina2xx.c (4d5c2d986757e4d6f56761af8ab689218a2bc432)
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: https://www.ti.com/product/ina219
8 *

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

301 dev_err(dev, "unable to reinitialize the chip\n");
302 return -ENODEV;
303}
304
305/*
306 * Turns alert limit values into register values.
307 * Opposite of the formula in ina2xx_get_value().
308 */
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: https://www.ti.com/product/ina219
8 *

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

301 dev_err(dev, "unable to reinitialize the chip\n");
302 return -ENODEV;
303}
304
305/*
306 * Turns alert limit values into register values.
307 * Opposite of the formula in ina2xx_get_value().
308 */
309static u16 ina226_alert_to_reg(struct ina2xx_data *data, int reg, unsigned long val)
309static u16 ina226_alert_to_reg(struct ina2xx_data *data, int reg, long val)
310{
311 switch (reg) {
312 case INA2XX_SHUNT_VOLTAGE:
313 val = clamp_val(val, 0, SHRT_MAX * data->config->shunt_div);
314 val *= data->config->shunt_div;
315 return clamp_val(val, 0, SHRT_MAX);
316 case INA2XX_BUS_VOLTAGE:
317 val = clamp_val(val, 0, 200000);
318 val = (val * 1000) << data->config->bus_voltage_shift;
319 val = DIV_ROUND_CLOSEST(val, data->config->bus_voltage_lsb);
320 return clamp_val(val, 0, USHRT_MAX);
321 case INA2XX_POWER:
322 val = clamp_val(val, 0, UINT_MAX - data->power_lsb_uW);
323 val = DIV_ROUND_CLOSEST(val, data->power_lsb_uW);
324 return clamp_val(val, 0, USHRT_MAX);
310{
311 switch (reg) {
312 case INA2XX_SHUNT_VOLTAGE:
313 val = clamp_val(val, 0, SHRT_MAX * data->config->shunt_div);
314 val *= data->config->shunt_div;
315 return clamp_val(val, 0, SHRT_MAX);
316 case INA2XX_BUS_VOLTAGE:
317 val = clamp_val(val, 0, 200000);
318 val = (val * 1000) << data->config->bus_voltage_shift;
319 val = DIV_ROUND_CLOSEST(val, data->config->bus_voltage_lsb);
320 return clamp_val(val, 0, USHRT_MAX);
321 case INA2XX_POWER:
322 val = clamp_val(val, 0, UINT_MAX - data->power_lsb_uW);
323 val = DIV_ROUND_CLOSEST(val, data->power_lsb_uW);
324 return clamp_val(val, 0, USHRT_MAX);
325 case INA2XX_CURRENT:
326 val = clamp_val(val, INT_MIN / 1000, INT_MAX / 1000);
327 /* signed register, result in mA */
328 val = DIV_ROUND_CLOSEST(val * 1000, data->current_lsb_uA);
329 return clamp_val(val, SHRT_MIN, SHRT_MAX);
325 default:
326 /* programmer goofed */
327 WARN_ON_ONCE(1);
328 return 0;
329 }
330}
331
332static int ina226_alert_limit_read(struct ina2xx_data *data, u32 mask, int reg, long *val)

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

468 return ina226_alert_read(data->regmap, INA226_POWER_OVER_LIMIT_MASK, val);
469 default:
470 return -EOPNOTSUPP;
471 }
472}
473
474static int ina2xx_curr_read(struct device *dev, u32 attr, long *val)
475{
330 default:
331 /* programmer goofed */
332 WARN_ON_ONCE(1);
333 return 0;
334 }
335}
336
337static int ina226_alert_limit_read(struct ina2xx_data *data, u32 mask, int reg, long *val)

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

473 return ina226_alert_read(data->regmap, INA226_POWER_OVER_LIMIT_MASK, val);
474 default:
475 return -EOPNOTSUPP;
476 }
477}
478
479static int ina2xx_curr_read(struct device *dev, u32 attr, long *val)
480{
481 struct ina2xx_data *data = dev_get_drvdata(dev);
482 struct regmap *regmap = data->regmap;
483
484 /*
485 * While the chips supported by this driver do not directly support
486 * current limits, they do support setting shunt voltage limits.
487 * The shunt voltage divided by the shunt resistor value is the current.
488 * On top of that, calibration values are set such that in the shunt
489 * voltage register and the current register report the same values.
490 * That means we can report and configure current limits based on shunt
491 * voltage limits.
492 */
476 switch (attr) {
477 case hwmon_curr_input:
478 return ina2xx_read_init(dev, INA2XX_CURRENT, val);
493 switch (attr) {
494 case hwmon_curr_input:
495 return ina2xx_read_init(dev, INA2XX_CURRENT, val);
496 case hwmon_curr_lcrit:
497 return ina226_alert_limit_read(data, INA226_SHUNT_UNDER_VOLTAGE_MASK,
498 INA2XX_CURRENT, val);
499 case hwmon_curr_crit:
500 return ina226_alert_limit_read(data, INA226_SHUNT_OVER_VOLTAGE_MASK,
501 INA2XX_CURRENT, val);
502 case hwmon_curr_lcrit_alarm:
503 return ina226_alert_read(regmap, INA226_SHUNT_UNDER_VOLTAGE_MASK, val);
504 case hwmon_curr_crit_alarm:
505 return ina226_alert_read(regmap, INA226_SHUNT_OVER_VOLTAGE_MASK, val);
479 default:
480 return -EOPNOTSUPP;
481 }
482}
483
484static int ina2xx_read(struct device *dev, enum hwmon_sensor_types type,
485 u32 attr, int channel, long *val)
486{

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

542 return ina226_alert_limit_write(data, INA226_POWER_OVER_LIMIT_MASK,
543 INA2XX_POWER, val);
544 default:
545 return -EOPNOTSUPP;
546 }
547 return 0;
548}
549
506 default:
507 return -EOPNOTSUPP;
508 }
509}
510
511static int ina2xx_read(struct device *dev, enum hwmon_sensor_types type,
512 u32 attr, int channel, long *val)
513{

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

569 return ina226_alert_limit_write(data, INA226_POWER_OVER_LIMIT_MASK,
570 INA2XX_POWER, val);
571 default:
572 return -EOPNOTSUPP;
573 }
574 return 0;
575}
576
577static int ina2xx_curr_write(struct device *dev, u32 attr, long val)
578{
579 struct ina2xx_data *data = dev_get_drvdata(dev);
580
581 switch (attr) {
582 case hwmon_curr_lcrit:
583 return ina226_alert_limit_write(data, INA226_SHUNT_UNDER_VOLTAGE_MASK,
584 INA2XX_CURRENT, val);
585 case hwmon_curr_crit:
586 return ina226_alert_limit_write(data, INA226_SHUNT_OVER_VOLTAGE_MASK,
587 INA2XX_CURRENT, val);
588 default:
589 return -EOPNOTSUPP;
590 }
591 return 0;
592}
593
550static int ina2xx_write(struct device *dev, enum hwmon_sensor_types type,
551 u32 attr, int channel, long val)
552{
553 switch (type) {
554 case hwmon_chip:
555 return ina2xx_chip_write(dev, attr, val);
556 case hwmon_in:
557 return ina2xx_in_write(dev, attr, channel, val);
558 case hwmon_power:
559 return ina2xx_power_write(dev, attr, val);
594static int ina2xx_write(struct device *dev, enum hwmon_sensor_types type,
595 u32 attr, int channel, long val)
596{
597 switch (type) {
598 case hwmon_chip:
599 return ina2xx_chip_write(dev, attr, val);
600 case hwmon_in:
601 return ina2xx_in_write(dev, attr, channel, val);
602 case hwmon_power:
603 return ina2xx_power_write(dev, attr, val);
604 case hwmon_curr:
605 return ina2xx_curr_write(dev, attr, val);
560 default:
561 return -EOPNOTSUPP;
562 }
563}
564
565static umode_t ina2xx_is_visible(const void *_data, enum hwmon_sensor_types type,
566 u32 attr, int channel)
567{

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

586 default:
587 break;
588 }
589 break;
590 case hwmon_curr:
591 switch (attr) {
592 case hwmon_curr_input:
593 return 0444;
606 default:
607 return -EOPNOTSUPP;
608 }
609}
610
611static umode_t ina2xx_is_visible(const void *_data, enum hwmon_sensor_types type,
612 u32 attr, int channel)
613{

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

632 default:
633 break;
634 }
635 break;
636 case hwmon_curr:
637 switch (attr) {
638 case hwmon_curr_input:
639 return 0444;
640 case hwmon_curr_lcrit:
641 case hwmon_curr_crit:
642 if (chip == ina226)
643 return 0644;
644 break;
645 case hwmon_curr_lcrit_alarm:
646 case hwmon_curr_crit_alarm:
647 if (chip == ina226)
648 return 0444;
649 break;
594 default:
595 break;
596 }
597 break;
598 case hwmon_power:
599 switch (attr) {
600 case hwmon_power_input:
601 return 0444;

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

631 HWMON_CHANNEL_INFO(chip,
632 HWMON_C_UPDATE_INTERVAL),
633 HWMON_CHANNEL_INFO(in,
634 HWMON_I_INPUT | HWMON_I_CRIT | HWMON_I_CRIT_ALARM |
635 HWMON_I_LCRIT | HWMON_I_LCRIT_ALARM,
636 HWMON_I_INPUT | HWMON_I_CRIT | HWMON_I_CRIT_ALARM |
637 HWMON_I_LCRIT | HWMON_I_LCRIT_ALARM
638 ),
650 default:
651 break;
652 }
653 break;
654 case hwmon_power:
655 switch (attr) {
656 case hwmon_power_input:
657 return 0444;

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

687 HWMON_CHANNEL_INFO(chip,
688 HWMON_C_UPDATE_INTERVAL),
689 HWMON_CHANNEL_INFO(in,
690 HWMON_I_INPUT | HWMON_I_CRIT | HWMON_I_CRIT_ALARM |
691 HWMON_I_LCRIT | HWMON_I_LCRIT_ALARM,
692 HWMON_I_INPUT | HWMON_I_CRIT | HWMON_I_CRIT_ALARM |
693 HWMON_I_LCRIT | HWMON_I_LCRIT_ALARM
694 ),
639 HWMON_CHANNEL_INFO(curr, HWMON_C_INPUT),
695 HWMON_CHANNEL_INFO(curr, HWMON_C_INPUT | HWMON_C_CRIT | HWMON_C_CRIT_ALARM |
696 HWMON_C_LCRIT | HWMON_C_LCRIT_ALARM),
640 HWMON_CHANNEL_INFO(power,
641 HWMON_P_INPUT | HWMON_P_CRIT | HWMON_P_CRIT_ALARM),
642 NULL
643};
644
645static const struct hwmon_ops ina2xx_hwmon_ops = {
646 .is_visible = ina2xx_is_visible,
647 .read = ina2xx_read,

--- 201 unchanged lines hidden ---
697 HWMON_CHANNEL_INFO(power,
698 HWMON_P_INPUT | HWMON_P_CRIT | HWMON_P_CRIT_ALARM),
699 NULL
700};
701
702static const struct hwmon_ops ina2xx_hwmon_ops = {
703 .is_visible = ina2xx_is_visible,
704 .read = ina2xx_read,

--- 201 unchanged lines hidden ---