1 // SPDX-License-Identifier: GPL-2.0 2 // 3 // max17040_battery.c 4 // fuel-gauge systems for lithium-ion (Li+) batteries 5 // 6 // Copyright (C) 2009 Samsung Electronics 7 // Minkyu Kang <mk7.kang@samsung.com> 8 9 #include <linux/module.h> 10 #include <linux/init.h> 11 #include <linux/platform_device.h> 12 #include <linux/mutex.h> 13 #include <linux/err.h> 14 #include <linux/i2c.h> 15 #include <linux/delay.h> 16 #include <linux/interrupt.h> 17 #include <linux/power_supply.h> 18 #include <linux/of_device.h> 19 #include <linux/regmap.h> 20 #include <linux/slab.h> 21 22 #define MAX17040_VCELL 0x02 23 #define MAX17040_SOC 0x04 24 #define MAX17040_MODE 0x06 25 #define MAX17040_VER 0x08 26 #define MAX17040_CONFIG 0x0C 27 #define MAX17040_STATUS 0x1A 28 #define MAX17040_CMD 0xFE 29 30 31 #define MAX17040_DELAY 1000 32 #define MAX17040_BATTERY_FULL 95 33 #define MAX17040_RCOMP_DEFAULT 0x9700 34 35 #define MAX17040_ATHD_MASK 0x3f 36 #define MAX17040_ALSC_MASK 0x40 37 #define MAX17040_ATHD_DEFAULT_POWER_UP 4 38 #define MAX17040_STATUS_HD_MASK 0x1000 39 #define MAX17040_STATUS_SC_MASK 0x2000 40 #define MAX17040_CFG_RCOMP_MASK 0xff00 41 42 enum chip_id { 43 ID_MAX17040, 44 ID_MAX17041, 45 ID_MAX17043, 46 ID_MAX17044, 47 ID_MAX17048, 48 ID_MAX17049, 49 ID_MAX17058, 50 ID_MAX17059, 51 }; 52 53 /* values that differ by chip_id */ 54 struct chip_data { 55 u16 reset_val; 56 u16 vcell_shift; 57 u16 vcell_mul; 58 u16 vcell_div; 59 u8 has_low_soc_alert; 60 u8 rcomp_bytes; 61 u8 has_soc_alert; 62 }; 63 64 static struct chip_data max17040_family[] = { 65 [ID_MAX17040] = { 66 .reset_val = 0x0054, 67 .vcell_shift = 4, 68 .vcell_mul = 1250, 69 .vcell_div = 1, 70 .has_low_soc_alert = 0, 71 .rcomp_bytes = 2, 72 .has_soc_alert = 0, 73 }, 74 [ID_MAX17041] = { 75 .reset_val = 0x0054, 76 .vcell_shift = 4, 77 .vcell_mul = 2500, 78 .vcell_div = 1, 79 .has_low_soc_alert = 0, 80 .rcomp_bytes = 2, 81 .has_soc_alert = 0, 82 }, 83 [ID_MAX17043] = { 84 .reset_val = 0x0054, 85 .vcell_shift = 4, 86 .vcell_mul = 1250, 87 .vcell_div = 1, 88 .has_low_soc_alert = 1, 89 .rcomp_bytes = 1, 90 .has_soc_alert = 0, 91 }, 92 [ID_MAX17044] = { 93 .reset_val = 0x0054, 94 .vcell_shift = 4, 95 .vcell_mul = 2500, 96 .vcell_div = 1, 97 .has_low_soc_alert = 1, 98 .rcomp_bytes = 1, 99 .has_soc_alert = 0, 100 }, 101 [ID_MAX17048] = { 102 .reset_val = 0x5400, 103 .vcell_shift = 0, 104 .vcell_mul = 625, 105 .vcell_div = 8, 106 .has_low_soc_alert = 1, 107 .rcomp_bytes = 1, 108 .has_soc_alert = 1, 109 }, 110 [ID_MAX17049] = { 111 .reset_val = 0x5400, 112 .vcell_shift = 0, 113 .vcell_mul = 625, 114 .vcell_div = 4, 115 .has_low_soc_alert = 1, 116 .rcomp_bytes = 1, 117 .has_soc_alert = 1, 118 }, 119 [ID_MAX17058] = { 120 .reset_val = 0x5400, 121 .vcell_shift = 0, 122 .vcell_mul = 625, 123 .vcell_div = 8, 124 .has_low_soc_alert = 1, 125 .rcomp_bytes = 1, 126 .has_soc_alert = 0, 127 }, 128 [ID_MAX17059] = { 129 .reset_val = 0x5400, 130 .vcell_shift = 0, 131 .vcell_mul = 625, 132 .vcell_div = 4, 133 .has_low_soc_alert = 1, 134 .rcomp_bytes = 1, 135 .has_soc_alert = 0, 136 }, 137 }; 138 139 struct max17040_chip { 140 struct i2c_client *client; 141 struct regmap *regmap; 142 struct delayed_work work; 143 struct power_supply *battery; 144 struct chip_data data; 145 146 /* battery capacity */ 147 int soc; 148 /* Low alert threshold from 32% to 1% of the State of Charge */ 149 u32 low_soc_alert; 150 /* some devices return twice the capacity */ 151 bool quirk_double_soc; 152 /* higher 8 bits for 17043+, 16 bits for 17040,41 */ 153 u16 rcomp; 154 }; 155 156 static int max17040_reset(struct max17040_chip *chip) 157 { 158 return regmap_write(chip->regmap, MAX17040_CMD, chip->data.reset_val); 159 } 160 161 static int max17040_set_low_soc_alert(struct max17040_chip *chip, u32 level) 162 { 163 level = 32 - level * (chip->quirk_double_soc ? 2 : 1); 164 return regmap_update_bits(chip->regmap, MAX17040_CONFIG, 165 MAX17040_ATHD_MASK, level); 166 } 167 168 static int max17040_set_soc_alert(struct max17040_chip *chip, bool enable) 169 { 170 return regmap_update_bits(chip->regmap, MAX17040_CONFIG, 171 MAX17040_ALSC_MASK, enable ? MAX17040_ALSC_MASK : 0); 172 } 173 174 static int max17040_set_rcomp(struct max17040_chip *chip, u16 rcomp) 175 { 176 u16 mask = chip->data.rcomp_bytes == 2 ? 177 0xffff : MAX17040_CFG_RCOMP_MASK; 178 179 return regmap_update_bits(chip->regmap, MAX17040_CONFIG, mask, rcomp); 180 } 181 182 static int max17040_raw_vcell_to_uvolts(struct max17040_chip *chip, u16 vcell) 183 { 184 struct chip_data *d = &chip->data; 185 186 return (vcell >> d->vcell_shift) * d->vcell_mul / d->vcell_div; 187 } 188 189 190 static int max17040_get_vcell(struct max17040_chip *chip) 191 { 192 u32 vcell; 193 194 regmap_read(chip->regmap, MAX17040_VCELL, &vcell); 195 196 return max17040_raw_vcell_to_uvolts(chip, vcell); 197 } 198 199 static int max17040_get_soc(struct max17040_chip *chip) 200 { 201 u32 soc; 202 203 regmap_read(chip->regmap, MAX17040_SOC, &soc); 204 205 return soc >> (chip->quirk_double_soc ? 9 : 8); 206 } 207 208 static int max17040_get_version(struct max17040_chip *chip) 209 { 210 int ret; 211 u32 version; 212 213 ret = regmap_read(chip->regmap, MAX17040_VER, &version); 214 215 return ret ? ret : version; 216 } 217 218 static int max17040_get_online(struct max17040_chip *chip) 219 { 220 return 1; 221 } 222 223 static int max17040_get_of_data(struct max17040_chip *chip) 224 { 225 struct device *dev = &chip->client->dev; 226 struct chip_data *data = &max17040_family[ 227 (uintptr_t) of_device_get_match_data(dev)]; 228 int rcomp_len; 229 u8 rcomp[2]; 230 231 chip->quirk_double_soc = device_property_read_bool(dev, 232 "maxim,double-soc"); 233 234 chip->low_soc_alert = MAX17040_ATHD_DEFAULT_POWER_UP; 235 device_property_read_u32(dev, 236 "maxim,alert-low-soc-level", 237 &chip->low_soc_alert); 238 239 if (chip->low_soc_alert <= 0 || 240 chip->low_soc_alert > (chip->quirk_double_soc ? 16 : 32)) { 241 dev_err(dev, "maxim,alert-low-soc-level out of bounds\n"); 242 return -EINVAL; 243 } 244 245 rcomp_len = device_property_count_u8(dev, "maxim,rcomp"); 246 chip->rcomp = MAX17040_RCOMP_DEFAULT; 247 if (rcomp_len == data->rcomp_bytes) { 248 if (!device_property_read_u8_array(dev, "maxim,rcomp", 249 rcomp, rcomp_len)) 250 chip->rcomp = rcomp_len == 2 ? rcomp[0] << 8 | rcomp[1] : 251 rcomp[0] << 8; 252 } else if (rcomp_len > 0) { 253 dev_err(dev, "maxim,rcomp has incorrect length\n"); 254 return -EINVAL; 255 } 256 257 return 0; 258 } 259 260 static void max17040_check_changes(struct max17040_chip *chip) 261 { 262 chip->soc = max17040_get_soc(chip); 263 } 264 265 static void max17040_queue_work(struct max17040_chip *chip) 266 { 267 queue_delayed_work(system_power_efficient_wq, &chip->work, 268 MAX17040_DELAY); 269 } 270 271 static void max17040_stop_work(void *data) 272 { 273 struct max17040_chip *chip = data; 274 275 cancel_delayed_work_sync(&chip->work); 276 } 277 278 static void max17040_work(struct work_struct *work) 279 { 280 struct max17040_chip *chip; 281 int last_soc; 282 283 chip = container_of(work, struct max17040_chip, work.work); 284 285 /* store SOC to check changes */ 286 last_soc = chip->soc; 287 max17040_check_changes(chip); 288 289 /* check changes and send uevent */ 290 if (last_soc != chip->soc) 291 power_supply_changed(chip->battery); 292 293 max17040_queue_work(chip); 294 } 295 296 /* Returns true if alert cause was SOC change, not low SOC */ 297 static bool max17040_handle_soc_alert(struct max17040_chip *chip) 298 { 299 bool ret = true; 300 u32 data; 301 302 regmap_read(chip->regmap, MAX17040_STATUS, &data); 303 304 if (data & MAX17040_STATUS_HD_MASK) { 305 // this alert was caused by low soc 306 ret = false; 307 } 308 if (data & MAX17040_STATUS_SC_MASK) { 309 // soc change bit -- deassert to mark as handled 310 regmap_write(chip->regmap, MAX17040_STATUS, 311 data & ~MAX17040_STATUS_SC_MASK); 312 } 313 314 return ret; 315 } 316 317 static irqreturn_t max17040_thread_handler(int id, void *dev) 318 { 319 struct max17040_chip *chip = dev; 320 321 if (!(chip->data.has_soc_alert && max17040_handle_soc_alert(chip))) 322 dev_warn(&chip->client->dev, "IRQ: Alert battery low level\n"); 323 324 /* read registers */ 325 max17040_check_changes(chip); 326 327 /* send uevent */ 328 power_supply_changed(chip->battery); 329 330 /* reset alert bit */ 331 max17040_set_low_soc_alert(chip, chip->low_soc_alert); 332 333 return IRQ_HANDLED; 334 } 335 336 static int max17040_enable_alert_irq(struct max17040_chip *chip) 337 { 338 struct i2c_client *client = chip->client; 339 int ret; 340 341 ret = devm_request_threaded_irq(&client->dev, client->irq, NULL, 342 max17040_thread_handler, IRQF_ONESHOT, 343 chip->battery->desc->name, chip); 344 345 return ret; 346 } 347 348 static int max17040_prop_writeable(struct power_supply *psy, 349 enum power_supply_property psp) 350 { 351 switch (psp) { 352 case POWER_SUPPLY_PROP_CAPACITY_ALERT_MIN: 353 return 1; 354 default: 355 return 0; 356 } 357 } 358 359 static int max17040_set_property(struct power_supply *psy, 360 enum power_supply_property psp, 361 const union power_supply_propval *val) 362 { 363 struct max17040_chip *chip = power_supply_get_drvdata(psy); 364 int ret; 365 366 switch (psp) { 367 case POWER_SUPPLY_PROP_CAPACITY_ALERT_MIN: 368 /* alert threshold can be programmed from 1% up to 16/32% */ 369 if ((val->intval < 1) || 370 (val->intval > (chip->quirk_double_soc ? 16 : 32))) { 371 ret = -EINVAL; 372 break; 373 } 374 ret = max17040_set_low_soc_alert(chip, val->intval); 375 chip->low_soc_alert = val->intval; 376 break; 377 default: 378 ret = -EINVAL; 379 } 380 381 return ret; 382 } 383 384 static int max17040_get_property(struct power_supply *psy, 385 enum power_supply_property psp, 386 union power_supply_propval *val) 387 { 388 struct max17040_chip *chip = power_supply_get_drvdata(psy); 389 390 switch (psp) { 391 case POWER_SUPPLY_PROP_ONLINE: 392 val->intval = max17040_get_online(chip); 393 break; 394 case POWER_SUPPLY_PROP_VOLTAGE_NOW: 395 val->intval = max17040_get_vcell(chip); 396 break; 397 case POWER_SUPPLY_PROP_CAPACITY: 398 val->intval = max17040_get_soc(chip); 399 break; 400 case POWER_SUPPLY_PROP_CAPACITY_ALERT_MIN: 401 val->intval = chip->low_soc_alert; 402 break; 403 default: 404 return -EINVAL; 405 } 406 return 0; 407 } 408 409 static const struct regmap_config max17040_regmap = { 410 .reg_bits = 8, 411 .reg_stride = 2, 412 .val_bits = 16, 413 .val_format_endian = REGMAP_ENDIAN_BIG, 414 }; 415 416 static enum power_supply_property max17040_battery_props[] = { 417 POWER_SUPPLY_PROP_ONLINE, 418 POWER_SUPPLY_PROP_VOLTAGE_NOW, 419 POWER_SUPPLY_PROP_CAPACITY, 420 POWER_SUPPLY_PROP_CAPACITY_ALERT_MIN, 421 }; 422 423 static const struct power_supply_desc max17040_battery_desc = { 424 .name = "battery", 425 .type = POWER_SUPPLY_TYPE_BATTERY, 426 .get_property = max17040_get_property, 427 .set_property = max17040_set_property, 428 .property_is_writeable = max17040_prop_writeable, 429 .properties = max17040_battery_props, 430 .num_properties = ARRAY_SIZE(max17040_battery_props), 431 }; 432 433 static int max17040_probe(struct i2c_client *client) 434 { 435 const struct i2c_device_id *id = i2c_client_get_device_id(client); 436 struct i2c_adapter *adapter = client->adapter; 437 struct power_supply_config psy_cfg = {}; 438 struct max17040_chip *chip; 439 enum chip_id chip_id; 440 bool enable_irq = false; 441 int ret; 442 443 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) 444 return -EIO; 445 446 chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL); 447 if (!chip) 448 return -ENOMEM; 449 450 chip->client = client; 451 chip->regmap = devm_regmap_init_i2c(client, &max17040_regmap); 452 if (IS_ERR(chip->regmap)) 453 return PTR_ERR(chip->regmap); 454 chip_id = (enum chip_id) id->driver_data; 455 if (client->dev.of_node) { 456 ret = max17040_get_of_data(chip); 457 if (ret) 458 return ret; 459 chip_id = (uintptr_t)of_device_get_match_data(&client->dev); 460 } 461 chip->data = max17040_family[chip_id]; 462 463 i2c_set_clientdata(client, chip); 464 psy_cfg.drv_data = chip; 465 466 chip->battery = devm_power_supply_register(&client->dev, 467 &max17040_battery_desc, &psy_cfg); 468 if (IS_ERR(chip->battery)) { 469 dev_err(&client->dev, "failed: power supply register\n"); 470 return PTR_ERR(chip->battery); 471 } 472 473 ret = max17040_get_version(chip); 474 if (ret < 0) 475 return ret; 476 dev_dbg(&chip->client->dev, "MAX17040 Fuel-Gauge Ver 0x%x\n", ret); 477 478 if (chip_id == ID_MAX17040 || chip_id == ID_MAX17041) 479 max17040_reset(chip); 480 481 max17040_set_rcomp(chip, chip->rcomp); 482 483 /* check interrupt */ 484 if (client->irq && chip->data.has_low_soc_alert) { 485 ret = max17040_set_low_soc_alert(chip, chip->low_soc_alert); 486 if (ret) { 487 dev_err(&client->dev, 488 "Failed to set low SOC alert: err %d\n", ret); 489 return ret; 490 } 491 492 enable_irq = true; 493 } 494 495 if (client->irq && chip->data.has_soc_alert) { 496 ret = max17040_set_soc_alert(chip, 1); 497 if (ret) { 498 dev_err(&client->dev, 499 "Failed to set SOC alert: err %d\n", ret); 500 return ret; 501 } 502 enable_irq = true; 503 } else { 504 /* soc alerts negate the need for polling */ 505 INIT_DEFERRABLE_WORK(&chip->work, max17040_work); 506 ret = devm_add_action(&client->dev, max17040_stop_work, chip); 507 if (ret) 508 return ret; 509 max17040_queue_work(chip); 510 } 511 512 if (enable_irq) { 513 ret = max17040_enable_alert_irq(chip); 514 if (ret) { 515 client->irq = 0; 516 dev_warn(&client->dev, 517 "Failed to get IRQ err %d\n", ret); 518 } 519 } 520 521 return 0; 522 } 523 524 #ifdef CONFIG_PM_SLEEP 525 526 static int max17040_suspend(struct device *dev) 527 { 528 struct i2c_client *client = to_i2c_client(dev); 529 struct max17040_chip *chip = i2c_get_clientdata(client); 530 531 if (client->irq && chip->data.has_soc_alert) 532 // disable soc alert to prevent wakeup 533 max17040_set_soc_alert(chip, 0); 534 else 535 cancel_delayed_work(&chip->work); 536 537 if (client->irq && device_may_wakeup(dev)) 538 enable_irq_wake(client->irq); 539 540 return 0; 541 } 542 543 static int max17040_resume(struct device *dev) 544 { 545 struct i2c_client *client = to_i2c_client(dev); 546 struct max17040_chip *chip = i2c_get_clientdata(client); 547 548 if (client->irq && device_may_wakeup(dev)) 549 disable_irq_wake(client->irq); 550 551 if (client->irq && chip->data.has_soc_alert) 552 max17040_set_soc_alert(chip, 1); 553 else 554 max17040_queue_work(chip); 555 556 return 0; 557 } 558 559 static SIMPLE_DEV_PM_OPS(max17040_pm_ops, max17040_suspend, max17040_resume); 560 #define MAX17040_PM_OPS (&max17040_pm_ops) 561 562 #else 563 564 #define MAX17040_PM_OPS NULL 565 566 #endif /* CONFIG_PM_SLEEP */ 567 568 static const struct i2c_device_id max17040_id[] = { 569 { "max17040", ID_MAX17040 }, 570 { "max17041", ID_MAX17041 }, 571 { "max17043", ID_MAX17043 }, 572 { "max77836-battery", ID_MAX17043 }, 573 { "max17044", ID_MAX17044 }, 574 { "max17048", ID_MAX17048 }, 575 { "max17049", ID_MAX17049 }, 576 { "max17058", ID_MAX17058 }, 577 { "max17059", ID_MAX17059 }, 578 { /* sentinel */ } 579 }; 580 MODULE_DEVICE_TABLE(i2c, max17040_id); 581 582 static const struct of_device_id max17040_of_match[] = { 583 { .compatible = "maxim,max17040", .data = (void *) ID_MAX17040 }, 584 { .compatible = "maxim,max17041", .data = (void *) ID_MAX17041 }, 585 { .compatible = "maxim,max17043", .data = (void *) ID_MAX17043 }, 586 { .compatible = "maxim,max77836-battery", .data = (void *) ID_MAX17043 }, 587 { .compatible = "maxim,max17044", .data = (void *) ID_MAX17044 }, 588 { .compatible = "maxim,max17048", .data = (void *) ID_MAX17048 }, 589 { .compatible = "maxim,max17049", .data = (void *) ID_MAX17049 }, 590 { .compatible = "maxim,max17058", .data = (void *) ID_MAX17058 }, 591 { .compatible = "maxim,max17059", .data = (void *) ID_MAX17059 }, 592 { /* sentinel */ }, 593 }; 594 MODULE_DEVICE_TABLE(of, max17040_of_match); 595 596 static struct i2c_driver max17040_i2c_driver = { 597 .driver = { 598 .name = "max17040", 599 .of_match_table = max17040_of_match, 600 .pm = MAX17040_PM_OPS, 601 }, 602 .probe_new = max17040_probe, 603 .id_table = max17040_id, 604 }; 605 module_i2c_driver(max17040_i2c_driver); 606 607 MODULE_AUTHOR("Minkyu Kang <mk7.kang@samsung.com>"); 608 MODULE_DESCRIPTION("MAX17040 Fuel Gauge"); 609 MODULE_LICENSE("GPL"); 610