diff options
-rw-r--r-- | Documentation/devicetree/bindings/leds/leds-lp55xx.txt | 109 | ||||
-rw-r--r-- | drivers/leds/leds-lp55xx-common.c | 61 |
2 files changed, 127 insertions, 43 deletions
diff --git a/Documentation/devicetree/bindings/leds/leds-lp55xx.txt b/Documentation/devicetree/bindings/leds/leds-lp55xx.txt index 348c88eaadfd..1ed6bb0ce777 100644 --- a/Documentation/devicetree/bindings/leds/leds-lp55xx.txt +++ b/Documentation/devicetree/bindings/leds/leds-lp55xx.txt | |||
@@ -2,20 +2,113 @@ Binding for National Semiconductor LP55xx Led Drivers | |||
2 | 2 | ||
3 | Required properties: | 3 | Required properties: |
4 | - compatible: "national,lp5521" or "national,lp5523" | 4 | - compatible: "national,lp5521" or "national,lp5523" |
5 | - label: Used for naming LEDs | 5 | - reg: I2C slave address |
6 | - num-channel: Number of LED channels | 6 | - clock-mode: Input clock mode, (0: automode, 1: internal, 2: external) |
7 | |||
8 | Each child has own specific current settings | ||
7 | - led-cur: Current setting at each led channel (mA x10, 0 if led is not connected) | 9 | - led-cur: Current setting at each led channel (mA x10, 0 if led is not connected) |
8 | - max-cur: Maximun current at each led channel. | 10 | - max-cur: Maximun current at each led channel. |
9 | - clock-mode: Input clock mode, (0: automode, 1: internal, 2: external) | ||
10 | 11 | ||
11 | example: | 12 | Optional properties: |
13 | - label: Used for naming LEDs | ||
14 | |||
15 | Alternatively, each child can have specific channel name | ||
16 | - chan-name: Name of each channel name | ||
17 | |||
18 | example 1) LP5521 | ||
19 | 3 LED channels, external clock used. Channel names are 'lp5521_pri:channel0', | ||
20 | 'lp5521_pri:channel1' and 'lp5521_pri:channel2' | ||
12 | 21 | ||
13 | lp5521@32 { | 22 | lp5521@32 { |
14 | compatible = "national,lp5521"; | 23 | compatible = "national,lp5521"; |
15 | reg = <0x32>; | 24 | reg = <0x32>; |
16 | label = "lp5521_pri"; | 25 | label = "lp5521_pri"; |
17 | num-channel = /bits/ 8 <3>; | 26 | clock-mode = /bits/ 8 <2>; |
18 | led-cur = /bits/ 8 <0x2f 0x2f 0x2f>; | 27 | |
19 | max-cur = /bits/ 8 <0x5f 0x5f 0x5f>; | 28 | chan0 { |
20 | clock-mode = /bits/8 <2>; | 29 | led-cur = /bits/ 8 <0x2f>; |
30 | max-cur = /bits/ 8 <0x5f>; | ||
31 | }; | ||
32 | |||
33 | chan1 { | ||
34 | led-cur = /bits/ 8 <0x2f>; | ||
35 | max-cur = /bits/ 8 <0x5f>; | ||
36 | }; | ||
37 | |||
38 | chan2 { | ||
39 | led-cur = /bits/ 8 <0x2f>; | ||
40 | max-cur = /bits/ 8 <0x5f>; | ||
41 | }; | ||
42 | }; | ||
43 | |||
44 | example 2) LP5523 | ||
45 | 9 LED channels with specific name. Internal clock used. | ||
46 | The I2C slave address is configurable with ASEL1 and ASEL0 pins. | ||
47 | Available addresses are 32/33/34/35h. | ||
48 | |||
49 | ASEL1 ASEL0 Address | ||
50 | ------------------------- | ||
51 | GND GND 32h | ||
52 | GND VEN 33h | ||
53 | VEN GND 34h | ||
54 | VEN VEN 35h | ||
55 | |||
56 | lp5523@32 { | ||
57 | compatible = "national,lp5523"; | ||
58 | reg = <0x32>; | ||
59 | clock-mode = /bits/ 8 <1>; | ||
60 | |||
61 | chan0 { | ||
62 | chan-name = "d1"; | ||
63 | led-cur = /bits/ 8 <0x14>; | ||
64 | max-cur = /bits/ 8 <0x20>; | ||
65 | }; | ||
66 | |||
67 | chan1 { | ||
68 | chan-name = "d2"; | ||
69 | led-cur = /bits/ 8 <0x14>; | ||
70 | max-cur = /bits/ 8 <0x20>; | ||
71 | }; | ||
72 | |||
73 | chan2 { | ||
74 | chan-name = "d3"; | ||
75 | led-cur = /bits/ 8 <0x14>; | ||
76 | max-cur = /bits/ 8 <0x20>; | ||
77 | }; | ||
78 | |||
79 | chan3 { | ||
80 | chan-name = "d4"; | ||
81 | led-cur = /bits/ 8 <0x14>; | ||
82 | max-cur = /bits/ 8 <0x20>; | ||
83 | }; | ||
84 | |||
85 | chan4 { | ||
86 | chan-name = "d5"; | ||
87 | led-cur = /bits/ 8 <0x14>; | ||
88 | max-cur = /bits/ 8 <0x20>; | ||
89 | }; | ||
90 | |||
91 | chan5 { | ||
92 | chan-name = "d6"; | ||
93 | led-cur = /bits/ 8 <0x14>; | ||
94 | max-cur = /bits/ 8 <0x20>; | ||
95 | }; | ||
96 | |||
97 | chan6 { | ||
98 | chan-name = "d7"; | ||
99 | led-cur = /bits/ 8 <0x14>; | ||
100 | max-cur = /bits/ 8 <0x20>; | ||
101 | }; | ||
102 | |||
103 | chan7 { | ||
104 | chan-name = "d8"; | ||
105 | led-cur = /bits/ 8 <0x14>; | ||
106 | max-cur = /bits/ 8 <0x20>; | ||
107 | }; | ||
108 | |||
109 | chan8 { | ||
110 | chan-name = "d9"; | ||
111 | led-cur = /bits/ 8 <0x14>; | ||
112 | max-cur = /bits/ 8 <0x20>; | ||
113 | }; | ||
21 | }; | 114 | }; |
diff --git a/drivers/leds/leds-lp55xx-common.c b/drivers/leds/leds-lp55xx-common.c index a0d2bd2fa23c..c2fecd4d391c 100644 --- a/drivers/leds/leds-lp55xx-common.c +++ b/drivers/leds/leds-lp55xx-common.c | |||
@@ -557,51 +557,42 @@ EXPORT_SYMBOL_GPL(lp55xx_unregister_sysfs); | |||
557 | 557 | ||
558 | int lp55xx_of_populate_pdata(struct device *dev, struct device_node *np) | 558 | int lp55xx_of_populate_pdata(struct device *dev, struct device_node *np) |
559 | { | 559 | { |
560 | struct device_node *child; | ||
560 | struct lp55xx_platform_data *pdata; | 561 | struct lp55xx_platform_data *pdata; |
561 | u8 led_cur[3]; | 562 | struct lp55xx_led_config *cfg; |
562 | u8 max_cur[3]; | 563 | int num_channels; |
563 | u8 clock_mode; | 564 | int i = 0; |
564 | u8 num_channel; | ||
565 | const char *label; | ||
566 | struct lp55xx_led_config *led_config; | ||
567 | int ret; | ||
568 | int i; | ||
569 | 565 | ||
570 | pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); | 566 | pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); |
571 | if (!pdata) | 567 | if (!pdata) |
572 | return -ENOMEM; | 568 | return -ENOMEM; |
573 | 569 | ||
574 | ret = of_property_read_u8(np, "num-channel", &num_channel); | 570 | num_channels = of_get_child_count(np); |
575 | if (ret < 0) | 571 | if (num_channels == 0) { |
576 | return ret; | 572 | dev_err(dev, "no LED channels\n"); |
577 | ret = of_property_read_u8_array(np, "led-cur", led_cur, num_channel); | 573 | return -EINVAL; |
578 | if (ret < 0) | 574 | } |
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 | 575 | ||
590 | led_config = devm_kzalloc(dev, sizeof(*led_config) * num_channel, | 576 | cfg = devm_kzalloc(dev, sizeof(*cfg) * num_channels, GFP_KERNEL); |
591 | GFP_KERNEL); | 577 | if (!cfg) |
592 | if (!led_config) | ||
593 | return -ENOMEM; | 578 | return -ENOMEM; |
594 | 579 | ||
595 | for (i = 0; i < num_channel; i++) { | 580 | pdata->led_config = &cfg[0]; |
596 | led_config[i].chan_nr = i; | 581 | pdata->num_channels = num_channels; |
597 | led_config[i].led_current = led_cur[i]; | 582 | |
598 | led_config[i].max_current = max_cur[i]; | 583 | for_each_child_of_node(np, child) { |
584 | cfg[i].chan_nr = i; | ||
585 | |||
586 | of_property_read_string(child, "chan-name", &cfg[i].name); | ||
587 | of_property_read_u8(child, "led-cur", &cfg[i].led_current); | ||
588 | of_property_read_u8(child, "max-cur", &cfg[i].max_current); | ||
589 | |||
590 | i++; | ||
599 | } | 591 | } |
600 | pdata->label = kzalloc(sizeof(char) * 32, GFP_KERNEL); | 592 | |
601 | strcpy((char *)pdata->label, (char *) label); | 593 | of_property_read_string(np, "label", &pdata->label); |
602 | pdata->led_config = &led_config[0]; | 594 | of_property_read_u8(np, "clock-mode", &pdata->clock_mode); |
603 | pdata->num_channels = num_channel; | 595 | |
604 | pdata->clock_mode = clock_mode; | ||
605 | dev->platform_data = pdata; | 596 | dev->platform_data = pdata; |
606 | 597 | ||
607 | return 0; | 598 | return 0; |