From: Lee Jones <lee@kernel.org>
To: Jean-Jacques Hiblot <jjhiblot@traphandler.com>
Cc: lee.jones@linaro.org, pavel@ucw.cz, robh+dt@kernel.org,
sven.schwermer@disruptive-technologies.com,
krzysztof.kozlowski+dt@linaro.org, johan+linaro@kernel.org,
marijn.suijten@somainline.org, andy.shevchenko@gmail.com,
jacek.anaszewski@gmail.com, linux-leds@vger.kernel.org,
devicetree@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH v7 6/6] leds: Add a multicolor LED driver to group monochromatic LEDs
Date: Wed, 15 Mar 2023 15:52:41 +0000 [thread overview]
Message-ID: <20230315155241.GA9667@google.com> (raw)
In-Reply-To: <20230102081021.138648-7-jjhiblot@traphandler.com>
On Mon, 02 Jan 2023, Jean-Jacques Hiblot wrote:
> By allowing to group multiple monochrome LED into multicolor LEDs,
Nit: s/LED/LEDs/
> all involved LEDs can be controlled in-sync. This enables using effects
> using triggers, etc.
Too many "using"s. Please reword.
> Signed-off-by: Jean-Jacques Hiblot <jjhiblot@traphandler.com>
> ---
> drivers/leds/rgb/Kconfig | 10 ++
> drivers/leds/rgb/Makefile | 1 +
> drivers/leds/rgb/leds-group-multicolor.c | 166 +++++++++++++++++++++++
> 3 files changed, 177 insertions(+)
> create mode 100644 drivers/leds/rgb/leds-group-multicolor.c
>
> diff --git a/drivers/leds/rgb/Kconfig b/drivers/leds/rgb/Kconfig
> index 204cf470beae..1a87f53faa8a 100644
> --- a/drivers/leds/rgb/Kconfig
> +++ b/drivers/leds/rgb/Kconfig
> @@ -2,6 +2,16 @@
>
> if LEDS_CLASS_MULTICOLOR
>
> +config LEDS_GRP_MULTICOLOR
Shortening "GROUP" saves nothing here and hurts readability.
Please expand it.
> + tristate "Multi-color LED grouping support"
Is it "multi-color group" or "group multi-color"?
Please be consistent throughout the whole driver.
I suggest "LEDs group multi-color" throughout.
> + depends on COMPILE_TEST || OF
These usually appear the other way around.
> + help
> + This option enables support for monochrome LEDs that are
> + grouped into multicolor LEDs.
Useful because ...
> + To compile this driver as a module, choose M here: the module
> + will be called leds-grp-multicolor.
> +
> config LEDS_PWM_MULTICOLOR
> tristate "PWM driven multi-color LED Support"
> depends on PWM
> diff --git a/drivers/leds/rgb/Makefile b/drivers/leds/rgb/Makefile
> index 0675bc0f6e18..4de087ad79bc 100644
> --- a/drivers/leds/rgb/Makefile
> +++ b/drivers/leds/rgb/Makefile
> @@ -1,4 +1,5 @@
> # SPDX-License-Identifier: GPL-2.0
>
> +obj-$(CONFIG_LEDS_GRP_MULTICOLOR) += leds-group-multicolor.o
> obj-$(CONFIG_LEDS_PWM_MULTICOLOR) += leds-pwm-multicolor.o
> obj-$(CONFIG_LEDS_QCOM_LPG) += leds-qcom-lpg.o
> diff --git a/drivers/leds/rgb/leds-group-multicolor.c b/drivers/leds/rgb/leds-group-multicolor.c
> new file mode 100644
> index 000000000000..1c99bedf8979
> --- /dev/null
> +++ b/drivers/leds/rgb/leds-group-multicolor.c
> @@ -0,0 +1,166 @@
> +// SPDX-License-Identifier: GPL-2.0-only
Why "only"?
> +/*
> + * multi-color LED built with monochromatic LED devices
Please expand a little.
> + * Copyright 2022 Jean-Jacques Hiblot <jjhiblot@traphandler.com>
Please update.
> + */
> +
> +#include <linux/err.h>
> +#include <linux/leds.h>
> +#include <linux/led-class-multicolor.h>
> +#include <linux/math.h>
> +#include <linux/module.h>
> +#include <linux/mod_devicetable.h>
> +#include <linux/platform_device.h>
> +#include <linux/property.h>
> +
> +struct led_mcg_priv {
Open out "mcg" everywhere.
Readability / maintainability is a high priority.
> + struct led_classdev_mc mc_cdev;
> + struct led_classdev **monochromatics;
If this is an array, better to be explicit.
*monochromatics[];
> +};
> +
> +static int led_mcg_set(struct led_classdev *cdev,
> + enum led_brightness brightness)
> +{
> + struct led_classdev_mc *mc_cdev = lcdev_to_mccdev(cdev);
> + struct led_mcg_priv *priv = container_of(mc_cdev, struct led_mcg_priv, mc_cdev);
> + const unsigned int mc_max_brightness = mc_cdev->led_cdev.max_brightness;
> + int i;
> +
> + for (i = 0; i < mc_cdev->num_colors; i++) {
> + struct led_classdev *mono = priv->monochromatics[i];
> + const unsigned int mono_max = mono->max_brightness;
You lose the meaning of the variable here.
"mono_max" max what?
> + unsigned int rel_intensity = mc_cdev->subled_info[i].intensity;
> + int b;
'b' is a terrible name for a variable.
> + /*
> + * Scale the brightness according to relative intensity of the
> + * color AND the max brightness of the monochromatic LED.
> + */
> + b = DIV_ROUND_CLOSEST(brightness * rel_intensity * mono_max,
> + mc_max_brightness * mc_max_brightness);
> +
> + led_set_brightness(mono, b);
> + }
> +
> + return 0;
> +}
> +
> +static void restore_sysfs_access(void *data)
> +{
> + struct led_classdev *led_cdev = data;
> +
> + mutex_lock(&led_cdev->led_access);
> + led_sysfs_enable(led_cdev);
> + mutex_unlock(&led_cdev->led_access);
> +}
> +
> +static int led_mcg_probe(struct platform_device *pdev)
> +{
> + struct device *dev = &pdev->dev;
> + struct led_init_data init_data = {};
> + struct led_classdev *cdev;
> + struct mc_subled *subled;
> + struct led_mcg_priv *priv;
> + unsigned int max_brightness;
> + int i, count, ret;
> +
> + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> + if (!priv)
> + return -ENOMEM;
> +
> + count = 0;
> + max_brightness = 0;
Initialise these during definition.
> + for (;;) {
> + struct led_classdev *led_cdev;
> +
> + led_cdev = devm_of_led_get_optional(dev, count);
> + if (IS_ERR(led_cdev))
Doesn't devm_of_led_get_optional() return NULL on failure?
> + return dev_err_probe(dev, PTR_ERR(led_cdev),
> + "Unable to get led #%d", count);
> + /* Reached the end of the list ?*/
Besides the incorrect formatting, that '?' isn't filling me with
confidence.
> + if (!led_cdev)
> + break;
> +
> + priv->monochromatics = devm_krealloc_array(dev, priv->monochromatics,
> + count + 1, sizeof(*priv->monochromatics),
> + GFP_KERNEL);
> + if (!priv->monochromatics)
> + return -ENOMEM;
> +
> + priv->monochromatics[count] = led_cdev;
> +
> + max_brightness = max(max_brightness, led_cdev->max_brightness);
> + count++;
> + }
> +
> + subled = devm_kcalloc(dev, count, sizeof(*subled), GFP_KERNEL);
> + if (!subled)
> + return -ENOMEM;
> + priv->mc_cdev.subled_info = subled;
> +
> + for (i = 0; i < count; i++) {
> + struct led_classdev *led_cdev = priv->monochromatics[i];
> +
> + subled[i].color_index = led_cdev->color;
'\n'
> + /* configure the LED intensity to its maximum */
Use correct grammar in comments please.
Start with an uppercase char.
> + subled[i].intensity = max_brightness;
> + }
> +
> + /* init the multicolor's LED class device */
As above and please be fully forthcoming in comments: "Initialise".
> + cdev = &priv->mc_cdev.led_cdev;
> + cdev->flags = LED_CORE_SUSPENDRESUME;
> + cdev->brightness_set_blocking = led_mcg_set;
> + cdev->max_brightness = max_brightness;
> + cdev->color = LED_COLOR_ID_MULTI;
> + priv->mc_cdev.num_colors = count;
> +
> + init_data.fwnode = dev_fwnode(dev);
> + ret = devm_led_classdev_multicolor_register_ext(dev, &priv->mc_cdev,
> + &init_data);
Use the full 100-char limit everywhere please.
> + if (ret)
> + return dev_err_probe(dev, ret,
> + "failed to register multicolor led for %s.\n",
"LED"
> + cdev->name);
> +
> + ret = led_mcg_set(cdev, cdev->brightness);
> + if (ret)
> + return dev_err_probe(dev, ret,
> + "failed to set led value for %s.",
> + cdev->name);
> +
> + for (i = 0; i < count; i++) {
> + struct led_classdev *led_cdev = priv->monochromatics[i];
> +
> + /* Make the sysfs of the monochromatic LED read-only */
> + mutex_lock(&led_cdev->led_access);
> + led_sysfs_disable(led_cdev);
> + mutex_unlock(&led_cdev->led_access);
> +
> + /* Restore sysfs access when the multicolor LED is released */
> + devm_add_action_or_reset(dev, restore_sysfs_access, led_cdev);
> + }
> +
> + return 0;
> +}
> +
> +static const struct of_device_id of_led_mcg_match[] = {
> + { .compatible = "leds-group-multicolor" },
> + {}
> +};
> +MODULE_DEVICE_TABLE(of, of_led_mcg_match);
> +
> +static struct platform_driver led_mcg_driver = {
> + .probe = led_mcg_probe,
> + .driver = {
> + .name = "leds_group_multicolor",
> + .of_match_table = of_led_mcg_match,
> + }
> +};
> +module_platform_driver(led_mcg_driver);
> +
> +MODULE_AUTHOR("Jean-Jacques Hiblot <jjhiblot@traphandler.com>");
> +MODULE_DESCRIPTION("multi-color LED group driver");
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS("platform:leds-group-multicolor");
> --
> 2.25.1
>
--
Lee Jones [李琼斯]
next prev parent reply other threads:[~2023-03-15 15:53 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-01-02 8:10 [PATCH v7 0/6] Add a multicolor LED driver for groups of monochromatic LEDs Jean-Jacques Hiblot
2023-01-02 8:10 ` [PATCH v7 1/6] devres: provide devm_krealloc_array() Jean-Jacques Hiblot
2023-01-02 8:10 ` [PATCH v7 2/6] leds: class: simplify the implementation of devm_of_led_get() Jean-Jacques Hiblot
2023-01-02 8:10 ` [PATCH v7 3/6] leds: provide devm_of_led_get_optional() Jean-Jacques Hiblot
2023-01-02 8:10 ` [PATCH v7 4/6] leds: class: store the color index in struct led_classdev Jean-Jacques Hiblot
2023-01-02 8:10 ` [PATCH v7 5/6] dt-bindings: leds: Add binding for a multicolor group of LEDs Jean-Jacques Hiblot
2023-01-02 8:10 ` [PATCH v7 6/6] leds: Add a multicolor LED driver to group monochromatic LEDs Jean-Jacques Hiblot
2023-03-15 15:52 ` Lee Jones [this message]
2023-03-28 15:31 ` Jean-Jacques Hiblot
2023-01-09 17:19 ` [PATCH v7 0/6] Add a multicolor LED driver for groups of " Lee Jones
2023-02-20 21:10 ` Jean-Jacques Hiblot
2023-02-22 15:04 ` Lee Jones
2023-03-15 15:53 ` Lee Jones
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230315155241.GA9667@google.com \
--to=lee@kernel.org \
--cc=andy.shevchenko@gmail.com \
--cc=devicetree@vger.kernel.org \
--cc=jacek.anaszewski@gmail.com \
--cc=jjhiblot@traphandler.com \
--cc=johan+linaro@kernel.org \
--cc=krzysztof.kozlowski+dt@linaro.org \
--cc=lee.jones@linaro.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-leds@vger.kernel.org \
--cc=marijn.suijten@somainline.org \
--cc=pavel@ucw.cz \
--cc=robh+dt@kernel.org \
--cc=sven.schwermer@disruptive-technologies.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.