1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Driver for Texas Instruments INA238 power monitor chip 4 * Datasheet: https://www.ti.com/product/ina238 5 * 6 * Copyright (C) 2021 Nathan Rossi <nathan.rossi@digi.com> 7 */ 8 9 #include <linux/err.h> 10 #include <linux/hwmon.h> 11 #include <linux/i2c.h> 12 #include <linux/init.h> 13 #include <linux/kernel.h> 14 #include <linux/module.h> 15 #include <linux/of.h> 16 #include <linux/regmap.h> 17 18 #include <linux/platform_data/ina2xx.h> 19 20 /* INA238 register definitions */ 21 #define INA238_CONFIG 0x0 22 #define INA238_ADC_CONFIG 0x1 23 #define INA238_SHUNT_CALIBRATION 0x2 24 #define SQ52206_SHUNT_TEMPCO 0x3 25 #define INA238_SHUNT_VOLTAGE 0x4 26 #define INA238_BUS_VOLTAGE 0x5 27 #define INA238_DIE_TEMP 0x6 28 #define INA238_CURRENT 0x7 29 #define INA238_POWER 0x8 30 #define SQ52206_ENERGY 0x9 31 #define SQ52206_CHARGE 0xa 32 #define INA238_DIAG_ALERT 0xb 33 #define INA238_SHUNT_OVER_VOLTAGE 0xc 34 #define INA238_SHUNT_UNDER_VOLTAGE 0xd 35 #define INA238_BUS_OVER_VOLTAGE 0xe 36 #define INA238_BUS_UNDER_VOLTAGE 0xf 37 #define INA238_TEMP_LIMIT 0x10 38 #define INA238_POWER_LIMIT 0x11 39 #define SQ52206_POWER_PEAK 0x20 40 #define INA238_DEVICE_ID 0x3f /* not available on INA237 */ 41 42 #define INA238_CONFIG_ADCRANGE BIT(4) 43 #define SQ52206_CONFIG_ADCRANGE_HIGH BIT(4) 44 #define SQ52206_CONFIG_ADCRANGE_LOW BIT(3) 45 46 #define INA238_DIAG_ALERT_TMPOL BIT(7) 47 #define INA238_DIAG_ALERT_SHNTOL BIT(6) 48 #define INA238_DIAG_ALERT_SHNTUL BIT(5) 49 #define INA238_DIAG_ALERT_BUSOL BIT(4) 50 #define INA238_DIAG_ALERT_BUSUL BIT(3) 51 #define INA238_DIAG_ALERT_POL BIT(2) 52 53 #define INA238_REGISTERS 0x20 54 55 #define INA238_RSHUNT_DEFAULT 10000 /* uOhm */ 56 57 /* Default configuration of device on reset. */ 58 #define INA238_CONFIG_DEFAULT 0 59 #define SQ52206_CONFIG_DEFAULT 0x0005 60 /* 16 sample averaging, 1052us conversion time, continuous mode */ 61 #define INA238_ADC_CONFIG_DEFAULT 0xfb6a 62 /* Configure alerts to be based on averaged value (SLOWALERT) */ 63 #define INA238_DIAG_ALERT_DEFAULT 0x2000 64 /* 65 * This driver uses a fixed calibration value in order to scale current/power 66 * based on a fixed shunt resistor value. This allows for conversion within the 67 * device to avoid integer limits whilst current/power accuracy is scaled 68 * relative to the shunt resistor value within the driver. This is similar to 69 * how the ina2xx driver handles current/power scaling. 70 * 71 * The end result of this is that increasing shunt values (from a fixed 20 mOhm 72 * shunt) increase the effective current/power accuracy whilst limiting the 73 * range and decreasing shunt values decrease the effective accuracy but 74 * increase the range. 75 * 76 * The value of the Current register is calculated given the following: 77 * Current (A) = (shunt voltage register * 5) * calibration / 81920 78 * 79 * The maximum shunt voltage is 163.835 mV (0x7fff, ADC_RANGE = 0, gain = 4). 80 * With the maximum current value of 0x7fff and a fixed shunt value results in 81 * a calibration value of 16384 (0x4000). 82 * 83 * 0x7fff = (0x7fff * 5) * calibration / 81920 84 * calibration = 0x4000 85 * 86 * Equivalent calibration is applied for the Power register (maximum value for 87 * bus voltage is 102396.875 mV, 0x7fff), where the maximum power that can 88 * occur is ~16776192 uW (register value 0x147a8): 89 * 90 * This scaling means the resulting values for Current and Power registers need 91 * to be scaled by the difference between the fixed shunt resistor and the 92 * actual shunt resistor: 93 * 94 * shunt = 0x4000 / (819.2 * 10^6) / 0.001 = 20000 uOhms (with 1mA/lsb) 95 * 96 * Current (mA) = register value * 20000 / rshunt / 4 * gain 97 * Power (mW) = 0.2 * register value * 20000 / rshunt / 4 * gain 98 * (Specific for SQ52206) 99 * Power (mW) = 0.24 * register value * 20000 / rshunt / 4 * gain 100 * Energy (mJ) = 16 * 0.24 * register value * 20000 / rshunt / 4 * gain 101 */ 102 #define INA238_CALIBRATION_VALUE 16384 103 #define INA238_FIXED_SHUNT 20000 104 105 #define INA238_SHUNT_VOLTAGE_LSB 5 /* 5 uV/lsb */ 106 #define INA238_BUS_VOLTAGE_LSB 3125 /* 3.125 mV/lsb */ 107 #define INA238_DIE_TEMP_LSB 1250000 /* 125.0000 mC/lsb */ 108 #define SQ52206_BUS_VOLTAGE_LSB 3750 /* 3.75 mV/lsb */ 109 #define SQ52206_DIE_TEMP_LSB 78125 /* 7.8125 mC/lsb */ 110 111 static const struct regmap_config ina238_regmap_config = { 112 .max_register = INA238_REGISTERS, 113 .reg_bits = 8, 114 .val_bits = 16, 115 }; 116 117 enum ina238_ids { ina238, ina237, sq52206 }; 118 119 struct ina238_config { 120 bool has_power_highest; /* chip detection power peak */ 121 bool has_energy; /* chip detection energy */ 122 u8 temp_shift; /* fixed parameters for temp calculate */ 123 u32 power_calculate_factor; /* fixed parameters for power calculate */ 124 u16 config_default; /* Power-on default state */ 125 int bus_voltage_lsb; /* use for temperature calculate, uV/lsb */ 126 int temp_lsb; /* use for temperature calculate */ 127 }; 128 129 struct ina238_data { 130 const struct ina238_config *config; 131 struct i2c_client *client; 132 struct mutex config_lock; 133 struct regmap *regmap; 134 u32 rshunt; 135 int gain; 136 }; 137 138 static const struct ina238_config ina238_config[] = { 139 [ina238] = { 140 .has_energy = false, 141 .has_power_highest = false, 142 .temp_shift = 4, 143 .power_calculate_factor = 20, 144 .config_default = INA238_CONFIG_DEFAULT, 145 .bus_voltage_lsb = INA238_BUS_VOLTAGE_LSB, 146 .temp_lsb = INA238_DIE_TEMP_LSB, 147 }, 148 [ina237] = { 149 .has_energy = false, 150 .has_power_highest = false, 151 .temp_shift = 4, 152 .power_calculate_factor = 20, 153 .config_default = INA238_CONFIG_DEFAULT, 154 .bus_voltage_lsb = INA238_BUS_VOLTAGE_LSB, 155 .temp_lsb = INA238_DIE_TEMP_LSB, 156 }, 157 [sq52206] = { 158 .has_energy = true, 159 .has_power_highest = true, 160 .temp_shift = 0, 161 .power_calculate_factor = 24, 162 .config_default = SQ52206_CONFIG_DEFAULT, 163 .bus_voltage_lsb = SQ52206_BUS_VOLTAGE_LSB, 164 .temp_lsb = SQ52206_DIE_TEMP_LSB, 165 }, 166 }; 167 168 static int ina238_read_reg24(const struct i2c_client *client, u8 reg, u32 *val) 169 { 170 u8 data[3]; 171 int err; 172 173 /* 24-bit register read */ 174 err = i2c_smbus_read_i2c_block_data(client, reg, 3, data); 175 if (err < 0) 176 return err; 177 if (err != 3) 178 return -EIO; 179 *val = (data[0] << 16) | (data[1] << 8) | data[2]; 180 181 return 0; 182 } 183 184 static int ina238_read_reg40(const struct i2c_client *client, u8 reg, u64 *val) 185 { 186 u8 data[5]; 187 u32 low; 188 int err; 189 190 /* 40-bit register read */ 191 err = i2c_smbus_read_i2c_block_data(client, reg, 5, data); 192 if (err < 0) 193 return err; 194 if (err != 5) 195 return -EIO; 196 low = (data[1] << 24) | (data[2] << 16) | (data[3] << 8) | data[4]; 197 *val = ((long long)data[0] << 32) | low; 198 199 return 0; 200 } 201 202 static int ina238_read_in(struct device *dev, u32 attr, int channel, 203 long *val) 204 { 205 struct ina238_data *data = dev_get_drvdata(dev); 206 int reg, mask; 207 int regval; 208 int err; 209 210 switch (channel) { 211 case 0: 212 switch (attr) { 213 case hwmon_in_input: 214 reg = INA238_SHUNT_VOLTAGE; 215 break; 216 case hwmon_in_max: 217 reg = INA238_SHUNT_OVER_VOLTAGE; 218 break; 219 case hwmon_in_min: 220 reg = INA238_SHUNT_UNDER_VOLTAGE; 221 break; 222 case hwmon_in_max_alarm: 223 reg = INA238_DIAG_ALERT; 224 mask = INA238_DIAG_ALERT_SHNTOL; 225 break; 226 case hwmon_in_min_alarm: 227 reg = INA238_DIAG_ALERT; 228 mask = INA238_DIAG_ALERT_SHNTUL; 229 break; 230 default: 231 return -EOPNOTSUPP; 232 } 233 break; 234 case 1: 235 switch (attr) { 236 case hwmon_in_input: 237 reg = INA238_BUS_VOLTAGE; 238 break; 239 case hwmon_in_max: 240 reg = INA238_BUS_OVER_VOLTAGE; 241 break; 242 case hwmon_in_min: 243 reg = INA238_BUS_UNDER_VOLTAGE; 244 break; 245 case hwmon_in_max_alarm: 246 reg = INA238_DIAG_ALERT; 247 mask = INA238_DIAG_ALERT_BUSOL; 248 break; 249 case hwmon_in_min_alarm: 250 reg = INA238_DIAG_ALERT; 251 mask = INA238_DIAG_ALERT_BUSUL; 252 break; 253 default: 254 return -EOPNOTSUPP; 255 } 256 break; 257 default: 258 return -EOPNOTSUPP; 259 } 260 261 err = regmap_read(data->regmap, reg, ®val); 262 if (err < 0) 263 return err; 264 265 switch (attr) { 266 case hwmon_in_input: 267 case hwmon_in_max: 268 case hwmon_in_min: 269 /* signed register, value in mV */ 270 regval = (s16)regval; 271 if (channel == 0) 272 /* gain of 1 -> LSB / 4 */ 273 *val = (regval * INA238_SHUNT_VOLTAGE_LSB) * 274 data->gain / (1000 * 4); 275 else 276 *val = (regval * data->config->bus_voltage_lsb) / 1000; 277 break; 278 case hwmon_in_max_alarm: 279 case hwmon_in_min_alarm: 280 *val = !!(regval & mask); 281 break; 282 } 283 284 return 0; 285 } 286 287 static int ina238_write_in(struct device *dev, u32 attr, int channel, 288 long val) 289 { 290 struct ina238_data *data = dev_get_drvdata(dev); 291 int regval; 292 293 if (attr != hwmon_in_max && attr != hwmon_in_min) 294 return -EOPNOTSUPP; 295 296 /* convert decimal to register value */ 297 switch (channel) { 298 case 0: 299 /* signed value, clamp to max range +/-163 mV */ 300 regval = clamp_val(val, -163, 163); 301 regval = (regval * 1000 * 4) / 302 (INA238_SHUNT_VOLTAGE_LSB * data->gain); 303 regval = clamp_val(regval, S16_MIN, S16_MAX); 304 305 switch (attr) { 306 case hwmon_in_max: 307 return regmap_write(data->regmap, 308 INA238_SHUNT_OVER_VOLTAGE, regval); 309 case hwmon_in_min: 310 return regmap_write(data->regmap, 311 INA238_SHUNT_UNDER_VOLTAGE, regval); 312 default: 313 return -EOPNOTSUPP; 314 } 315 case 1: 316 /* signed value, positive values only. Clamp to max 102.396 V */ 317 regval = clamp_val(val, 0, 102396); 318 regval = (regval * 1000) / data->config->bus_voltage_lsb; 319 regval = clamp_val(regval, 0, S16_MAX); 320 321 switch (attr) { 322 case hwmon_in_max: 323 return regmap_write(data->regmap, 324 INA238_BUS_OVER_VOLTAGE, regval); 325 case hwmon_in_min: 326 return regmap_write(data->regmap, 327 INA238_BUS_UNDER_VOLTAGE, regval); 328 default: 329 return -EOPNOTSUPP; 330 } 331 default: 332 return -EOPNOTSUPP; 333 } 334 } 335 336 static int ina238_read_current(struct device *dev, u32 attr, long *val) 337 { 338 struct ina238_data *data = dev_get_drvdata(dev); 339 int regval; 340 int err; 341 342 switch (attr) { 343 case hwmon_curr_input: 344 err = regmap_read(data->regmap, INA238_CURRENT, ®val); 345 if (err < 0) 346 return err; 347 348 /* Signed register, fixed 1mA current lsb. result in mA */ 349 *val = div_s64((s16)regval * INA238_FIXED_SHUNT * data->gain, 350 data->rshunt * 4); 351 break; 352 default: 353 return -EOPNOTSUPP; 354 } 355 356 return 0; 357 } 358 359 static int ina238_read_power(struct device *dev, u32 attr, long *val) 360 { 361 struct ina238_data *data = dev_get_drvdata(dev); 362 long long power; 363 int regval; 364 int err; 365 366 switch (attr) { 367 case hwmon_power_input: 368 err = ina238_read_reg24(data->client, INA238_POWER, ®val); 369 if (err) 370 return err; 371 372 /* Fixed 1mA lsb, scaled by 1000000 to have result in uW */ 373 power = div_u64(regval * 1000ULL * INA238_FIXED_SHUNT * data->gain * 374 data->config->power_calculate_factor, 4 * 100 * data->rshunt); 375 /* Clamp value to maximum value of long */ 376 *val = clamp_val(power, 0, LONG_MAX); 377 break; 378 case hwmon_power_input_highest: 379 err = ina238_read_reg24(data->client, SQ52206_POWER_PEAK, ®val); 380 if (err) 381 return err; 382 383 /* Fixed 1mA lsb, scaled by 1000000 to have result in uW */ 384 power = div_u64(regval * 1000ULL * INA238_FIXED_SHUNT * data->gain * 385 data->config->power_calculate_factor, 4 * 100 * data->rshunt); 386 /* Clamp value to maximum value of long */ 387 *val = clamp_val(power, 0, LONG_MAX); 388 break; 389 case hwmon_power_max: 390 err = regmap_read(data->regmap, INA238_POWER_LIMIT, ®val); 391 if (err) 392 return err; 393 394 /* 395 * Truncated 24-bit compare register, lower 8-bits are 396 * truncated. Same conversion to/from uW as POWER register. 397 */ 398 power = div_u64((regval << 8) * 1000ULL * INA238_FIXED_SHUNT * data->gain * 399 data->config->power_calculate_factor, 4 * 100 * data->rshunt); 400 /* Clamp value to maximum value of long */ 401 *val = clamp_val(power, 0, LONG_MAX); 402 break; 403 case hwmon_power_max_alarm: 404 err = regmap_read(data->regmap, INA238_DIAG_ALERT, ®val); 405 if (err) 406 return err; 407 408 *val = !!(regval & INA238_DIAG_ALERT_POL); 409 break; 410 default: 411 return -EOPNOTSUPP; 412 } 413 414 return 0; 415 } 416 417 static int ina238_write_power(struct device *dev, u32 attr, long val) 418 { 419 struct ina238_data *data = dev_get_drvdata(dev); 420 long regval; 421 422 if (attr != hwmon_power_max) 423 return -EOPNOTSUPP; 424 425 /* 426 * Unsigned postive values. Compared against the 24-bit power register, 427 * lower 8-bits are truncated. Same conversion to/from uW as POWER 428 * register. 429 */ 430 regval = clamp_val(val, 0, LONG_MAX); 431 regval = div_u64(val * 4 * 100 * data->rshunt, data->config->power_calculate_factor * 432 1000ULL * INA238_FIXED_SHUNT * data->gain); 433 regval = clamp_val(regval >> 8, 0, U16_MAX); 434 435 return regmap_write(data->regmap, INA238_POWER_LIMIT, regval); 436 } 437 438 static int ina238_read_temp(struct device *dev, u32 attr, long *val) 439 { 440 struct ina238_data *data = dev_get_drvdata(dev); 441 int regval; 442 int err; 443 444 switch (attr) { 445 case hwmon_temp_input: 446 err = regmap_read(data->regmap, INA238_DIE_TEMP, ®val); 447 if (err) 448 return err; 449 /* Signed, result in mC */ 450 *val = div_s64(((s64)((s16)regval) >> data->config->temp_shift) * 451 (s64)data->config->temp_lsb, 10000); 452 break; 453 case hwmon_temp_max: 454 err = regmap_read(data->regmap, INA238_TEMP_LIMIT, ®val); 455 if (err) 456 return err; 457 /* Signed, result in mC */ 458 *val = div_s64(((s64)((s16)regval) >> data->config->temp_shift) * 459 (s64)data->config->temp_lsb, 10000); 460 break; 461 case hwmon_temp_max_alarm: 462 err = regmap_read(data->regmap, INA238_DIAG_ALERT, ®val); 463 if (err) 464 return err; 465 466 *val = !!(regval & INA238_DIAG_ALERT_TMPOL); 467 break; 468 default: 469 return -EOPNOTSUPP; 470 } 471 472 return 0; 473 } 474 475 static int ina238_write_temp(struct device *dev, u32 attr, long val) 476 { 477 struct ina238_data *data = dev_get_drvdata(dev); 478 int regval; 479 480 if (attr != hwmon_temp_max) 481 return -EOPNOTSUPP; 482 483 /* Signed */ 484 regval = clamp_val(val, -40000, 125000); 485 regval = div_s64(val * 10000, data->config->temp_lsb) << data->config->temp_shift; 486 regval = clamp_val(regval, S16_MIN, S16_MAX) & (0xffff << data->config->temp_shift); 487 488 return regmap_write(data->regmap, INA238_TEMP_LIMIT, regval); 489 } 490 491 static ssize_t energy1_input_show(struct device *dev, 492 struct device_attribute *da, char *buf) 493 { 494 struct ina238_data *data = dev_get_drvdata(dev); 495 int ret; 496 u64 regval; 497 u64 energy; 498 499 ret = ina238_read_reg40(data->client, SQ52206_ENERGY, ®val); 500 if (ret) 501 return ret; 502 503 /* result in mJ */ 504 energy = div_u64(regval * INA238_FIXED_SHUNT * data->gain * 16 * 505 data->config->power_calculate_factor, 4 * 100 * data->rshunt); 506 507 return sysfs_emit(buf, "%llu\n", energy); 508 } 509 510 static int ina238_read(struct device *dev, enum hwmon_sensor_types type, 511 u32 attr, int channel, long *val) 512 { 513 switch (type) { 514 case hwmon_in: 515 return ina238_read_in(dev, attr, channel, val); 516 case hwmon_curr: 517 return ina238_read_current(dev, attr, val); 518 case hwmon_power: 519 return ina238_read_power(dev, attr, val); 520 case hwmon_temp: 521 return ina238_read_temp(dev, attr, val); 522 default: 523 return -EOPNOTSUPP; 524 } 525 return 0; 526 } 527 528 static int ina238_write(struct device *dev, enum hwmon_sensor_types type, 529 u32 attr, int channel, long val) 530 { 531 struct ina238_data *data = dev_get_drvdata(dev); 532 int err; 533 534 mutex_lock(&data->config_lock); 535 536 switch (type) { 537 case hwmon_in: 538 err = ina238_write_in(dev, attr, channel, val); 539 break; 540 case hwmon_power: 541 err = ina238_write_power(dev, attr, val); 542 break; 543 case hwmon_temp: 544 err = ina238_write_temp(dev, attr, val); 545 break; 546 default: 547 err = -EOPNOTSUPP; 548 break; 549 } 550 551 mutex_unlock(&data->config_lock); 552 return err; 553 } 554 555 static umode_t ina238_is_visible(const void *drvdata, 556 enum hwmon_sensor_types type, 557 u32 attr, int channel) 558 { 559 const struct ina238_data *data = drvdata; 560 bool has_power_highest = data->config->has_power_highest; 561 562 switch (type) { 563 case hwmon_in: 564 switch (attr) { 565 case hwmon_in_input: 566 case hwmon_in_max_alarm: 567 case hwmon_in_min_alarm: 568 return 0444; 569 case hwmon_in_max: 570 case hwmon_in_min: 571 return 0644; 572 default: 573 return 0; 574 } 575 case hwmon_curr: 576 switch (attr) { 577 case hwmon_curr_input: 578 return 0444; 579 default: 580 return 0; 581 } 582 case hwmon_power: 583 switch (attr) { 584 case hwmon_power_input: 585 case hwmon_power_max_alarm: 586 return 0444; 587 case hwmon_power_max: 588 return 0644; 589 case hwmon_power_input_highest: 590 if (has_power_highest) 591 return 0444; 592 return 0; 593 default: 594 return 0; 595 } 596 case hwmon_temp: 597 switch (attr) { 598 case hwmon_temp_input: 599 case hwmon_temp_max_alarm: 600 return 0444; 601 case hwmon_temp_max: 602 return 0644; 603 default: 604 return 0; 605 } 606 default: 607 return 0; 608 } 609 } 610 611 #define INA238_HWMON_IN_CONFIG (HWMON_I_INPUT | \ 612 HWMON_I_MAX | HWMON_I_MAX_ALARM | \ 613 HWMON_I_MIN | HWMON_I_MIN_ALARM) 614 615 static const struct hwmon_channel_info * const ina238_info[] = { 616 HWMON_CHANNEL_INFO(in, 617 /* 0: shunt voltage */ 618 INA238_HWMON_IN_CONFIG, 619 /* 1: bus voltage */ 620 INA238_HWMON_IN_CONFIG), 621 HWMON_CHANNEL_INFO(curr, 622 /* 0: current through shunt */ 623 HWMON_C_INPUT), 624 HWMON_CHANNEL_INFO(power, 625 /* 0: power */ 626 HWMON_P_INPUT | HWMON_P_MAX | 627 HWMON_P_MAX_ALARM | HWMON_P_INPUT_HIGHEST), 628 HWMON_CHANNEL_INFO(temp, 629 /* 0: die temperature */ 630 HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_ALARM), 631 NULL 632 }; 633 634 static const struct hwmon_ops ina238_hwmon_ops = { 635 .is_visible = ina238_is_visible, 636 .read = ina238_read, 637 .write = ina238_write, 638 }; 639 640 static const struct hwmon_chip_info ina238_chip_info = { 641 .ops = &ina238_hwmon_ops, 642 .info = ina238_info, 643 }; 644 645 /* energy attributes are 5 bytes wide so we need u64 */ 646 static DEVICE_ATTR_RO(energy1_input); 647 648 static struct attribute *ina238_attrs[] = { 649 &dev_attr_energy1_input.attr, 650 NULL, 651 }; 652 ATTRIBUTE_GROUPS(ina238); 653 654 static int ina238_probe(struct i2c_client *client) 655 { 656 struct ina2xx_platform_data *pdata = dev_get_platdata(&client->dev); 657 struct device *dev = &client->dev; 658 struct device *hwmon_dev; 659 struct ina238_data *data; 660 enum ina238_ids chip; 661 int config; 662 int ret; 663 664 chip = (uintptr_t)i2c_get_match_data(client); 665 666 data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); 667 if (!data) 668 return -ENOMEM; 669 670 data->client = client; 671 /* set the device type */ 672 data->config = &ina238_config[chip]; 673 674 mutex_init(&data->config_lock); 675 676 data->regmap = devm_regmap_init_i2c(client, &ina238_regmap_config); 677 if (IS_ERR(data->regmap)) { 678 dev_err(dev, "failed to allocate register map\n"); 679 return PTR_ERR(data->regmap); 680 } 681 682 /* load shunt value */ 683 data->rshunt = INA238_RSHUNT_DEFAULT; 684 if (device_property_read_u32(dev, "shunt-resistor", &data->rshunt) < 0 && pdata) 685 data->rshunt = pdata->shunt_uohms; 686 if (data->rshunt == 0) { 687 dev_err(dev, "invalid shunt resister value %u\n", data->rshunt); 688 return -EINVAL; 689 } 690 691 /* load shunt gain value */ 692 if (device_property_read_u32(dev, "ti,shunt-gain", &data->gain) < 0) 693 data->gain = 4; /* Default of ADCRANGE = 0 */ 694 if (data->gain != 1 && data->gain != 2 && data->gain != 4) { 695 dev_err(dev, "invalid shunt gain value %u\n", data->gain); 696 return -EINVAL; 697 } 698 699 /* Setup CONFIG register */ 700 config = data->config->config_default; 701 if (chip == sq52206) { 702 if (data->gain == 1) 703 config |= SQ52206_CONFIG_ADCRANGE_HIGH; /* ADCRANGE = 10/11 is /1 */ 704 else if (data->gain == 2) 705 config |= SQ52206_CONFIG_ADCRANGE_LOW; /* ADCRANGE = 01 is /2 */ 706 } else if (data->gain == 1) { 707 config |= INA238_CONFIG_ADCRANGE; /* ADCRANGE = 1 is /1 */ 708 } 709 ret = regmap_write(data->regmap, INA238_CONFIG, config); 710 if (ret < 0) { 711 dev_err(dev, "error configuring the device: %d\n", ret); 712 return -ENODEV; 713 } 714 715 /* Setup ADC_CONFIG register */ 716 ret = regmap_write(data->regmap, INA238_ADC_CONFIG, 717 INA238_ADC_CONFIG_DEFAULT); 718 if (ret < 0) { 719 dev_err(dev, "error configuring the device: %d\n", ret); 720 return -ENODEV; 721 } 722 723 /* Setup SHUNT_CALIBRATION register with fixed value */ 724 ret = regmap_write(data->regmap, INA238_SHUNT_CALIBRATION, 725 INA238_CALIBRATION_VALUE); 726 if (ret < 0) { 727 dev_err(dev, "error configuring the device: %d\n", ret); 728 return -ENODEV; 729 } 730 731 /* Setup alert/alarm configuration */ 732 ret = regmap_write(data->regmap, INA238_DIAG_ALERT, 733 INA238_DIAG_ALERT_DEFAULT); 734 if (ret < 0) { 735 dev_err(dev, "error configuring the device: %d\n", ret); 736 return -ENODEV; 737 } 738 739 hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, data, 740 &ina238_chip_info, 741 data->config->has_energy ? 742 ina238_groups : NULL); 743 if (IS_ERR(hwmon_dev)) 744 return PTR_ERR(hwmon_dev); 745 746 dev_info(dev, "power monitor %s (Rshunt = %u uOhm, gain = %u)\n", 747 client->name, data->rshunt, data->gain); 748 749 return 0; 750 } 751 752 static const struct i2c_device_id ina238_id[] = { 753 { "ina237", ina237 }, 754 { "ina238", ina238 }, 755 { "sq52206", sq52206 }, 756 { } 757 }; 758 MODULE_DEVICE_TABLE(i2c, ina238_id); 759 760 static const struct of_device_id __maybe_unused ina238_of_match[] = { 761 { 762 .compatible = "ti,ina237", 763 .data = (void *)ina237 764 }, 765 { 766 .compatible = "ti,ina238", 767 .data = (void *)ina238 768 }, 769 { 770 .compatible = "silergy,sq52206", 771 .data = (void *)sq52206 772 }, 773 { } 774 }; 775 MODULE_DEVICE_TABLE(of, ina238_of_match); 776 777 static struct i2c_driver ina238_driver = { 778 .driver = { 779 .name = "ina238", 780 .of_match_table = of_match_ptr(ina238_of_match), 781 }, 782 .probe = ina238_probe, 783 .id_table = ina238_id, 784 }; 785 786 module_i2c_driver(ina238_driver); 787 788 MODULE_AUTHOR("Nathan Rossi <nathan.rossi@digi.com>"); 789 MODULE_DESCRIPTION("ina238 driver"); 790 MODULE_LICENSE("GPL"); 791