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