android_battery.c revision 1e34b11bc23cb33c285455d750852ee7a5df1ef1
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/timer.h> 35#include <linux/platform_data/android_battery.h> 36 37struct android_bat_data { 38 struct android_bat_platform_data *pdata; 39 struct android_bat_callbacks callbacks; 40 41 struct device *dev; 42 43 struct power_supply psy_bat; 44 45 struct wake_lock monitor_wake_lock; 46 struct wake_lock charger_wake_lock; 47 48 int charge_source; 49 50 int batt_temp; 51 int batt_current; 52 unsigned int batt_health; 53 unsigned int batt_vcell; 54 unsigned int batt_soc; 55 unsigned int charging_status; 56 57 struct workqueue_struct *monitor_wqueue; 58 struct delayed_work monitor_work; 59 struct work_struct charger_work; 60 61 bool slow_poll; 62 ktime_t last_poll; 63}; 64 65static enum power_supply_property android_battery_props[] = { 66 POWER_SUPPLY_PROP_STATUS, 67 POWER_SUPPLY_PROP_HEALTH, 68 POWER_SUPPLY_PROP_PRESENT, 69 POWER_SUPPLY_PROP_TEMP, 70 POWER_SUPPLY_PROP_ONLINE, 71 POWER_SUPPLY_PROP_VOLTAGE_NOW, 72 POWER_SUPPLY_PROP_CAPACITY, 73 POWER_SUPPLY_PROP_TECHNOLOGY, 74 POWER_SUPPLY_PROP_CURRENT_NOW, 75}; 76 77static void android_bat_update_data(struct android_bat_data *battery); 78 79static char *charge_source_str(int charge_source) 80{ 81 switch (charge_source) { 82 case CHARGE_SOURCE_NONE: 83 return "none"; 84 case CHARGE_SOURCE_AC: 85 return "ac"; 86 case CHARGE_SOURCE_USB: 87 return "usb"; 88 default: 89 break; 90 } 91 92 return "?"; 93} 94 95static int android_bat_get_property(struct power_supply *ps, 96 enum power_supply_property psp, 97 union power_supply_propval *val) 98{ 99 struct android_bat_data *battery = 100 container_of(ps, struct android_bat_data, psy_bat); 101 102 switch (psp) { 103 case POWER_SUPPLY_PROP_STATUS: 104 val->intval = battery->charging_status; 105 break; 106 case POWER_SUPPLY_PROP_HEALTH: 107 val->intval = battery->batt_health; 108 break; 109 case POWER_SUPPLY_PROP_PRESENT: 110 val->intval = 1; 111 break; 112 case POWER_SUPPLY_PROP_TEMP: 113 val->intval = battery->batt_temp; 114 break; 115 case POWER_SUPPLY_PROP_ONLINE: 116 val->intval = 1; 117 break; 118 case POWER_SUPPLY_PROP_VOLTAGE_NOW: 119 android_bat_update_data(battery); 120 val->intval = battery->batt_vcell; 121 if (val->intval == -1) 122 return -EINVAL; 123 break; 124 case POWER_SUPPLY_PROP_CAPACITY: 125 val->intval = battery->batt_soc; 126 if (val->intval == -1) 127 return -EINVAL; 128 break; 129 case POWER_SUPPLY_PROP_TECHNOLOGY: 130 val->intval = POWER_SUPPLY_TECHNOLOGY_LION; 131 break; 132 case POWER_SUPPLY_PROP_CURRENT_NOW: 133 android_bat_update_data(battery); 134 val->intval = battery->batt_current; 135 break; 136 default: 137 return -EINVAL; 138 } 139 return 0; 140} 141 142static void android_bat_get_temp(struct android_bat_data *battery) 143{ 144 int batt_temp = 25000; 145 int health = battery->batt_health; 146 147 if (battery->pdata->get_temperature) 148 battery->pdata->get_temperature(&batt_temp); 149 150 if (batt_temp >= battery->pdata->temp_high_threshold) { 151 if (health != POWER_SUPPLY_HEALTH_OVERHEAT && 152 health != POWER_SUPPLY_HEALTH_UNSPEC_FAILURE) { 153 pr_info("battery overheat (%d>=%d), charging unavailable\n", 154 batt_temp, battery->pdata->temp_high_threshold); 155 battery->batt_health = POWER_SUPPLY_HEALTH_OVERHEAT; 156 } 157 } else if (batt_temp <= battery->pdata->temp_high_recovery && 158 batt_temp >= battery->pdata->temp_low_recovery) { 159 if (health == POWER_SUPPLY_HEALTH_OVERHEAT || 160 health == POWER_SUPPLY_HEALTH_COLD) { 161 pr_info("battery recovery (%d,%d~%d), charging available\n", 162 batt_temp, battery->pdata->temp_low_recovery, 163 battery->pdata->temp_high_recovery); 164 battery->batt_health = POWER_SUPPLY_HEALTH_GOOD; 165 } 166 } else if (batt_temp <= battery->pdata->temp_low_threshold) { 167 if (health != POWER_SUPPLY_HEALTH_COLD && 168 health != POWER_SUPPLY_HEALTH_UNSPEC_FAILURE) { 169 pr_info("battery cold (%d <= %d), charging unavailable\n", 170 batt_temp, battery->pdata->temp_low_threshold); 171 battery->batt_health = POWER_SUPPLY_HEALTH_COLD; 172 } 173 } 174 175 battery->batt_temp = batt_temp/1000; 176} 177 178static void android_bat_update_data(struct android_bat_data *battery) 179{ 180 int ret; 181 int v; 182 183 if (battery->pdata->poll_charge_source) 184 battery->charge_source = battery->pdata->poll_charge_source(); 185 186 if (battery->pdata->get_voltage_now) { 187 ret = battery->pdata->get_voltage_now(); 188 battery->batt_vcell = ret >= 0 ? ret : -1; 189 } 190 191 if (battery->pdata->get_capacity) { 192 ret = battery->pdata->get_capacity(); 193 battery->batt_soc = ret >= 0 ? ret : -1; 194 } 195 196 if (battery->pdata->get_current_now) { 197 ret = battery->pdata->get_current_now(&v); 198 199 if (!ret) 200 battery->batt_current = v; 201 } 202 203 android_bat_get_temp(battery); 204} 205 206static int android_bat_enable_charging(struct android_bat_data *battery, 207 bool enable) 208{ 209 if (enable && (battery->batt_health != POWER_SUPPLY_HEALTH_GOOD)) { 210 battery->charging_status = 211 POWER_SUPPLY_STATUS_NOT_CHARGING; 212 return -EPERM; 213 } 214 215 if (enable) { 216 if (battery->pdata && battery->pdata->set_charging_current) 217 battery->pdata->set_charging_current 218 (battery->charge_source); 219 } 220 221 if (battery->pdata && battery->pdata->set_charging_enable) 222 battery->pdata->set_charging_enable(enable); 223 224 pr_info("battery: enable=%d charger: %s\n", enable, 225 charge_source_str(battery->charge_source)); 226 227 return 0; 228} 229 230static void android_bat_charge_source_changed(struct android_bat_callbacks *ptr, 231 int charge_source) 232{ 233 struct android_bat_data *battery; 234 235 battery = container_of(ptr, struct android_bat_data, callbacks); 236 wake_lock(&battery->charger_wake_lock); 237 battery->charge_source = charge_source; 238 239 pr_info("battery: charge source type was changed: %s\n", 240 charge_source_str(battery->charge_source)); 241 242 queue_work(battery->monitor_wqueue, &battery->charger_work); 243} 244 245static void android_bat_charger_work(struct work_struct *work) 246{ 247 struct android_bat_data *battery = 248 container_of(work, struct android_bat_data, charger_work); 249 250 switch (battery->charge_source) { 251 case CHARGE_SOURCE_NONE: 252 battery->charging_status = POWER_SUPPLY_STATUS_DISCHARGING; 253 android_bat_enable_charging(battery, false); 254 if (battery->batt_health == POWER_SUPPLY_HEALTH_OVERVOLTAGE) 255 battery->batt_health = POWER_SUPPLY_HEALTH_GOOD; 256 break; 257 case CHARGE_SOURCE_USB: 258 case CHARGE_SOURCE_AC: 259 battery->charging_status = POWER_SUPPLY_STATUS_CHARGING; 260 android_bat_enable_charging(battery, true); 261 break; 262 default: 263 pr_err("%s: Invalid charger type\n", __func__); 264 break; 265 } 266 267 wake_lock_timeout(&battery->charger_wake_lock, HZ * 2); 268} 269 270static void android_bat_monitor_work(struct work_struct *work) 271{ 272 struct android_bat_data *battery; 273 battery = container_of(work, struct android_bat_data, 274 monitor_work.work); 275 276 wake_lock(&battery->monitor_wake_lock); 277 android_bat_update_data(battery); 278 279 switch (battery->charging_status) { 280 case POWER_SUPPLY_STATUS_FULL: 281 case POWER_SUPPLY_STATUS_DISCHARGING: 282 break; 283 case POWER_SUPPLY_STATUS_CHARGING: 284 switch (battery->batt_health) { 285 case POWER_SUPPLY_HEALTH_OVERHEAT: 286 case POWER_SUPPLY_HEALTH_COLD: 287 case POWER_SUPPLY_HEALTH_OVERVOLTAGE: 288 case POWER_SUPPLY_HEALTH_DEAD: 289 case POWER_SUPPLY_HEALTH_UNSPEC_FAILURE: 290 battery->charging_status = 291 POWER_SUPPLY_STATUS_NOT_CHARGING; 292 android_bat_enable_charging(battery, false); 293 294 pr_info("battery: Not charging, health=%d\n", 295 battery->batt_health); 296 break; 297 default: 298 break; 299 } 300 break; 301 case POWER_SUPPLY_STATUS_NOT_CHARGING: 302 if (battery->batt_health == POWER_SUPPLY_HEALTH_GOOD) { 303 pr_info("battery: battery health recovered\n"); 304 if (battery->charge_source != CHARGE_SOURCE_NONE) { 305 android_bat_enable_charging(battery, true); 306 battery->charging_status 307 = POWER_SUPPLY_STATUS_CHARGING; 308 } else 309 battery->charging_status 310 = POWER_SUPPLY_STATUS_DISCHARGING; 311 } 312 break; 313 default: 314 wake_unlock(&battery->monitor_wake_lock); 315 pr_err("%s: Undefined battery status: %d\n", __func__, 316 battery->charging_status); 317 return; 318 } 319 320 pr_info("battery: l=%d v=%d c=%d temp=%d h=%d st=%d type=%s\n", 321 battery->batt_soc, battery->batt_vcell/1000, 322 battery->batt_current, battery->batt_temp, battery->batt_health, 323 battery->charging_status, 324 charge_source_str(battery->charge_source)); 325 power_supply_changed(&battery->psy_bat); 326 queue_delayed_work(battery->monitor_wqueue, 327 &battery->monitor_work, msecs_to_jiffies(50000)); 328 wake_unlock(&battery->monitor_wake_lock); 329 330 return; 331} 332 333static __devinit int android_bat_probe(struct platform_device *pdev) 334{ 335 struct android_bat_platform_data *pdata = dev_get_platdata(&pdev->dev); 336 struct android_bat_data *battery; 337 int ret = 0; 338 339 dev_info(&pdev->dev, "Android Battery Driver\n"); 340 battery = kzalloc(sizeof(*battery), GFP_KERNEL); 341 if (!battery) 342 return -ENOMEM; 343 344 battery->pdata = pdata; 345 if (!battery->pdata) { 346 pr_err("%s : No platform data\n", __func__); 347 ret = -EINVAL; 348 goto err_pdata; 349 } 350 351 battery->dev = &pdev->dev; 352 platform_set_drvdata(pdev, battery); 353 battery->batt_health = POWER_SUPPLY_HEALTH_GOOD; 354 355 battery->psy_bat.name = "android-battery", 356 battery->psy_bat.type = POWER_SUPPLY_TYPE_BATTERY, 357 battery->psy_bat.properties = android_battery_props, 358 battery->psy_bat.num_properties = ARRAY_SIZE(android_battery_props), 359 battery->psy_bat.get_property = android_bat_get_property, 360 361 battery->batt_vcell = -1; 362 battery->batt_soc = -1; 363 364 wake_lock_init(&battery->monitor_wake_lock, WAKE_LOCK_SUSPEND, 365 "android-battery-monitor"); 366 wake_lock_init(&battery->charger_wake_lock, WAKE_LOCK_SUSPEND, 367 "android-chargerdetect"); 368 369 ret = power_supply_register(&pdev->dev, &battery->psy_bat); 370 if (ret) { 371 dev_err(battery->dev, "%s: failed to register psy_bat\n", 372 __func__); 373 goto err_psy_reg; 374 } 375 376 battery->monitor_wqueue = 377 create_singlethread_workqueue(dev_name(&pdev->dev)); 378 if (!battery->monitor_wqueue) { 379 dev_err(battery->dev, "%s: fail to create workqueue\n", 380 __func__); 381 goto err_wq; 382 } 383 384 INIT_DELAYED_WORK_DEFERRABLE(&battery->monitor_work, 385 android_bat_monitor_work); 386 INIT_WORK(&battery->charger_work, android_bat_charger_work); 387 388 battery->callbacks.charge_source_changed = 389 android_bat_charge_source_changed; 390 if (battery->pdata && battery->pdata->register_callbacks) 391 battery->pdata->register_callbacks(&battery->callbacks); 392 393 /* get initial charger status */ 394 if (battery->pdata->poll_charge_source) 395 battery->charge_source = battery->pdata->poll_charge_source(); 396 397 wake_lock(&battery->charger_wake_lock); 398 queue_work(battery->monitor_wqueue, &battery->charger_work); 399 400 queue_delayed_work(battery->monitor_wqueue, 401 &battery->monitor_work, msecs_to_jiffies(0)); 402 return 0; 403 404 405err_wq: 406 power_supply_unregister(&battery->psy_bat); 407err_psy_reg: 408 wake_lock_destroy(&battery->monitor_wake_lock); 409 wake_lock_destroy(&battery->charger_wake_lock); 410err_pdata: 411 kfree(battery); 412 413 return ret; 414} 415 416static int __devexit android_bat_remove(struct platform_device *pdev) 417{ 418 struct android_bat_data *battery = platform_get_drvdata(pdev); 419 420 flush_workqueue(battery->monitor_wqueue); 421 destroy_workqueue(battery->monitor_wqueue); 422 power_supply_unregister(&battery->psy_bat); 423 wake_lock_destroy(&battery->monitor_wake_lock); 424 wake_lock_destroy(&battery->charger_wake_lock); 425 kfree(battery); 426 return 0; 427} 428 429static int android_bat_suspend(struct device *dev) 430{ 431 struct android_bat_data *battery = dev_get_drvdata(dev); 432 433 cancel_delayed_work_sync(&battery->monitor_work); 434 return 0; 435} 436 437static int android_bat_resume(struct device *dev) 438{ 439 struct android_bat_data *battery = dev_get_drvdata(dev); 440 441 queue_delayed_work(battery->monitor_wqueue, 442 &battery->monitor_work, msecs_to_jiffies(0)); 443 return 0; 444} 445 446static const struct dev_pm_ops android_bat_pm_ops = { 447 .suspend = android_bat_suspend, 448 .resume = android_bat_resume, 449}; 450 451static struct platform_driver android_bat_driver = { 452 .driver = { 453 .name = "android-battery", 454 .owner = THIS_MODULE, 455 .pm = &android_bat_pm_ops, 456 }, 457 .probe = android_bat_probe, 458 .remove = __devexit_p(android_bat_remove), 459}; 460 461static int __init android_bat_init(void) 462{ 463 return platform_driver_register(&android_bat_driver); 464} 465 466static void __exit android_bat_exit(void) 467{ 468 platform_driver_unregister(&android_bat_driver); 469} 470 471late_initcall(android_bat_init); 472module_exit(android_bat_exit); 473 474MODULE_DESCRIPTION("Android battery driver"); 475MODULE_LICENSE("GPL"); 476