All of lore.kernel.org
 help / color / mirror / Atom feed
From: Marek Behun <marek.behun@nic.cz>
To: Hermes Zhang <chenhui.zhang@axis.com>
Cc: <pavel@ucw.cz>, <dmurphy@ti.com>, <robh+dt@kernel.org>,
	<linux-leds@vger.kernel.org>, <devicetree@vger.kernel.org>,
	<linux-kernel@vger.kernel.org>, <chenhuiz@axis.com>,
	<lkml@axis.com>, <kernel@axis.com>
Subject: Re: [PATCH 1/2] leds: leds-multi-gpio: Add multiple GPIOs LED driver
Date: Wed, 24 Mar 2021 10:34:31 +0000	[thread overview]
Message-ID: <20210324103431.4b945915@thinkpad> (raw)
In-Reply-To: <20210324075631.5004-2-chenhui.zhang@axis.com>

On Wed, 24 Mar 2021 15:56:30 +0800
Hermes Zhang <chenhui.zhang@axis.com> wrote:

> From: Hermes Zhang <chenhuiz@axis.com>
> 
> Introduce a new multiple GPIOs LED driver. This LED will made of
> multiple GPIOs (up to 8) and will map different brightness to different
> GPIOs states which defined in dts file.

I wonder how many boards have such LEDs.

Also if it wouldn't be better to expand the original leds-gpio driver.
Probably depends on how much larger would such expansion make the
leds-gpio driver.

> +#include <linux/err.h>
> +#include <linux/gpio.h>
> +#include <linux/gpio/consumer.h>
> +#include <linux/kernel.h>
> +#include <linux/leds.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_gpio.h>
> +#include <linux/platform_device.h>
> +#include <linux/property.h>
> +#include <linux/slab.h>

Why do you include slab.h?

> +
> +#define MAX_GPIO_NUM  8
> +
> +struct multi_gpio_led_priv {
> +	struct led_classdev cdev;
> +
> +	struct gpio_descs *gpios;
> +
> +	u8 *states;
> +	int nr_states;
> +};

Use flexible array members. Allocate with
  devm_kzalloc(dev, struct_size(priv, states, priv->nr_states),
               GFP_KERNEL)

> +
> +
> +static void multi_gpio_led_set(struct led_classdev *led_cdev,
> +	enum led_brightness value)
> +{
> +	struct multi_gpio_led_priv *priv;
> +	int idx;
> +
> +	DECLARE_BITMAP(values, MAX_GPIO_NUM);
> +
> +	priv = container_of(led_cdev, struct multi_gpio_led_priv, cdev);
> +
> +	idx = (value - LED_OFF) * priv->nr_states / (LED_FULL + 1);

LED_FULL / LED_OFF are deprecated, don't use them.

> +
> +	values[0] = priv->states[idx];
> +
> +	gpiod_set_array_value(priv->gpios->ndescs, priv->gpios->desc,
> +	    priv->gpios->info, values);
> +}
> +
> +static int multi_gpio_led_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct device_node *node = dev->of_node;
> +	struct multi_gpio_led_priv *priv = NULL;
> +	int ret;
> +	const char *state = NULL;
> +	struct led_init_data init_data = {};
> +
> +	priv = devm_kzalloc(dev, sizeof(struct multi_gpio_led_priv), GFP_KERNEL);
> +	if (!priv)
> +		return -ENOMEM;
> +
> +	priv->gpios = devm_gpiod_get_array(dev, "led", GPIOD_OUT_LOW);
> +	if (IS_ERR(priv->gpios))
> +		return PTR_ERR(priv->gpios);
> +
> +	if (priv->gpios->ndescs >= MAX_GPIO_NUM) {
> +		dev_err(dev, "Too many GPIOs\n");
> +		return -EINVAL;
> +	}
> +
> +	ret = of_property_count_u8_elems(node, "led-states");
> +	if (ret < 0)
> +		return ret;
> +
> +	priv->nr_states = ret;
> +	priv->states = devm_kzalloc(dev, sizeof(*priv->states) * priv->nr_states, GFP_KERNEL);
> +	if (!priv->states)
> +		return -ENOMEM;
> +
> +	ret = of_property_read_u8_array(node, "led-states", priv->states, priv->nr_states);
> +	if (ret)
> +		return ret;
> +
> +	priv->cdev.max_brightness = LED_FULL;

???? max_brightness is not 255 (= LED_FULL). max_brightness must be
derived from the led-states property.


> +	priv->cdev.default_trigger = of_get_property(node, "linux,default-trigger", NULL);
> +	priv->cdev.brightness_set = multi_gpio_led_set;
> +
> +	init_data.fwnode = of_fwnode_handle(node);
> +
> +	ret = devm_led_classdev_register_ext(dev, &priv->cdev, &init_data);
> +	if (ret < 0)
> +		return ret;
> +
> +	of_property_read_string(node, "default-state", &state);
> +	if (!strcmp(state, "on"))
> +		multi_gpio_led_set(&priv->cdev, LED_FULL);
> +	else
> +		multi_gpio_led_set(&priv->cdev, LED_OFF);

Again LED_FULL and LED_OFF...
What about default-state = "keep" ?

Hermes, do you actually have a device that controls LEDs this way? How
many brightness options do they have?

Also I think this functionality could be easily incorporated into the
existing leds-gpio driver, instead of creating new driver.

Moreover your driver can control only one LED, so it needs to be
probed multiple times for multiple LEDs. Meanwhile the leds-gpio driver
can register multiple LEDs in one probe...

Marek

  reply	other threads:[~2021-03-24  9:35 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-03-24  7:56 [PATCH 0/2] New multiple GPIOs LED driver Hermes Zhang
2021-03-24  7:56 ` [PATCH 1/2] leds: leds-multi-gpio: Add " Hermes Zhang
2021-03-24 10:34   ` Marek Behun [this message]
2021-03-24 10:40     ` Pavel Machek
2021-03-24 10:42     ` Pavel Machek
2021-03-25  6:04     ` Hermes Zhang
2021-03-25 12:26       ` Marek Behun
2021-03-24 10:41   ` Pavel Machek
2021-03-24  7:56 ` [PATCH 2/2] dt-binding: leds: Document leds-multi-gpio bindings Hermes Zhang
2021-03-24 10:40   ` Marek Behun
2021-03-25  5:27   ` Vesa Jääskeläinen
2021-03-25 18:41     ` Pavel Machek
2021-03-28 20:46       ` Vesa Jääskeläinen
2021-03-24 10:42 ` [PATCH 0/2] New multiple GPIOs LED driver Marek Behun

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=20210324103431.4b945915@thinkpad \
    --to=marek.behun@nic.cz \
    --cc=chenhui.zhang@axis.com \
    --cc=chenhuiz@axis.com \
    --cc=devicetree@vger.kernel.org \
    --cc=dmurphy@ti.com \
    --cc=kernel@axis.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-leds@vger.kernel.org \
    --cc=lkml@axis.com \
    --cc=pavel@ucw.cz \
    --cc=robh+dt@kernel.org \
    /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.