From: Sven Schwermer <sven.schwermer@xxxxxxxxxxxxxxxxxxxxxxxxxxx> Hi, This patch series is getting mature. I have removed the RFC tag for this version. The initial discussion happened here [1]. I would appreciate if anyone would test this code. It runs on my i.MX6ULL-based hardware. Best regards, Sven [1]:https://lore.kernel.org/linux-leds/37540afd-f2f1-52dd-f4f1-6e7b436e9595@xxxxxxxxxxxxxxxx/ Sven Schwermer (2): dt-bindings: leds: Add multicolor PWM LED bindings leds: Add PWM multicolor driver .../bindings/leds/leds-pwm-multicolor.yaml | 75 +++++++ drivers/leds/Kconfig | 11 ++ drivers/leds/Makefile | 1 + drivers/leds/leds-pwm-multicolor.c | 186 ++++++++++++++++++ 4 files changed, 273 insertions(+) create mode 100644 Documentation/devicetree/bindings/leds/leds-pwm-multicolor.yaml create mode 100644 drivers/leds/leds-pwm-multicolor.c Interdiff against v4: diff --git a/drivers/leds/leds-pwm-multicolor.c b/drivers/leds/leds-pwm-multicolor.c index 96712b8ca98e..45e38708ecb1 100644 --- a/drivers/leds/leds-pwm-multicolor.c +++ b/drivers/leds/leds-pwm-multicolor.c @@ -58,6 +58,43 @@ static int led_pwm_mc_set(struct led_classdev *cdev, return ret; } +static int iterate_subleds(struct device *dev, struct pwm_mc_led *priv, + struct fwnode_handle *mcnode) +{ + struct mc_subled *subled = priv->mc_cdev.subled_info; + struct fwnode_handle *fwnode; + struct pwm_led *pwmled; + u32 color; + int ret; + + /* iterate over the nodes inside the multi-led node */ + fwnode_for_each_child_node(mcnode, fwnode) { + pwmled = &priv->leds[priv->mc_cdev.num_colors]; + pwmled->pwm = devm_fwnode_pwm_get(dev, fwnode, NULL); + if (IS_ERR(pwmled->pwm)) { + ret = PTR_ERR(pwmled->pwm); + dev_err(dev, "unable to request PWM: %d\n", ret); + goto release_fwnode; + } + pwm_init_state(pwmled->pwm, &pwmled->state); + + ret = fwnode_property_read_u32(fwnode, "color", &color); + if (ret) { + dev_err(dev, "cannot read color: %d\n", ret); + goto release_fwnode; + } + + subled[priv->mc_cdev.num_colors].color_index = color; + priv->mc_cdev.num_colors++; + } + + return 0; + +release_fwnode: + fwnode_handle_put(fwnode); + return ret; +} + static int led_pwm_mc_probe(struct platform_device *pdev) { struct fwnode_handle *mcnode, *fwnode; @@ -65,10 +102,8 @@ static int led_pwm_mc_probe(struct platform_device *pdev) struct led_classdev *cdev; struct mc_subled *subled; struct pwm_mc_led *priv; - struct pwm_led *pwmled; int count = 0; int ret = 0; - u32 color; mcnode = device_get_named_child_node(&pdev->dev, "multi-led"); if (!mcnode) @@ -101,28 +136,9 @@ static int led_pwm_mc_probe(struct platform_device *pdev) cdev->flags = LED_CORE_SUSPENDRESUME; cdev->brightness_set_blocking = led_pwm_mc_set; - /* iterate over the nodes inside the multi-led node */ - fwnode_for_each_child_node(mcnode, fwnode) { - pwmled = &priv->leds[priv->mc_cdev.num_colors]; - pwmled->pwm = devm_fwnode_pwm_get(&pdev->dev, fwnode, NULL); - if (IS_ERR(pwmled->pwm)) { - ret = PTR_ERR(pwmled->pwm); - dev_err(&pdev->dev, "unable to request PWM: %d\n", ret); - fwnode_handle_put(fwnode); - goto release_mcnode; - } - pwm_init_state(pwmled->pwm, &pwmled->state); - - ret = fwnode_property_read_u32(fwnode, "color", &color); - if (ret) { - dev_err(&pdev->dev, "cannot read color: %d\n", ret); - fwnode_handle_put(fwnode); - goto release_mcnode; - } - - subled[priv->mc_cdev.num_colors].color_index = color; - priv->mc_cdev.num_colors++; - } + ret = iterate_subleds(&pdev->dev, priv, mcnode); + if (ret) + goto release_mcnode; init_data.fwnode = mcnode; ret = devm_led_classdev_multicolor_register_ext(&pdev->dev, -- 2.35.1