diff options
| author | Kim, Milo <Milo.Kim@ti.com> | 2013-05-10 03:17:51 -0400 |
|---|---|---|
| committer | Anton Vorontsov <anton@enomsg.org> | 2013-06-06 20:19:54 -0400 |
| commit | 17b4565b308ed31fa20b59842c75e685a101dc8a (patch) | |
| tree | 6f6462adc90736ce91d57bffc5c6b73865bda56e | |
| parent | 0f1e0169e08e1645a8406ab84286ebaf19c5cce5 (diff) | |
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>
| -rw-r--r-- | Documentation/devicetree/bindings/power_supply/lp8727_charger.txt | 44 | ||||
| -rw-r--r-- | drivers/power/lp8727_charger.c | 68 |
2 files changed, 112 insertions, 0 deletions
diff --git a/Documentation/devicetree/bindings/power_supply/lp8727_charger.txt b/Documentation/devicetree/bindings/power_supply/lp8727_charger.txt new file mode 100644 index 000000000000..2246bc5c874b --- /dev/null +++ b/Documentation/devicetree/bindings/power_supply/lp8727_charger.txt | |||
| @@ -0,0 +1,44 @@ | |||
| 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 | }; | ||
diff --git a/drivers/power/lp8727_charger.c b/drivers/power/lp8727_charger.c index 5ef41b819172..32de636dcd73 100644 --- a/drivers/power/lp8727_charger.c +++ b/drivers/power/lp8727_charger.c | |||
| @@ -16,6 +16,7 @@ | |||
| 16 | #include <linux/i2c.h> | 16 | #include <linux/i2c.h> |
| 17 | #include <linux/power_supply.h> | 17 | #include <linux/power_supply.h> |
| 18 | #include <linux/platform_data/lp8727.h> | 18 | #include <linux/platform_data/lp8727.h> |
| 19 | #include <linux/of.h> | ||
| 19 | 20 | ||
| 20 | #define LP8788_NUM_INTREGS 2 | 21 | #define LP8788_NUM_INTREGS 2 |
| 21 | #define DEFAULT_DEBOUNCE_MSEC 270 | 22 | #define DEFAULT_DEBOUNCE_MSEC 270 |
| @@ -481,6 +482,60 @@ static void lp8727_unregister_psy(struct lp8727_chg *pchg) | |||
| 481 | power_supply_unregister(&psy->batt); | 482 | power_supply_unregister(&psy->batt); |
| 482 | } | 483 | } |
| 483 | 484 | ||
| 485 | #ifdef CONFIG_OF | ||
| 486 | static 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 *)¶m->eoc_level); | ||
| 496 | of_property_read_u8(np, "charging-current", (u8 *)¶m->ichg); | ||
| 497 | out: | ||
| 498 | return param; | ||
| 499 | } | ||
| 500 | |||
| 501 | static 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; | ||
| 529 | out: | ||
| 530 | return 0; | ||
| 531 | } | ||
| 532 | #else | ||
| 533 | static int lp8727_parse_dt(struct device *dev) | ||
| 534 | { | ||
| 535 | return 0; | ||
| 536 | } | ||
| 537 | #endif | ||
| 538 | |||
| 484 | static int lp8727_probe(struct i2c_client *cl, const struct i2c_device_id *id) | 539 | static int lp8727_probe(struct i2c_client *cl, const struct i2c_device_id *id) |
| 485 | { | 540 | { |
| 486 | struct lp8727_chg *pchg; | 541 | struct lp8727_chg *pchg; |
| @@ -489,6 +544,12 @@ static int lp8727_probe(struct i2c_client *cl, const struct i2c_device_id *id) | |||
| 489 | if (!i2c_check_functionality(cl->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) | 544 | if (!i2c_check_functionality(cl->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) |
| 490 | return -EIO; | 545 | return -EIO; |
| 491 | 546 | ||
| 547 | if (cl->dev.of_node) { | ||
| 548 | ret = lp8727_parse_dt(&cl->dev); | ||
| 549 | if (ret) | ||
| 550 | return ret; | ||
| 551 | } | ||
| 552 | |||
| 492 | pchg = devm_kzalloc(&cl->dev, sizeof(*pchg), GFP_KERNEL); | 553 | pchg = devm_kzalloc(&cl->dev, sizeof(*pchg), GFP_KERNEL); |
| 493 | if (!pchg) | 554 | if (!pchg) |
| 494 | return -ENOMEM; | 555 | return -ENOMEM; |
| @@ -531,6 +592,12 @@ static int lp8727_remove(struct i2c_client *cl) | |||
| 531 | return 0; | 592 | return 0; |
| 532 | } | 593 | } |
| 533 | 594 | ||
| 595 | static const struct of_device_id lp8727_dt_ids[] = { | ||
| 596 | { .compatible = "ti,lp8727", }, | ||
| 597 | { } | ||
| 598 | }; | ||
| 599 | MODULE_DEVICE_TABLE(of, lp8727_dt_ids); | ||
| 600 | |||
| 534 | static const struct i2c_device_id lp8727_ids[] = { | 601 | static const struct i2c_device_id lp8727_ids[] = { |
| 535 | {"lp8727", 0}, | 602 | {"lp8727", 0}, |
| 536 | { } | 603 | { } |
| @@ -540,6 +607,7 @@ MODULE_DEVICE_TABLE(i2c, lp8727_ids); | |||
| 540 | static struct i2c_driver lp8727_driver = { | 607 | static struct i2c_driver lp8727_driver = { |
| 541 | .driver = { | 608 | .driver = { |
| 542 | .name = "lp8727", | 609 | .name = "lp8727", |
| 610 | .of_match_table = of_match_ptr(lp8727_dt_ids), | ||
| 543 | }, | 611 | }, |
| 544 | .probe = lp8727_probe, | 612 | .probe = lp8727_probe, |
| 545 | .remove = lp8727_remove, | 613 | .remove = lp8727_remove, |
