[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <pbbqct3a7ft466aerdkm6k5kmwstfgpbegrakfvdxzj2tdpdyu@pws3zzu4sfiq>
Date: Mon, 5 Jan 2026 09:38:44 -0600
From: Bjorn Andersson <andersson@...nel.org>
To: Sudarshan Shetty <tessolveupstream@...il.com>
Cc: konradybcio@...nel.org, robh@...nel.org, krzk+dt@...nel.org,
conor+dt@...nel.org, linux-arm-msm@...r.kernel.org, devicetree@...r.kernel.org,
linux-kernel@...r.kernel.org
Subject: Re: [PATCH v10 3/5] backlight: gpio: add support for multiple GPIOs
for backlight control
On Tue, Dec 30, 2025 at 06:32:25PM +0530, Sudarshan Shetty wrote:
> Extend the gpio-backlight driver to handle multiple GPIOs instead of a
> single one. This allows panels that require driving several enable pins
> to be controlled by the backlight framework.
Can you please elaborate on the problem described here. Preferrably in
the form described in
https://docs.kernel.org/process/submitting-patches.html#describe-your-changes,
i.e. start with your problem description, then a description of your
solution.
What does it mean for a backlight device to have multiple enable GPIOs?
PS. The associated binding patch needs to be merged before the
DeviceTree (dts) changes can be merged, but it would be more efficient
to upstream them separately - as each set of reviewers could focus on
their part and you could update the patches based on the feedback from
each part.
Regards,
Bjorn
>
> Signed-off-by: Sudarshan Shetty <tessolveupstream@...il.com>
> ---
> drivers/video/backlight/gpio_backlight.c | 61 +++++++++++++++++-------
> 1 file changed, 45 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/video/backlight/gpio_backlight.c b/drivers/video/backlight/gpio_backlight.c
> index 728a546904b0..037e1c111e48 100644
> --- a/drivers/video/backlight/gpio_backlight.c
> +++ b/drivers/video/backlight/gpio_backlight.c
> @@ -17,14 +17,18 @@
>
> struct gpio_backlight {
> struct device *dev;
> - struct gpio_desc *gpiod;
> + struct gpio_desc **gpiods;
> + unsigned int num_gpios;
> };
>
> static int gpio_backlight_update_status(struct backlight_device *bl)
> {
> struct gpio_backlight *gbl = bl_get_data(bl);
> + unsigned int i;
> + int br = backlight_get_brightness(bl);
>
> - gpiod_set_value_cansleep(gbl->gpiod, backlight_get_brightness(bl));
> + for (i = 0; i < gbl->num_gpios; i++)
> + gpiod_set_value_cansleep(gbl->gpiods[i], br);
>
> return 0;
> }
> @@ -52,6 +56,7 @@ static int gpio_backlight_probe(struct platform_device *pdev)
> struct backlight_device *bl;
> struct gpio_backlight *gbl;
> int ret, init_brightness, def_value;
> + unsigned int i;
>
> gbl = devm_kzalloc(dev, sizeof(*gbl), GFP_KERNEL);
> if (gbl == NULL)
> @@ -62,10 +67,22 @@ static int gpio_backlight_probe(struct platform_device *pdev)
>
> def_value = device_property_read_bool(dev, "default-on");
>
> - gbl->gpiod = devm_gpiod_get(dev, NULL, GPIOD_ASIS);
> - if (IS_ERR(gbl->gpiod))
> - return dev_err_probe(dev, PTR_ERR(gbl->gpiod),
> - "The gpios parameter is missing or invalid\n");
> + gbl->num_gpios = gpiod_count(dev, NULL);
> + if (gbl->num_gpios == 0)
> + return dev_err_probe(dev, -EINVAL,
> + "The gpios parameter is missing or invalid\n");
> + gbl->gpiods = devm_kcalloc(dev, gbl->num_gpios, sizeof(*gbl->gpiods),
> + GFP_KERNEL);
> + if (!gbl->gpiods)
> + return -ENOMEM;
> +
> + for (i = 0; i < gbl->num_gpios; i++) {
> + gbl->gpiods[i] =
> + devm_gpiod_get_index(dev, NULL, i, GPIOD_ASIS);
> + if (IS_ERR(gbl->gpiods[i]))
> + return dev_err_probe(dev, PTR_ERR(gbl->gpiods[i]),
> + "Failed to get GPIO at index %u\n", i);
> + }
>
> memset(&props, 0, sizeof(props));
> props.type = BACKLIGHT_RAW;
> @@ -78,22 +95,34 @@ static int gpio_backlight_probe(struct platform_device *pdev)
> }
>
> /* Set the initial power state */
> - if (!of_node || !of_node->phandle)
> + if (!of_node || !of_node->phandle) {
> /* Not booted with device tree or no phandle link to the node */
> bl->props.power = def_value ? BACKLIGHT_POWER_ON
> - : BACKLIGHT_POWER_OFF;
> - else if (gpiod_get_value_cansleep(gbl->gpiod) == 0)
> - bl->props.power = BACKLIGHT_POWER_OFF;
> - else
> - bl->props.power = BACKLIGHT_POWER_ON;
> + : BACKLIGHT_POWER_OFF;
> + } else {
> + bool all_high = true;
> +
> + for (i = 0; i < gbl->num_gpios; i++) {
> + if (gpiod_get_value_cansleep(gbl->gpiods[i]) != 0) {
> + all_high = false;
> + break;
> + }
> + }
> +
> + bl->props.power =
> + all_high ? BACKLIGHT_POWER_ON : BACKLIGHT_POWER_OFF;
> + }
>
> bl->props.brightness = 1;
>
> init_brightness = backlight_get_brightness(bl);
> - ret = gpiod_direction_output(gbl->gpiod, init_brightness);
> - if (ret) {
> - dev_err(dev, "failed to set initial brightness\n");
> - return ret;
> +
> + for (i = 0; i < gbl->num_gpios; i++) {
> + ret = gpiod_direction_output(gbl->gpiods[i], init_brightness);
> + if (ret)
> + return dev_err_probe(dev, ret,
> + "failed to set gpio %u direction\n",
> + i);
> }
>
> platform_set_drvdata(pdev, bl);
> --
> 2.34.1
>
Powered by blists - more mailing lists