lp8727_charger.c revision e39b828f5355e41a8fd24f413fb9dfb81d808397
1/* 2 * Driver for LP8727 Micro/Mini USB IC with intergrated charger 3 * 4 * Copyright (C) 2011 Texas Instruments 5 * Copyright (C) 2011 National Semiconductor 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License version 2 as 9 * published by the Free Software Foundation. 10 * 11 */ 12 13#include <linux/module.h> 14#include <linux/slab.h> 15#include <linux/interrupt.h> 16#include <linux/i2c.h> 17#include <linux/power_supply.h> 18#include <linux/lp8727.h> 19 20#define DEBOUNCE_MSEC 270 21 22/* Registers */ 23#define CTRL1 0x1 24#define CTRL2 0x2 25#define SWCTRL 0x3 26#define INT1 0x4 27#define INT2 0x5 28#define STATUS1 0x6 29#define STATUS2 0x7 30#define CHGCTRL2 0x9 31 32/* CTRL1 register */ 33#define CP_EN (1 << 0) 34#define ADC_EN (1 << 1) 35#define ID200_EN (1 << 4) 36 37/* CTRL2 register */ 38#define CHGDET_EN (1 << 1) 39#define INT_EN (1 << 6) 40 41/* SWCTRL register */ 42#define SW_DM1_DM (0x0 << 0) 43#define SW_DM1_U1 (0x1 << 0) 44#define SW_DM1_HiZ (0x7 << 0) 45#define SW_DP2_DP (0x0 << 3) 46#define SW_DP2_U2 (0x1 << 3) 47#define SW_DP2_HiZ (0x7 << 3) 48 49/* INT1 register */ 50#define IDNO (0xF << 0) 51#define VBUS (1 << 4) 52 53/* STATUS1 register */ 54#define CHGSTAT (3 << 4) 55#define CHPORT (1 << 6) 56#define DCPORT (1 << 7) 57 58/* STATUS2 register */ 59#define TEMP_STAT (3 << 5) 60 61enum lp8727_dev_id { 62 ID_NONE, 63 ID_TA, 64 ID_DEDICATED_CHG, 65 ID_USB_CHG, 66 ID_USB_DS, 67 ID_MAX, 68}; 69 70enum lp8727_chg_stat { 71 PRECHG, 72 CC, 73 CV, 74 EOC, 75}; 76 77struct lp8727_psy { 78 struct power_supply ac; 79 struct power_supply usb; 80 struct power_supply batt; 81}; 82 83struct lp8727_chg { 84 struct device *dev; 85 struct i2c_client *client; 86 struct mutex xfer_lock; 87 struct delayed_work work; 88 struct workqueue_struct *irqthread; 89 struct lp8727_platform_data *pdata; 90 struct lp8727_psy *psy; 91 struct lp8727_chg_param *chg_parm; 92 enum lp8727_dev_id devid; 93}; 94 95static int lp8727_i2c_read(struct lp8727_chg *pchg, u8 reg, u8 *data, u8 len) 96{ 97 s32 ret; 98 99 mutex_lock(&pchg->xfer_lock); 100 ret = i2c_smbus_read_i2c_block_data(pchg->client, reg, len, data); 101 mutex_unlock(&pchg->xfer_lock); 102 103 return (ret != len) ? -EIO : 0; 104} 105 106static int lp8727_i2c_write(struct lp8727_chg *pchg, u8 reg, u8 *data, u8 len) 107{ 108 s32 ret; 109 110 mutex_lock(&pchg->xfer_lock); 111 ret = i2c_smbus_write_i2c_block_data(pchg->client, reg, len, data); 112 mutex_unlock(&pchg->xfer_lock); 113 114 return ret; 115} 116 117static inline int lp8727_i2c_read_byte(struct lp8727_chg *pchg, u8 reg, 118 u8 *data) 119{ 120 return lp8727_i2c_read(pchg, reg, data, 1); 121} 122 123static inline int lp8727_i2c_write_byte(struct lp8727_chg *pchg, u8 reg, 124 u8 *data) 125{ 126 return lp8727_i2c_write(pchg, reg, data, 1); 127} 128 129static int lp8727_is_charger_attached(const char *name, int id) 130{ 131 if (name) { 132 if (!strcmp(name, "ac")) 133 return (id == ID_TA || id == ID_DEDICATED_CHG) ? 1 : 0; 134 else if (!strcmp(name, "usb")) 135 return (id == ID_USB_CHG) ? 1 : 0; 136 } 137 138 return (id >= ID_TA && id <= ID_USB_CHG) ? 1 : 0; 139} 140 141static void lp8727_init_device(struct lp8727_chg *pchg) 142{ 143 u8 val; 144 145 val = ID200_EN | ADC_EN | CP_EN; 146 if (lp8727_i2c_write_byte(pchg, CTRL1, &val)) 147 dev_err(pchg->dev, "i2c write err : addr=0x%.2x\n", CTRL1); 148 149 val = INT_EN | CHGDET_EN; 150 if (lp8727_i2c_write_byte(pchg, CTRL2, &val)) 151 dev_err(pchg->dev, "i2c write err : addr=0x%.2x\n", CTRL2); 152} 153 154static int lp8727_is_dedicated_charger(struct lp8727_chg *pchg) 155{ 156 u8 val; 157 lp8727_i2c_read_byte(pchg, STATUS1, &val); 158 return (val & DCPORT); 159} 160 161static int lp8727_is_usb_charger(struct lp8727_chg *pchg) 162{ 163 u8 val; 164 lp8727_i2c_read_byte(pchg, STATUS1, &val); 165 return (val & CHPORT); 166} 167 168static void lp8727_ctrl_switch(struct lp8727_chg *pchg, u8 sw) 169{ 170 u8 val = sw; 171 lp8727_i2c_write_byte(pchg, SWCTRL, &val); 172} 173 174static void lp8727_id_detection(struct lp8727_chg *pchg, u8 id, int vbusin) 175{ 176 u8 devid = ID_NONE; 177 u8 swctrl = SW_DM1_HiZ | SW_DP2_HiZ; 178 179 switch (id) { 180 case 0x5: 181 devid = ID_TA; 182 pchg->chg_parm = &pchg->pdata->ac; 183 break; 184 case 0xB: 185 if (lp8727_is_dedicated_charger(pchg)) { 186 pchg->chg_parm = &pchg->pdata->ac; 187 devid = ID_DEDICATED_CHG; 188 } else if (lp8727_is_usb_charger(pchg)) { 189 pchg->chg_parm = &pchg->pdata->usb; 190 devid = ID_USB_CHG; 191 swctrl = SW_DM1_DM | SW_DP2_DP; 192 } else if (vbusin) { 193 devid = ID_USB_DS; 194 swctrl = SW_DM1_DM | SW_DP2_DP; 195 } 196 break; 197 default: 198 devid = ID_NONE; 199 pchg->chg_parm = NULL; 200 break; 201 } 202 203 pchg->devid = devid; 204 lp8727_ctrl_switch(pchg, swctrl); 205} 206 207static void lp8727_enable_chgdet(struct lp8727_chg *pchg) 208{ 209 u8 val; 210 211 lp8727_i2c_read_byte(pchg, CTRL2, &val); 212 val |= CHGDET_EN; 213 lp8727_i2c_write_byte(pchg, CTRL2, &val); 214} 215 216static void lp8727_delayed_func(struct work_struct *_work) 217{ 218 u8 intstat[2], idno, vbus; 219 struct lp8727_chg *pchg = 220 container_of(_work, struct lp8727_chg, work.work); 221 222 if (lp8727_i2c_read(pchg, INT1, intstat, 2)) { 223 dev_err(pchg->dev, "can not read INT registers\n"); 224 return; 225 } 226 227 idno = intstat[0] & IDNO; 228 vbus = intstat[0] & VBUS; 229 230 lp8727_id_detection(pchg, idno, vbus); 231 lp8727_enable_chgdet(pchg); 232 233 power_supply_changed(&pchg->psy->ac); 234 power_supply_changed(&pchg->psy->usb); 235 power_supply_changed(&pchg->psy->batt); 236} 237 238static irqreturn_t lp8727_isr_func(int irq, void *ptr) 239{ 240 struct lp8727_chg *pchg = ptr; 241 unsigned long delay = msecs_to_jiffies(DEBOUNCE_MSEC); 242 243 queue_delayed_work(pchg->irqthread, &pchg->work, delay); 244 245 return IRQ_HANDLED; 246} 247 248static void lp8727_intr_config(struct lp8727_chg *pchg) 249{ 250 INIT_DELAYED_WORK(&pchg->work, lp8727_delayed_func); 251 252 pchg->irqthread = create_singlethread_workqueue("lp8727-irqthd"); 253 if (!pchg->irqthread) 254 dev_err(pchg->dev, "can not create thread for lp8727\n"); 255 256 if (request_threaded_irq(pchg->client->irq, 257 NULL, 258 lp8727_isr_func, 259 IRQF_TRIGGER_FALLING, "lp8727_irq", pchg)) { 260 dev_err(pchg->dev, "lp8727 irq can not be registered\n"); 261 } 262} 263 264static enum power_supply_property lp8727_charger_prop[] = { 265 POWER_SUPPLY_PROP_ONLINE, 266}; 267 268static enum power_supply_property lp8727_battery_prop[] = { 269 POWER_SUPPLY_PROP_STATUS, 270 POWER_SUPPLY_PROP_HEALTH, 271 POWER_SUPPLY_PROP_PRESENT, 272 POWER_SUPPLY_PROP_VOLTAGE_NOW, 273 POWER_SUPPLY_PROP_CAPACITY, 274 POWER_SUPPLY_PROP_TEMP, 275}; 276 277static char *battery_supplied_to[] = { 278 "main_batt", 279}; 280 281static int lp8727_charger_get_property(struct power_supply *psy, 282 enum power_supply_property psp, 283 union power_supply_propval *val) 284{ 285 struct lp8727_chg *pchg = dev_get_drvdata(psy->dev->parent); 286 287 if (psp == POWER_SUPPLY_PROP_ONLINE) 288 val->intval = lp8727_is_charger_attached(psy->name, 289 pchg->devid); 290 291 return 0; 292} 293 294static int lp8727_battery_get_property(struct power_supply *psy, 295 enum power_supply_property psp, 296 union power_supply_propval *val) 297{ 298 struct lp8727_chg *pchg = dev_get_drvdata(psy->dev->parent); 299 u8 read; 300 301 switch (psp) { 302 case POWER_SUPPLY_PROP_STATUS: 303 if (lp8727_is_charger_attached(psy->name, pchg->devid)) { 304 lp8727_i2c_read_byte(pchg, STATUS1, &read); 305 if (((read & CHGSTAT) >> 4) == EOC) 306 val->intval = POWER_SUPPLY_STATUS_FULL; 307 else 308 val->intval = POWER_SUPPLY_STATUS_CHARGING; 309 } else { 310 val->intval = POWER_SUPPLY_STATUS_DISCHARGING; 311 } 312 break; 313 case POWER_SUPPLY_PROP_HEALTH: 314 lp8727_i2c_read_byte(pchg, STATUS2, &read); 315 read = (read & TEMP_STAT) >> 5; 316 if (read >= 0x1 && read <= 0x3) 317 val->intval = POWER_SUPPLY_HEALTH_OVERHEAT; 318 else 319 val->intval = POWER_SUPPLY_HEALTH_GOOD; 320 break; 321 case POWER_SUPPLY_PROP_PRESENT: 322 if (pchg->pdata->get_batt_present) 323 val->intval = pchg->pdata->get_batt_present(); 324 break; 325 case POWER_SUPPLY_PROP_VOLTAGE_NOW: 326 if (pchg->pdata->get_batt_level) 327 val->intval = pchg->pdata->get_batt_level(); 328 break; 329 case POWER_SUPPLY_PROP_CAPACITY: 330 if (pchg->pdata->get_batt_capacity) 331 val->intval = pchg->pdata->get_batt_capacity(); 332 break; 333 case POWER_SUPPLY_PROP_TEMP: 334 if (pchg->pdata->get_batt_temp) 335 val->intval = pchg->pdata->get_batt_temp(); 336 break; 337 default: 338 break; 339 } 340 341 return 0; 342} 343 344static void lp8727_charger_changed(struct power_supply *psy) 345{ 346 struct lp8727_chg *pchg = dev_get_drvdata(psy->dev->parent); 347 u8 val; 348 u8 eoc_level, ichg; 349 350 if (lp8727_is_charger_attached(psy->name, pchg->devid)) { 351 if (pchg->chg_parm) { 352 eoc_level = pchg->chg_parm->eoc_level; 353 ichg = pchg->chg_parm->ichg; 354 val = (ichg << 4) | eoc_level; 355 lp8727_i2c_write_byte(pchg, CHGCTRL2, &val); 356 } 357 } 358} 359 360static int lp8727_register_psy(struct lp8727_chg *pchg) 361{ 362 struct lp8727_psy *psy; 363 364 psy = kzalloc(sizeof(*psy), GFP_KERNEL); 365 if (!psy) 366 goto err_mem; 367 368 pchg->psy = psy; 369 370 psy->ac.name = "ac"; 371 psy->ac.type = POWER_SUPPLY_TYPE_MAINS; 372 psy->ac.properties = lp8727_charger_prop; 373 psy->ac.num_properties = ARRAY_SIZE(lp8727_charger_prop); 374 psy->ac.get_property = lp8727_charger_get_property; 375 psy->ac.supplied_to = battery_supplied_to; 376 psy->ac.num_supplicants = ARRAY_SIZE(battery_supplied_to); 377 378 if (power_supply_register(pchg->dev, &psy->ac)) 379 goto err_psy; 380 381 psy->usb.name = "usb"; 382 psy->usb.type = POWER_SUPPLY_TYPE_USB; 383 psy->usb.properties = lp8727_charger_prop; 384 psy->usb.num_properties = ARRAY_SIZE(lp8727_charger_prop); 385 psy->usb.get_property = lp8727_charger_get_property; 386 psy->usb.supplied_to = battery_supplied_to; 387 psy->usb.num_supplicants = ARRAY_SIZE(battery_supplied_to); 388 389 if (power_supply_register(pchg->dev, &psy->usb)) 390 goto err_psy; 391 392 psy->batt.name = "main_batt"; 393 psy->batt.type = POWER_SUPPLY_TYPE_BATTERY; 394 psy->batt.properties = lp8727_battery_prop; 395 psy->batt.num_properties = ARRAY_SIZE(lp8727_battery_prop); 396 psy->batt.get_property = lp8727_battery_get_property; 397 psy->batt.external_power_changed = lp8727_charger_changed; 398 399 if (power_supply_register(pchg->dev, &psy->batt)) 400 goto err_psy; 401 402 return 0; 403 404err_mem: 405 return -ENOMEM; 406err_psy: 407 kfree(psy); 408 return -EPERM; 409} 410 411static void lp8727_unregister_psy(struct lp8727_chg *pchg) 412{ 413 struct lp8727_psy *psy = pchg->psy; 414 415 if (!psy) 416 return; 417 418 power_supply_unregister(&psy->ac); 419 power_supply_unregister(&psy->usb); 420 power_supply_unregister(&psy->batt); 421 kfree(psy); 422} 423 424static int lp8727_probe(struct i2c_client *cl, const struct i2c_device_id *id) 425{ 426 struct lp8727_chg *pchg; 427 int ret; 428 429 if (!i2c_check_functionality(cl->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) 430 return -EIO; 431 432 pchg = kzalloc(sizeof(*pchg), GFP_KERNEL); 433 if (!pchg) 434 return -ENOMEM; 435 436 pchg->client = cl; 437 pchg->dev = &cl->dev; 438 pchg->pdata = cl->dev.platform_data; 439 i2c_set_clientdata(cl, pchg); 440 441 mutex_init(&pchg->xfer_lock); 442 443 lp8727_init_device(pchg); 444 lp8727_intr_config(pchg); 445 446 ret = lp8727_register_psy(pchg); 447 if (ret) 448 dev_err(pchg->dev, 449 "can not register power supplies. err=%d", ret); 450 451 return 0; 452} 453 454static int __devexit lp8727_remove(struct i2c_client *cl) 455{ 456 struct lp8727_chg *pchg = i2c_get_clientdata(cl); 457 458 lp8727_unregister_psy(pchg); 459 free_irq(pchg->client->irq, pchg); 460 flush_workqueue(pchg->irqthread); 461 destroy_workqueue(pchg->irqthread); 462 kfree(pchg); 463 return 0; 464} 465 466static const struct i2c_device_id lp8727_ids[] = { 467 {"lp8727", 0}, 468 { } 469}; 470 471static struct i2c_driver lp8727_driver = { 472 .driver = { 473 .name = "lp8727", 474 }, 475 .probe = lp8727_probe, 476 .remove = __devexit_p(lp8727_remove), 477 .id_table = lp8727_ids, 478}; 479 480static int __init lp8727_init(void) 481{ 482 return i2c_add_driver(&lp8727_driver); 483} 484 485static void __exit lp8727_exit(void) 486{ 487 i2c_del_driver(&lp8727_driver); 488} 489 490module_init(lp8727_init); 491module_exit(lp8727_exit); 492 493MODULE_DESCRIPTION("TI/National Semiconductor LP8727 charger driver"); 494MODULE_AUTHOR 495 ("Woogyom Kim <milo.kim@ti.com>, Daniel Jeong <daniel.jeong@ti.com>"); 496MODULE_LICENSE("GPL"); 497