1 /* 2 * Batttery Driver for Dialog DA9052 PMICs 3 * 4 * Copyright(c) 2011 Dialog Semiconductor Ltd. 5 * 6 * Author: David Dajun Chen <dchen@diasemi.com> 7 * 8 * This program is free software; you can redistribute it and/or modify it 9 * under the terms of the GNU General Public License as published by the 10 * Free Software Foundation; either version 2 of the License, or (at your 11 * option) any later version. 12 */ 13 14 #include <linux/delay.h> 15 #include <linux/freezer.h> 16 #include <linux/fs.h> 17 #include <linux/jiffies.h> 18 #include <linux/module.h> 19 #include <linux/timer.h> 20 #include <linux/uaccess.h> 21 #include <linux/platform_device.h> 22 #include <linux/power_supply.h> 23 24 #include <linux/mfd/da9052/da9052.h> 25 #include <linux/mfd/da9052/pdata.h> 26 #include <linux/mfd/da9052/reg.h> 27 28 /* STATIC CONFIGURATION */ 29 #define DA9052_BAT_CUTOFF_VOLT 2800 30 #define DA9052_BAT_TSH 62000 31 #define DA9052_BAT_LOW_CAP 4 32 #define DA9052_AVG_SZ 4 33 #define DA9052_VC_TBL_SZ 68 34 #define DA9052_VC_TBL_REF_SZ 3 35 36 #define DA9052_ISET_USB_MASK 0x0F 37 #define DA9052_CHG_USB_ILIM_MASK 0x40 38 #define DA9052_CHG_LIM_COLS 16 39 40 #define DA9052_MEAN(x, y) ((x + y) / 2) 41 42 enum charger_type_enum { 43 DA9052_NOCHARGER = 1, 44 DA9052_CHARGER, 45 }; 46 47 static const u16 da9052_chg_current_lim[2][DA9052_CHG_LIM_COLS] = { 48 {70, 80, 90, 100, 110, 120, 400, 450, 49 500, 550, 600, 650, 700, 900, 1100, 1300}, 50 {80, 90, 100, 110, 120, 400, 450, 500, 51 550, 600, 800, 1000, 1200, 1400, 1600, 1800}, 52 }; 53 54 static const u16 vc_tbl_ref[3] = {10, 25, 40}; 55 /* Lookup table for voltage vs capacity */ 56 static u32 const vc_tbl[3][68][2] = { 57 /* For temperature 10 degree Celsius */ 58 { 59 {4082, 100}, {4036, 98}, 60 {4020, 96}, {4008, 95}, 61 {3997, 93}, {3983, 91}, 62 {3964, 90}, {3943, 88}, 63 {3926, 87}, {3912, 85}, 64 {3900, 84}, {3890, 82}, 65 {3881, 80}, {3873, 79}, 66 {3865, 77}, {3857, 76}, 67 {3848, 74}, {3839, 73}, 68 {3829, 71}, {3820, 70}, 69 {3811, 68}, {3802, 67}, 70 {3794, 65}, {3785, 64}, 71 {3778, 62}, {3770, 61}, 72 {3763, 59}, {3756, 58}, 73 {3750, 56}, {3744, 55}, 74 {3738, 53}, {3732, 52}, 75 {3727, 50}, {3722, 49}, 76 {3717, 47}, {3712, 46}, 77 {3708, 44}, {3703, 43}, 78 {3700, 41}, {3696, 40}, 79 {3693, 38}, {3691, 37}, 80 {3688, 35}, {3686, 34}, 81 {3683, 32}, {3681, 31}, 82 {3678, 29}, {3675, 28}, 83 {3672, 26}, {3669, 25}, 84 {3665, 23}, {3661, 22}, 85 {3656, 21}, {3651, 19}, 86 {3645, 18}, {3639, 16}, 87 {3631, 15}, {3622, 13}, 88 {3611, 12}, {3600, 10}, 89 {3587, 9}, {3572, 7}, 90 {3548, 6}, {3503, 5}, 91 {3420, 3}, {3268, 2}, 92 {2992, 1}, {2746, 0} 93 }, 94 /* For temperature 25 degree Celsius */ 95 { 96 {4102, 100}, {4065, 98}, 97 {4048, 96}, {4034, 95}, 98 {4021, 93}, {4011, 92}, 99 {4001, 90}, {3986, 88}, 100 {3968, 87}, {3952, 85}, 101 {3938, 84}, {3926, 82}, 102 {3916, 81}, {3908, 79}, 103 {3900, 77}, {3892, 76}, 104 {3883, 74}, {3874, 73}, 105 {3864, 71}, {3855, 70}, 106 {3846, 68}, {3836, 67}, 107 {3827, 65}, {3819, 64}, 108 {3810, 62}, {3801, 61}, 109 {3793, 59}, {3786, 58}, 110 {3778, 56}, {3772, 55}, 111 {3765, 53}, {3759, 52}, 112 {3754, 50}, {3748, 49}, 113 {3743, 47}, {3738, 46}, 114 {3733, 44}, {3728, 43}, 115 {3724, 41}, {3720, 40}, 116 {3716, 38}, {3712, 37}, 117 {3709, 35}, {3706, 34}, 118 {3703, 33}, {3701, 31}, 119 {3698, 30}, {3696, 28}, 120 {3693, 27}, {3690, 25}, 121 {3687, 24}, {3683, 22}, 122 {3680, 21}, {3675, 19}, 123 {3671, 18}, {3666, 17}, 124 {3660, 15}, {3654, 14}, 125 {3647, 12}, {3639, 11}, 126 {3630, 9}, {3621, 8}, 127 {3613, 6}, {3606, 5}, 128 {3597, 4}, {3582, 2}, 129 {3546, 1}, {2747, 0} 130 }, 131 /* For temperature 40 degree Celsius */ 132 { 133 {4114, 100}, {4081, 98}, 134 {4065, 96}, {4050, 95}, 135 {4036, 93}, {4024, 92}, 136 {4013, 90}, {4002, 88}, 137 {3990, 87}, {3976, 85}, 138 {3962, 84}, {3950, 82}, 139 {3939, 81}, {3930, 79}, 140 {3921, 77}, {3912, 76}, 141 {3902, 74}, {3893, 73}, 142 {3883, 71}, {3874, 70}, 143 {3865, 68}, {3856, 67}, 144 {3847, 65}, {3838, 64}, 145 {3829, 62}, {3820, 61}, 146 {3812, 59}, {3803, 58}, 147 {3795, 56}, {3787, 55}, 148 {3780, 53}, {3773, 52}, 149 {3767, 50}, {3761, 49}, 150 {3756, 47}, {3751, 46}, 151 {3746, 44}, {3741, 43}, 152 {3736, 41}, {3732, 40}, 153 {3728, 38}, {3724, 37}, 154 {3720, 35}, {3716, 34}, 155 {3713, 33}, {3710, 31}, 156 {3707, 30}, {3704, 28}, 157 {3701, 27}, {3698, 25}, 158 {3695, 24}, {3691, 22}, 159 {3686, 21}, {3681, 19}, 160 {3676, 18}, {3671, 17}, 161 {3666, 15}, {3661, 14}, 162 {3655, 12}, {3648, 11}, 163 {3640, 9}, {3632, 8}, 164 {3622, 6}, {3616, 5}, 165 {3611, 4}, {3604, 2}, 166 {3594, 1}, {2747, 0} 167 } 168 }; 169 170 struct da9052_battery { 171 struct da9052 *da9052; 172 struct power_supply *psy; 173 struct notifier_block nb; 174 int charger_type; 175 int status; 176 int health; 177 }; 178 179 static inline int volt_reg_to_mV(int value) 180 { 181 return ((value * 1000) / 512) + 2500; 182 } 183 184 static inline int ichg_reg_to_mA(int value) 185 { 186 return (value * 3900) / 1000; 187 } 188 189 static int da9052_read_chgend_current(struct da9052_battery *bat, 190 int *current_mA) 191 { 192 int ret; 193 194 if (bat->status == POWER_SUPPLY_STATUS_DISCHARGING) 195 return -EINVAL; 196 197 ret = da9052_reg_read(bat->da9052, DA9052_ICHG_END_REG); 198 if (ret < 0) 199 return ret; 200 201 *current_mA = ichg_reg_to_mA(ret & DA9052_ICHGEND_ICHGEND); 202 203 return 0; 204 } 205 206 static int da9052_read_chg_current(struct da9052_battery *bat, int *current_mA) 207 { 208 int ret; 209 210 if (bat->status == POWER_SUPPLY_STATUS_DISCHARGING) 211 return -EINVAL; 212 213 ret = da9052_reg_read(bat->da9052, DA9052_ICHG_AV_REG); 214 if (ret < 0) 215 return ret; 216 217 *current_mA = ichg_reg_to_mA(ret & DA9052_ICHGAV_ICHGAV); 218 219 return 0; 220 } 221 222 static int da9052_bat_check_status(struct da9052_battery *bat, int *status) 223 { 224 u8 v[2] = {0, 0}; 225 u8 bat_status; 226 u8 chg_end; 227 int ret; 228 int chg_current; 229 int chg_end_current; 230 bool dcinsel; 231 bool dcindet; 232 bool vbussel; 233 bool vbusdet; 234 bool dc; 235 bool vbus; 236 237 ret = da9052_group_read(bat->da9052, DA9052_STATUS_A_REG, 2, v); 238 if (ret < 0) 239 return ret; 240 241 bat_status = v[0]; 242 chg_end = v[1]; 243 244 dcinsel = bat_status & DA9052_STATUSA_DCINSEL; 245 dcindet = bat_status & DA9052_STATUSA_DCINDET; 246 vbussel = bat_status & DA9052_STATUSA_VBUSSEL; 247 vbusdet = bat_status & DA9052_STATUSA_VBUSDET; 248 dc = dcinsel && dcindet; 249 vbus = vbussel && vbusdet; 250 251 /* Preference to WALL(DCIN) charger unit */ 252 if (dc || vbus) { 253 bat->charger_type = DA9052_CHARGER; 254 255 /* If charging end flag is set and Charging current is greater 256 * than charging end limit then battery is charging 257 */ 258 if ((chg_end & DA9052_STATUSB_CHGEND) != 0) { 259 ret = da9052_read_chg_current(bat, &chg_current); 260 if (ret < 0) 261 return ret; 262 ret = da9052_read_chgend_current(bat, &chg_end_current); 263 if (ret < 0) 264 return ret; 265 266 if (chg_current >= chg_end_current) 267 bat->status = POWER_SUPPLY_STATUS_CHARGING; 268 else 269 bat->status = POWER_SUPPLY_STATUS_NOT_CHARGING; 270 } else { 271 /* If Charging end flag is cleared then battery is 272 * charging 273 */ 274 bat->status = POWER_SUPPLY_STATUS_CHARGING; 275 } 276 } else if (dcindet || vbusdet) { 277 bat->charger_type = DA9052_CHARGER; 278 bat->status = POWER_SUPPLY_STATUS_NOT_CHARGING; 279 } else { 280 bat->charger_type = DA9052_NOCHARGER; 281 bat->status = POWER_SUPPLY_STATUS_DISCHARGING; 282 } 283 284 if (status != NULL) 285 *status = bat->status; 286 return 0; 287 } 288 289 static int da9052_bat_read_volt(struct da9052_battery *bat, int *volt_mV) 290 { 291 int volt; 292 293 volt = da9052_adc_manual_read(bat->da9052, DA9052_ADC_MAN_MUXSEL_VBAT); 294 if (volt < 0) 295 return volt; 296 297 *volt_mV = volt_reg_to_mV(volt); 298 299 return 0; 300 } 301 302 static int da9052_bat_check_presence(struct da9052_battery *bat, int *illegal) 303 { 304 int bat_temp; 305 306 bat_temp = da9052_adc_read_temp(bat->da9052); 307 if (bat_temp < 0) 308 return bat_temp; 309 310 if (bat_temp > DA9052_BAT_TSH) 311 *illegal = 1; 312 else 313 *illegal = 0; 314 315 return 0; 316 } 317 318 static int da9052_bat_interpolate(int vbat_lower, int vbat_upper, 319 int level_lower, int level_upper, 320 int bat_voltage) 321 { 322 int tmp; 323 324 tmp = ((level_upper - level_lower) * 1000) / (vbat_upper - vbat_lower); 325 tmp = level_lower + (((bat_voltage - vbat_lower) * tmp) / 1000); 326 327 return tmp; 328 } 329 330 static unsigned char da9052_determine_vc_tbl_index(unsigned char adc_temp) 331 { 332 int i; 333 334 if (adc_temp <= vc_tbl_ref[0]) 335 return 0; 336 337 if (adc_temp > vc_tbl_ref[DA9052_VC_TBL_REF_SZ - 1]) 338 return DA9052_VC_TBL_REF_SZ - 1; 339 340 for (i = 0; i < DA9052_VC_TBL_REF_SZ - 1; i++) { 341 if ((adc_temp > vc_tbl_ref[i]) && 342 (adc_temp <= DA9052_MEAN(vc_tbl_ref[i], vc_tbl_ref[i + 1]))) 343 return i; 344 if ((adc_temp > DA9052_MEAN(vc_tbl_ref[i], vc_tbl_ref[i + 1])) 345 && (adc_temp <= vc_tbl_ref[i])) 346 return i + 1; 347 } 348 /* 349 * For some reason authors of the driver didn't presume that we can 350 * end up here. It might be OK, but might be not, no one knows for 351 * sure. Go check your battery, is it on fire? 352 */ 353 WARN_ON(1); 354 return 0; 355 } 356 357 static int da9052_bat_read_capacity(struct da9052_battery *bat, int *capacity) 358 { 359 int adc_temp; 360 int bat_voltage; 361 int vbat_lower; 362 int vbat_upper; 363 int level_upper; 364 int level_lower; 365 int ret; 366 int flag; 367 int i = 0; 368 int j; 369 370 ret = da9052_bat_read_volt(bat, &bat_voltage); 371 if (ret < 0) 372 return ret; 373 374 adc_temp = da9052_adc_read_temp(bat->da9052); 375 if (adc_temp < 0) 376 return adc_temp; 377 378 i = da9052_determine_vc_tbl_index(adc_temp); 379 380 if (bat_voltage >= vc_tbl[i][0][0]) { 381 *capacity = 100; 382 return 0; 383 } 384 if (bat_voltage <= vc_tbl[i][DA9052_VC_TBL_SZ - 1][0]) { 385 *capacity = 0; 386 return 0; 387 } 388 flag = 0; 389 390 for (j = 0; j < (DA9052_VC_TBL_SZ-1); j++) { 391 if ((bat_voltage <= vc_tbl[i][j][0]) && 392 (bat_voltage >= vc_tbl[i][j + 1][0])) { 393 vbat_upper = vc_tbl[i][j][0]; 394 vbat_lower = vc_tbl[i][j + 1][0]; 395 level_upper = vc_tbl[i][j][1]; 396 level_lower = vc_tbl[i][j + 1][1]; 397 flag = 1; 398 break; 399 } 400 } 401 if (!flag) 402 return -EIO; 403 404 *capacity = da9052_bat_interpolate(vbat_lower, vbat_upper, level_lower, 405 level_upper, bat_voltage); 406 407 return 0; 408 } 409 410 static int da9052_bat_check_health(struct da9052_battery *bat, int *health) 411 { 412 int ret; 413 int bat_illegal; 414 int capacity; 415 416 ret = da9052_bat_check_presence(bat, &bat_illegal); 417 if (ret < 0) 418 return ret; 419 420 if (bat_illegal) { 421 bat->health = POWER_SUPPLY_HEALTH_UNKNOWN; 422 return 0; 423 } 424 425 if (bat->health != POWER_SUPPLY_HEALTH_OVERHEAT) { 426 ret = da9052_bat_read_capacity(bat, &capacity); 427 if (ret < 0) 428 return ret; 429 if (capacity < DA9052_BAT_LOW_CAP) 430 bat->health = POWER_SUPPLY_HEALTH_DEAD; 431 else 432 bat->health = POWER_SUPPLY_HEALTH_GOOD; 433 } 434 435 *health = bat->health; 436 437 return 0; 438 } 439 440 static irqreturn_t da9052_bat_irq(int irq, void *data) 441 { 442 struct da9052_battery *bat = data; 443 int virq; 444 445 virq = regmap_irq_get_virq(bat->da9052->irq_data, irq); 446 irq -= virq; 447 448 if (irq == DA9052_IRQ_CHGEND) 449 bat->status = POWER_SUPPLY_STATUS_FULL; 450 else 451 da9052_bat_check_status(bat, NULL); 452 453 if (irq == DA9052_IRQ_CHGEND || irq == DA9052_IRQ_DCIN || 454 irq == DA9052_IRQ_VBUS || irq == DA9052_IRQ_TBAT) { 455 power_supply_changed(bat->psy); 456 } 457 458 return IRQ_HANDLED; 459 } 460 461 static int da9052_USB_current_notifier(struct notifier_block *nb, 462 unsigned long events, void *data) 463 { 464 u8 row; 465 u8 col; 466 int *current_mA = data; 467 int ret; 468 struct da9052_battery *bat = container_of(nb, struct da9052_battery, 469 nb); 470 471 if (bat->status == POWER_SUPPLY_STATUS_DISCHARGING) 472 return -EPERM; 473 474 ret = da9052_reg_read(bat->da9052, DA9052_CHGBUCK_REG); 475 if (ret & DA9052_CHG_USB_ILIM_MASK) 476 return -EPERM; 477 478 if (bat->da9052->chip_id == DA9052) 479 row = 0; 480 else 481 row = 1; 482 483 if (*current_mA < da9052_chg_current_lim[row][0] || 484 *current_mA > da9052_chg_current_lim[row][DA9052_CHG_LIM_COLS - 1]) 485 return -EINVAL; 486 487 for (col = 0; col <= DA9052_CHG_LIM_COLS - 1 ; col++) { 488 if (*current_mA <= da9052_chg_current_lim[row][col]) 489 break; 490 } 491 492 return da9052_reg_update(bat->da9052, DA9052_ISET_REG, 493 DA9052_ISET_USB_MASK, col); 494 } 495 496 static int da9052_bat_get_property(struct power_supply *psy, 497 enum power_supply_property psp, 498 union power_supply_propval *val) 499 { 500 int ret; 501 int illegal; 502 struct da9052_battery *bat = power_supply_get_drvdata(psy); 503 504 ret = da9052_bat_check_presence(bat, &illegal); 505 if (ret < 0) 506 return ret; 507 508 if (illegal && psp != POWER_SUPPLY_PROP_PRESENT) 509 return -ENODEV; 510 511 switch (psp) { 512 case POWER_SUPPLY_PROP_STATUS: 513 ret = da9052_bat_check_status(bat, &val->intval); 514 break; 515 case POWER_SUPPLY_PROP_ONLINE: 516 val->intval = 517 (bat->charger_type == DA9052_NOCHARGER) ? 0 : 1; 518 break; 519 case POWER_SUPPLY_PROP_PRESENT: 520 ret = da9052_bat_check_presence(bat, &val->intval); 521 break; 522 case POWER_SUPPLY_PROP_HEALTH: 523 ret = da9052_bat_check_health(bat, &val->intval); 524 break; 525 case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: 526 val->intval = DA9052_BAT_CUTOFF_VOLT * 1000; 527 break; 528 case POWER_SUPPLY_PROP_VOLTAGE_AVG: 529 ret = da9052_bat_read_volt(bat, &val->intval); 530 break; 531 case POWER_SUPPLY_PROP_CURRENT_AVG: 532 ret = da9052_read_chg_current(bat, &val->intval); 533 break; 534 case POWER_SUPPLY_PROP_CAPACITY: 535 ret = da9052_bat_read_capacity(bat, &val->intval); 536 break; 537 case POWER_SUPPLY_PROP_TEMP: 538 val->intval = da9052_adc_read_temp(bat->da9052); 539 ret = val->intval; 540 break; 541 case POWER_SUPPLY_PROP_TECHNOLOGY: 542 val->intval = POWER_SUPPLY_TECHNOLOGY_LION; 543 break; 544 default: 545 return -EINVAL; 546 } 547 return ret; 548 } 549 550 static enum power_supply_property da9052_bat_props[] = { 551 POWER_SUPPLY_PROP_STATUS, 552 POWER_SUPPLY_PROP_ONLINE, 553 POWER_SUPPLY_PROP_PRESENT, 554 POWER_SUPPLY_PROP_HEALTH, 555 POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, 556 POWER_SUPPLY_PROP_VOLTAGE_AVG, 557 POWER_SUPPLY_PROP_CURRENT_AVG, 558 POWER_SUPPLY_PROP_CAPACITY, 559 POWER_SUPPLY_PROP_TEMP, 560 POWER_SUPPLY_PROP_TECHNOLOGY, 561 }; 562 563 static struct power_supply_desc psy_desc = { 564 .name = "da9052-bat", 565 .type = POWER_SUPPLY_TYPE_BATTERY, 566 .properties = da9052_bat_props, 567 .num_properties = ARRAY_SIZE(da9052_bat_props), 568 .get_property = da9052_bat_get_property, 569 }; 570 571 static char *da9052_bat_irqs[] = { 572 "BATT TEMP", 573 "DCIN DET", 574 "DCIN REM", 575 "VBUS DET", 576 "VBUS REM", 577 "CHG END", 578 }; 579 580 static int da9052_bat_irq_bits[] = { 581 DA9052_IRQ_TBAT, 582 DA9052_IRQ_DCIN, 583 DA9052_IRQ_DCINREM, 584 DA9052_IRQ_VBUS, 585 DA9052_IRQ_VBUSREM, 586 DA9052_IRQ_CHGEND, 587 }; 588 589 static s32 da9052_bat_probe(struct platform_device *pdev) 590 { 591 struct da9052_pdata *pdata; 592 struct da9052_battery *bat; 593 struct power_supply_config psy_cfg = {}; 594 int ret; 595 int i; 596 597 bat = devm_kzalloc(&pdev->dev, sizeof(struct da9052_battery), 598 GFP_KERNEL); 599 if (!bat) 600 return -ENOMEM; 601 602 psy_cfg.drv_data = bat; 603 604 bat->da9052 = dev_get_drvdata(pdev->dev.parent); 605 bat->charger_type = DA9052_NOCHARGER; 606 bat->status = POWER_SUPPLY_STATUS_UNKNOWN; 607 bat->health = POWER_SUPPLY_HEALTH_UNKNOWN; 608 bat->nb.notifier_call = da9052_USB_current_notifier; 609 610 pdata = bat->da9052->dev->platform_data; 611 if (pdata != NULL && pdata->use_for_apm) 612 psy_desc.use_for_apm = pdata->use_for_apm; 613 else 614 psy_desc.use_for_apm = 1; 615 616 for (i = 0; i < ARRAY_SIZE(da9052_bat_irqs); i++) { 617 ret = da9052_request_irq(bat->da9052, 618 da9052_bat_irq_bits[i], da9052_bat_irqs[i], 619 da9052_bat_irq, bat); 620 621 if (ret != 0) { 622 dev_err(bat->da9052->dev, 623 "DA9052 failed to request %s IRQ: %d\n", 624 da9052_bat_irqs[i], ret); 625 goto err; 626 } 627 } 628 629 bat->psy = power_supply_register(&pdev->dev, &psy_desc, &psy_cfg); 630 if (IS_ERR(bat->psy)) { 631 ret = PTR_ERR(bat->psy); 632 goto err; 633 } 634 635 platform_set_drvdata(pdev, bat); 636 return 0; 637 638 err: 639 while (--i >= 0) 640 da9052_free_irq(bat->da9052, da9052_bat_irq_bits[i], bat); 641 642 return ret; 643 } 644 static int da9052_bat_remove(struct platform_device *pdev) 645 { 646 int i; 647 struct da9052_battery *bat = platform_get_drvdata(pdev); 648 649 for (i = 0; i < ARRAY_SIZE(da9052_bat_irqs); i++) 650 da9052_free_irq(bat->da9052, da9052_bat_irq_bits[i], bat); 651 652 power_supply_unregister(bat->psy); 653 654 return 0; 655 } 656 657 static struct platform_driver da9052_bat_driver = { 658 .probe = da9052_bat_probe, 659 .remove = da9052_bat_remove, 660 .driver = { 661 .name = "da9052-bat", 662 }, 663 }; 664 module_platform_driver(da9052_bat_driver); 665 666 MODULE_DESCRIPTION("DA9052 BAT Device Driver"); 667 MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>"); 668 MODULE_LICENSE("GPL"); 669 MODULE_ALIAS("platform:da9052-bat"); 670