Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.13 620 lines 14 kB view raw
1/* 2 * Driver for LP8727 Micro/Mini USB IC with integrated 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/platform_data/lp8727.h> 19#include <linux/of.h> 20 21#define LP8788_NUM_INTREGS 2 22#define DEFAULT_DEBOUNCE_MSEC 270 23 24/* Registers */ 25#define LP8727_CTRL1 0x1 26#define LP8727_CTRL2 0x2 27#define LP8727_SWCTRL 0x3 28#define LP8727_INT1 0x4 29#define LP8727_INT2 0x5 30#define LP8727_STATUS1 0x6 31#define LP8727_STATUS2 0x7 32#define LP8727_CHGCTRL2 0x9 33 34/* CTRL1 register */ 35#define LP8727_CP_EN BIT(0) 36#define LP8727_ADC_EN BIT(1) 37#define LP8727_ID200_EN BIT(4) 38 39/* CTRL2 register */ 40#define LP8727_CHGDET_EN BIT(1) 41#define LP8727_INT_EN BIT(6) 42 43/* SWCTRL register */ 44#define LP8727_SW_DM1_DM (0x0 << 0) 45#define LP8727_SW_DM1_HiZ (0x7 << 0) 46#define LP8727_SW_DP2_DP (0x0 << 3) 47#define LP8727_SW_DP2_HiZ (0x7 << 3) 48 49/* INT1 register */ 50#define LP8727_IDNO (0xF << 0) 51#define LP8727_VBUS BIT(4) 52 53/* STATUS1 register */ 54#define LP8727_CHGSTAT (3 << 4) 55#define LP8727_CHPORT BIT(6) 56#define LP8727_DCPORT BIT(7) 57#define LP8727_STAT_EOC 0x30 58 59/* STATUS2 register */ 60#define LP8727_TEMP_STAT (3 << 5) 61#define LP8727_TEMP_SHIFT 5 62 63/* CHGCTRL2 register */ 64#define LP8727_ICHG_SHIFT 4 65 66enum lp8727_dev_id { 67 LP8727_ID_NONE, 68 LP8727_ID_TA, 69 LP8727_ID_DEDICATED_CHG, 70 LP8727_ID_USB_CHG, 71 LP8727_ID_USB_DS, 72 LP8727_ID_MAX, 73}; 74 75enum lp8727_die_temp { 76 LP8788_TEMP_75C, 77 LP8788_TEMP_95C, 78 LP8788_TEMP_115C, 79 LP8788_TEMP_135C, 80}; 81 82struct lp8727_psy { 83 struct power_supply ac; 84 struct power_supply usb; 85 struct power_supply batt; 86}; 87 88struct lp8727_chg { 89 struct device *dev; 90 struct i2c_client *client; 91 struct mutex xfer_lock; 92 struct lp8727_psy *psy; 93 struct lp8727_platform_data *pdata; 94 95 /* Charger Data */ 96 enum lp8727_dev_id devid; 97 struct lp8727_chg_param *chg_param; 98 99 /* Interrupt Handling */ 100 int irq; 101 struct delayed_work work; 102 unsigned long debounce_jiffies; 103}; 104 105static int lp8727_read_bytes(struct lp8727_chg *pchg, u8 reg, u8 *data, u8 len) 106{ 107 s32 ret; 108 109 mutex_lock(&pchg->xfer_lock); 110 ret = i2c_smbus_read_i2c_block_data(pchg->client, reg, len, data); 111 mutex_unlock(&pchg->xfer_lock); 112 113 return (ret != len) ? -EIO : 0; 114} 115 116static inline int lp8727_read_byte(struct lp8727_chg *pchg, u8 reg, u8 *data) 117{ 118 return lp8727_read_bytes(pchg, reg, data, 1); 119} 120 121static int lp8727_write_byte(struct lp8727_chg *pchg, u8 reg, u8 data) 122{ 123 int ret; 124 125 mutex_lock(&pchg->xfer_lock); 126 ret = i2c_smbus_write_byte_data(pchg->client, reg, data); 127 mutex_unlock(&pchg->xfer_lock); 128 129 return ret; 130} 131 132static bool lp8727_is_charger_attached(const char *name, int id) 133{ 134 if (!strcmp(name, "ac")) 135 return id == LP8727_ID_TA || id == LP8727_ID_DEDICATED_CHG; 136 else if (!strcmp(name, "usb")) 137 return id == LP8727_ID_USB_CHG; 138 139 return id >= LP8727_ID_TA && id <= LP8727_ID_USB_CHG; 140} 141 142static int lp8727_init_device(struct lp8727_chg *pchg) 143{ 144 u8 val; 145 int ret; 146 u8 intstat[LP8788_NUM_INTREGS]; 147 148 /* clear interrupts */ 149 ret = lp8727_read_bytes(pchg, LP8727_INT1, intstat, LP8788_NUM_INTREGS); 150 if (ret) 151 return ret; 152 153 val = LP8727_ID200_EN | LP8727_ADC_EN | LP8727_CP_EN; 154 ret = lp8727_write_byte(pchg, LP8727_CTRL1, val); 155 if (ret) 156 return ret; 157 158 val = LP8727_INT_EN | LP8727_CHGDET_EN; 159 return lp8727_write_byte(pchg, LP8727_CTRL2, val); 160} 161 162static int lp8727_is_dedicated_charger(struct lp8727_chg *pchg) 163{ 164 u8 val; 165 166 lp8727_read_byte(pchg, LP8727_STATUS1, &val); 167 return val & LP8727_DCPORT; 168} 169 170static int lp8727_is_usb_charger(struct lp8727_chg *pchg) 171{ 172 u8 val; 173 174 lp8727_read_byte(pchg, LP8727_STATUS1, &val); 175 return val & LP8727_CHPORT; 176} 177 178static inline void lp8727_ctrl_switch(struct lp8727_chg *pchg, u8 sw) 179{ 180 lp8727_write_byte(pchg, LP8727_SWCTRL, sw); 181} 182 183static void lp8727_id_detection(struct lp8727_chg *pchg, u8 id, int vbusin) 184{ 185 struct lp8727_platform_data *pdata = pchg->pdata; 186 u8 devid = LP8727_ID_NONE; 187 u8 swctrl = LP8727_SW_DM1_HiZ | LP8727_SW_DP2_HiZ; 188 189 switch (id) { 190 case 0x5: 191 devid = LP8727_ID_TA; 192 pchg->chg_param = pdata ? pdata->ac : NULL; 193 break; 194 case 0xB: 195 if (lp8727_is_dedicated_charger(pchg)) { 196 pchg->chg_param = pdata ? pdata->ac : NULL; 197 devid = LP8727_ID_DEDICATED_CHG; 198 } else if (lp8727_is_usb_charger(pchg)) { 199 pchg->chg_param = pdata ? pdata->usb : NULL; 200 devid = LP8727_ID_USB_CHG; 201 swctrl = LP8727_SW_DM1_DM | LP8727_SW_DP2_DP; 202 } else if (vbusin) { 203 devid = LP8727_ID_USB_DS; 204 swctrl = LP8727_SW_DM1_DM | LP8727_SW_DP2_DP; 205 } 206 break; 207 default: 208 devid = LP8727_ID_NONE; 209 pchg->chg_param = NULL; 210 break; 211 } 212 213 pchg->devid = devid; 214 lp8727_ctrl_switch(pchg, swctrl); 215} 216 217static void lp8727_enable_chgdet(struct lp8727_chg *pchg) 218{ 219 u8 val; 220 221 lp8727_read_byte(pchg, LP8727_CTRL2, &val); 222 val |= LP8727_CHGDET_EN; 223 lp8727_write_byte(pchg, LP8727_CTRL2, val); 224} 225 226static void lp8727_delayed_func(struct work_struct *_work) 227{ 228 struct lp8727_chg *pchg = container_of(_work, struct lp8727_chg, 229 work.work); 230 u8 intstat[LP8788_NUM_INTREGS]; 231 u8 idno; 232 u8 vbus; 233 234 if (lp8727_read_bytes(pchg, LP8727_INT1, intstat, LP8788_NUM_INTREGS)) { 235 dev_err(pchg->dev, "can not read INT registers\n"); 236 return; 237 } 238 239 idno = intstat[0] & LP8727_IDNO; 240 vbus = intstat[0] & LP8727_VBUS; 241 242 lp8727_id_detection(pchg, idno, vbus); 243 lp8727_enable_chgdet(pchg); 244 245 power_supply_changed(&pchg->psy->ac); 246 power_supply_changed(&pchg->psy->usb); 247 power_supply_changed(&pchg->psy->batt); 248} 249 250static irqreturn_t lp8727_isr_func(int irq, void *ptr) 251{ 252 struct lp8727_chg *pchg = ptr; 253 254 schedule_delayed_work(&pchg->work, pchg->debounce_jiffies); 255 return IRQ_HANDLED; 256} 257 258static int lp8727_setup_irq(struct lp8727_chg *pchg) 259{ 260 int ret; 261 int irq = pchg->client->irq; 262 unsigned delay_msec = pchg->pdata ? pchg->pdata->debounce_msec : 263 DEFAULT_DEBOUNCE_MSEC; 264 265 INIT_DELAYED_WORK(&pchg->work, lp8727_delayed_func); 266 267 if (irq <= 0) { 268 dev_warn(pchg->dev, "invalid irq number: %d\n", irq); 269 return 0; 270 } 271 272 ret = request_threaded_irq(irq, NULL, lp8727_isr_func, 273 IRQF_TRIGGER_FALLING | IRQF_ONESHOT, 274 "lp8727_irq", pchg); 275 276 if (ret) 277 return ret; 278 279 pchg->irq = irq; 280 pchg->debounce_jiffies = msecs_to_jiffies(delay_msec); 281 282 return 0; 283} 284 285static void lp8727_release_irq(struct lp8727_chg *pchg) 286{ 287 cancel_delayed_work_sync(&pchg->work); 288 289 if (pchg->irq) 290 free_irq(pchg->irq, pchg); 291} 292 293static enum power_supply_property lp8727_charger_prop[] = { 294 POWER_SUPPLY_PROP_ONLINE, 295}; 296 297static enum power_supply_property lp8727_battery_prop[] = { 298 POWER_SUPPLY_PROP_STATUS, 299 POWER_SUPPLY_PROP_HEALTH, 300 POWER_SUPPLY_PROP_PRESENT, 301 POWER_SUPPLY_PROP_VOLTAGE_NOW, 302 POWER_SUPPLY_PROP_CAPACITY, 303 POWER_SUPPLY_PROP_TEMP, 304}; 305 306static char *battery_supplied_to[] = { 307 "main_batt", 308}; 309 310static int lp8727_charger_get_property(struct power_supply *psy, 311 enum power_supply_property psp, 312 union power_supply_propval *val) 313{ 314 struct lp8727_chg *pchg = dev_get_drvdata(psy->dev->parent); 315 316 if (psp != POWER_SUPPLY_PROP_ONLINE) 317 return -EINVAL; 318 319 val->intval = lp8727_is_charger_attached(psy->name, pchg->devid); 320 321 return 0; 322} 323 324static bool lp8727_is_high_temperature(enum lp8727_die_temp temp) 325{ 326 switch (temp) { 327 case LP8788_TEMP_95C: 328 case LP8788_TEMP_115C: 329 case LP8788_TEMP_135C: 330 return true; 331 default: 332 return false; 333 } 334} 335 336static int lp8727_battery_get_property(struct power_supply *psy, 337 enum power_supply_property psp, 338 union power_supply_propval *val) 339{ 340 struct lp8727_chg *pchg = dev_get_drvdata(psy->dev->parent); 341 struct lp8727_platform_data *pdata = pchg->pdata; 342 enum lp8727_die_temp temp; 343 u8 read; 344 345 switch (psp) { 346 case POWER_SUPPLY_PROP_STATUS: 347 if (!lp8727_is_charger_attached(psy->name, pchg->devid)) { 348 val->intval = POWER_SUPPLY_STATUS_DISCHARGING; 349 return 0; 350 } 351 352 lp8727_read_byte(pchg, LP8727_STATUS1, &read); 353 354 val->intval = (read & LP8727_CHGSTAT) == LP8727_STAT_EOC ? 355 POWER_SUPPLY_STATUS_FULL : 356 POWER_SUPPLY_STATUS_CHARGING; 357 break; 358 case POWER_SUPPLY_PROP_HEALTH: 359 lp8727_read_byte(pchg, LP8727_STATUS2, &read); 360 temp = (read & LP8727_TEMP_STAT) >> LP8727_TEMP_SHIFT; 361 362 val->intval = lp8727_is_high_temperature(temp) ? 363 POWER_SUPPLY_HEALTH_OVERHEAT : 364 POWER_SUPPLY_HEALTH_GOOD; 365 break; 366 case POWER_SUPPLY_PROP_PRESENT: 367 if (!pdata) 368 return -EINVAL; 369 370 if (pdata->get_batt_present) 371 val->intval = pdata->get_batt_present(); 372 break; 373 case POWER_SUPPLY_PROP_VOLTAGE_NOW: 374 if (!pdata) 375 return -EINVAL; 376 377 if (pdata->get_batt_level) 378 val->intval = pdata->get_batt_level(); 379 break; 380 case POWER_SUPPLY_PROP_CAPACITY: 381 if (!pdata) 382 return -EINVAL; 383 384 if (pdata->get_batt_capacity) 385 val->intval = pdata->get_batt_capacity(); 386 break; 387 case POWER_SUPPLY_PROP_TEMP: 388 if (!pdata) 389 return -EINVAL; 390 391 if (pdata->get_batt_temp) 392 val->intval = pdata->get_batt_temp(); 393 break; 394 default: 395 break; 396 } 397 398 return 0; 399} 400 401static void lp8727_charger_changed(struct power_supply *psy) 402{ 403 struct lp8727_chg *pchg = dev_get_drvdata(psy->dev->parent); 404 u8 eoc_level; 405 u8 ichg; 406 u8 val; 407 408 /* skip if no charger exists */ 409 if (!lp8727_is_charger_attached(psy->name, pchg->devid)) 410 return; 411 412 /* update charging parameters */ 413 if (pchg->chg_param) { 414 eoc_level = pchg->chg_param->eoc_level; 415 ichg = pchg->chg_param->ichg; 416 val = (ichg << LP8727_ICHG_SHIFT) | eoc_level; 417 lp8727_write_byte(pchg, LP8727_CHGCTRL2, val); 418 } 419} 420 421static int lp8727_register_psy(struct lp8727_chg *pchg) 422{ 423 struct lp8727_psy *psy; 424 425 psy = devm_kzalloc(pchg->dev, sizeof(*psy), GFP_KERNEL); 426 if (!psy) 427 return -ENOMEM; 428 429 pchg->psy = psy; 430 431 psy->ac.name = "ac"; 432 psy->ac.type = POWER_SUPPLY_TYPE_MAINS; 433 psy->ac.properties = lp8727_charger_prop; 434 psy->ac.num_properties = ARRAY_SIZE(lp8727_charger_prop); 435 psy->ac.get_property = lp8727_charger_get_property; 436 psy->ac.supplied_to = battery_supplied_to; 437 psy->ac.num_supplicants = ARRAY_SIZE(battery_supplied_to); 438 439 if (power_supply_register(pchg->dev, &psy->ac)) 440 goto err_psy_ac; 441 442 psy->usb.name = "usb"; 443 psy->usb.type = POWER_SUPPLY_TYPE_USB; 444 psy->usb.properties = lp8727_charger_prop; 445 psy->usb.num_properties = ARRAY_SIZE(lp8727_charger_prop); 446 psy->usb.get_property = lp8727_charger_get_property; 447 psy->usb.supplied_to = battery_supplied_to; 448 psy->usb.num_supplicants = ARRAY_SIZE(battery_supplied_to); 449 450 if (power_supply_register(pchg->dev, &psy->usb)) 451 goto err_psy_usb; 452 453 psy->batt.name = "main_batt"; 454 psy->batt.type = POWER_SUPPLY_TYPE_BATTERY; 455 psy->batt.properties = lp8727_battery_prop; 456 psy->batt.num_properties = ARRAY_SIZE(lp8727_battery_prop); 457 psy->batt.get_property = lp8727_battery_get_property; 458 psy->batt.external_power_changed = lp8727_charger_changed; 459 460 if (power_supply_register(pchg->dev, &psy->batt)) 461 goto err_psy_batt; 462 463 return 0; 464 465err_psy_batt: 466 power_supply_unregister(&psy->usb); 467err_psy_usb: 468 power_supply_unregister(&psy->ac); 469err_psy_ac: 470 return -EPERM; 471} 472 473static void lp8727_unregister_psy(struct lp8727_chg *pchg) 474{ 475 struct lp8727_psy *psy = pchg->psy; 476 477 if (!psy) 478 return; 479 480 power_supply_unregister(&psy->ac); 481 power_supply_unregister(&psy->usb); 482 power_supply_unregister(&psy->batt); 483} 484 485#ifdef CONFIG_OF 486static struct lp8727_chg_param 487*lp8727_parse_charge_pdata(struct device *dev, struct device_node *np) 488{ 489 struct lp8727_chg_param *param; 490 491 param = devm_kzalloc(dev, sizeof(*param), GFP_KERNEL); 492 if (!param) 493 goto out; 494 495 of_property_read_u8(np, "eoc-level", (u8 *)&param->eoc_level); 496 of_property_read_u8(np, "charging-current", (u8 *)&param->ichg); 497out: 498 return param; 499} 500 501static int lp8727_parse_dt(struct device *dev) 502{ 503 struct device_node *np = dev->of_node; 504 struct device_node *child; 505 struct lp8727_platform_data *pdata; 506 const char *type; 507 508 /* If charging parameter is not defined, just skip parsing the dt */ 509 if (of_get_child_count(np) == 0) 510 goto out; 511 512 pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); 513 if (!pdata) 514 return -ENOMEM; 515 516 of_property_read_u32(np, "debounce-ms", &pdata->debounce_msec); 517 518 for_each_child_of_node(np, child) { 519 of_property_read_string(child, "charger-type", &type); 520 521 if (!strcmp(type, "ac")) 522 pdata->ac = lp8727_parse_charge_pdata(dev, child); 523 524 if (!strcmp(type, "usb")) 525 pdata->usb = lp8727_parse_charge_pdata(dev, child); 526 } 527 528 dev->platform_data = pdata; 529out: 530 return 0; 531} 532#else 533static int lp8727_parse_dt(struct device *dev) 534{ 535 return 0; 536} 537#endif 538 539static int lp8727_probe(struct i2c_client *cl, const struct i2c_device_id *id) 540{ 541 struct lp8727_chg *pchg; 542 int ret; 543 544 if (!i2c_check_functionality(cl->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) 545 return -EIO; 546 547 if (cl->dev.of_node) { 548 ret = lp8727_parse_dt(&cl->dev); 549 if (ret) 550 return ret; 551 } 552 553 pchg = devm_kzalloc(&cl->dev, sizeof(*pchg), GFP_KERNEL); 554 if (!pchg) 555 return -ENOMEM; 556 557 pchg->client = cl; 558 pchg->dev = &cl->dev; 559 pchg->pdata = cl->dev.platform_data; 560 i2c_set_clientdata(cl, pchg); 561 562 mutex_init(&pchg->xfer_lock); 563 564 ret = lp8727_init_device(pchg); 565 if (ret) { 566 dev_err(pchg->dev, "i2c communication err: %d", ret); 567 return ret; 568 } 569 570 ret = lp8727_register_psy(pchg); 571 if (ret) { 572 dev_err(pchg->dev, "power supplies register err: %d", ret); 573 return ret; 574 } 575 576 ret = lp8727_setup_irq(pchg); 577 if (ret) { 578 dev_err(pchg->dev, "irq handler err: %d", ret); 579 lp8727_unregister_psy(pchg); 580 return ret; 581 } 582 583 return 0; 584} 585 586static int lp8727_remove(struct i2c_client *cl) 587{ 588 struct lp8727_chg *pchg = i2c_get_clientdata(cl); 589 590 lp8727_release_irq(pchg); 591 lp8727_unregister_psy(pchg); 592 return 0; 593} 594 595static const struct of_device_id lp8727_dt_ids[] = { 596 { .compatible = "ti,lp8727", }, 597 { } 598}; 599MODULE_DEVICE_TABLE(of, lp8727_dt_ids); 600 601static const struct i2c_device_id lp8727_ids[] = { 602 {"lp8727", 0}, 603 { } 604}; 605MODULE_DEVICE_TABLE(i2c, lp8727_ids); 606 607static struct i2c_driver lp8727_driver = { 608 .driver = { 609 .name = "lp8727", 610 .of_match_table = of_match_ptr(lp8727_dt_ids), 611 }, 612 .probe = lp8727_probe, 613 .remove = lp8727_remove, 614 .id_table = lp8727_ids, 615}; 616module_i2c_driver(lp8727_driver); 617 618MODULE_DESCRIPTION("TI/National Semiconductor LP8727 charger driver"); 619MODULE_AUTHOR("Milo Kim <milo.kim@ti.com>, Daniel Jeong <daniel.jeong@ti.com>"); 620MODULE_LICENSE("GPL");