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

leds: lp55xx: support dynamic channel settings in the device tree structure

Currently, the LP55xx DT structure supports max 3 channels.
However, LP5523 has max 9 channels and LP5562 has 4 channels.
To enhance this constraint, the DT structure has been changed.

(a) Use the child node for various channel settings instead of fixed array
(b) Remove 'num_channel' property.
This value can be retrieved by counting the children node.
(c) 'chan-name' property supported
(d) Documentation updates for LP5521 and LP5523

(cooloney@gmail.com: fix a coding style issue in leds-lp55xx.txt)

Cc: Gabriel Fernandez <gabriel.fernandez@stericsson.com>
Signed-off-by: Milo(Woogyom) Kim <milo.kim@ti.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Bryan Wu <cooloney@gmail.com>

authored by

Kim, Milo and committed by
Bryan Wu
2dac9128 a036e4cd

+128 -44
+102 -9
Documentation/devicetree/bindings/leds/leds-lp55xx.txt
··· 2 2 3 3 Required properties: 4 4 - compatible: "national,lp5521" or "national,lp5523" 5 - - label: Used for naming LEDs 6 - - num-channel: Number of LED channels 7 - - 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. 5 + - reg: I2C slave address 9 6 - clock-mode: Input clock mode, (0: automode, 1: internal, 2: external) 10 7 11 - example: 8 + Each child has own specific current settings 9 + - led-cur: Current setting at each led channel (mA x10, 0 if led is not connected) 10 + - max-cur: Maximun current at each led channel. 11 + 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 22 lp5521@32 { 14 23 compatible = "national,lp5521"; 15 24 reg = <0x32>; 16 25 label = "lp5521_pri"; 17 - num-channel = /bits/ 8 <3>; 18 - led-cur = /bits/ 8 <0x2f 0x2f 0x2f>; 19 - max-cur = /bits/ 8 <0x5f 0x5f 0x5f>; 20 - clock-mode = /bits/8 <2>; 26 + clock-mode = /bits/ 8 <2>; 27 + 28 + chan0 { 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 };
+26 -35
drivers/leds/leds-lp55xx-common.c
··· 557 557 558 558 int lp55xx_of_populate_pdata(struct device *dev, struct device_node *np) 559 559 { 560 + struct device_node *child; 560 561 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; 562 + struct lp55xx_led_config *cfg; 563 + int num_channels; 564 + int i = 0; 569 565 570 566 pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); 571 567 if (!pdata) 572 568 return -ENOMEM; 573 569 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; 570 + num_channels = of_get_child_count(np); 571 + if (num_channels == 0) { 572 + dev_err(dev, "no LED channels\n"); 573 + return -EINVAL; 574 + } 589 575 590 - led_config = devm_kzalloc(dev, sizeof(*led_config) * num_channel, 591 - GFP_KERNEL); 592 - if (!led_config) 576 + cfg = devm_kzalloc(dev, sizeof(*cfg) * num_channels, GFP_KERNEL); 577 + if (!cfg) 593 578 return -ENOMEM; 594 579 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]; 580 + pdata->led_config = &cfg[0]; 581 + pdata->num_channels = num_channels; 582 + 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); 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; 592 + 593 + of_property_read_string(np, "label", &pdata->label); 594 + of_property_read_u8(np, "clock-mode", &pdata->clock_mode); 595 + 605 596 dev->platform_data = pdata; 606 597 607 598 return 0;