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

lp8727_charger: Support the device tree feature

The interrupt and charging parameters are configurable in the device tree
structure. In the board test, a GPIO is used for handling LP8727
interrupts. The device tree binding documentation is added also.

Signed-off-by: Milo(Woogyom) Kim <milo.kim@ti.com>
Signed-off-by: Anton Vorontsov <anton@enomsg.org>

authored by

Kim, Milo and committed by
Anton Vorontsov
17b4565b 0f1e0169

+112
+44
Documentation/devicetree/bindings/power_supply/lp8727_charger.txt
··· 1 + Binding for TI/National Semiconductor LP8727 Charger 2 + 3 + Required properties: 4 + - compatible: "ti,lp8727" 5 + - reg: I2C slave address 27h 6 + 7 + Optional properties: 8 + - interrupt-parent: interrupt controller node (see interrupt binding[0]) 9 + - interrupts: interrupt specifier (see interrupt binding[0]) 10 + - debounce-ms: interrupt debounce time. (u32) 11 + 12 + AC and USB charging parameters 13 + - charger-type: "ac" or "usb" (string) 14 + - eoc-level: value of 'enum lp8727_eoc_level' (u8) 15 + - charging-current: value of 'enum lp8727_ichg' (u8) 16 + 17 + [0]: Documentation/devicetree/bindings/interrupt-controller/interrupts.txt 18 + 19 + Example) 20 + 21 + lp8727@27 { 22 + compatible = "ti,lp8727"; 23 + reg = <0x27>; 24 + 25 + /* GPIO 134 is used for LP8728 interrupt pin */ 26 + interrupt-parent = <&gpio5>; /* base = 128 */ 27 + interrupts = <6 0x2>; /* offset = 6, falling edge type */ 28 + 29 + debounce-ms = <300>; 30 + 31 + /* AC charger: 5% EOC and 500mA charging current */ 32 + ac { 33 + charger-type = "ac"; 34 + eoc-level = /bits/ 8 <0>; 35 + charging-current = /bits/ 8 <4>; 36 + }; 37 + 38 + /* USB charger: 10% EOC and 400mA charging current */ 39 + usb { 40 + charger-type = "usb"; 41 + eoc-level = /bits/ 8 <1>; 42 + charging-current = /bits/ 8 <2>; 43 + }; 44 + };
+68
drivers/power/lp8727_charger.c
··· 16 16 #include <linux/i2c.h> 17 17 #include <linux/power_supply.h> 18 18 #include <linux/platform_data/lp8727.h> 19 + #include <linux/of.h> 19 20 20 21 #define LP8788_NUM_INTREGS 2 21 22 #define DEFAULT_DEBOUNCE_MSEC 270 ··· 482 481 power_supply_unregister(&psy->batt); 483 482 } 484 483 484 + #ifdef CONFIG_OF 485 + static struct lp8727_chg_param 486 + *lp8727_parse_charge_pdata(struct device *dev, struct device_node *np) 487 + { 488 + struct lp8727_chg_param *param; 489 + 490 + param = devm_kzalloc(dev, sizeof(*param), GFP_KERNEL); 491 + if (!param) 492 + goto out; 493 + 494 + of_property_read_u8(np, "eoc-level", (u8 *)&param->eoc_level); 495 + of_property_read_u8(np, "charging-current", (u8 *)&param->ichg); 496 + out: 497 + return param; 498 + } 499 + 500 + static int lp8727_parse_dt(struct device *dev) 501 + { 502 + struct device_node *np = dev->of_node; 503 + struct device_node *child; 504 + struct lp8727_platform_data *pdata; 505 + const char *type; 506 + 507 + /* If charging parameter is not defined, just skip parsing the dt */ 508 + if (of_get_child_count(np) == 0) 509 + goto out; 510 + 511 + pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); 512 + if (!pdata) 513 + return -ENOMEM; 514 + 515 + of_property_read_u32(np, "debounce-ms", &pdata->debounce_msec); 516 + 517 + for_each_child_of_node(np, child) { 518 + of_property_read_string(child, "charger-type", &type); 519 + 520 + if (!strcmp(type, "ac")) 521 + pdata->ac = lp8727_parse_charge_pdata(dev, child); 522 + 523 + if (!strcmp(type, "usb")) 524 + pdata->usb = lp8727_parse_charge_pdata(dev, child); 525 + } 526 + 527 + dev->platform_data = pdata; 528 + out: 529 + return 0; 530 + } 531 + #else 532 + static int lp8727_parse_dt(struct device *dev) 533 + { 534 + return 0; 535 + } 536 + #endif 537 + 485 538 static int lp8727_probe(struct i2c_client *cl, const struct i2c_device_id *id) 486 539 { 487 540 struct lp8727_chg *pchg; ··· 543 488 544 489 if (!i2c_check_functionality(cl->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) 545 490 return -EIO; 491 + 492 + if (cl->dev.of_node) { 493 + ret = lp8727_parse_dt(&cl->dev); 494 + if (ret) 495 + return ret; 496 + } 546 497 547 498 pchg = devm_kzalloc(&cl->dev, sizeof(*pchg), GFP_KERNEL); 548 499 if (!pchg) ··· 592 531 return 0; 593 532 } 594 533 534 + static const struct of_device_id lp8727_dt_ids[] = { 535 + { .compatible = "ti,lp8727", }, 536 + { } 537 + }; 538 + MODULE_DEVICE_TABLE(of, lp8727_dt_ids); 539 + 595 540 static const struct i2c_device_id lp8727_ids[] = { 596 541 {"lp8727", 0}, 597 542 { } ··· 607 540 static struct i2c_driver lp8727_driver = { 608 541 .driver = { 609 542 .name = "lp8727", 543 + .of_match_table = of_match_ptr(lp8727_dt_ids), 610 544 }, 611 545 .probe = lp8727_probe, 612 546 .remove = lp8727_remove,