On 7/12/26 23:38, Ingo Reitz wrote:
> Port the parsing logic for num-interpolated-steps from linux, which populates
> brightness-levels between 2 brightness level by linear interpolation.
> This is useful if the amount of brightness levels exeeds what can
> practically can be written into the devicetree array.
> 
> Signed-off-by: Ingo Reitz <[email protected]>

Reviewed-by: Ahmad Fatoum <[email protected]>

Title (s/backlight/backlight/) can be fixed up on apply time perhaps? 

Cheers,
Ahmad

> ---
>  drivers/video/backlight-pwm.c | 76 ++++++++++++++++++++++++++++++++++-
>  1 file changed, 75 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/video/backlight-pwm.c b/drivers/video/backlight-pwm.c
> index 14fad55637..581fa0237c 100644
> --- a/drivers/video/backlight-pwm.c
> +++ b/drivers/video/backlight-pwm.c
> @@ -12,6 +12,7 @@
>  #include <linux/err.h>
>  #include <of.h>
>  #include <regulator.h>
> +#include <linux/device.h>
>  #include <linux/gpio/consumer.h>
>  #include <linux/math64.h>
>  
> @@ -101,7 +102,9 @@ static int pwm_backlight_parse_dt(struct device *dev,
>  {
>       struct device_node *node = dev->of_node;
>       struct property *prop;
> -     int length;
> +     unsigned int length;
> +
>       unsigned int num_steps = 0;
> +     unsigned int *table;
>       u32 value;
>       int ret, i;
>  
> @@ -134,6 +137,77 @@ static int pwm_backlight_parse_dt(struct device *dev,
>               if (ret < 0)
>                       return ret;
>  
> +             /*
> +              * This property is optional, if is set enables linear
> +              * interpolation between each of the values of brightness levels
> +              * and creates a new pre-computed table.
> +              */
> +             of_property_read_u32(node, "num-interpolated-steps",
> +                                  &num_steps);
> +
> +             if (num_steps) {
> +                     unsigned int num_input_levels = length;
> +                     unsigned int i;
> +                     u32 x1, x2, x, dx;
> +                     u32 y1, y2;
> +                     s64 dy;
> +
> +                     /*
> +                      * Make sure that there is at least two entries in the
> +                      * brightness-levels table, otherwise we can't 
> interpolate
> +                      * between two points.
> +                      */
> +                     if (num_input_levels < 2) {
> +                             dev_err(dev, "can't interpolate\n");
> +                             return -EINVAL;
> +                     }
> +
> +                     /*
> +                      * Recalculate the number of brightness levels, now
> +                      * taking in consideration the number o
> f interpolated
> +                      * steps between two levels.
> +                      */
> +                     length = (num_input_levels - 1) * num_steps + 1;
> +                     dev_dbg(dev, "new number of brightness levels: %d\n",
> +                             length);
> +
> +                     /*
> +                      * Create a new table of brightness levels with all the
> +                      * interpolated steps.
> +                      */
> +                     table = devm_kcalloc(dev, length, sizeof(*table),
> +                                          GFP_KERNEL);
> +                     if (!table)
> +                             return -ENOMEM;
> +                     /*
> +                      * Fill the interpolated table[x] = y
> +                      * by draw lines between each (x1, y1) to (x2, y2).
> +                      */
> +                     dx = num_steps;
> +                     for (i = 0; i < num_input_levels - 1; i++) {
> +                             x1 = i * dx;
> +                             x2 = x1 + dx;
> +                             y1 = pwm_backlight->levels[i];
> +                             y2 = pwm_backlight->levels[i + 1];
> +                             dy = (s64)y2 - y1;
> +
> +                             for (x = x1; x < x2; x++) {
> +                                     table[x] =
> +                                             y1 + div_s64(dy * (x - x1), dx);
> +                             }
> +                     }
> +                     /* Fill in the last point, since no line starts here. */
> +                     table[x2] = y2;
> +
> +                     /*
> +                      * As we use interpolation lets remove current
> 
> +                      * brightness levels table and replace for the
> +                      * new interpolated table.
> +                      */
> +                     devm_kfree(dev, pwm_backlight->levels);
> +                     pwm_backlight->levels = table;
> +             }
> +
>               pwm_backlight->backlight.brightness_max = length - 1;
>  
>               for (i = 0; i < length; i++)


-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

Reply via email to