Re: [PATCH] video: backlicht-pwm: parse num-interpolated-steps
Ahmad Fatoum <[email protected]> Mon, 20 Jul 2026 10:32:55 +0200
| Newsgroups | org.infradead.lists.barebox |
|---|---|
| Message-ID | <[email protected]> |
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 |