aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/leds
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2013-04-23 07:52:59 -0400
committerBryan Wu <cooloney@gmail.com>2013-06-20 19:21:31 -0400
commit7542a04b1515f0f878b267beb233c4ef067243fb (patch)
treef5516bc2113773391893cbbd2b309feb45829f18 /drivers/leds
parent7d132055814ef17a6c7b69f342244c410a5e000f (diff)
leds: lp55xx: add support for Device Tree bindings
This patch allows the lp5521 driver to be successfully probed and initialised when Device Tree support is enabled. Based on a patch by Gabriel Fernandez, rewritten in accordance with review feedback. Cc: Gabriel Fernandez <gabriel.fernandez@stericsson.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> Acked-by: Milo Kim <milo.kim@ti.com> Signed-off-by: Bryan Wu <cooloney@gmail.com>
Diffstat (limited to 'drivers/leds')
-rw-r--r--drivers/leds/leds-lp5521.c20
-rw-r--r--drivers/leds/leds-lp5523.c19
-rw-r--r--drivers/leds/leds-lp55xx-common.c54
-rw-r--r--drivers/leds/leds-lp55xx-common.h4
4 files changed, 87 insertions, 10 deletions
diff --git a/drivers/leds/leds-lp5521.c b/drivers/leds/leds-lp5521.c
index 19752c928aa2..d461e2664b09 100644
--- a/drivers/leds/leds-lp5521.c
+++ b/drivers/leds/leds-lp5521.c
@@ -31,6 +31,7 @@
31#include <linux/mutex.h> 31#include <linux/mutex.h>
32#include <linux/platform_data/leds-lp55xx.h> 32#include <linux/platform_data/leds-lp55xx.h>
33#include <linux/slab.h> 33#include <linux/slab.h>
34#include <linux/of.h>
34 35
35#include "leds-lp55xx-common.h" 36#include "leds-lp55xx-common.h"
36 37
@@ -416,12 +417,20 @@ static int lp5521_probe(struct i2c_client *client,
416 int ret; 417 int ret;
417 struct lp55xx_chip *chip; 418 struct lp55xx_chip *chip;
418 struct lp55xx_led *led; 419 struct lp55xx_led *led;
419 struct lp55xx_platform_data *pdata = client->dev.platform_data; 420 struct lp55xx_platform_data *pdata;
420 421 struct device_node *np = client->dev.of_node;
421 if (!pdata) { 422
422 dev_err(&client->dev, "no platform data\n"); 423 if (!client->dev.platform_data) {
423 return -EINVAL; 424 if (np) {
425 ret = lp55xx_of_populate_pdata(&client->dev, np);
426 if (ret < 0)
427 return ret;
428 } else {
429 dev_err(&client->dev, "no platform data\n");
430 return -EINVAL;
431 }
424 } 432 }
433 pdata = client->dev.platform_data;
425 434
426 chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL); 435 chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
427 if (!chip) 436 if (!chip)
@@ -481,6 +490,7 @@ static int lp5521_remove(struct i2c_client *client)
481 490
482static const struct i2c_device_id lp5521_id[] = { 491static const struct i2c_device_id lp5521_id[] = {
483 { "lp5521", 0 }, /* Three channel chip */ 492 { "lp5521", 0 }, /* Three channel chip */
493 { "national,lp5521", 0 }, /* OF compatible */
484 { } 494 { }
485}; 495};
486MODULE_DEVICE_TABLE(i2c, lp5521_id); 496MODULE_DEVICE_TABLE(i2c, lp5521_id);
diff --git a/drivers/leds/leds-lp5523.c b/drivers/leds/leds-lp5523.c
index 229f734040af..365e9148e5e8 100644
--- a/drivers/leds/leds-lp5523.c
+++ b/drivers/leds/leds-lp5523.c
@@ -429,12 +429,20 @@ static int lp5523_probe(struct i2c_client *client,
429 int ret; 429 int ret;
430 struct lp55xx_chip *chip; 430 struct lp55xx_chip *chip;
431 struct lp55xx_led *led; 431 struct lp55xx_led *led;
432 struct lp55xx_platform_data *pdata = client->dev.platform_data; 432 struct lp55xx_platform_data *pdata;
433 433 struct device_node *np = client->dev.of_node;
434 if (!pdata) { 434
435 dev_err(&client->dev, "no platform data\n"); 435 if (!client->dev.platform_data) {
436 return -EINVAL; 436 if (np) {
437 ret = lp55xx_of_populate_pdata(&client->dev, np);
438 if (ret < 0)
439 return ret;
440 } else {
441 dev_err(&client->dev, "no platform data\n");
442 return -EINVAL;
443 }
437 } 444 }
445 pdata = client->dev.platform_data;
438 446
439 chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL); 447 chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
440 if (!chip) 448 if (!chip)
@@ -495,6 +503,7 @@ static int lp5523_remove(struct i2c_client *client)
495static const struct i2c_device_id lp5523_id[] = { 503static const struct i2c_device_id lp5523_id[] = {
496 { "lp5523", LP5523 }, 504 { "lp5523", LP5523 },
497 { "lp55231", LP55231 }, 505 { "lp55231", LP55231 },
506 { "national,lp5523", 0 }, /* OF compatible */
498 { } 507 { }
499}; 508};
500 509
diff --git a/drivers/leds/leds-lp55xx-common.c b/drivers/leds/leds-lp55xx-common.c
index ba34199dc3d9..a0d2bd2fa23c 100644
--- a/drivers/leds/leds-lp55xx-common.c
+++ b/drivers/leds/leds-lp55xx-common.c
@@ -19,6 +19,7 @@
19#include <linux/leds.h> 19#include <linux/leds.h>
20#include <linux/module.h> 20#include <linux/module.h>
21#include <linux/platform_data/leds-lp55xx.h> 21#include <linux/platform_data/leds-lp55xx.h>
22#include <linux/slab.h>
22 23
23#include "leds-lp55xx-common.h" 24#include "leds-lp55xx-common.h"
24 25
@@ -554,6 +555,59 @@ void lp55xx_unregister_sysfs(struct lp55xx_chip *chip)
554} 555}
555EXPORT_SYMBOL_GPL(lp55xx_unregister_sysfs); 556EXPORT_SYMBOL_GPL(lp55xx_unregister_sysfs);
556 557
558int lp55xx_of_populate_pdata(struct device *dev, struct device_node *np)
559{
560 struct lp55xx_platform_data *pdata;
561 u8 led_cur[3];
562 u8 max_cur[3];
563 u8 clock_mode;
564 u8 num_channel;
565 const char *label;
566 struct lp55xx_led_config *led_config;
567 int ret;
568 int i;
569
570 pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
571 if (!pdata)
572 return -ENOMEM;
573
574 ret = of_property_read_u8(np, "num-channel", &num_channel);
575 if (ret < 0)
576 return ret;
577 ret = of_property_read_u8_array(np, "led-cur", led_cur, num_channel);
578 if (ret < 0)
579 return ret;
580 ret = of_property_read_u8_array(np, "max-cur", max_cur, num_channel);
581 if (ret < 0)
582 return ret;
583 ret = of_property_read_string(np, "label", &label);
584 if (ret < 0)
585 return ret;
586 ret = of_property_read_u8_array(np, "clock-mode", &clock_mode, 1);
587 if (ret < 0)
588 return ret;
589
590 led_config = devm_kzalloc(dev, sizeof(*led_config) * num_channel,
591 GFP_KERNEL);
592 if (!led_config)
593 return -ENOMEM;
594
595 for (i = 0; i < num_channel; i++) {
596 led_config[i].chan_nr = i;
597 led_config[i].led_current = led_cur[i];
598 led_config[i].max_current = max_cur[i];
599 }
600 pdata->label = kzalloc(sizeof(char) * 32, GFP_KERNEL);
601 strcpy((char *)pdata->label, (char *) label);
602 pdata->led_config = &led_config[0];
603 pdata->num_channels = num_channel;
604 pdata->clock_mode = clock_mode;
605 dev->platform_data = pdata;
606
607 return 0;
608}
609EXPORT_SYMBOL_GPL(lp55xx_of_populate_pdata);
610
557MODULE_AUTHOR("Milo Kim <milo.kim@ti.com>"); 611MODULE_AUTHOR("Milo Kim <milo.kim@ti.com>");
558MODULE_DESCRIPTION("LP55xx Common Driver"); 612MODULE_DESCRIPTION("LP55xx Common Driver");
559MODULE_LICENSE("GPL"); 613MODULE_LICENSE("GPL");
diff --git a/drivers/leds/leds-lp55xx-common.h b/drivers/leds/leds-lp55xx-common.h
index fa6a078bf547..dbbf86df0f1f 100644
--- a/drivers/leds/leds-lp55xx-common.h
+++ b/drivers/leds/leds-lp55xx-common.h
@@ -135,4 +135,8 @@ extern void lp55xx_unregister_leds(struct lp55xx_led *led,
135extern int lp55xx_register_sysfs(struct lp55xx_chip *chip); 135extern int lp55xx_register_sysfs(struct lp55xx_chip *chip);
136extern void lp55xx_unregister_sysfs(struct lp55xx_chip *chip); 136extern void lp55xx_unregister_sysfs(struct lp55xx_chip *chip);
137 137
138/* common device tree population function */
139extern int lp55xx_of_populate_pdata(struct device *dev,
140 struct device_node *np);
141
138#endif /* _LEDS_LP55XX_COMMON_H */ 142#endif /* _LEDS_LP55XX_COMMON_H */