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 --- |