1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Driver for Analog Devices (Linear Technology) LTC4162-L charger IC. 4 * Copyright (C) 2020, Topic Embedded Products 5 */ 6 7 #include <linux/module.h> 8 #include <linux/delay.h> 9 #include <linux/of.h> 10 #include <linux/pm_runtime.h> 11 #include <linux/power_supply.h> 12 #include <linux/i2c.h> 13 #include <linux/regmap.h> 14 15 /* Registers (names based on what datasheet uses) */ 16 #define LTC4162L_EN_LIMIT_ALERTS_REG 0x0D 17 #define LTC4162L_EN_CHARGER_STATE_ALERTS_REG 0x0E 18 #define LTC4162L_EN_CHARGE_STATUS_ALERTS_REG 0x0F 19 #define LTC4162L_CONFIG_BITS_REG 0x14 20 #define LTC4162L_IIN_LIMIT_TARGET 0x15 21 #define LTC4162L_ARM_SHIP_MODE 0x19 22 #define LTC4162L_CHARGE_CURRENT_SETTING 0X1A 23 #define LTC4162L_VCHARGE_SETTING 0X1B 24 #define LTC4162L_C_OVER_X_THRESHOLD 0x1C 25 #define LTC4162L_MAX_CV_TIME 0X1D 26 #define LTC4162L_MAX_CHARGE_TIME 0X1E 27 #define LTC4162L_CHARGER_CONFIG_BITS 0x29 28 #define LTC4162L_CHARGER_STATE 0x34 29 #define LTC4162L_CHARGE_STATUS 0x35 30 #define LTC4162L_LIMIT_ALERTS_REG 0x36 31 #define LTC4162L_CHARGER_STATE_ALERTS_REG 0x37 32 #define LTC4162L_CHARGE_STATUS_ALERTS_REG 0x38 33 #define LTC4162L_SYSTEM_STATUS_REG 0x39 34 #define LTC4162L_VBAT 0x3A 35 #define LTC4162L_VIN 0x3B 36 #define LTC4162L_VOUT 0x3C 37 #define LTC4162L_IBAT 0x3D 38 #define LTC4162L_IIN 0x3E 39 #define LTC4162L_DIE_TEMPERATURE 0x3F 40 #define LTC4162L_THERMISTOR_VOLTAGE 0x40 41 #define LTC4162L_BSR 0x41 42 #define LTC4162L_JEITA_REGION 0x42 43 #define LTC4162L_CHEM_CELLS_REG 0x43 44 #define LTC4162L_ICHARGE_DAC 0x44 45 #define LTC4162L_VCHARGE_DAC 0x45 46 #define LTC4162L_IIN_LIMIT_DAC 0x46 47 #define LTC4162L_VBAT_FILT 0x47 48 #define LTC4162L_INPUT_UNDERVOLTAGE_DAC 0x4B 49 50 /* Enumeration as in datasheet. Individual bits are mutually exclusive. */ 51 enum ltc4162l_state { 52 battery_detection = 2048, 53 charger_suspended = 256, 54 precharge = 128, /* trickle on low bat voltage */ 55 cc_cv_charge = 64, /* normal charge */ 56 ntc_pause = 32, 57 timer_term = 16, 58 c_over_x_term = 8, /* battery is full */ 59 max_charge_time_fault = 4, 60 bat_missing_fault = 2, 61 bat_short_fault = 1 62 }; 63 64 /* Individual bits are mutually exclusive. Only active in charging states.*/ 65 enum ltc4162l_charge_status { 66 ilim_reg_active = 32, 67 thermal_reg_active = 16, 68 vin_uvcl_active = 8, 69 iin_limit_active = 4, 70 constant_current = 2, 71 constant_voltage = 1, 72 charger_off = 0 73 }; 74 75 /* Magic number to write to ARM_SHIP_MODE register */ 76 #define LTC4162L_ARM_SHIP_MODE_MAGIC 21325 77 78 struct ltc4162l_info { 79 struct i2c_client *client; 80 struct regmap *regmap; 81 struct power_supply *charger; 82 u32 rsnsb; /* Series resistor that sets charge current, microOhm */ 83 u32 rsnsi; /* Series resistor to measure input current, microOhm */ 84 u8 cell_count; /* Number of connected cells, 0 while unknown */ 85 }; 86 87 static u8 ltc4162l_get_cell_count(struct ltc4162l_info *info) 88 { 89 int ret; 90 unsigned int val; 91 92 /* Once read successfully */ 93 if (info->cell_count) 94 return info->cell_count; 95 96 ret = regmap_read(info->regmap, LTC4162L_CHEM_CELLS_REG, &val); 97 if (ret) 98 return 0; 99 100 /* Lower 4 bits is the cell count, or 0 if the chip doesn't know yet */ 101 val &= 0x0f; 102 if (!val) 103 return 0; 104 105 /* Once determined, keep the value */ 106 info->cell_count = val; 107 108 return val; 109 }; 110 111 /* Convert enum value to POWER_SUPPLY_STATUS value */ 112 static int ltc4162l_state_decode(enum ltc4162l_state value) 113 { 114 switch (value) { 115 case precharge: 116 case cc_cv_charge: 117 return POWER_SUPPLY_STATUS_CHARGING; 118 case c_over_x_term: 119 return POWER_SUPPLY_STATUS_FULL; 120 case bat_missing_fault: 121 case bat_short_fault: 122 return POWER_SUPPLY_STATUS_UNKNOWN; 123 default: 124 return POWER_SUPPLY_STATUS_NOT_CHARGING; 125 } 126 }; 127 128 static int ltc4162l_get_status(struct ltc4162l_info *info, 129 union power_supply_propval *val) 130 { 131 unsigned int regval; 132 int ret; 133 134 ret = regmap_read(info->regmap, LTC4162L_CHARGER_STATE, ®val); 135 if (ret) { 136 dev_err(&info->client->dev, "Failed to read CHARGER_STATE\n"); 137 return ret; 138 } 139 140 val->intval = ltc4162l_state_decode(regval); 141 142 return 0; 143 } 144 145 static int ltc4162l_charge_status_decode(enum ltc4162l_charge_status value) 146 { 147 if (!value) 148 return POWER_SUPPLY_CHARGE_TYPE_NONE; 149 150 /* constant voltage/current and input_current limit are "fast" modes */ 151 if (value <= iin_limit_active) 152 return POWER_SUPPLY_CHARGE_TYPE_FAST; 153 154 /* Anything that's not fast we'll return as trickle */ 155 return POWER_SUPPLY_CHARGE_TYPE_TRICKLE; 156 } 157 158 static int ltc4162l_get_charge_type(struct ltc4162l_info *info, 159 union power_supply_propval *val) 160 { 161 unsigned int regval; 162 int ret; 163 164 ret = regmap_read(info->regmap, LTC4162L_CHARGE_STATUS, ®val); 165 if (ret) 166 return ret; 167 168 val->intval = ltc4162l_charge_status_decode(regval); 169 170 return 0; 171 } 172 173 static int ltc4162l_state_to_health(enum ltc4162l_state value) 174 { 175 switch (value) { 176 case ntc_pause: 177 return POWER_SUPPLY_HEALTH_OVERHEAT; 178 case timer_term: 179 return POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE; 180 case max_charge_time_fault: 181 return POWER_SUPPLY_HEALTH_WATCHDOG_TIMER_EXPIRE; 182 case bat_missing_fault: 183 return POWER_SUPPLY_HEALTH_UNSPEC_FAILURE; 184 case bat_short_fault: 185 return POWER_SUPPLY_HEALTH_DEAD; 186 default: 187 return POWER_SUPPLY_HEALTH_GOOD; 188 } 189 } 190 191 static int ltc4162l_get_health(struct ltc4162l_info *info, 192 union power_supply_propval *val) 193 { 194 unsigned int regval; 195 int ret; 196 197 ret = regmap_read(info->regmap, LTC4162L_CHARGER_STATE, ®val); 198 if (ret) 199 return ret; 200 201 val->intval = ltc4162l_state_to_health(regval); 202 203 return 0; 204 } 205 206 static int ltc4162l_get_online(struct ltc4162l_info *info, 207 union power_supply_propval *val) 208 { 209 unsigned int regval; 210 int ret; 211 212 ret = regmap_read(info->regmap, LTC4162L_SYSTEM_STATUS_REG, ®val); 213 if (ret) 214 return ret; 215 216 /* BIT(2) indicates if input voltage is sufficient to charge */ 217 val->intval = !!(regval & BIT(2)); 218 219 return 0; 220 } 221 222 static int ltc4162l_get_vbat(struct ltc4162l_info *info, 223 unsigned int reg, 224 union power_supply_propval *val) 225 { 226 unsigned int regval; 227 int ret; 228 229 ret = regmap_read(info->regmap, reg, ®val); 230 if (ret) 231 return ret; 232 233 /* cell_count × 192.4μV/LSB */ 234 regval *= 1924; 235 regval *= ltc4162l_get_cell_count(info); 236 regval /= 10; 237 val->intval = regval; 238 239 return 0; 240 } 241 242 static int ltc4162l_get_ibat(struct ltc4162l_info *info, 243 union power_supply_propval *val) 244 { 245 unsigned int regval; 246 int ret; 247 248 ret = regmap_read(info->regmap, LTC4162L_IBAT, ®val); 249 if (ret) 250 return ret; 251 252 /* Signed 16-bit number, 1.466μV / RSNSB amperes/LSB. */ 253 ret = (s16)(regval & 0xFFFF); 254 val->intval = 100 * mult_frac(ret, 14660, (int)info->rsnsb); 255 256 return 0; 257 } 258 259 260 static int ltc4162l_get_input_voltage(struct ltc4162l_info *info, 261 union power_supply_propval *val) 262 { 263 unsigned int regval; 264 int ret; 265 266 ret = regmap_read(info->regmap, LTC4162L_VIN, ®val); 267 if (ret) 268 return ret; 269 270 /* 1.649mV/LSB */ 271 val->intval = regval * 1694; 272 273 return 0; 274 } 275 276 static int ltc4162l_get_input_current(struct ltc4162l_info *info, 277 union power_supply_propval *val) 278 { 279 unsigned int regval; 280 int ret; 281 282 ret = regmap_read(info->regmap, LTC4162L_IIN, ®val); 283 if (ret) 284 return ret; 285 286 /* Signed 16-bit number, 1.466μV / RSNSI amperes/LSB. */ 287 ret = (s16)(regval & 0xFFFF); 288 ret *= 14660; 289 ret /= info->rsnsi; 290 ret *= 100; 291 292 val->intval = ret; 293 294 return 0; 295 } 296 297 static int ltc4162l_get_icharge(struct ltc4162l_info *info, 298 unsigned int reg, 299 union power_supply_propval *val) 300 { 301 unsigned int regval; 302 int ret; 303 304 ret = regmap_read(info->regmap, reg, ®val); 305 if (ret) 306 return ret; 307 308 regval &= BIT(6) - 1; /* Only the lower 5 bits */ 309 310 /* The charge current servo level: (icharge_dac + 1) × 1mV/RSNSB */ 311 ++regval; 312 val->intval = 10000u * mult_frac(regval, 100000u, info->rsnsb); 313 314 return 0; 315 } 316 317 static int ltc4162l_set_icharge(struct ltc4162l_info *info, 318 unsigned int reg, 319 unsigned int value) 320 { 321 value = mult_frac(value, info->rsnsb, 100000u); 322 value /= 10000u; 323 324 /* Round to lowest possible */ 325 if (value) 326 --value; 327 328 if (value > 31) 329 return -EINVAL; 330 331 return regmap_write(info->regmap, reg, value); 332 } 333 334 335 static int ltc4162l_get_vcharge(struct ltc4162l_info *info, 336 unsigned int reg, 337 union power_supply_propval *val) 338 { 339 unsigned int regval; 340 int ret; 341 u32 voltage; 342 343 ret = regmap_read(info->regmap, reg, ®val); 344 if (ret) 345 return ret; 346 347 regval &= BIT(6) - 1; /* Only the lower 5 bits */ 348 349 /* 350 * charge voltage setting can be computed from 351 * cell_count × (vcharge_setting × 12.5mV + 3.8125V) 352 * where vcharge_setting ranges from 0 to 31 (4.2V max). 353 */ 354 voltage = 3812500 + (regval * 12500); 355 voltage *= ltc4162l_get_cell_count(info); 356 val->intval = voltage; 357 358 return 0; 359 } 360 361 static int ltc4162l_set_vcharge(struct ltc4162l_info *info, 362 unsigned int reg, 363 unsigned int value) 364 { 365 u8 cell_count = ltc4162l_get_cell_count(info); 366 367 if (!cell_count) 368 return -EBUSY; /* Not available yet, try again later */ 369 370 value /= cell_count; 371 372 if (value < 3812500) 373 return -EINVAL; 374 375 value -= 3812500; 376 value /= 12500; 377 378 if (value > 31) 379 return -EINVAL; 380 381 return regmap_write(info->regmap, reg, value); 382 } 383 384 static int ltc4162l_get_iin_limit_dac(struct ltc4162l_info *info, 385 union power_supply_propval *val) 386 { 387 unsigned int regval; 388 int ret; 389 390 ret = regmap_read(info->regmap, LTC4162L_IIN_LIMIT_DAC, ®val); 391 if (ret) 392 return ret; 393 394 regval &= BIT(6) - 1; /* Only 6 bits */ 395 396 /* (iin_limit_dac + 1) × 500μV / RSNSI */ 397 ++regval; 398 regval *= 5000000u; 399 regval /= info->rsnsi; 400 val->intval = 100u * regval; 401 402 return 0; 403 } 404 405 static int ltc4162l_set_iin_limit(struct ltc4162l_info *info, 406 unsigned int value) 407 { 408 unsigned int regval; 409 410 regval = mult_frac(value, info->rsnsi, 50000u); 411 regval /= 10000u; 412 if (regval) 413 --regval; 414 if (regval > 63) 415 regval = 63; 416 417 return regmap_write(info->regmap, LTC4162L_IIN_LIMIT_TARGET, regval); 418 } 419 420 static int ltc4162l_get_die_temp(struct ltc4162l_info *info, 421 union power_supply_propval *val) 422 { 423 unsigned int regval; 424 int ret; 425 426 ret = regmap_read(info->regmap, LTC4162L_DIE_TEMPERATURE, ®val); 427 if (ret) 428 return ret; 429 430 /* die_temp × 0.0215°C/LSB - 264.4°C */ 431 ret = (s16)(regval & 0xFFFF); 432 ret *= 215; 433 ret /= 100; /* Centidegrees scale */ 434 ret -= 26440; 435 val->intval = ret; 436 437 return 0; 438 } 439 440 static int ltc4162l_get_term_current(struct ltc4162l_info *info, 441 union power_supply_propval *val) 442 { 443 unsigned int regval; 444 int ret; 445 446 ret = regmap_read(info->regmap, LTC4162L_CHARGER_CONFIG_BITS, ®val); 447 if (ret) 448 return ret; 449 450 /* Check if C_OVER_X_THRESHOLD is enabled */ 451 if (!(regval & BIT(2))) { 452 val->intval = 0; 453 return 0; 454 } 455 456 ret = regmap_read(info->regmap, LTC4162L_C_OVER_X_THRESHOLD, ®val); 457 if (ret) 458 return ret; 459 460 /* 1.466μV / RSNSB amperes/LSB */ 461 regval *= 14660u; 462 regval /= info->rsnsb; 463 val->intval = 100 * regval; 464 465 return 0; 466 } 467 468 static int ltc4162l_set_term_current(struct ltc4162l_info *info, 469 unsigned int value) 470 { 471 int ret; 472 unsigned int regval; 473 474 if (!value) { 475 /* Disable en_c_over_x_term when set to zero */ 476 return regmap_update_bits(info->regmap, 477 LTC4162L_CHARGER_CONFIG_BITS, 478 BIT(2), 0); 479 } 480 481 regval = mult_frac(value, info->rsnsb, 14660u); 482 regval /= 100u; 483 484 ret = regmap_write(info->regmap, LTC4162L_C_OVER_X_THRESHOLD, regval); 485 if (ret) 486 return ret; 487 488 /* Set en_c_over_x_term after changing the threshold value */ 489 return regmap_update_bits(info->regmap, LTC4162L_CHARGER_CONFIG_BITS, 490 BIT(2), BIT(2)); 491 } 492 493 /* Custom properties */ 494 static const char * const ltc4162l_charge_status_name[] = { 495 "ilim_reg_active", /* 32 */ 496 "thermal_reg_active", 497 "vin_uvcl_active", 498 "iin_limit_active", 499 "constant_current", 500 "constant_voltage", 501 "charger_off" /* 0 */ 502 }; 503 504 static ssize_t charge_status_show(struct device *dev, 505 struct device_attribute *attr, char *buf) 506 { 507 struct power_supply *psy = to_power_supply(dev); 508 struct ltc4162l_info *info = power_supply_get_drvdata(psy); 509 const char *result = ltc4162l_charge_status_name[ 510 ARRAY_SIZE(ltc4162l_charge_status_name) - 1]; 511 unsigned int regval; 512 unsigned int mask; 513 unsigned int index; 514 int ret; 515 516 ret = regmap_read(info->regmap, LTC4162L_CHARGE_STATUS, ®val); 517 if (ret) 518 return ret; 519 520 /* Only one bit is set according to datasheet, let's be safe here */ 521 for (mask = 32, index = 0; mask != 0; mask >>= 1, ++index) { 522 if (regval & mask) { 523 result = ltc4162l_charge_status_name[index]; 524 break; 525 } 526 } 527 528 return sysfs_emit(buf, "%s\n", result); 529 } 530 static DEVICE_ATTR_RO(charge_status); 531 532 static ssize_t vbat_show(struct device *dev, 533 struct device_attribute *attr, char *buf) 534 { 535 struct power_supply *psy = to_power_supply(dev); 536 struct ltc4162l_info *info = power_supply_get_drvdata(psy); 537 union power_supply_propval val; 538 int ret; 539 540 ret = ltc4162l_get_vbat(info, LTC4162L_VBAT, &val); 541 if (ret) 542 return ret; 543 544 return sysfs_emit(buf, "%d\n", val.intval); 545 } 546 static DEVICE_ATTR_RO(vbat); 547 548 static ssize_t vbat_avg_show(struct device *dev, 549 struct device_attribute *attr, char *buf) 550 { 551 struct power_supply *psy = to_power_supply(dev); 552 struct ltc4162l_info *info = power_supply_get_drvdata(psy); 553 union power_supply_propval val; 554 int ret; 555 556 ret = ltc4162l_get_vbat(info, LTC4162L_VBAT_FILT, &val); 557 if (ret) 558 return ret; 559 560 return sysfs_emit(buf, "%d\n", val.intval); 561 } 562 static DEVICE_ATTR_RO(vbat_avg); 563 564 static ssize_t ibat_show(struct device *dev, 565 struct device_attribute *attr, char *buf) 566 { 567 struct power_supply *psy = to_power_supply(dev); 568 struct ltc4162l_info *info = power_supply_get_drvdata(psy); 569 union power_supply_propval val; 570 int ret; 571 572 ret = ltc4162l_get_ibat(info, &val); 573 if (ret) 574 return ret; 575 576 return sysfs_emit(buf, "%d\n", val.intval); 577 } 578 static DEVICE_ATTR_RO(ibat); 579 580 static ssize_t force_telemetry_show(struct device *dev, 581 struct device_attribute *attr, char *buf) 582 { 583 struct power_supply *psy = to_power_supply(dev); 584 struct ltc4162l_info *info = power_supply_get_drvdata(psy); 585 unsigned int regval; 586 int ret; 587 588 ret = regmap_read(info->regmap, LTC4162L_CONFIG_BITS_REG, ®val); 589 if (ret) 590 return ret; 591 592 return sysfs_emit(buf, "%u\n", regval & BIT(2) ? 1 : 0); 593 } 594 595 static ssize_t force_telemetry_store(struct device *dev, 596 struct device_attribute *attr, 597 const char *buf, 598 size_t count) 599 { 600 struct power_supply *psy = to_power_supply(dev); 601 struct ltc4162l_info *info = power_supply_get_drvdata(psy); 602 int ret; 603 unsigned int value; 604 605 ret = kstrtouint(buf, 0, &value); 606 if (ret < 0) 607 return ret; 608 609 ret = regmap_update_bits(info->regmap, LTC4162L_CONFIG_BITS_REG, 610 BIT(2), value ? BIT(2) : 0); 611 if (ret < 0) 612 return ret; 613 614 return count; 615 } 616 617 static DEVICE_ATTR_RW(force_telemetry); 618 619 static ssize_t arm_ship_mode_show(struct device *dev, 620 struct device_attribute *attr, char *buf) 621 { 622 struct power_supply *psy = to_power_supply(dev); 623 struct ltc4162l_info *info = power_supply_get_drvdata(psy); 624 unsigned int regval; 625 int ret; 626 627 ret = regmap_read(info->regmap, LTC4162L_ARM_SHIP_MODE, ®val); 628 if (ret) 629 return ret; 630 631 return sysfs_emit(buf, "%u\n", 632 regval == LTC4162L_ARM_SHIP_MODE_MAGIC ? 1 : 0); 633 } 634 635 static ssize_t arm_ship_mode_store(struct device *dev, 636 struct device_attribute *attr, 637 const char *buf, 638 size_t count) 639 { 640 struct power_supply *psy = to_power_supply(dev); 641 struct ltc4162l_info *info = power_supply_get_drvdata(psy); 642 int ret; 643 unsigned int value; 644 645 ret = kstrtouint(buf, 0, &value); 646 if (ret < 0) 647 return ret; 648 649 ret = regmap_write(info->regmap, LTC4162L_ARM_SHIP_MODE, 650 value ? LTC4162L_ARM_SHIP_MODE_MAGIC : 0); 651 if (ret < 0) 652 return ret; 653 654 return count; 655 } 656 657 static DEVICE_ATTR_RW(arm_ship_mode); 658 659 static struct attribute *ltc4162l_sysfs_entries[] = { 660 &dev_attr_charge_status.attr, 661 &dev_attr_ibat.attr, 662 &dev_attr_vbat.attr, 663 &dev_attr_vbat_avg.attr, 664 &dev_attr_force_telemetry.attr, 665 &dev_attr_arm_ship_mode.attr, 666 NULL, 667 }; 668 669 static const struct attribute_group ltc4162l_attr_group = { 670 .name = NULL, /* put in device directory */ 671 .attrs = ltc4162l_sysfs_entries, 672 }; 673 674 static const struct attribute_group *ltc4162l_attr_groups[] = { 675 <c4162l_attr_group, 676 NULL, 677 }; 678 679 static int ltc4162l_get_property(struct power_supply *psy, 680 enum power_supply_property psp, 681 union power_supply_propval *val) 682 { 683 struct ltc4162l_info *info = power_supply_get_drvdata(psy); 684 685 switch (psp) { 686 case POWER_SUPPLY_PROP_STATUS: 687 return ltc4162l_get_status(info, val); 688 case POWER_SUPPLY_PROP_CHARGE_TYPE: 689 return ltc4162l_get_charge_type(info, val); 690 case POWER_SUPPLY_PROP_HEALTH: 691 return ltc4162l_get_health(info, val); 692 case POWER_SUPPLY_PROP_ONLINE: 693 return ltc4162l_get_online(info, val); 694 case POWER_SUPPLY_PROP_VOLTAGE_NOW: 695 return ltc4162l_get_input_voltage(info, val); 696 case POWER_SUPPLY_PROP_CURRENT_NOW: 697 return ltc4162l_get_input_current(info, val); 698 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: 699 return ltc4162l_get_icharge(info, 700 LTC4162L_ICHARGE_DAC, val); 701 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: 702 return ltc4162l_get_icharge(info, 703 LTC4162L_CHARGE_CURRENT_SETTING, val); 704 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE: 705 return ltc4162l_get_vcharge(info, 706 LTC4162L_VCHARGE_DAC, val); 707 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX: 708 return ltc4162l_get_vcharge(info, 709 LTC4162L_VCHARGE_SETTING, val); 710 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: 711 return ltc4162l_get_iin_limit_dac(info, val); 712 case POWER_SUPPLY_PROP_TEMP: 713 return ltc4162l_get_die_temp(info, val); 714 case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT: 715 return ltc4162l_get_term_current(info, val); 716 default: 717 return -EINVAL; 718 } 719 } 720 721 static int ltc4162l_set_property(struct power_supply *psy, 722 enum power_supply_property psp, 723 const union power_supply_propval *val) 724 { 725 struct ltc4162l_info *info = power_supply_get_drvdata(psy); 726 727 switch (psp) { 728 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: 729 return ltc4162l_set_icharge(info, 730 LTC4162L_CHARGE_CURRENT_SETTING, val->intval); 731 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX: 732 return ltc4162l_set_vcharge(info, 733 LTC4162L_VCHARGE_SETTING, val->intval); 734 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: 735 return ltc4162l_set_iin_limit(info, val->intval); 736 case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT: 737 return ltc4162l_set_term_current(info, val->intval); 738 default: 739 return -EINVAL; 740 } 741 } 742 743 static int ltc4162l_property_is_writeable(struct power_supply *psy, 744 enum power_supply_property psp) 745 { 746 switch (psp) { 747 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: 748 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX: 749 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: 750 case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT: 751 return 1; 752 default: 753 return 0; 754 } 755 } 756 757 /* Charger power supply property routines */ 758 static enum power_supply_property ltc4162l_properties[] = { 759 POWER_SUPPLY_PROP_STATUS, 760 POWER_SUPPLY_PROP_CHARGE_TYPE, 761 POWER_SUPPLY_PROP_HEALTH, 762 POWER_SUPPLY_PROP_ONLINE, 763 POWER_SUPPLY_PROP_VOLTAGE_NOW, 764 POWER_SUPPLY_PROP_CURRENT_NOW, 765 POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT, 766 POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, 767 POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE, 768 POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX, 769 POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, 770 POWER_SUPPLY_PROP_TEMP, 771 POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT, 772 }; 773 774 static const struct power_supply_desc ltc4162l_desc = { 775 .name = "ltc4162-l", 776 .type = POWER_SUPPLY_TYPE_MAINS, 777 .properties = ltc4162l_properties, 778 .num_properties = ARRAY_SIZE(ltc4162l_properties), 779 .get_property = ltc4162l_get_property, 780 .set_property = ltc4162l_set_property, 781 .property_is_writeable = ltc4162l_property_is_writeable, 782 }; 783 784 static bool ltc4162l_is_writeable_reg(struct device *dev, unsigned int reg) 785 { 786 /* all registers up to this one are writeable */ 787 if (reg <= LTC4162L_CHARGER_CONFIG_BITS) 788 return true; 789 790 /* The ALERTS registers can be written to clear alerts */ 791 if (reg >= LTC4162L_LIMIT_ALERTS_REG && 792 reg <= LTC4162L_CHARGE_STATUS_ALERTS_REG) 793 return true; 794 795 return false; 796 } 797 798 static bool ltc4162l_is_volatile_reg(struct device *dev, unsigned int reg) 799 { 800 /* all registers after this one are read-only status registers */ 801 return reg > LTC4162L_CHARGER_CONFIG_BITS; 802 } 803 804 static const struct regmap_config ltc4162l_regmap_config = { 805 .reg_bits = 8, 806 .val_bits = 16, 807 .val_format_endian = REGMAP_ENDIAN_LITTLE, 808 .writeable_reg = ltc4162l_is_writeable_reg, 809 .volatile_reg = ltc4162l_is_volatile_reg, 810 .max_register = LTC4162L_INPUT_UNDERVOLTAGE_DAC, 811 .cache_type = REGCACHE_RBTREE, 812 }; 813 814 static void ltc4162l_clear_interrupts(struct ltc4162l_info *info) 815 { 816 /* Acknowledge interrupt to chip by clearing all events */ 817 regmap_write(info->regmap, LTC4162L_LIMIT_ALERTS_REG, 0); 818 regmap_write(info->regmap, LTC4162L_CHARGER_STATE_ALERTS_REG, 0); 819 regmap_write(info->regmap, LTC4162L_CHARGE_STATUS_ALERTS_REG, 0); 820 } 821 822 static int ltc4162l_probe(struct i2c_client *client) 823 { 824 struct i2c_adapter *adapter = client->adapter; 825 struct device *dev = &client->dev; 826 struct ltc4162l_info *info; 827 struct power_supply_config ltc4162l_config = {}; 828 u32 value; 829 int ret; 830 831 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) { 832 dev_err(dev, "No support for SMBUS_WORD_DATA\n"); 833 return -ENODEV; 834 } 835 info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL); 836 if (!info) 837 return -ENOMEM; 838 839 info->client = client; 840 i2c_set_clientdata(client, info); 841 842 info->regmap = devm_regmap_init_i2c(client, <c4162l_regmap_config); 843 if (IS_ERR(info->regmap)) { 844 dev_err(dev, "Failed to initialize register map\n"); 845 return PTR_ERR(info->regmap); 846 } 847 848 ret = device_property_read_u32(dev, "lltc,rsnsb-micro-ohms", 849 &info->rsnsb); 850 if (ret) { 851 dev_err(dev, "Missing lltc,rsnsb-micro-ohms property\n"); 852 return ret; 853 } 854 if (!info->rsnsb) 855 return -EINVAL; 856 857 ret = device_property_read_u32(dev, "lltc,rsnsi-micro-ohms", 858 &info->rsnsi); 859 if (ret) { 860 dev_err(dev, "Missing lltc,rsnsi-micro-ohms property\n"); 861 return ret; 862 } 863 if (!info->rsnsi) 864 return -EINVAL; 865 866 if (!device_property_read_u32(dev, "lltc,cell-count", &value)) 867 info->cell_count = value; 868 869 ltc4162l_config.of_node = dev->of_node; 870 ltc4162l_config.drv_data = info; 871 ltc4162l_config.attr_grp = ltc4162l_attr_groups; 872 873 info->charger = devm_power_supply_register(dev, <c4162l_desc, 874 <c4162l_config); 875 if (IS_ERR(info->charger)) { 876 dev_err(dev, "Failed to register charger\n"); 877 return PTR_ERR(info->charger); 878 } 879 880 /* Disable the threshold alerts, we're not using them */ 881 regmap_write(info->regmap, LTC4162L_EN_LIMIT_ALERTS_REG, 0); 882 883 /* Enable interrupts on all status changes */ 884 regmap_write(info->regmap, LTC4162L_EN_CHARGER_STATE_ALERTS_REG, 885 0x1fff); 886 regmap_write(info->regmap, LTC4162L_EN_CHARGE_STATUS_ALERTS_REG, 0x1f); 887 888 ltc4162l_clear_interrupts(info); 889 890 return 0; 891 } 892 893 static void ltc4162l_alert(struct i2c_client *client, 894 enum i2c_alert_protocol type, unsigned int flag) 895 { 896 struct ltc4162l_info *info = i2c_get_clientdata(client); 897 898 if (type != I2C_PROTOCOL_SMBUS_ALERT) 899 return; 900 901 ltc4162l_clear_interrupts(info); 902 power_supply_changed(info->charger); 903 } 904 905 static const struct i2c_device_id ltc4162l_i2c_id_table[] = { 906 { "ltc4162-l" }, 907 { } 908 }; 909 MODULE_DEVICE_TABLE(i2c, ltc4162l_i2c_id_table); 910 911 static const struct of_device_id ltc4162l_of_match[] __maybe_unused = { 912 { .compatible = "lltc,ltc4162-l", }, 913 { }, 914 }; 915 MODULE_DEVICE_TABLE(of, ltc4162l_of_match); 916 917 static struct i2c_driver ltc4162l_driver = { 918 .probe = ltc4162l_probe, 919 .alert = ltc4162l_alert, 920 .id_table = ltc4162l_i2c_id_table, 921 .driver = { 922 .name = "ltc4162-l-charger", 923 .of_match_table = of_match_ptr(ltc4162l_of_match), 924 }, 925 }; 926 module_i2c_driver(ltc4162l_driver); 927 928 MODULE_LICENSE("GPL"); 929 MODULE_AUTHOR("Mike Looijmans <mike.looijmans@topic.nl>"); 930 MODULE_DESCRIPTION("LTC4162-L charger driver"); 931