ds2760_battery.c revision b0525b48f06714e8d5cf6a3266261b71de8d6dd4
1/* 2 * Driver for batteries with DS2760 chips inside. 3 * 4 * Copyright © 2007 Anton Vorontsov 5 * 2004-2007 Matt Reimer 6 * 2004 Szabolcs Gyurko 7 * 8 * Use consistent with the GNU GPL is permitted, 9 * provided that this copyright notice is 10 * preserved in its entirety in all copies and derived works. 11 * 12 * Author: Anton Vorontsov <cbou@mail.ru> 13 * February 2007 14 * 15 * Matt Reimer <mreimer@vpop.net> 16 * April 2004, 2005, 2007 17 * 18 * Szabolcs Gyurko <szabolcs.gyurko@tlt.hu> 19 * September 2004 20 */ 21 22#include <linux/module.h> 23#include <linux/param.h> 24#include <linux/jiffies.h> 25#include <linux/workqueue.h> 26#include <linux/pm.h> 27#include <linux/platform_device.h> 28#include <linux/power_supply.h> 29 30#include "../w1/w1.h" 31#include "../w1/slaves/w1_ds2760.h" 32 33struct ds2760_device_info { 34 struct device *dev; 35 36 /* DS2760 data, valid after calling ds2760_battery_read_status() */ 37 unsigned long update_time; /* jiffies when data read */ 38 char raw[DS2760_DATA_SIZE]; /* raw DS2760 data */ 39 int voltage_raw; /* units of 4.88 mV */ 40 int voltage_uV; /* units of µV */ 41 int current_raw; /* units of 0.625 mA */ 42 int current_uA; /* units of µA */ 43 int accum_current_raw; /* units of 0.25 mAh */ 44 int accum_current_uAh; /* units of µAh */ 45 int temp_raw; /* units of 0.125 °C */ 46 int temp_C; /* units of 0.1 °C */ 47 int rated_capacity; /* units of µAh */ 48 int rem_capacity; /* percentage */ 49 int full_active_uAh; /* units of µAh */ 50 int empty_uAh; /* units of µAh */ 51 int life_sec; /* units of seconds */ 52 int charge_status; /* POWER_SUPPLY_STATUS_* */ 53 54 int full_counter; 55 struct power_supply bat; 56 struct device *w1_dev; 57 struct workqueue_struct *monitor_wqueue; 58 struct delayed_work monitor_work; 59 struct delayed_work set_charged_work; 60}; 61 62static unsigned int cache_time = 1000; 63module_param(cache_time, uint, 0644); 64MODULE_PARM_DESC(cache_time, "cache time in milliseconds"); 65 66static unsigned int pmod_enabled; 67module_param(pmod_enabled, bool, 0644); 68MODULE_PARM_DESC(pmod_enabled, "PMOD enable bit"); 69 70static unsigned int rated_capacity; 71module_param(rated_capacity, uint, 0644); 72MODULE_PARM_DESC(rated_capacity, "rated battery capacity, 10*mAh or index"); 73 74static unsigned int current_accum; 75module_param(current_accum, uint, 0644); 76MODULE_PARM_DESC(current_accum, "current accumulator value"); 77 78/* Some batteries have their rated capacity stored a N * 10 mAh, while 79 * others use an index into this table. */ 80static int rated_capacities[] = { 81 0, 82 920, /* Samsung */ 83 920, /* BYD */ 84 920, /* Lishen */ 85 920, /* NEC */ 86 1440, /* Samsung */ 87 1440, /* BYD */ 88 1440, /* Lishen */ 89 1440, /* NEC */ 90 2880, /* Samsung */ 91 2880, /* BYD */ 92 2880, /* Lishen */ 93 2880 /* NEC */ 94}; 95 96/* array is level at temps 0°C, 10°C, 20°C, 30°C, 40°C 97 * temp is in Celsius */ 98static int battery_interpolate(int array[], int temp) 99{ 100 int index, dt; 101 102 if (temp <= 0) 103 return array[0]; 104 if (temp >= 40) 105 return array[4]; 106 107 index = temp / 10; 108 dt = temp % 10; 109 110 return array[index] + (((array[index + 1] - array[index]) * dt) / 10); 111} 112 113static int ds2760_battery_read_status(struct ds2760_device_info *di) 114{ 115 int ret, i, start, count, scale[5]; 116 117 if (di->update_time && time_before(jiffies, di->update_time + 118 msecs_to_jiffies(cache_time))) 119 return 0; 120 121 /* The first time we read the entire contents of SRAM/EEPROM, 122 * but after that we just read the interesting bits that change. */ 123 if (di->update_time == 0) { 124 start = 0; 125 count = DS2760_DATA_SIZE; 126 } else { 127 start = DS2760_VOLTAGE_MSB; 128 count = DS2760_TEMP_LSB - start + 1; 129 } 130 131 ret = w1_ds2760_read(di->w1_dev, di->raw + start, start, count); 132 if (ret != count) { 133 dev_warn(di->dev, "call to w1_ds2760_read failed (0x%p)\n", 134 di->w1_dev); 135 return 1; 136 } 137 138 di->update_time = jiffies; 139 140 /* DS2760 reports voltage in units of 4.88mV, but the battery class 141 * reports in units of uV, so convert by multiplying by 4880. */ 142 di->voltage_raw = (di->raw[DS2760_VOLTAGE_MSB] << 3) | 143 (di->raw[DS2760_VOLTAGE_LSB] >> 5); 144 di->voltage_uV = di->voltage_raw * 4880; 145 146 /* DS2760 reports current in signed units of 0.625mA, but the battery 147 * class reports in units of µA, so convert by multiplying by 625. */ 148 di->current_raw = 149 (((signed char)di->raw[DS2760_CURRENT_MSB]) << 5) | 150 (di->raw[DS2760_CURRENT_LSB] >> 3); 151 di->current_uA = di->current_raw * 625; 152 153 /* DS2760 reports accumulated current in signed units of 0.25mAh. */ 154 di->accum_current_raw = 155 (((signed char)di->raw[DS2760_CURRENT_ACCUM_MSB]) << 8) | 156 di->raw[DS2760_CURRENT_ACCUM_LSB]; 157 di->accum_current_uAh = di->accum_current_raw * 250; 158 159 /* DS2760 reports temperature in signed units of 0.125°C, but the 160 * battery class reports in units of 1/10 °C, so we convert by 161 * multiplying by .125 * 10 = 1.25. */ 162 di->temp_raw = (((signed char)di->raw[DS2760_TEMP_MSB]) << 3) | 163 (di->raw[DS2760_TEMP_LSB] >> 5); 164 di->temp_C = di->temp_raw + (di->temp_raw / 4); 165 166 /* At least some battery monitors (e.g. HP iPAQ) store the battery's 167 * maximum rated capacity. */ 168 if (di->raw[DS2760_RATED_CAPACITY] < ARRAY_SIZE(rated_capacities)) 169 di->rated_capacity = rated_capacities[ 170 (unsigned int)di->raw[DS2760_RATED_CAPACITY]]; 171 else 172 di->rated_capacity = di->raw[DS2760_RATED_CAPACITY] * 10; 173 174 di->rated_capacity *= 1000; /* convert to µAh */ 175 176 /* Calculate the full level at the present temperature. */ 177 di->full_active_uAh = di->raw[DS2760_ACTIVE_FULL] << 8 | 178 di->raw[DS2760_ACTIVE_FULL + 1]; 179 180 /* If the full_active_uAh value is not given, fall back to the rated 181 * capacity. This is likely to happen when chips are not part of the 182 * battery pack and is therefore not bootstrapped. */ 183 if (di->full_active_uAh == 0) 184 di->full_active_uAh = di->rated_capacity / 1000L; 185 186 scale[0] = di->full_active_uAh; 187 for (i = 1; i < 5; i++) 188 scale[i] = scale[i - 1] + di->raw[DS2760_ACTIVE_FULL + 2 + i]; 189 190 di->full_active_uAh = battery_interpolate(scale, di->temp_C / 10); 191 di->full_active_uAh *= 1000; /* convert to µAh */ 192 193 /* Calculate the empty level at the present temperature. */ 194 scale[4] = di->raw[DS2760_ACTIVE_EMPTY + 4]; 195 for (i = 3; i >= 0; i--) 196 scale[i] = scale[i + 1] + di->raw[DS2760_ACTIVE_EMPTY + i]; 197 198 di->empty_uAh = battery_interpolate(scale, di->temp_C / 10); 199 di->empty_uAh *= 1000; /* convert to µAh */ 200 201 if (di->full_active_uAh == di->empty_uAh) 202 di->rem_capacity = 0; 203 else 204 /* From Maxim Application Note 131: remaining capacity = 205 * ((ICA - Empty Value) / (Full Value - Empty Value)) x 100% */ 206 di->rem_capacity = ((di->accum_current_uAh - di->empty_uAh) * 100L) / 207 (di->full_active_uAh - di->empty_uAh); 208 209 if (di->rem_capacity < 0) 210 di->rem_capacity = 0; 211 if (di->rem_capacity > 100) 212 di->rem_capacity = 100; 213 214 if (di->current_uA >= 100L) 215 di->life_sec = -((di->accum_current_uAh - di->empty_uAh) * 36L) 216 / (di->current_uA / 100L); 217 else 218 di->life_sec = 0; 219 220 return 0; 221} 222 223static void ds2760_battery_set_current_accum(struct ds2760_device_info *di, 224 unsigned int acr_val) 225{ 226 unsigned char acr[2]; 227 228 /* acr is in units of 0.25 mAh */ 229 acr_val *= 4L; 230 acr_val /= 1000; 231 232 acr[0] = acr_val >> 8; 233 acr[1] = acr_val & 0xff; 234 235 if (w1_ds2760_write(di->w1_dev, acr, DS2760_CURRENT_ACCUM_MSB, 2) < 2) 236 dev_warn(di->dev, "ACR write failed\n"); 237} 238 239static void ds2760_battery_update_status(struct ds2760_device_info *di) 240{ 241 int old_charge_status = di->charge_status; 242 243 ds2760_battery_read_status(di); 244 245 if (di->charge_status == POWER_SUPPLY_STATUS_UNKNOWN) 246 di->full_counter = 0; 247 248 if (power_supply_am_i_supplied(&di->bat)) { 249 if (di->current_uA > 10000) { 250 di->charge_status = POWER_SUPPLY_STATUS_CHARGING; 251 di->full_counter = 0; 252 } else if (di->current_uA < -5000) { 253 if (di->charge_status != POWER_SUPPLY_STATUS_NOT_CHARGING) 254 dev_notice(di->dev, "not enough power to " 255 "charge\n"); 256 di->charge_status = POWER_SUPPLY_STATUS_NOT_CHARGING; 257 di->full_counter = 0; 258 } else if (di->current_uA < 10000 && 259 di->charge_status != POWER_SUPPLY_STATUS_FULL) { 260 261 /* Don't consider the battery to be full unless 262 * we've seen the current < 10 mA at least two 263 * consecutive times. */ 264 265 di->full_counter++; 266 267 if (di->full_counter < 2) { 268 di->charge_status = POWER_SUPPLY_STATUS_CHARGING; 269 } else { 270 di->charge_status = POWER_SUPPLY_STATUS_FULL; 271 ds2760_battery_set_current_accum(di, 272 di->full_active_uAh); 273 } 274 } 275 } else { 276 di->charge_status = POWER_SUPPLY_STATUS_DISCHARGING; 277 di->full_counter = 0; 278 } 279 280 if (di->charge_status != old_charge_status) 281 power_supply_changed(&di->bat); 282} 283 284static void ds2760_battery_write_status(struct ds2760_device_info *di, 285 char status) 286{ 287 if (status == di->raw[DS2760_STATUS_REG]) 288 return; 289 290 w1_ds2760_write(di->w1_dev, &status, DS2760_STATUS_WRITE_REG, 1); 291 w1_ds2760_store_eeprom(di->w1_dev, DS2760_EEPROM_BLOCK1); 292 w1_ds2760_recall_eeprom(di->w1_dev, DS2760_EEPROM_BLOCK1); 293} 294 295static void ds2760_battery_write_rated_capacity(struct ds2760_device_info *di, 296 unsigned char rated_capacity) 297{ 298 if (rated_capacity == di->raw[DS2760_RATED_CAPACITY]) 299 return; 300 301 w1_ds2760_write(di->w1_dev, &rated_capacity, DS2760_RATED_CAPACITY, 1); 302 w1_ds2760_store_eeprom(di->w1_dev, DS2760_EEPROM_BLOCK1); 303 w1_ds2760_recall_eeprom(di->w1_dev, DS2760_EEPROM_BLOCK1); 304} 305 306static void ds2760_battery_work(struct work_struct *work) 307{ 308 struct ds2760_device_info *di = container_of(work, 309 struct ds2760_device_info, monitor_work.work); 310 const int interval = HZ * 60; 311 312 dev_dbg(di->dev, "%s\n", __func__); 313 314 ds2760_battery_update_status(di); 315 queue_delayed_work(di->monitor_wqueue, &di->monitor_work, interval); 316} 317 318#define to_ds2760_device_info(x) container_of((x), struct ds2760_device_info, \ 319 bat); 320 321static void ds2760_battery_external_power_changed(struct power_supply *psy) 322{ 323 struct ds2760_device_info *di = to_ds2760_device_info(psy); 324 325 dev_dbg(di->dev, "%s\n", __func__); 326 327 cancel_delayed_work(&di->monitor_work); 328 queue_delayed_work(di->monitor_wqueue, &di->monitor_work, HZ/10); 329} 330 331 332static void ds2760_battery_set_charged_work(struct work_struct *work) 333{ 334 char bias; 335 struct ds2760_device_info *di = container_of(work, 336 struct ds2760_device_info, set_charged_work.work); 337 338 dev_dbg(di->dev, "%s\n", __func__); 339 340 ds2760_battery_read_status(di); 341 342 /* When we get notified by external circuitry that the battery is 343 * considered fully charged now, we know that there is no current 344 * flow any more. However, the ds2760's internal current meter is 345 * too inaccurate to rely on - spec say something ~15% failure. 346 * Hence, we use the current offset bias register to compensate 347 * that error. 348 */ 349 350 if (!power_supply_am_i_supplied(&di->bat)) 351 return; 352 353 bias = (signed char) di->current_raw + 354 (signed char) di->raw[DS2760_CURRENT_OFFSET_BIAS]; 355 356 dev_dbg(di->dev, "%s: bias = %d\n", __func__, bias); 357 358 w1_ds2760_write(di->w1_dev, &bias, DS2760_CURRENT_OFFSET_BIAS, 1); 359 w1_ds2760_store_eeprom(di->w1_dev, DS2760_EEPROM_BLOCK1); 360 w1_ds2760_recall_eeprom(di->w1_dev, DS2760_EEPROM_BLOCK1); 361 362 /* Write to the di->raw[] buffer directly - the CURRENT_OFFSET_BIAS 363 * value won't be read back by ds2760_battery_read_status() */ 364 di->raw[DS2760_CURRENT_OFFSET_BIAS] = bias; 365} 366 367static void ds2760_battery_set_charged(struct power_supply *psy) 368{ 369 struct ds2760_device_info *di = to_ds2760_device_info(psy); 370 371 /* postpone the actual work by 20 secs. This is for debouncing GPIO 372 * signals and to let the current value settle. See AN4188. */ 373 cancel_delayed_work(&di->set_charged_work); 374 queue_delayed_work(di->monitor_wqueue, &di->set_charged_work, HZ * 20); 375} 376 377static int ds2760_battery_get_property(struct power_supply *psy, 378 enum power_supply_property psp, 379 union power_supply_propval *val) 380{ 381 struct ds2760_device_info *di = to_ds2760_device_info(psy); 382 383 switch (psp) { 384 case POWER_SUPPLY_PROP_STATUS: 385 val->intval = di->charge_status; 386 return 0; 387 default: 388 break; 389 } 390 391 ds2760_battery_read_status(di); 392 393 switch (psp) { 394 case POWER_SUPPLY_PROP_VOLTAGE_NOW: 395 val->intval = di->voltage_uV; 396 break; 397 case POWER_SUPPLY_PROP_CURRENT_NOW: 398 val->intval = di->current_uA; 399 break; 400 case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: 401 val->intval = di->rated_capacity; 402 break; 403 case POWER_SUPPLY_PROP_CHARGE_FULL: 404 val->intval = di->full_active_uAh; 405 break; 406 case POWER_SUPPLY_PROP_CHARGE_EMPTY: 407 val->intval = di->empty_uAh; 408 break; 409 case POWER_SUPPLY_PROP_CHARGE_NOW: 410 val->intval = di->accum_current_uAh; 411 break; 412 case POWER_SUPPLY_PROP_TEMP: 413 val->intval = di->temp_C; 414 break; 415 case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW: 416 val->intval = di->life_sec; 417 break; 418 case POWER_SUPPLY_PROP_CAPACITY: 419 val->intval = di->rem_capacity; 420 break; 421 default: 422 return -EINVAL; 423 } 424 425 return 0; 426} 427 428static enum power_supply_property ds2760_battery_props[] = { 429 POWER_SUPPLY_PROP_STATUS, 430 POWER_SUPPLY_PROP_VOLTAGE_NOW, 431 POWER_SUPPLY_PROP_CURRENT_NOW, 432 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, 433 POWER_SUPPLY_PROP_CHARGE_FULL, 434 POWER_SUPPLY_PROP_CHARGE_EMPTY, 435 POWER_SUPPLY_PROP_CHARGE_NOW, 436 POWER_SUPPLY_PROP_TEMP, 437 POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW, 438 POWER_SUPPLY_PROP_CAPACITY, 439}; 440 441static int ds2760_battery_probe(struct platform_device *pdev) 442{ 443 char status; 444 int retval = 0; 445 struct ds2760_device_info *di; 446 447 di = kzalloc(sizeof(*di), GFP_KERNEL); 448 if (!di) { 449 retval = -ENOMEM; 450 goto di_alloc_failed; 451 } 452 453 platform_set_drvdata(pdev, di); 454 455 di->dev = &pdev->dev; 456 di->w1_dev = pdev->dev.parent; 457 di->bat.name = dev_name(&pdev->dev); 458 di->bat.type = POWER_SUPPLY_TYPE_BATTERY; 459 di->bat.properties = ds2760_battery_props; 460 di->bat.num_properties = ARRAY_SIZE(ds2760_battery_props); 461 di->bat.get_property = ds2760_battery_get_property; 462 di->bat.set_charged = ds2760_battery_set_charged; 463 di->bat.external_power_changed = 464 ds2760_battery_external_power_changed; 465 466 di->charge_status = POWER_SUPPLY_STATUS_UNKNOWN; 467 468 /* enable sleep mode feature */ 469 ds2760_battery_read_status(di); 470 status = di->raw[DS2760_STATUS_REG]; 471 if (pmod_enabled) 472 status |= DS2760_STATUS_PMOD; 473 else 474 status &= ~DS2760_STATUS_PMOD; 475 476 ds2760_battery_write_status(di, status); 477 478 /* set rated capacity from module param */ 479 if (rated_capacity) 480 ds2760_battery_write_rated_capacity(di, rated_capacity); 481 482 /* set current accumulator if given as parameter. 483 * this should only be done for bootstrapping the value */ 484 if (current_accum) 485 ds2760_battery_set_current_accum(di, current_accum); 486 487 retval = power_supply_register(&pdev->dev, &di->bat); 488 if (retval) { 489 dev_err(di->dev, "failed to register battery\n"); 490 goto batt_failed; 491 } 492 493 INIT_DELAYED_WORK(&di->monitor_work, ds2760_battery_work); 494 INIT_DELAYED_WORK(&di->set_charged_work, 495 ds2760_battery_set_charged_work); 496 di->monitor_wqueue = create_singlethread_workqueue(dev_name(&pdev->dev)); 497 if (!di->monitor_wqueue) { 498 retval = -ESRCH; 499 goto workqueue_failed; 500 } 501 queue_delayed_work(di->monitor_wqueue, &di->monitor_work, HZ * 1); 502 503 goto success; 504 505workqueue_failed: 506 power_supply_unregister(&di->bat); 507batt_failed: 508 kfree(di); 509di_alloc_failed: 510success: 511 return retval; 512} 513 514static int ds2760_battery_remove(struct platform_device *pdev) 515{ 516 struct ds2760_device_info *di = platform_get_drvdata(pdev); 517 518 cancel_rearming_delayed_workqueue(di->monitor_wqueue, 519 &di->monitor_work); 520 cancel_rearming_delayed_workqueue(di->monitor_wqueue, 521 &di->set_charged_work); 522 destroy_workqueue(di->monitor_wqueue); 523 power_supply_unregister(&di->bat); 524 525 return 0; 526} 527 528#ifdef CONFIG_PM 529 530static int ds2760_battery_suspend(struct platform_device *pdev, 531 pm_message_t state) 532{ 533 struct ds2760_device_info *di = platform_get_drvdata(pdev); 534 535 di->charge_status = POWER_SUPPLY_STATUS_UNKNOWN; 536 537 return 0; 538} 539 540static int ds2760_battery_resume(struct platform_device *pdev) 541{ 542 struct ds2760_device_info *di = platform_get_drvdata(pdev); 543 544 di->charge_status = POWER_SUPPLY_STATUS_UNKNOWN; 545 power_supply_changed(&di->bat); 546 547 cancel_delayed_work(&di->monitor_work); 548 queue_delayed_work(di->monitor_wqueue, &di->monitor_work, HZ); 549 550 return 0; 551} 552 553#else 554 555#define ds2760_battery_suspend NULL 556#define ds2760_battery_resume NULL 557 558#endif /* CONFIG_PM */ 559 560MODULE_ALIAS("platform:ds2760-battery"); 561 562static struct platform_driver ds2760_battery_driver = { 563 .driver = { 564 .name = "ds2760-battery", 565 }, 566 .probe = ds2760_battery_probe, 567 .remove = ds2760_battery_remove, 568 .suspend = ds2760_battery_suspend, 569 .resume = ds2760_battery_resume, 570}; 571 572static int __init ds2760_battery_init(void) 573{ 574 return platform_driver_register(&ds2760_battery_driver); 575} 576 577static void __exit ds2760_battery_exit(void) 578{ 579 platform_driver_unregister(&ds2760_battery_driver); 580} 581 582module_init(ds2760_battery_init); 583module_exit(ds2760_battery_exit); 584 585MODULE_LICENSE("GPL"); 586MODULE_AUTHOR("Szabolcs Gyurko <szabolcs.gyurko@tlt.hu>, " 587 "Matt Reimer <mreimer@vpop.net>, " 588 "Anton Vorontsov <cbou@mail.ru>"); 589MODULE_DESCRIPTION("ds2760 battery driver"); 590