1 /* 2 * INA3221 Triple Current/Voltage Monitor 3 * 4 * Copyright (C) 2016 Texas Instruments Incorporated - http://www.ti.com/ 5 * Andrew F. Davis <afd@ti.com> 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License version 2 as 9 * published by the Free Software Foundation. 10 * 11 * This program is distributed in the hope that it will be useful, but 12 * WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * General Public License for more details. 15 */ 16 17 #include <linux/hwmon.h> 18 #include <linux/hwmon-sysfs.h> 19 #include <linux/i2c.h> 20 #include <linux/module.h> 21 #include <linux/of.h> 22 #include <linux/regmap.h> 23 24 #define INA3221_DRIVER_NAME "ina3221" 25 26 #define INA3221_CONFIG 0x00 27 #define INA3221_SHUNT1 0x01 28 #define INA3221_BUS1 0x02 29 #define INA3221_SHUNT2 0x03 30 #define INA3221_BUS2 0x04 31 #define INA3221_SHUNT3 0x05 32 #define INA3221_BUS3 0x06 33 #define INA3221_CRIT1 0x07 34 #define INA3221_WARN1 0x08 35 #define INA3221_CRIT2 0x09 36 #define INA3221_WARN2 0x0a 37 #define INA3221_CRIT3 0x0b 38 #define INA3221_WARN3 0x0c 39 #define INA3221_MASK_ENABLE 0x0f 40 41 #define INA3221_CONFIG_MODE_MASK GENMASK(2, 0) 42 #define INA3221_CONFIG_MODE_POWERDOWN 0 43 #define INA3221_CONFIG_MODE_SHUNT BIT(0) 44 #define INA3221_CONFIG_MODE_BUS BIT(1) 45 #define INA3221_CONFIG_MODE_CONTINUOUS BIT(2) 46 #define INA3221_CONFIG_CHx_EN(x) BIT(14 - (x)) 47 48 #define INA3221_RSHUNT_DEFAULT 10000 49 50 enum ina3221_fields { 51 /* Configuration */ 52 F_RST, 53 54 /* Alert Flags */ 55 F_WF3, F_WF2, F_WF1, 56 F_CF3, F_CF2, F_CF1, 57 58 /* sentinel */ 59 F_MAX_FIELDS 60 }; 61 62 static const struct reg_field ina3221_reg_fields[] = { 63 [F_RST] = REG_FIELD(INA3221_CONFIG, 15, 15), 64 65 [F_WF3] = REG_FIELD(INA3221_MASK_ENABLE, 3, 3), 66 [F_WF2] = REG_FIELD(INA3221_MASK_ENABLE, 4, 4), 67 [F_WF1] = REG_FIELD(INA3221_MASK_ENABLE, 5, 5), 68 [F_CF3] = REG_FIELD(INA3221_MASK_ENABLE, 7, 7), 69 [F_CF2] = REG_FIELD(INA3221_MASK_ENABLE, 8, 8), 70 [F_CF1] = REG_FIELD(INA3221_MASK_ENABLE, 9, 9), 71 }; 72 73 enum ina3221_channels { 74 INA3221_CHANNEL1, 75 INA3221_CHANNEL2, 76 INA3221_CHANNEL3, 77 INA3221_NUM_CHANNELS 78 }; 79 80 /** 81 * struct ina3221_input - channel input source specific information 82 * @label: label of channel input source 83 * @shunt_resistor: shunt resistor value of channel input source 84 * @disconnected: connection status of channel input source 85 */ 86 struct ina3221_input { 87 const char *label; 88 int shunt_resistor; 89 bool disconnected; 90 }; 91 92 /** 93 * struct ina3221_data - device specific information 94 * @regmap: Register map of the device 95 * @fields: Register fields of the device 96 * @inputs: Array of channel input source specific structures 97 * @reg_config: Register value of INA3221_CONFIG 98 */ 99 struct ina3221_data { 100 struct regmap *regmap; 101 struct regmap_field *fields[F_MAX_FIELDS]; 102 struct ina3221_input inputs[INA3221_NUM_CHANNELS]; 103 u32 reg_config; 104 }; 105 106 static inline bool ina3221_is_enabled(struct ina3221_data *ina, int channel) 107 { 108 return ina->reg_config & INA3221_CONFIG_CHx_EN(channel); 109 } 110 111 static int ina3221_read_value(struct ina3221_data *ina, unsigned int reg, 112 int *val) 113 { 114 unsigned int regval; 115 int ret; 116 117 ret = regmap_read(ina->regmap, reg, ®val); 118 if (ret) 119 return ret; 120 121 *val = sign_extend32(regval >> 3, 12); 122 123 return 0; 124 } 125 126 static const u8 ina3221_in_reg[] = { 127 INA3221_BUS1, 128 INA3221_BUS2, 129 INA3221_BUS3, 130 INA3221_SHUNT1, 131 INA3221_SHUNT2, 132 INA3221_SHUNT3, 133 }; 134 135 static int ina3221_read_in(struct device *dev, u32 attr, int channel, long *val) 136 { 137 const bool is_shunt = channel > INA3221_CHANNEL3; 138 struct ina3221_data *ina = dev_get_drvdata(dev); 139 u8 reg = ina3221_in_reg[channel]; 140 int regval, ret; 141 142 /* Translate shunt channel index to sensor channel index */ 143 channel %= INA3221_NUM_CHANNELS; 144 145 switch (attr) { 146 case hwmon_in_input: 147 if (!ina3221_is_enabled(ina, channel)) 148 return -ENODATA; 149 150 ret = ina3221_read_value(ina, reg, ®val); 151 if (ret) 152 return ret; 153 154 /* 155 * Scale of shunt voltage (uV): LSB is 40uV 156 * Scale of bus voltage (mV): LSB is 8mV 157 */ 158 *val = regval * (is_shunt ? 40 : 8); 159 return 0; 160 case hwmon_in_enable: 161 *val = ina3221_is_enabled(ina, channel); 162 return 0; 163 default: 164 return -EOPNOTSUPP; 165 } 166 } 167 168 static const u8 ina3221_curr_reg[][INA3221_NUM_CHANNELS] = { 169 [hwmon_curr_input] = { INA3221_SHUNT1, INA3221_SHUNT2, INA3221_SHUNT3 }, 170 [hwmon_curr_max] = { INA3221_WARN1, INA3221_WARN2, INA3221_WARN3 }, 171 [hwmon_curr_crit] = { INA3221_CRIT1, INA3221_CRIT2, INA3221_CRIT3 }, 172 [hwmon_curr_max_alarm] = { F_WF1, F_WF2, F_WF3 }, 173 [hwmon_curr_crit_alarm] = { F_CF1, F_CF2, F_CF3 }, 174 }; 175 176 static int ina3221_read_curr(struct device *dev, u32 attr, 177 int channel, long *val) 178 { 179 struct ina3221_data *ina = dev_get_drvdata(dev); 180 struct ina3221_input *input = &ina->inputs[channel]; 181 int resistance_uo = input->shunt_resistor; 182 u8 reg = ina3221_curr_reg[attr][channel]; 183 int regval, voltage_nv, ret; 184 185 switch (attr) { 186 case hwmon_curr_input: 187 if (!ina3221_is_enabled(ina, channel)) 188 return -ENODATA; 189 /* fall through */ 190 case hwmon_curr_crit: 191 case hwmon_curr_max: 192 ret = ina3221_read_value(ina, reg, ®val); 193 if (ret) 194 return ret; 195 196 /* Scale of shunt voltage: LSB is 40uV (40000nV) */ 197 voltage_nv = regval * 40000; 198 /* Return current in mA */ 199 *val = DIV_ROUND_CLOSEST(voltage_nv, resistance_uo); 200 return 0; 201 case hwmon_curr_crit_alarm: 202 case hwmon_curr_max_alarm: 203 ret = regmap_field_read(ina->fields[reg], ®val); 204 if (ret) 205 return ret; 206 *val = regval; 207 return 0; 208 default: 209 return -EOPNOTSUPP; 210 } 211 } 212 213 static int ina3221_write_curr(struct device *dev, u32 attr, 214 int channel, long val) 215 { 216 struct ina3221_data *ina = dev_get_drvdata(dev); 217 struct ina3221_input *input = &ina->inputs[channel]; 218 int resistance_uo = input->shunt_resistor; 219 u8 reg = ina3221_curr_reg[attr][channel]; 220 int regval, current_ma, voltage_uv; 221 222 /* clamp current */ 223 current_ma = clamp_val(val, 224 INT_MIN / resistance_uo, 225 INT_MAX / resistance_uo); 226 227 voltage_uv = DIV_ROUND_CLOSEST(current_ma * resistance_uo, 1000); 228 229 /* clamp voltage */ 230 voltage_uv = clamp_val(voltage_uv, -163800, 163800); 231 232 /* 1 / 40uV(scale) << 3(register shift) = 5 */ 233 regval = DIV_ROUND_CLOSEST(voltage_uv, 5) & 0xfff8; 234 235 return regmap_write(ina->regmap, reg, regval); 236 } 237 238 static int ina3221_write_enable(struct device *dev, int channel, bool enable) 239 { 240 struct ina3221_data *ina = dev_get_drvdata(dev); 241 u16 config, mask = INA3221_CONFIG_CHx_EN(channel); 242 int ret; 243 244 config = enable ? mask : 0; 245 246 /* Enable or disable the channel */ 247 ret = regmap_update_bits(ina->regmap, INA3221_CONFIG, mask, config); 248 if (ret) 249 return ret; 250 251 /* Cache the latest config register value */ 252 ret = regmap_read(ina->regmap, INA3221_CONFIG, &ina->reg_config); 253 if (ret) 254 return ret; 255 256 return 0; 257 } 258 259 static int ina3221_read(struct device *dev, enum hwmon_sensor_types type, 260 u32 attr, int channel, long *val) 261 { 262 switch (type) { 263 case hwmon_in: 264 /* 0-align channel ID */ 265 return ina3221_read_in(dev, attr, channel - 1, val); 266 case hwmon_curr: 267 return ina3221_read_curr(dev, attr, channel, val); 268 default: 269 return -EOPNOTSUPP; 270 } 271 } 272 273 static int ina3221_write(struct device *dev, enum hwmon_sensor_types type, 274 u32 attr, int channel, long val) 275 { 276 switch (type) { 277 case hwmon_in: 278 /* 0-align channel ID */ 279 return ina3221_write_enable(dev, channel - 1, val); 280 case hwmon_curr: 281 return ina3221_write_curr(dev, attr, channel, val); 282 default: 283 return -EOPNOTSUPP; 284 } 285 } 286 287 static int ina3221_read_string(struct device *dev, enum hwmon_sensor_types type, 288 u32 attr, int channel, const char **str) 289 { 290 struct ina3221_data *ina = dev_get_drvdata(dev); 291 int index = channel - 1; 292 293 *str = ina->inputs[index].label; 294 295 return 0; 296 } 297 298 static umode_t ina3221_is_visible(const void *drvdata, 299 enum hwmon_sensor_types type, 300 u32 attr, int channel) 301 { 302 const struct ina3221_data *ina = drvdata; 303 const struct ina3221_input *input = NULL; 304 305 switch (type) { 306 case hwmon_in: 307 /* Ignore in0_ */ 308 if (channel == 0) 309 return 0; 310 311 switch (attr) { 312 case hwmon_in_label: 313 if (channel - 1 <= INA3221_CHANNEL3) 314 input = &ina->inputs[channel - 1]; 315 /* Hide label node if label is not provided */ 316 return (input && input->label) ? 0444 : 0; 317 case hwmon_in_input: 318 return 0444; 319 case hwmon_in_enable: 320 return 0644; 321 default: 322 return 0; 323 } 324 case hwmon_curr: 325 switch (attr) { 326 case hwmon_curr_input: 327 case hwmon_curr_crit_alarm: 328 case hwmon_curr_max_alarm: 329 return 0444; 330 case hwmon_curr_crit: 331 case hwmon_curr_max: 332 return 0644; 333 default: 334 return 0; 335 } 336 default: 337 return 0; 338 } 339 } 340 341 static const u32 ina3221_in_config[] = { 342 /* 0: dummy, skipped in is_visible */ 343 HWMON_I_INPUT, 344 /* 1-3: input voltage Channels */ 345 HWMON_I_INPUT | HWMON_I_ENABLE | HWMON_I_LABEL, 346 HWMON_I_INPUT | HWMON_I_ENABLE | HWMON_I_LABEL, 347 HWMON_I_INPUT | HWMON_I_ENABLE | HWMON_I_LABEL, 348 /* 4-6: shunt voltage Channels */ 349 HWMON_I_INPUT, 350 HWMON_I_INPUT, 351 HWMON_I_INPUT, 352 0 353 }; 354 355 static const struct hwmon_channel_info ina3221_in = { 356 .type = hwmon_in, 357 .config = ina3221_in_config, 358 }; 359 360 #define INA3221_HWMON_CURR_CONFIG (HWMON_C_INPUT | \ 361 HWMON_C_CRIT | HWMON_C_CRIT_ALARM | \ 362 HWMON_C_MAX | HWMON_C_MAX_ALARM) 363 364 static const u32 ina3221_curr_config[] = { 365 INA3221_HWMON_CURR_CONFIG, 366 INA3221_HWMON_CURR_CONFIG, 367 INA3221_HWMON_CURR_CONFIG, 368 0 369 }; 370 371 static const struct hwmon_channel_info ina3221_curr = { 372 .type = hwmon_curr, 373 .config = ina3221_curr_config, 374 }; 375 376 static const struct hwmon_channel_info *ina3221_info[] = { 377 &ina3221_in, 378 &ina3221_curr, 379 NULL 380 }; 381 382 static const struct hwmon_ops ina3221_hwmon_ops = { 383 .is_visible = ina3221_is_visible, 384 .read_string = ina3221_read_string, 385 .read = ina3221_read, 386 .write = ina3221_write, 387 }; 388 389 static const struct hwmon_chip_info ina3221_chip_info = { 390 .ops = &ina3221_hwmon_ops, 391 .info = ina3221_info, 392 }; 393 394 /* Extra attribute groups */ 395 static ssize_t ina3221_show_shunt(struct device *dev, 396 struct device_attribute *attr, char *buf) 397 { 398 struct sensor_device_attribute *sd_attr = to_sensor_dev_attr(attr); 399 struct ina3221_data *ina = dev_get_drvdata(dev); 400 unsigned int channel = sd_attr->index; 401 struct ina3221_input *input = &ina->inputs[channel]; 402 403 return snprintf(buf, PAGE_SIZE, "%d\n", input->shunt_resistor); 404 } 405 406 static ssize_t ina3221_set_shunt(struct device *dev, 407 struct device_attribute *attr, 408 const char *buf, size_t count) 409 { 410 struct sensor_device_attribute *sd_attr = to_sensor_dev_attr(attr); 411 struct ina3221_data *ina = dev_get_drvdata(dev); 412 unsigned int channel = sd_attr->index; 413 struct ina3221_input *input = &ina->inputs[channel]; 414 int val; 415 int ret; 416 417 ret = kstrtoint(buf, 0, &val); 418 if (ret) 419 return ret; 420 421 val = clamp_val(val, 1, INT_MAX); 422 423 input->shunt_resistor = val; 424 425 return count; 426 } 427 428 /* shunt resistance */ 429 static SENSOR_DEVICE_ATTR(shunt1_resistor, S_IRUGO | S_IWUSR, 430 ina3221_show_shunt, ina3221_set_shunt, INA3221_CHANNEL1); 431 static SENSOR_DEVICE_ATTR(shunt2_resistor, S_IRUGO | S_IWUSR, 432 ina3221_show_shunt, ina3221_set_shunt, INA3221_CHANNEL2); 433 static SENSOR_DEVICE_ATTR(shunt3_resistor, S_IRUGO | S_IWUSR, 434 ina3221_show_shunt, ina3221_set_shunt, INA3221_CHANNEL3); 435 436 static struct attribute *ina3221_attrs[] = { 437 &sensor_dev_attr_shunt1_resistor.dev_attr.attr, 438 &sensor_dev_attr_shunt2_resistor.dev_attr.attr, 439 &sensor_dev_attr_shunt3_resistor.dev_attr.attr, 440 NULL, 441 }; 442 ATTRIBUTE_GROUPS(ina3221); 443 444 static const struct regmap_range ina3221_yes_ranges[] = { 445 regmap_reg_range(INA3221_CONFIG, INA3221_BUS3), 446 regmap_reg_range(INA3221_MASK_ENABLE, INA3221_MASK_ENABLE), 447 }; 448 449 static const struct regmap_access_table ina3221_volatile_table = { 450 .yes_ranges = ina3221_yes_ranges, 451 .n_yes_ranges = ARRAY_SIZE(ina3221_yes_ranges), 452 }; 453 454 static const struct regmap_config ina3221_regmap_config = { 455 .reg_bits = 8, 456 .val_bits = 16, 457 458 .cache_type = REGCACHE_RBTREE, 459 .volatile_table = &ina3221_volatile_table, 460 }; 461 462 static int ina3221_probe_child_from_dt(struct device *dev, 463 struct device_node *child, 464 struct ina3221_data *ina) 465 { 466 struct ina3221_input *input; 467 u32 val; 468 int ret; 469 470 ret = of_property_read_u32(child, "reg", &val); 471 if (ret) { 472 dev_err(dev, "missing reg property of %s\n", child->name); 473 return ret; 474 } else if (val > INA3221_CHANNEL3) { 475 dev_err(dev, "invalid reg %d of %s\n", val, child->name); 476 return ret; 477 } 478 479 input = &ina->inputs[val]; 480 481 /* Log the disconnected channel input */ 482 if (!of_device_is_available(child)) { 483 input->disconnected = true; 484 return 0; 485 } 486 487 /* Save the connected input label if available */ 488 of_property_read_string(child, "label", &input->label); 489 490 /* Overwrite default shunt resistor value optionally */ 491 if (!of_property_read_u32(child, "shunt-resistor-micro-ohms", &val)) { 492 if (val < 1 || val > INT_MAX) { 493 dev_err(dev, "invalid shunt resistor value %u of %s\n", 494 val, child->name); 495 return -EINVAL; 496 } 497 input->shunt_resistor = val; 498 } 499 500 return 0; 501 } 502 503 static int ina3221_probe_from_dt(struct device *dev, struct ina3221_data *ina) 504 { 505 const struct device_node *np = dev->of_node; 506 struct device_node *child; 507 int ret; 508 509 /* Compatible with non-DT platforms */ 510 if (!np) 511 return 0; 512 513 for_each_child_of_node(np, child) { 514 ret = ina3221_probe_child_from_dt(dev, child, ina); 515 if (ret) 516 return ret; 517 } 518 519 return 0; 520 } 521 522 static int ina3221_probe(struct i2c_client *client, 523 const struct i2c_device_id *id) 524 { 525 struct device *dev = &client->dev; 526 struct ina3221_data *ina; 527 struct device *hwmon_dev; 528 int i, ret; 529 530 ina = devm_kzalloc(dev, sizeof(*ina), GFP_KERNEL); 531 if (!ina) 532 return -ENOMEM; 533 534 ina->regmap = devm_regmap_init_i2c(client, &ina3221_regmap_config); 535 if (IS_ERR(ina->regmap)) { 536 dev_err(dev, "Unable to allocate register map\n"); 537 return PTR_ERR(ina->regmap); 538 } 539 540 for (i = 0; i < F_MAX_FIELDS; i++) { 541 ina->fields[i] = devm_regmap_field_alloc(dev, 542 ina->regmap, 543 ina3221_reg_fields[i]); 544 if (IS_ERR(ina->fields[i])) { 545 dev_err(dev, "Unable to allocate regmap fields\n"); 546 return PTR_ERR(ina->fields[i]); 547 } 548 } 549 550 for (i = 0; i < INA3221_NUM_CHANNELS; i++) 551 ina->inputs[i].shunt_resistor = INA3221_RSHUNT_DEFAULT; 552 553 ret = ina3221_probe_from_dt(dev, ina); 554 if (ret) { 555 dev_err(dev, "Unable to probe from device tree\n"); 556 return ret; 557 } 558 559 ret = regmap_field_write(ina->fields[F_RST], true); 560 if (ret) { 561 dev_err(dev, "Unable to reset device\n"); 562 return ret; 563 } 564 565 /* Sync config register after reset */ 566 ret = regmap_read(ina->regmap, INA3221_CONFIG, &ina->reg_config); 567 if (ret) 568 return ret; 569 570 /* Disable channels if their inputs are disconnected */ 571 for (i = 0; i < INA3221_NUM_CHANNELS; i++) { 572 if (ina->inputs[i].disconnected) 573 ina->reg_config &= ~INA3221_CONFIG_CHx_EN(i); 574 } 575 ret = regmap_write(ina->regmap, INA3221_CONFIG, ina->reg_config); 576 if (ret) 577 return ret; 578 579 dev_set_drvdata(dev, ina); 580 581 hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, ina, 582 &ina3221_chip_info, 583 ina3221_groups); 584 if (IS_ERR(hwmon_dev)) { 585 dev_err(dev, "Unable to register hwmon device\n"); 586 return PTR_ERR(hwmon_dev); 587 } 588 589 return 0; 590 } 591 592 static int __maybe_unused ina3221_suspend(struct device *dev) 593 { 594 struct ina3221_data *ina = dev_get_drvdata(dev); 595 int ret; 596 597 /* Save config register value and enable cache-only */ 598 ret = regmap_read(ina->regmap, INA3221_CONFIG, &ina->reg_config); 599 if (ret) 600 return ret; 601 602 /* Set to power-down mode for power saving */ 603 ret = regmap_update_bits(ina->regmap, INA3221_CONFIG, 604 INA3221_CONFIG_MODE_MASK, 605 INA3221_CONFIG_MODE_POWERDOWN); 606 if (ret) 607 return ret; 608 609 regcache_cache_only(ina->regmap, true); 610 regcache_mark_dirty(ina->regmap); 611 612 return 0; 613 } 614 615 static int __maybe_unused ina3221_resume(struct device *dev) 616 { 617 struct ina3221_data *ina = dev_get_drvdata(dev); 618 int ret; 619 620 regcache_cache_only(ina->regmap, false); 621 622 /* Software reset the chip */ 623 ret = regmap_field_write(ina->fields[F_RST], true); 624 if (ret) { 625 dev_err(dev, "Unable to reset device\n"); 626 return ret; 627 } 628 629 /* Restore cached register values to hardware */ 630 ret = regcache_sync(ina->regmap); 631 if (ret) 632 return ret; 633 634 /* Restore config register value to hardware */ 635 ret = regmap_write(ina->regmap, INA3221_CONFIG, ina->reg_config); 636 if (ret) 637 return ret; 638 639 return 0; 640 } 641 642 static const struct dev_pm_ops ina3221_pm = { 643 SET_SYSTEM_SLEEP_PM_OPS(ina3221_suspend, ina3221_resume) 644 }; 645 646 static const struct of_device_id ina3221_of_match_table[] = { 647 { .compatible = "ti,ina3221", }, 648 { /* sentinel */ } 649 }; 650 MODULE_DEVICE_TABLE(of, ina3221_of_match_table); 651 652 static const struct i2c_device_id ina3221_ids[] = { 653 { "ina3221", 0 }, 654 { /* sentinel */ } 655 }; 656 MODULE_DEVICE_TABLE(i2c, ina3221_ids); 657 658 static struct i2c_driver ina3221_i2c_driver = { 659 .probe = ina3221_probe, 660 .driver = { 661 .name = INA3221_DRIVER_NAME, 662 .of_match_table = ina3221_of_match_table, 663 .pm = &ina3221_pm, 664 }, 665 .id_table = ina3221_ids, 666 }; 667 module_i2c_driver(ina3221_i2c_driver); 668 669 MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>"); 670 MODULE_DESCRIPTION("Texas Instruments INA3221 HWMon Driver"); 671 MODULE_LICENSE("GPL v2"); 672