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) & 0xffff; 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 * The first clamp_val() is to establish a baseline to avoid overflows. 521 */ 522 regval = clamp_val(val, 0, LONG_MAX / 2); 523 regval = div_u64(regval * 4 * 100 * data->rshunt, data->config->power_calculate_factor * 524 1000ULL * INA238_FIXED_SHUNT * data->gain); 525 regval = clamp_val(regval >> 8, 0, U16_MAX); 526 527 return regmap_write(data->regmap, INA238_POWER_LIMIT, regval); 528 } 529 530 static int ina238_read_temp(struct device *dev, u32 attr, long *val) 531 { 532 struct ina238_data *data = dev_get_drvdata(dev); 533 int regval; 534 int err; 535 536 switch (attr) { 537 case hwmon_temp_input: 538 err = regmap_read(data->regmap, INA238_DIE_TEMP, ®val); 539 if (err) 540 return err; 541 /* Signed, result in mC */ 542 *val = div_s64(((s64)((s16)regval) >> data->config->temp_shift) * 543 (s64)data->config->temp_lsb, 10000); 544 break; 545 case hwmon_temp_max: 546 err = regmap_read(data->regmap, INA238_TEMP_LIMIT, ®val); 547 if (err) 548 return err; 549 /* Signed, result in mC */ 550 *val = div_s64(((s64)((s16)regval) >> data->config->temp_shift) * 551 (s64)data->config->temp_lsb, 10000); 552 break; 553 case hwmon_temp_max_alarm: 554 err = regmap_read(data->regmap, INA238_DIAG_ALERT, ®val); 555 if (err) 556 return err; 557 558 *val = !!(regval & INA238_DIAG_ALERT_TMPOL); 559 break; 560 default: 561 return -EOPNOTSUPP; 562 } 563 564 return 0; 565 } 566 567 static int ina238_write_temp(struct device *dev, u32 attr, long val) 568 { 569 struct ina238_data *data = dev_get_drvdata(dev); 570 int regval; 571 572 if (attr != hwmon_temp_max) 573 return -EOPNOTSUPP; 574 575 /* Signed */ 576 val = clamp_val(val, -40000, 125000); 577 regval = div_s64(val * 10000, data->config->temp_lsb) << data->config->temp_shift; 578 regval = clamp_val(regval, S16_MIN, S16_MAX) & (0xffff << data->config->temp_shift); 579 580 return regmap_write(data->regmap, INA238_TEMP_LIMIT, regval); 581 } 582 583 static ssize_t energy1_input_show(struct device *dev, 584 struct device_attribute *da, char *buf) 585 { 586 struct ina238_data *data = dev_get_drvdata(dev); 587 int ret; 588 u64 regval; 589 u64 energy; 590 591 ret = ina238_read_reg40(data->client, SQ52206_ENERGY, ®val); 592 if (ret) 593 return ret; 594 595 /* result in uJ */ 596 energy = div_u64(regval * INA238_FIXED_SHUNT * data->gain * 16 * 10 * 597 data->config->power_calculate_factor, 4 * data->rshunt); 598 599 return sysfs_emit(buf, "%llu\n", energy); 600 } 601 602 static int ina238_read(struct device *dev, enum hwmon_sensor_types type, 603 u32 attr, int channel, long *val) 604 { 605 switch (type) { 606 case hwmon_in: 607 return ina238_read_in(dev, attr, channel, val); 608 case hwmon_curr: 609 return ina238_read_current(dev, attr, val); 610 case hwmon_power: 611 return ina238_read_power(dev, attr, val); 612 case hwmon_temp: 613 return ina238_read_temp(dev, attr, val); 614 default: 615 return -EOPNOTSUPP; 616 } 617 return 0; 618 } 619 620 static int ina238_write(struct device *dev, enum hwmon_sensor_types type, 621 u32 attr, int channel, long val) 622 { 623 struct ina238_data *data = dev_get_drvdata(dev); 624 int err; 625 626 mutex_lock(&data->config_lock); 627 628 switch (type) { 629 case hwmon_in: 630 err = ina238_write_in(dev, attr, channel, val); 631 break; 632 case hwmon_power: 633 err = ina238_write_power(dev, attr, val); 634 break; 635 case hwmon_temp: 636 err = ina238_write_temp(dev, attr, val); 637 break; 638 default: 639 err = -EOPNOTSUPP; 640 break; 641 } 642 643 mutex_unlock(&data->config_lock); 644 return err; 645 } 646 647 static umode_t ina238_is_visible(const void *drvdata, 648 enum hwmon_sensor_types type, 649 u32 attr, int channel) 650 { 651 const struct ina238_data *data = drvdata; 652 bool has_power_highest = data->config->has_power_highest; 653 654 switch (type) { 655 case hwmon_in: 656 switch (attr) { 657 case hwmon_in_input: 658 case hwmon_in_max_alarm: 659 case hwmon_in_min_alarm: 660 return 0444; 661 case hwmon_in_max: 662 case hwmon_in_min: 663 return 0644; 664 default: 665 return 0; 666 } 667 case hwmon_curr: 668 switch (attr) { 669 case hwmon_curr_input: 670 return 0444; 671 default: 672 return 0; 673 } 674 case hwmon_power: 675 switch (attr) { 676 case hwmon_power_input: 677 case hwmon_power_max_alarm: 678 return 0444; 679 case hwmon_power_max: 680 return 0644; 681 case hwmon_power_input_highest: 682 if (has_power_highest) 683 return 0444; 684 return 0; 685 default: 686 return 0; 687 } 688 case hwmon_temp: 689 switch (attr) { 690 case hwmon_temp_input: 691 case hwmon_temp_max_alarm: 692 return 0444; 693 case hwmon_temp_max: 694 return 0644; 695 default: 696 return 0; 697 } 698 default: 699 return 0; 700 } 701 } 702 703 #define INA238_HWMON_IN_CONFIG (HWMON_I_INPUT | \ 704 HWMON_I_MAX | HWMON_I_MAX_ALARM | \ 705 HWMON_I_MIN | HWMON_I_MIN_ALARM) 706 707 static const struct hwmon_channel_info * const ina238_info[] = { 708 HWMON_CHANNEL_INFO(in, 709 /* 0: shunt voltage */ 710 INA238_HWMON_IN_CONFIG, 711 /* 1: bus voltage */ 712 INA238_HWMON_IN_CONFIG), 713 HWMON_CHANNEL_INFO(curr, 714 /* 0: current through shunt */ 715 HWMON_C_INPUT), 716 HWMON_CHANNEL_INFO(power, 717 /* 0: power */ 718 HWMON_P_INPUT | HWMON_P_MAX | 719 HWMON_P_MAX_ALARM | HWMON_P_INPUT_HIGHEST), 720 HWMON_CHANNEL_INFO(temp, 721 /* 0: die temperature */ 722 HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_ALARM), 723 NULL 724 }; 725 726 static const struct hwmon_ops ina238_hwmon_ops = { 727 .is_visible = ina238_is_visible, 728 .read = ina238_read, 729 .write = ina238_write, 730 }; 731 732 static const struct hwmon_chip_info ina238_chip_info = { 733 .ops = &ina238_hwmon_ops, 734 .info = ina238_info, 735 }; 736 737 /* energy attributes are 5 bytes wide so we need u64 */ 738 static DEVICE_ATTR_RO(energy1_input); 739 740 static struct attribute *ina238_attrs[] = { 741 &dev_attr_energy1_input.attr, 742 NULL, 743 }; 744 ATTRIBUTE_GROUPS(ina238); 745 746 static int ina238_probe(struct i2c_client *client) 747 { 748 struct ina2xx_platform_data *pdata = dev_get_platdata(&client->dev); 749 struct device *dev = &client->dev; 750 struct device *hwmon_dev; 751 struct ina238_data *data; 752 enum ina238_ids chip; 753 int config; 754 int ret; 755 756 chip = (uintptr_t)i2c_get_match_data(client); 757 758 data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); 759 if (!data) 760 return -ENOMEM; 761 762 data->client = client; 763 /* set the device type */ 764 data->config = &ina238_config[chip]; 765 766 mutex_init(&data->config_lock); 767 768 data->regmap = devm_regmap_init_i2c(client, &ina238_regmap_config); 769 if (IS_ERR(data->regmap)) { 770 dev_err(dev, "failed to allocate register map\n"); 771 return PTR_ERR(data->regmap); 772 } 773 774 /* load shunt value */ 775 data->rshunt = INA238_RSHUNT_DEFAULT; 776 if (device_property_read_u32(dev, "shunt-resistor", &data->rshunt) < 0 && pdata) 777 data->rshunt = pdata->shunt_uohms; 778 if (data->rshunt == 0) { 779 dev_err(dev, "invalid shunt resister value %u\n", data->rshunt); 780 return -EINVAL; 781 } 782 783 /* load shunt gain value */ 784 if (device_property_read_u32(dev, "ti,shunt-gain", &data->gain) < 0) 785 data->gain = 4; /* Default of ADCRANGE = 0 */ 786 if (data->gain != 1 && data->gain != 2 && data->gain != 4) { 787 dev_err(dev, "invalid shunt gain value %u\n", data->gain); 788 return -EINVAL; 789 } 790 791 /* Setup CONFIG register */ 792 config = data->config->config_default; 793 if (chip == sq52206) { 794 if (data->gain == 1) 795 config |= SQ52206_CONFIG_ADCRANGE_HIGH; /* ADCRANGE = 10/11 is /1 */ 796 else if (data->gain == 2) 797 config |= SQ52206_CONFIG_ADCRANGE_LOW; /* ADCRANGE = 01 is /2 */ 798 } else if (data->gain == 1) { 799 config |= INA238_CONFIG_ADCRANGE; /* ADCRANGE = 1 is /1 */ 800 } 801 ret = regmap_write(data->regmap, INA238_CONFIG, config); 802 if (ret < 0) { 803 dev_err(dev, "error configuring the device: %d\n", ret); 804 return -ENODEV; 805 } 806 807 /* Setup ADC_CONFIG register */ 808 ret = regmap_write(data->regmap, INA238_ADC_CONFIG, 809 INA238_ADC_CONFIG_DEFAULT); 810 if (ret < 0) { 811 dev_err(dev, "error configuring the device: %d\n", ret); 812 return -ENODEV; 813 } 814 815 /* Setup SHUNT_CALIBRATION register with fixed value */ 816 ret = regmap_write(data->regmap, INA238_SHUNT_CALIBRATION, 817 INA238_CALIBRATION_VALUE); 818 if (ret < 0) { 819 dev_err(dev, "error configuring the device: %d\n", ret); 820 return -ENODEV; 821 } 822 823 /* Setup alert/alarm configuration */ 824 ret = regmap_write(data->regmap, INA238_DIAG_ALERT, 825 INA238_DIAG_ALERT_DEFAULT); 826 if (ret < 0) { 827 dev_err(dev, "error configuring the device: %d\n", ret); 828 return -ENODEV; 829 } 830 831 hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, data, 832 &ina238_chip_info, 833 data->config->has_energy ? 834 ina238_groups : NULL); 835 if (IS_ERR(hwmon_dev)) 836 return PTR_ERR(hwmon_dev); 837 838 dev_info(dev, "power monitor %s (Rshunt = %u uOhm, gain = %u)\n", 839 client->name, data->rshunt, data->gain); 840 841 return 0; 842 } 843 844 static const struct i2c_device_id ina238_id[] = { 845 { "ina228", ina228 }, 846 { "ina237", ina237 }, 847 { "ina238", ina238 }, 848 { "sq52206", sq52206 }, 849 { } 850 }; 851 MODULE_DEVICE_TABLE(i2c, ina238_id); 852 853 static const struct of_device_id __maybe_unused ina238_of_match[] = { 854 { 855 .compatible = "ti,ina228", 856 .data = (void *)ina228 857 }, 858 { 859 .compatible = "ti,ina237", 860 .data = (void *)ina237 861 }, 862 { 863 .compatible = "ti,ina238", 864 .data = (void *)ina238 865 }, 866 { 867 .compatible = "silergy,sq52206", 868 .data = (void *)sq52206 869 }, 870 { } 871 }; 872 MODULE_DEVICE_TABLE(of, ina238_of_match); 873 874 static struct i2c_driver ina238_driver = { 875 .driver = { 876 .name = "ina238", 877 .of_match_table = of_match_ptr(ina238_of_match), 878 }, 879 .probe = ina238_probe, 880 .id_table = ina238_id, 881 }; 882 883 module_i2c_driver(ina238_driver); 884 885 MODULE_AUTHOR("Nathan Rossi <nathan.rossi@digi.com>"); 886 MODULE_DESCRIPTION("ina238 driver"); 887 MODULE_LICENSE("GPL"); 888