android_battery.c revision cf3bfd9426609a72cc480ff2ce4b5168ed900e6b
1/* 2 * android_battery.c 3 * Android Battery Driver 4 * 5 * Copyright (C) 2012 Google, Inc. 6 * Copyright (C) 2012 Samsung Electronics 7 * 8 * Based on work by himihee.seo@samsung.com, ms925.kim@samsung.com, and 9 * joshua.chang@samsung.com. 10 * 11 * This software is licensed under the terms of the GNU General Public 12 * License version 2, as published by the Free Software Foundation, and 13 * may be copied, distributed, and modified under those terms. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 */ 20 21#include <linux/types.h> 22#include <linux/module.h> 23#include <linux/delay.h> 24#include <linux/err.h> 25#include <linux/init.h> 26#include <linux/interrupt.h> 27#include <linux/io.h> 28#include <linux/jiffies.h> 29#include <linux/platform_device.h> 30#include <linux/power_supply.h> 31#include <linux/slab.h> 32#include <linux/wakelock.h> 33#include <linux/workqueue.h> 34#include <linux/alarmtimer.h> 35#include <linux/timer.h> 36#include <linux/debugfs.h> 37#include <linux/platform_data/android_battery.h> 38 39#define FAST_POLL (1 * 60) 40#define SLOW_POLL (10 * 60) 41 42struct android_bat_data { 43 struct android_bat_platform_data *pdata; 44 struct android_bat_callbacks callbacks; 45 46 struct device *dev; 47 48 struct power_supply psy_bat; 49 50 struct wake_lock monitor_wake_lock; 51 struct wake_lock charger_wake_lock; 52 53 int charge_source; 54 55 int batt_temp; 56 int batt_current; 57 unsigned int batt_health; 58 unsigned int batt_vcell; 59 unsigned int batt_soc; 60 unsigned int charging_status; 61 62 struct workqueue_struct *monitor_wqueue; 63 struct work_struct monitor_work; 64 struct work_struct charger_work; 65 66 struct alarm monitor_alarm; 67 ktime_t last_poll; 68 69 struct dentry *debugfs_entry; 70}; 71 72static enum power_supply_property android_battery_props[] = { 73 POWER_SUPPLY_PROP_STATUS, 74 POWER_SUPPLY_PROP_HEALTH, 75 POWER_SUPPLY_PROP_PRESENT, 76 POWER_SUPPLY_PROP_TEMP, 77 POWER_SUPPLY_PROP_ONLINE, 78 POWER_SUPPLY_PROP_VOLTAGE_NOW, 79 POWER_SUPPLY_PROP_CAPACITY, 80 POWER_SUPPLY_PROP_TECHNOLOGY, 81 POWER_SUPPLY_PROP_CURRENT_NOW, 82}; 83 84static void android_bat_update_data(struct android_bat_data *battery); 85 86static char *charge_source_str(int charge_source) 87{ 88 switch (charge_source) { 89 case CHARGE_SOURCE_NONE: 90 return "none"; 91 case CHARGE_SOURCE_AC: 92 return "ac"; 93 case CHARGE_SOURCE_USB: 94 return "usb"; 95 default: 96 break; 97 } 98 99 return "?"; 100} 101 102static int android_bat_get_property(struct power_supply *ps, 103 enum power_supply_property psp, 104 union power_supply_propval *val) 105{ 106 struct android_bat_data *battery = 107 container_of(ps, struct android_bat_data, psy_bat); 108 109 switch (psp) { 110 case POWER_SUPPLY_PROP_STATUS: 111 val->intval = battery->charging_status; 112 break; 113 case POWER_SUPPLY_PROP_HEALTH: 114 val->intval = battery->batt_health; 115 break; 116 case POWER_SUPPLY_PROP_PRESENT: 117 val->intval = 1; 118 break; 119 case POWER_SUPPLY_PROP_TEMP: 120 val->intval = battery->batt_temp; 121 break; 122 case POWER_SUPPLY_PROP_ONLINE: 123 val->intval = 1; 124 break; 125 case POWER_SUPPLY_PROP_VOLTAGE_NOW: 126 android_bat_update_data(battery); 127 val->intval = battery->batt_vcell; 128 if (val->intval == -1) 129 return -EINVAL; 130 break; 131 case POWER_SUPPLY_PROP_CAPACITY: 132 val->intval = battery->batt_soc; 133 if (val->intval == -1) 134 return -EINVAL; 135 break; 136 case POWER_SUPPLY_PROP_TECHNOLOGY: 137 val->intval = POWER_SUPPLY_TECHNOLOGY_LION; 138 break; 139 case POWER_SUPPLY_PROP_CURRENT_NOW: 140 android_bat_update_data(battery); 141 val->intval = battery->batt_current; 142 break; 143 default: 144 return -EINVAL; 145 } 146 return 0; 147} 148 149static void android_bat_get_temp(struct android_bat_data *battery) 150{ 151 int batt_temp = 250000; /* 25.0C */ 152 int health = battery->batt_health; 153 154 if (battery->pdata->get_temperature) 155 battery->pdata->get_temperature(&batt_temp); 156 157 if (batt_temp >= battery->pdata->temp_high_threshold) { 158 if (health != POWER_SUPPLY_HEALTH_OVERHEAT && 159 health != POWER_SUPPLY_HEALTH_UNSPEC_FAILURE) { 160 pr_info("battery overheat (%d>=%d), charging unavailable\n", 161 batt_temp, battery->pdata->temp_high_threshold); 162 battery->batt_health = POWER_SUPPLY_HEALTH_OVERHEAT; 163 } 164 } else if (batt_temp <= battery->pdata->temp_high_recovery && 165 batt_temp >= battery->pdata->temp_low_recovery) { 166 if (health == POWER_SUPPLY_HEALTH_OVERHEAT || 167 health == POWER_SUPPLY_HEALTH_COLD) { 168 pr_info("battery recovery (%d,%d~%d), charging available\n", 169 batt_temp, battery->pdata->temp_low_recovery, 170 battery->pdata->temp_high_recovery); 171 battery->batt_health = POWER_SUPPLY_HEALTH_GOOD; 172 } 173 } else if (batt_temp <= battery->pdata->temp_low_threshold) { 174 if (health != POWER_SUPPLY_HEALTH_COLD && 175 health != POWER_SUPPLY_HEALTH_UNSPEC_FAILURE) { 176 pr_info("battery cold (%d <= %d), charging unavailable\n", 177 batt_temp, battery->pdata->temp_low_threshold); 178 battery->batt_health = POWER_SUPPLY_HEALTH_COLD; 179 } 180 } 181 182 battery->batt_temp = batt_temp/1000; 183} 184 185static void android_bat_update_data(struct android_bat_data *battery) 186{ 187 int ret; 188 int v; 189 190 if (battery->pdata->poll_charge_source) 191 battery->charge_source = battery->pdata->poll_charge_source(); 192 193 if (battery->pdata->get_voltage_now) { 194 ret = battery->pdata->get_voltage_now(); 195 battery->batt_vcell = ret >= 0 ? ret : -1; 196 } 197 198 if (battery->pdata->get_capacity) { 199 ret = battery->pdata->get_capacity(); 200 battery->batt_soc = ret >= 0 ? ret : -1; 201 } 202 203 if (battery->pdata->get_current_now) { 204 ret = battery->pdata->get_current_now(&v); 205 206 if (!ret) 207 battery->batt_current = v; 208 } 209 210 android_bat_get_temp(battery); 211} 212 213static int android_bat_enable_charging(struct android_bat_data *battery, 214 bool enable) 215{ 216 if (enable && (battery->batt_health != POWER_SUPPLY_HEALTH_GOOD)) { 217 battery->charging_status = 218 POWER_SUPPLY_STATUS_NOT_CHARGING; 219 return -EPERM; 220 } 221 222 if (enable) { 223 if (battery->pdata && battery->pdata->set_charging_current) 224 battery->pdata->set_charging_current 225 (battery->charge_source); 226 } 227 228 if (battery->pdata && battery->pdata->set_charging_enable) 229 battery->pdata->set_charging_enable(enable); 230 231 pr_info("battery: enable=%d charger: %s\n", enable, 232 charge_source_str(battery->charge_source)); 233 234 return 0; 235} 236 237static void android_bat_charge_source_changed(struct android_bat_callbacks *ptr, 238 int charge_source) 239{ 240 struct android_bat_data *battery; 241 242 battery = container_of(ptr, struct android_bat_data, callbacks); 243 wake_lock(&battery->charger_wake_lock); 244 battery->charge_source = charge_source; 245 246 pr_info("battery: charge source type was changed: %s\n", 247 charge_source_str(battery->charge_source)); 248 249 queue_work(battery->monitor_wqueue, &battery->charger_work); 250} 251 252static void android_bat_charger_work(struct work_struct *work) 253{ 254 struct android_bat_data *battery = 255 container_of(work, struct android_bat_data, charger_work); 256 257 switch (battery->charge_source) { 258 case CHARGE_SOURCE_NONE: 259 battery->charging_status = POWER_SUPPLY_STATUS_DISCHARGING; 260 android_bat_enable_charging(battery, false); 261 if (battery->batt_health == POWER_SUPPLY_HEALTH_OVERVOLTAGE) 262 battery->batt_health = POWER_SUPPLY_HEALTH_GOOD; 263 break; 264 case CHARGE_SOURCE_USB: 265 case CHARGE_SOURCE_AC: 266 battery->charging_status = POWER_SUPPLY_STATUS_CHARGING; 267 android_bat_enable_charging(battery, true); 268 break; 269 default: 270 pr_err("%s: Invalid charger type\n", __func__); 271 break; 272 } 273 274 wake_lock_timeout(&battery->charger_wake_lock, HZ * 2); 275} 276 277 278static void android_bat_monitor_set_alarm(struct android_bat_data *battery, 279 int seconds) 280{ 281 alarm_start(&battery->monitor_alarm, 282 ktime_add(battery->last_poll, ktime_set(seconds, 0))); 283} 284 285static void android_bat_monitor_work(struct work_struct *work) 286{ 287 struct android_bat_data *battery; 288 battery = container_of(work, struct android_bat_data, monitor_work); 289 290 wake_lock(&battery->monitor_wake_lock); 291 android_bat_update_data(battery); 292 293 switch (battery->charging_status) { 294 case POWER_SUPPLY_STATUS_FULL: 295 case POWER_SUPPLY_STATUS_DISCHARGING: 296 break; 297 case POWER_SUPPLY_STATUS_CHARGING: 298 switch (battery->batt_health) { 299 case POWER_SUPPLY_HEALTH_OVERHEAT: 300 case POWER_SUPPLY_HEALTH_COLD: 301 case POWER_SUPPLY_HEALTH_OVERVOLTAGE: 302 case POWER_SUPPLY_HEALTH_DEAD: 303 case POWER_SUPPLY_HEALTH_UNSPEC_FAILURE: 304 battery->charging_status = 305 POWER_SUPPLY_STATUS_NOT_CHARGING; 306 android_bat_enable_charging(battery, false); 307 308 pr_info("battery: Not charging, health=%d\n", 309 battery->batt_health); 310 break; 311 default: 312 break; 313 } 314 break; 315 case POWER_SUPPLY_STATUS_NOT_CHARGING: 316 if (battery->batt_health == POWER_SUPPLY_HEALTH_GOOD) { 317 pr_info("battery: battery health recovered\n"); 318 if (battery->charge_source != CHARGE_SOURCE_NONE) { 319 android_bat_enable_charging(battery, true); 320 battery->charging_status 321 = POWER_SUPPLY_STATUS_CHARGING; 322 } else 323 battery->charging_status 324 = POWER_SUPPLY_STATUS_DISCHARGING; 325 } 326 break; 327 default: 328 pr_err("%s: Undefined battery status: %d\n", __func__, 329 battery->charging_status); 330 break; 331 } 332 333 pr_info("battery: l=%d v=%d c=%d temp=%s%ld.%ld h=%d st=%d type=%s\n", 334 battery->batt_soc, battery->batt_vcell/1000, 335 battery->batt_current, battery->batt_temp < 0 ? "-" : "", 336 abs(battery->batt_temp / 10), abs(battery->batt_temp % 10), 337 battery->batt_health, battery->charging_status, 338 charge_source_str(battery->charge_source)); 339 power_supply_changed(&battery->psy_bat); 340 battery->last_poll = ktime_get_boottime(); 341 android_bat_monitor_set_alarm(battery, FAST_POLL); 342 wake_unlock(&battery->monitor_wake_lock); 343 return; 344} 345 346static enum alarmtimer_restart android_bat_monitor_alarm( 347 struct alarm *alarm, ktime_t now) 348{ 349 struct android_bat_data *battery = 350 container_of(alarm, struct android_bat_data, monitor_alarm); 351 352 wake_lock(&battery->monitor_wake_lock); 353 queue_work(battery->monitor_wqueue, &battery->monitor_work); 354 return ALARMTIMER_NORESTART; 355} 356 357static int android_power_debug_dump(struct seq_file *s, void *unused) 358{ 359 struct android_bat_data *battery = s->private; 360 361 android_bat_update_data(battery); 362 seq_printf(s, "l=%d v=%d c=%d temp=%d h=%d st=%d type=%s\n", 363 battery->batt_soc, battery->batt_vcell/1000, 364 battery->batt_current, battery->batt_temp, 365 battery->batt_health, battery->charging_status, 366 charge_source_str(battery->charge_source)); 367 368 return 0; 369} 370 371static int android_power_debug_open(struct inode *inode, struct file *file) 372{ 373 return single_open(file, android_power_debug_dump, inode->i_private); 374} 375 376static const struct file_operations android_power_debug_fops = { 377 .open = android_power_debug_open, 378 .read = seq_read, 379 .llseek = seq_lseek, 380 .release = single_release, 381}; 382 383static __devinit int android_bat_probe(struct platform_device *pdev) 384{ 385 struct android_bat_platform_data *pdata = dev_get_platdata(&pdev->dev); 386 struct android_bat_data *battery; 387 int ret = 0; 388 389 dev_info(&pdev->dev, "Android Battery Driver\n"); 390 battery = kzalloc(sizeof(*battery), GFP_KERNEL); 391 if (!battery) 392 return -ENOMEM; 393 394 battery->pdata = pdata; 395 if (!battery->pdata) { 396 pr_err("%s : No platform data\n", __func__); 397 ret = -EINVAL; 398 goto err_pdata; 399 } 400 401 battery->dev = &pdev->dev; 402 platform_set_drvdata(pdev, battery); 403 battery->batt_health = POWER_SUPPLY_HEALTH_GOOD; 404 405 battery->psy_bat.name = "android-battery", 406 battery->psy_bat.type = POWER_SUPPLY_TYPE_BATTERY, 407 battery->psy_bat.properties = android_battery_props, 408 battery->psy_bat.num_properties = ARRAY_SIZE(android_battery_props), 409 battery->psy_bat.get_property = android_bat_get_property, 410 411 battery->batt_vcell = -1; 412 battery->batt_soc = -1; 413 414 wake_lock_init(&battery->monitor_wake_lock, WAKE_LOCK_SUSPEND, 415 "android-battery-monitor"); 416 wake_lock_init(&battery->charger_wake_lock, WAKE_LOCK_SUSPEND, 417 "android-chargerdetect"); 418 419 ret = power_supply_register(&pdev->dev, &battery->psy_bat); 420 if (ret) { 421 dev_err(battery->dev, "%s: failed to register psy_bat\n", 422 __func__); 423 goto err_psy_reg; 424 } 425 426 battery->monitor_wqueue = 427 create_singlethread_workqueue(dev_name(&pdev->dev)); 428 if (!battery->monitor_wqueue) { 429 dev_err(battery->dev, "%s: fail to create workqueue\n", 430 __func__); 431 goto err_wq; 432 } 433 434 INIT_WORK(&battery->monitor_work, android_bat_monitor_work); 435 INIT_WORK(&battery->charger_work, android_bat_charger_work); 436 437 battery->callbacks.charge_source_changed = 438 android_bat_charge_source_changed; 439 if (battery->pdata && battery->pdata->register_callbacks) 440 battery->pdata->register_callbacks(&battery->callbacks); 441 442 /* get initial charger status */ 443 if (battery->pdata->poll_charge_source) 444 battery->charge_source = battery->pdata->poll_charge_source(); 445 446 wake_lock(&battery->charger_wake_lock); 447 queue_work(battery->monitor_wqueue, &battery->charger_work); 448 449 wake_lock(&battery->monitor_wake_lock); 450 battery->last_poll = ktime_get_boottime(); 451 alarm_init(&battery->monitor_alarm, ALARM_BOOTTIME, 452 android_bat_monitor_alarm); 453 queue_work(battery->monitor_wqueue, &battery->monitor_work); 454 455 battery->debugfs_entry = 456 debugfs_create_file("android-power", S_IRUGO, NULL, 457 battery, &android_power_debug_fops); 458 if (!battery->debugfs_entry) 459 pr_err("failed to create android-power debugfs entry\n"); 460 461 return 0; 462 463err_wq: 464 power_supply_unregister(&battery->psy_bat); 465err_psy_reg: 466 wake_lock_destroy(&battery->monitor_wake_lock); 467 wake_lock_destroy(&battery->charger_wake_lock); 468err_pdata: 469 kfree(battery); 470 471 return ret; 472} 473 474static int __devexit android_bat_remove(struct platform_device *pdev) 475{ 476 struct android_bat_data *battery = platform_get_drvdata(pdev); 477 478 alarm_cancel(&battery->monitor_alarm); 479 flush_workqueue(battery->monitor_wqueue); 480 destroy_workqueue(battery->monitor_wqueue); 481 power_supply_unregister(&battery->psy_bat); 482 wake_lock_destroy(&battery->monitor_wake_lock); 483 wake_lock_destroy(&battery->charger_wake_lock); 484 debugfs_remove(battery->debugfs_entry); 485 kfree(battery); 486 return 0; 487} 488 489static int android_bat_suspend(struct device *dev) 490{ 491 struct android_bat_data *battery = dev_get_drvdata(dev); 492 493 cancel_work_sync(&battery->monitor_work); 494 android_bat_monitor_set_alarm(battery, SLOW_POLL); 495 return 0; 496} 497 498static int android_bat_resume(struct device *dev) 499{ 500 struct android_bat_data *battery = dev_get_drvdata(dev); 501 502 android_bat_monitor_set_alarm(battery, FAST_POLL); 503 return 0; 504} 505 506static const struct dev_pm_ops android_bat_pm_ops = { 507 .suspend = android_bat_suspend, 508 .resume = android_bat_resume, 509}; 510 511static struct platform_driver android_bat_driver = { 512 .driver = { 513 .name = "android-battery", 514 .owner = THIS_MODULE, 515 .pm = &android_bat_pm_ops, 516 }, 517 .probe = android_bat_probe, 518 .remove = __devexit_p(android_bat_remove), 519}; 520 521static int __init android_bat_init(void) 522{ 523 return platform_driver_register(&android_bat_driver); 524} 525 526static void __exit android_bat_exit(void) 527{ 528 platform_driver_unregister(&android_bat_driver); 529} 530 531late_initcall(android_bat_init); 532module_exit(android_bat_exit); 533 534MODULE_DESCRIPTION("Android battery driver"); 535MODULE_LICENSE("GPL"); 536