ltc4162-l-charger.c (23555B)
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_device.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. */ 51enum 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.*/ 65enum 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 78struct 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 87static 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 */ 112static 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 128static 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 145static 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 158static 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 173static 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 191static 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 206static 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 222static 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 242static 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 260static 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 276static 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 297static 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 317static 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 335static 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 361static 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 384static 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 405static 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 420static 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 440static 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 468static 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 */ 494static 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 504static 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 sprintf(buf, "%s\n", result); 529} 530static DEVICE_ATTR_RO(charge_status); 531 532static 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 sprintf(buf, "%d\n", val.intval); 545} 546static DEVICE_ATTR_RO(vbat); 547 548static 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 sprintf(buf, "%d\n", val.intval); 561} 562static DEVICE_ATTR_RO(vbat_avg); 563 564static 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 sprintf(buf, "%d\n", val.intval); 577} 578static DEVICE_ATTR_RO(ibat); 579 580static 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 sprintf(buf, "%u\n", regval & BIT(2) ? 1 : 0); 593} 594 595static 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 617static DEVICE_ATTR_RW(force_telemetry); 618 619static 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 sprintf(buf, "%u\n", 632 regval == LTC4162L_ARM_SHIP_MODE_MAGIC ? 1 : 0); 633} 634 635static 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 657static DEVICE_ATTR_RW(arm_ship_mode); 658 659static 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 669static const struct attribute_group ltc4162l_attr_group = { 670 .name = NULL, /* put in device directory */ 671 .attrs = ltc4162l_sysfs_entries, 672}; 673 674static const struct attribute_group *ltc4162l_attr_groups[] = { 675 <c4162l_attr_group, 676 NULL, 677}; 678 679static 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 721static 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 743static 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 */ 758static 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 774static 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 784static 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 798static 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 804static 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 814static 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 822static int ltc4162l_probe(struct i2c_client *client, 823 const struct i2c_device_id *id) 824{ 825 struct i2c_adapter *adapter = client->adapter; 826 struct device *dev = &client->dev; 827 struct ltc4162l_info *info; 828 struct power_supply_config ltc4162l_config = {}; 829 u32 value; 830 int ret; 831 832 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) { 833 dev_err(dev, "No support for SMBUS_WORD_DATA\n"); 834 return -ENODEV; 835 } 836 info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL); 837 if (!info) 838 return -ENOMEM; 839 840 info->client = client; 841 i2c_set_clientdata(client, info); 842 843 info->regmap = devm_regmap_init_i2c(client, <c4162l_regmap_config); 844 if (IS_ERR(info->regmap)) { 845 dev_err(dev, "Failed to initialize register map\n"); 846 return PTR_ERR(info->regmap); 847 } 848 849 ret = device_property_read_u32(dev, "lltc,rsnsb-micro-ohms", 850 &info->rsnsb); 851 if (ret) { 852 dev_err(dev, "Missing lltc,rsnsb-micro-ohms property\n"); 853 return ret; 854 } 855 if (!info->rsnsb) 856 return -EINVAL; 857 858 ret = device_property_read_u32(dev, "lltc,rsnsi-micro-ohms", 859 &info->rsnsi); 860 if (ret) { 861 dev_err(dev, "Missing lltc,rsnsi-micro-ohms property\n"); 862 return ret; 863 } 864 if (!info->rsnsi) 865 return -EINVAL; 866 867 if (!device_property_read_u32(dev, "lltc,cell-count", &value)) 868 info->cell_count = value; 869 870 ltc4162l_config.of_node = dev->of_node; 871 ltc4162l_config.drv_data = info; 872 ltc4162l_config.attr_grp = ltc4162l_attr_groups; 873 874 info->charger = devm_power_supply_register(dev, <c4162l_desc, 875 <c4162l_config); 876 if (IS_ERR(info->charger)) { 877 dev_err(dev, "Failed to register charger\n"); 878 return PTR_ERR(info->charger); 879 } 880 881 /* Disable the threshold alerts, we're not using them */ 882 regmap_write(info->regmap, LTC4162L_EN_LIMIT_ALERTS_REG, 0); 883 884 /* Enable interrupts on all status changes */ 885 regmap_write(info->regmap, LTC4162L_EN_CHARGER_STATE_ALERTS_REG, 886 0x1fff); 887 regmap_write(info->regmap, LTC4162L_EN_CHARGE_STATUS_ALERTS_REG, 0x1f); 888 889 ltc4162l_clear_interrupts(info); 890 891 return 0; 892} 893 894static void ltc4162l_alert(struct i2c_client *client, 895 enum i2c_alert_protocol type, unsigned int flag) 896{ 897 struct ltc4162l_info *info = i2c_get_clientdata(client); 898 899 if (type != I2C_PROTOCOL_SMBUS_ALERT) 900 return; 901 902 ltc4162l_clear_interrupts(info); 903 power_supply_changed(info->charger); 904} 905 906static const struct i2c_device_id ltc4162l_i2c_id_table[] = { 907 { "ltc4162-l", 0 }, 908 { }, 909}; 910MODULE_DEVICE_TABLE(i2c, ltc4162l_i2c_id_table); 911 912static const struct of_device_id ltc4162l_of_match[] = { 913 { .compatible = "lltc,ltc4162-l", }, 914 { }, 915}; 916MODULE_DEVICE_TABLE(of, ltc4162l_of_match); 917 918static struct i2c_driver ltc4162l_driver = { 919 .probe = ltc4162l_probe, 920 .alert = ltc4162l_alert, 921 .id_table = ltc4162l_i2c_id_table, 922 .driver = { 923 .name = "ltc4162-l-charger", 924 .of_match_table = of_match_ptr(ltc4162l_of_match), 925 }, 926}; 927module_i2c_driver(ltc4162l_driver); 928 929MODULE_LICENSE("GPL"); 930MODULE_AUTHOR("Mike Looijmans <mike.looijmans@topic.nl>"); 931MODULE_DESCRIPTION("LTC4162-L charger driver");