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, ®val); 379 if (ret) 380 goto abort; 381 382 if (regval & BIT(attr->index)) { 383 ret = regmap_read(data->regmap, INA226_ALERT_LIMIT, ®val); 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, ®val); 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 --- |