devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/4] backlight: pwm_bl: support linear interpolation and brightness to human eye
@ 2018-01-10 22:30 Enric Balletbo i Serra
  2018-01-10 22:30 ` [PATCH 1/4] backlight: pwm_bl: linear interpolation between brightness-levels Enric Balletbo i Serra
                   ` (3 more replies)
  0 siblings, 4 replies; 11+ messages in thread
From: Enric Balletbo i Serra @ 2018-01-10 22:30 UTC (permalink / raw)
  To: Daniel Thompson, Doug Anderson, Pavel Machek, Rob Herring
  Cc: Jingoo Han, Richard Purdie, Jacek Anaszewski, Brian Norris,
	Guenter Roeck, Lee Jones, Alexandru Stan, linux-leds, devicetree,
	linux-kernel

Dear all,

This series is a first patchset based on the discussion of two previous RFCs
[1] and [2].

The first and second patch what tries to solve is the problem of granularity
for high resolution PWMs. The idea is simple interpolate between 2
brightness values so we can have a high PWM duty cycle (a 16 bits PWM is up
to 65535 possible steps) without having to list out every possible value in
the dts. I think that this patch is required to not break backward
compability, to be more flexible and also extend the functionality to be
able to use high resolution PWM with enough steps to have a good UI
experience in userspace.

The thirth and fourth patch is a bit more ambicious, the idea is let decide
the driver the brightness-levels required in function of the PWM resolution.
To do this create a brightness-levels table filled with the CIE 1931
algorithm values to convert brightness to PWM duty cycle.

More detailed info is available in the commit message of every patch.

Both functionalities were tested on a Samsung Chromebook Plus (that has a
16 bits PWM) and a SL50 device (with a 8 bits PWM)

Waiting for your feedback.

[1] http://www.spinics.net/lists/devicetree/msg193262.html
[2] https://lkml.org/lkml/2017/11/16/301

Best regards,

Enric Balletbo i Serra (4):
  backlight: pwm_bl: linear interpolation between brightness-levels
  dt-bindings: pwm-backlight: add a num-interpolation-steps property.
  backlight: pwm_bl: compute brightness of LED linearly to human eye.
  dt-bindings: pwm-backlight: move brightness-levels to optional.

 .../bindings/leds/backlight/pwm-backlight.txt      |  36 +++-
 drivers/video/backlight/pwm_bl.c                   | 237 +++++++++++++++++++--
 2 files changed, 253 insertions(+), 20 deletions(-)

-- 
2.15.1

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 1/4] backlight: pwm_bl: linear interpolation between brightness-levels
  2018-01-10 22:30 [PATCH 0/4] backlight: pwm_bl: support linear interpolation and brightness to human eye Enric Balletbo i Serra
@ 2018-01-10 22:30 ` Enric Balletbo i Serra
  2018-01-10 22:30 ` [PATCH 2/4] dt-bindings: pwm-backlight: add a num-interpolation-steps property Enric Balletbo i Serra
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 11+ messages in thread
From: Enric Balletbo i Serra @ 2018-01-10 22:30 UTC (permalink / raw)
  To: Daniel Thompson, Doug Anderson, Pavel Machek, Rob Herring
  Cc: Jingoo Han, Richard Purdie, Jacek Anaszewski, Brian Norris,
	Guenter Roeck, Lee Jones, Alexandru Stan, linux-leds, devicetree,
	linux-kernel

Setting num-interpolated-steps in the dts will allow you to have linear
interpolation between values of brightness-levels. This way a high
resolution pwm duty cycle can be used without having to list out every
possible value in the dts. This system also allows for gamma corrected
values.

The most simple example is interpolate between two brightness values a
number of steps, this can be done setting the following in the dts:

  brightness-levels = <0 65535>;
  num-interpolated-steps = <1024>;
  default-brightness-level = <512>;

This will create a brightness-level table with the following values:

  <0 63 126 189 252 315 378 441 ... 64260 64323 64386 64449 65535>

Another use case can be describe a gamma corrected curve, as we have
better sensitivity at low luminance than high luminance we probably
want have smaller steps for low brightness levels values and bigger
steps for high brightness levels values. This can be achieved with
the following in the dts:

  brightness-levels = <0 4096 65535>;
  num-interpolated-steps = <1024>;
  default-brightness-level = <512>;

This will create a brightness-levels table with the following values:

  <0 4 8 12 16 20 ... 4096 4156 4216 4276 ... 65535>

Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
---
Changes since RFCv2:
- Replace use-linear-interpolation for num-interpolated-steps so it's
  more flexible to specify any kind of curve to the user.
- Reworked the code to interpolate between two points.
  - Pre-compute the brightness-levels table at boot.
Changes since RFCv1:
- Add linear interpolation for high resolution PWM.

 drivers/video/backlight/pwm_bl.c | 88 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 88 insertions(+)

diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c
index 8e3f1245f5c5..eabe0a4462af 100644
--- a/drivers/video/backlight/pwm_bl.c
+++ b/drivers/video/backlight/pwm_bl.c
@@ -147,7 +147,11 @@ static int pwm_backlight_parse_dt(struct device *dev,
 				  struct platform_pwm_backlight_data *data)
 {
 	struct device_node *node = dev->of_node;
+	unsigned int num_levels = 0;
+	unsigned int levels_count;
+	unsigned int num_steps;
 	struct property *prop;
+	unsigned int *table;
 	int length;
 	u32 value;
 	int ret;
@@ -167,6 +171,7 @@ static int pwm_backlight_parse_dt(struct device *dev,
 	/* read brightness levels from DT property */
 	if (data->max_brightness > 0) {
 		size_t size = sizeof(*data->levels) * data->max_brightness;
+		unsigned int i, j, n = 0;
 
 		data->levels = devm_kzalloc(dev, size, GFP_KERNEL);
 		if (!data->levels)
@@ -184,6 +189,89 @@ static int pwm_backlight_parse_dt(struct device *dev,
 			return ret;
 
 		data->dft_brightness = value;
+
+		/*
+		 * 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.
+		 */
+		ret = of_property_read_u32(node, "num-interpolated-steps",
+					   &num_steps);
+		if (ret < 0)
+			return ret;
+
+		/*
+		 * Make sure that there is at least two entries in the
+		 * brightness-levels table, otherwise we can't interpolate
+		 * between two points.
+		 */
+		if (num_steps) {
+			if (data->max_brightness < 2) {
+				dev_err(dev, "can't interpolate\n");
+				return -EINVAL;
+			}
+
+			/*
+			 * Recalculate the number of brightness levels, now
+			 * taking in consideration the number of interpolated
+			 * steps between two levels.
+			 */
+			for (i = 0; i < data->max_brightness - 1; i++) {
+				if ((data->levels[i + 1] - data->levels[i]) /
+				   num_steps)
+					num_levels += num_steps;
+				else
+					num_levels++;
+			}
+			num_levels++;
+			dev_dbg(dev, "new number of brightness levels: %d\n",
+				num_levels);
+
+			/*
+			 * Create a new table of brightness levels with all the
+			 * interpolated steps.
+			 */
+			table = kcalloc(num_levels, sizeof(*table), GFP_KERNEL);
+			if (!table)
+				return -ENOMEM;
+
+			/* Fill the interpolated table. */
+			levels_count = 0;
+			for (i = 0; i < data->max_brightness - 1; i++) {
+				value = data->levels[i];
+				n = (data->levels[i + 1] - value) / num_steps;
+				if (n > 0) {
+					for (j = 0; j < num_steps; j++) {
+						table[levels_count] = value;
+						value += n;
+						levels_count++;
+					}
+				} else {
+					table[levels_count] = data->levels[i];
+					levels_count++;
+				}
+			}
+			table[levels_count] = data->levels[i];
+
+			/*
+			 * As we use interpolation lets remove current
+			 * brightness levels table for the new interpolated
+			 * table.
+			 */
+			devm_kfree(dev, data->levels);
+			data->levels = devm_kcalloc(dev, num_levels,
+						    sizeof(*data->levels),
+						    GFP_KERNEL);
+			memcpy(data->levels, table,
+			       num_levels * sizeof(*table));
+			kfree(table);
+			/*
+			 * Reassign max_brightness value to the new total number
+			 * of brightness levels.
+			 */
+			data->max_brightness = num_levels;
+		}
+
 		data->max_brightness--;
 	}
 
-- 
2.15.1

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 2/4] dt-bindings: pwm-backlight: add a num-interpolation-steps property.
  2018-01-10 22:30 [PATCH 0/4] backlight: pwm_bl: support linear interpolation and brightness to human eye Enric Balletbo i Serra
  2018-01-10 22:30 ` [PATCH 1/4] backlight: pwm_bl: linear interpolation between brightness-levels Enric Balletbo i Serra
@ 2018-01-10 22:30 ` Enric Balletbo i Serra
  2018-01-19 20:52   ` Rob Herring
  2018-01-10 22:30 ` [PATCH 3/4] backlight: pwm_bl: compute brightness of LED linearly to human eye Enric Balletbo i Serra
  2018-01-10 22:30 ` [PATCH 4/4] dt-bindings: pwm-backlight: move brightness-levels to optional Enric Balletbo i Serra
  3 siblings, 1 reply; 11+ messages in thread
From: Enric Balletbo i Serra @ 2018-01-10 22:30 UTC (permalink / raw)
  To: Daniel Thompson, Doug Anderson, Pavel Machek, Rob Herring
  Cc: Jingoo Han, Richard Purdie, Jacek Anaszewski, Brian Norris,
	Guenter Roeck, Lee Jones, Alexandru Stan, linux-leds, devicetree,
	linux-kernel

The num-interpolated-steps property specifies the number of
interpolated steps between each value of brightness-level table. This is
useful for high resolution PWMs to not have to list out every possible
value in the brightness-level array.

Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
---
 .../bindings/leds/backlight/pwm-backlight.txt       | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/Documentation/devicetree/bindings/leds/backlight/pwm-backlight.txt b/Documentation/devicetree/bindings/leds/backlight/pwm-backlight.txt
index 310810906613..605432c910c5 100644
--- a/Documentation/devicetree/bindings/leds/backlight/pwm-backlight.txt
+++ b/Documentation/devicetree/bindings/leds/backlight/pwm-backlight.txt
@@ -21,6 +21,11 @@ Optional properties:
                           and enabling the backlight using GPIO.
   - pwm-off-delay-ms: Delay in ms between disabling the backlight using GPIO
                       and setting PWM value to 0.
+  - num-interpolated-steps: Number of interpolated steps between each value
+                            of brightness-levels table. This way a high
+                            resolution pwm duty cycle can be used without
+                            having to list out every possible value in the
+                            brightness-level array.
 
 [0]: Documentation/devicetree/bindings/pwm/pwm.txt
 [1]: Documentation/devicetree/bindings/gpio/gpio.txt
@@ -39,3 +44,19 @@ Example:
 		post-pwm-on-delay-ms = <10>;
 		pwm-off-delay-ms = <10>;
 	};
+
+Example using num-interpolation-steps:
+
+	backlight {
+		compatible = "pwm-backlight";
+		pwms = <&pwm 0 5000000>;
+
+		brightness-levels = <0 65535>;
+		num-interpolated-steps = <4096>;
+		default-brightness-level = <6>;
+
+		power-supply = <&vdd_bl_reg>;
+		enable-gpios = <&gpio 58 0>;
+		post-pwm-on-delay-ms = <10>;
+		pwm-off-delay-ms = <10>;
+	};
-- 
2.15.1

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 3/4] backlight: pwm_bl: compute brightness of LED linearly to human eye.
  2018-01-10 22:30 [PATCH 0/4] backlight: pwm_bl: support linear interpolation and brightness to human eye Enric Balletbo i Serra
  2018-01-10 22:30 ` [PATCH 1/4] backlight: pwm_bl: linear interpolation between brightness-levels Enric Balletbo i Serra
  2018-01-10 22:30 ` [PATCH 2/4] dt-bindings: pwm-backlight: add a num-interpolation-steps property Enric Balletbo i Serra
@ 2018-01-10 22:30 ` Enric Balletbo i Serra
       [not found]   ` <20180110223046.17696-4-enric.balletbo-ZGY8ohtN/8qB+jHODAdFcQ@public.gmane.org>
  2018-01-10 22:30 ` [PATCH 4/4] dt-bindings: pwm-backlight: move brightness-levels to optional Enric Balletbo i Serra
  3 siblings, 1 reply; 11+ messages in thread
From: Enric Balletbo i Serra @ 2018-01-10 22:30 UTC (permalink / raw)
  To: Daniel Thompson, Doug Anderson, Pavel Machek, Rob Herring
  Cc: Jingoo Han, Richard Purdie, Jacek Anaszewski, Brian Norris,
	Guenter Roeck, Lee Jones, Alexandru Stan, linux-leds, devicetree,
	linux-kernel

When you want to change the brightness using a PWM signal, one thing you
need to consider is how human perceive the brightness. Human perceive
the brightness change non-linearly, we have better sensitivity at low
luminance than high luminance, so to achieve perceived linear dimming,
the brightness must be matches to the way our eyes behave. The CIE 1931
lightness formula is what actually describes how we perceive light.

This patch computes a default table with the brightness levels filled
with the numbers provided by the CIE 1931 algorithm, the number of the
brightness levels is calculated based on the PWM resolution.

The calculation of the table using the CIE 1931 algorithm is enabled by
default when you do not define the 'brightness-levels' propriety in your
device tree.

Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
---
Changes since RFCv2:
- Pre-compute the table at boot using the cie 1931 algorithm, this
  introduced again the fixed point calculations that needs to be
  reviewed.
- Calculate the number of needed steps based on the number of bits of
  the PWM. 
- Improve some code documentation.

Changes since RFCv1:
- Get rid of fixed point calculations and use a table instead.

 drivers/video/backlight/pwm_bl.c | 149 +++++++++++++++++++++++++++++++++++----
 1 file changed, 136 insertions(+), 13 deletions(-)

diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c
index eabe0a4462af..9398516db0ce 100644
--- a/drivers/video/backlight/pwm_bl.c
+++ b/drivers/video/backlight/pwm_bl.c
@@ -143,6 +143,107 @@ static const struct backlight_ops pwm_backlight_ops = {
 };
 
 #ifdef CONFIG_OF
+#define PWM_LUMINANCE_SCALE	10000 /* luminance scale */
+
+/* An integer based power function */
+static u64 int_pow(u64 base, int exp)
+{
+	u64 result = 1;
+
+	while (exp) {
+		if (exp & 1)
+			result *= base;
+		exp >>= 1;
+		base *= base;
+	}
+
+	return result;
+}
+
+/*
+ * CIE lightness to PWM conversion.
+ *
+ * The CIE 1931 lightness formula is what actually describes how we perceive
+ * light:
+ *          Y = (L* / 902.3)           if L* ≤ 0.08856
+ *          Y = ((L* + 16) / 116)^3    if L* > 0.08856
+ *
+ * Where Y is the luminance, the amount of light coming out of the screen, and
+ * is a number between 0.0 and 1.0; and L* is the lightness, how bright a human
+ * perceives the screen to be, and is a number between 0 and 100.
+ *
+ * The following function does the fixed point maths needed to implement the
+ * above formula.
+ */
+static u64 cie1931(unsigned int lightness, unsigned int scale)
+{
+	u64 retval;
+
+	lightness *= 100;
+	if (lightness <= (8 * scale)) {
+		retval = DIV_ROUND_CLOSEST_ULL(lightness * 10, 9023);
+	} else {
+		retval = int_pow((lightness + (16 * scale)) / 116, 3);
+		retval = DIV_ROUND_CLOSEST_ULL(retval, (scale * scale));
+	}
+
+	return retval;
+}
+
+/*
+ * Create a default correction table for PWM values to create linear brightness
+ * for LED based backlights using the CIE1931 algorithm.
+ */
+static
+int pwm_backlight_brightness_default(struct device *dev,
+				     struct platform_pwm_backlight_data *data,
+				     unsigned int period)
+{
+	unsigned int counter = 0;
+	unsigned int i, n;
+	u64 retval;
+
+	/*
+	 * Count the number of bits needed to represent the period number. The
+	 * number of bits is used to calculate the number of levels used for the
+	 * brightness-levels table, the purpose of this calculation is have a
+	 * pre-computed table with enough levels to get linear brightness
+	 * perception. The period is divided by the number of bits so for a
+	 * 8-bit PWM we have 255 / 8 = 32 brightness levels or for a 16-bit PWM
+	 * we have 65535 / 16 = 4096 brightness levels.
+	 *
+	 * Note that this method is based on empirical testing on different
+	 * devices with PWM of 8 and 16 bits of resolution.
+	 */
+	n = period;
+	while (n) {
+		counter += n % 2;
+		n >>= 1;
+	}
+
+	data->max_brightness = DIV_ROUND_UP(period, counter);
+	data->levels = devm_kcalloc(dev, data->max_brightness,
+				    sizeof(*data->levels), GFP_KERNEL);
+	if (!data->levels)
+		return -ENOMEM;
+
+	/* Fill the table using the cie1931 algorithm */
+	for (i = 0; i < data->max_brightness; i++) {
+		retval = cie1931((i * PWM_LUMINANCE_SCALE) /
+				 data->max_brightness, PWM_LUMINANCE_SCALE) *
+				 period;
+		retval = DIV_ROUND_CLOSEST_ULL(retval, PWM_LUMINANCE_SCALE);
+		if (retval > UINT_MAX)
+			return -EINVAL;
+		data->levels[i] = (unsigned int)retval;
+	}
+
+	data->dft_brightness = data->max_brightness / 2;
+	data->max_brightness--;
+
+	return 0;
+}
+
 static int pwm_backlight_parse_dt(struct device *dev,
 				  struct platform_pwm_backlight_data *data)
 {
@@ -161,10 +262,13 @@ static int pwm_backlight_parse_dt(struct device *dev,
 
 	memset(data, 0, sizeof(*data));
 
-	/* determine the number of brightness levels */
+	/*
+	 * Determine the number of brightness levels, if this property is not
+	 * set a default table of brightness levels will be used.
+	 */
 	prop = of_find_property(node, "brightness-levels", &length);
 	if (!prop)
-		return -EINVAL;
+		return 0;
 
 	data->max_brightness = length / sizeof(u32);
 
@@ -299,6 +403,14 @@ static int pwm_backlight_parse_dt(struct device *dev,
 {
 	return -ENODEV;
 }
+
+static
+int pwm_backlight_brightness_default(struct device *dev,
+				     struct platform_pwm_backlight_data *data,
+				     unsigned int period)
+{
+	return -ENODEV;
+}
 #endif
 
 static int pwm_backlight_initial_power_state(const struct pwm_bl_data *pb)
@@ -339,7 +451,9 @@ static int pwm_backlight_probe(struct platform_device *pdev)
 	struct backlight_device *bl;
 	struct device_node *node = pdev->dev.of_node;
 	struct pwm_bl_data *pb;
+	struct pwm_state state;
 	struct pwm_args pargs;
+	unsigned int i;
 	int ret;
 
 	if (!data) {
@@ -364,17 +478,6 @@ static int pwm_backlight_probe(struct platform_device *pdev)
 		goto err_alloc;
 	}
 
-	if (data->levels) {
-		unsigned int i;
-
-		for (i = 0; i <= data->max_brightness; i++)
-			if (data->levels[i] > pb->scale)
-				pb->scale = data->levels[i];
-
-		pb->levels = data->levels;
-	} else
-		pb->scale = data->max_brightness;
-
 	pb->notify = data->notify;
 	pb->notify_after = data->notify_after;
 	pb->check_fb = data->check_fb;
@@ -441,6 +544,26 @@ static int pwm_backlight_probe(struct platform_device *pdev)
 
 	dev_dbg(&pdev->dev, "got pwm for backlight\n");
 
+	if (!data->levels) {
+		/* Get the PWM period (in nanoseconds) */
+		pwm_get_state(pb->pwm, &state);
+
+		ret = pwm_backlight_brightness_default(&pdev->dev, data,
+						       state.period);
+		if (ret < 0) {
+			dev_err(&pdev->dev,
+				"failed to setup default brightness table\n");
+			goto err_alloc;
+		}
+	}
+
+	for (i = 0; i <= data->max_brightness; i++)
+		if (data->levels[i] > pb->scale)
+			pb->scale = data->levels[i];
+
+		pb->levels = data->levels;
+	}
+
 	/*
 	 * FIXME: pwm_apply_args() should be removed when switching to
 	 * the atomic PWM API.
-- 
2.15.1

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 4/4] dt-bindings: pwm-backlight: move brightness-levels to optional.
  2018-01-10 22:30 [PATCH 0/4] backlight: pwm_bl: support linear interpolation and brightness to human eye Enric Balletbo i Serra
                   ` (2 preceding siblings ...)
  2018-01-10 22:30 ` [PATCH 3/4] backlight: pwm_bl: compute brightness of LED linearly to human eye Enric Balletbo i Serra
@ 2018-01-10 22:30 ` Enric Balletbo i Serra
       [not found]   ` <20180110223046.17696-5-enric.balletbo-ZGY8ohtN/8qB+jHODAdFcQ@public.gmane.org>
  3 siblings, 1 reply; 11+ messages in thread
From: Enric Balletbo i Serra @ 2018-01-10 22:30 UTC (permalink / raw)
  To: Daniel Thompson, Doug Anderson, Pavel Machek, Rob Herring
  Cc: Jingoo Han, Richard Purdie, Jacek Anaszewski, Brian Norris,
	Guenter Roeck, Lee Jones, Alexandru Stan, linux-leds, devicetree,
	linux-kernel

The patch 'backlight: pwm_bl: compute brightness of LED linearly to
human eye' introduced a default brightness-levels table that is used
when brightness-levels is not availablel in the dts so move move
brightness-levels and default-brightness-level to be optional.

Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
---
 .../devicetree/bindings/leds/backlight/pwm-backlight.txt  | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/Documentation/devicetree/bindings/leds/backlight/pwm-backlight.txt b/Documentation/devicetree/bindings/leds/backlight/pwm-backlight.txt
index 605432c910c5..3d5a148bd66d 100644
--- a/Documentation/devicetree/bindings/leds/backlight/pwm-backlight.txt
+++ b/Documentation/devicetree/bindings/leds/backlight/pwm-backlight.txt
@@ -3,13 +3,6 @@ pwm-backlight bindings
 Required properties:
   - compatible: "pwm-backlight"
   - pwms: OF device-tree PWM specification (see PWM binding[0])
-  - brightness-levels: Array of distinct brightness levels. Typically these
-      are in the range from 0 to 255, but any range starting at 0 will do.
-      The actual brightness level (PWM duty cycle) will be interpolated
-      from these values. 0 means a 0% duty cycle (darkest/off), while the
-      last value in the array represents a 100% duty cycle (brightest).
-  - default-brightness-level: the default brightness level (index into the
-      array defined by the "brightness-levels" property)
   - power-supply: regulator for supply voltage
 
 Optional properties:
@@ -21,6 +14,14 @@ Optional properties:
                           and enabling the backlight using GPIO.
   - pwm-off-delay-ms: Delay in ms between disabling the backlight using GPIO
                       and setting PWM value to 0.
+  - brightness-levels: Array of distinct brightness levels. Typically these
+                       are in the range from 0 to 255, but any range starting at
+                       0 will do. The actual brightness level (PWM duty cycle)
+                       will be interpolated from these values. 0 means a 0% duty
+                       cycle (darkest/off), while the last value in the array
+                       represents a 100% duty cycle (brightest).
+  - default-brightness-level: The default brightness level (index into the
+                              array defined by the "brightness-levels" property).
   - num-interpolated-steps: Number of interpolated steps between each value
                             of brightness-levels table. This way a high
                             resolution pwm duty cycle can be used without
-- 
2.15.1

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH 3/4] backlight: pwm_bl: compute brightness of LED linearly to human eye.
       [not found]   ` <20180110223046.17696-4-enric.balletbo-ZGY8ohtN/8qB+jHODAdFcQ@public.gmane.org>
@ 2018-01-12 10:14     ` Enric Balletbo Serra
       [not found]       ` <CAFqH_50zs+TMZaRNegxYPQOcysvwm9EY5iB8DqNeGYN+QaJP6Q-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  0 siblings, 1 reply; 11+ messages in thread
From: Enric Balletbo Serra @ 2018-01-12 10:14 UTC (permalink / raw)
  To: Enric Balletbo i Serra
  Cc: Daniel Thompson, Doug Anderson, Pavel Machek, Rob Herring,
	Jingoo Han, Richard Purdie, Jacek Anaszewski, Brian Norris,
	Guenter Roeck, Lee Jones, Alexandru Stan,
	linux-leds-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, linux-kernel

2018-01-10 23:30 GMT+01:00 Enric Balletbo i Serra
<enric.balletbo-ZGY8ohtN/8qB+jHODAdFcQ@public.gmane.org>:
> When you want to change the brightness using a PWM signal, one thing you
> need to consider is how human perceive the brightness. Human perceive
> the brightness change non-linearly, we have better sensitivity at low
> luminance than high luminance, so to achieve perceived linear dimming,
> the brightness must be matches to the way our eyes behave. The CIE 1931
> lightness formula is what actually describes how we perceive light.
>
> This patch computes a default table with the brightness levels filled
> with the numbers provided by the CIE 1931 algorithm, the number of the
> brightness levels is calculated based on the PWM resolution.
>
> The calculation of the table using the CIE 1931 algorithm is enabled by
> default when you do not define the 'brightness-levels' propriety in your
> device tree.
>
> Signed-off-by: Enric Balletbo i Serra <enric.balletbo-ZGY8ohtN/8qB+jHODAdFcQ@public.gmane.org>
> ---
> Changes since RFCv2:
> - Pre-compute the table at boot using the cie 1931 algorithm, this
>   introduced again the fixed point calculations that needs to be
>   reviewed.
> - Calculate the number of needed steps based on the number of bits of
>   the PWM.
> - Improve some code documentation.
>
> Changes since RFCv1:
> - Get rid of fixed point calculations and use a table instead.
>
>  drivers/video/backlight/pwm_bl.c | 149 +++++++++++++++++++++++++++++++++++----
>  1 file changed, 136 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c
> index eabe0a4462af..9398516db0ce 100644
> --- a/drivers/video/backlight/pwm_bl.c
> +++ b/drivers/video/backlight/pwm_bl.c
> @@ -143,6 +143,107 @@ static const struct backlight_ops pwm_backlight_ops = {
>  };
>
>  #ifdef CONFIG_OF
> +#define PWM_LUMINANCE_SCALE    10000 /* luminance scale */
> +
> +/* An integer based power function */
> +static u64 int_pow(u64 base, int exp)
> +{
> +       u64 result = 1;
> +
> +       while (exp) {
> +               if (exp & 1)
> +                       result *= base;
> +               exp >>= 1;
> +               base *= base;
> +       }
> +
> +       return result;
> +}
> +
> +/*
> + * CIE lightness to PWM conversion.
> + *
> + * The CIE 1931 lightness formula is what actually describes how we perceive
> + * light:
> + *          Y = (L* / 902.3)           if L* ≤ 0.08856
> + *          Y = ((L* + 16) / 116)^3    if L* > 0.08856
> + *
> + * Where Y is the luminance, the amount of light coming out of the screen, and
> + * is a number between 0.0 and 1.0; and L* is the lightness, how bright a human
> + * perceives the screen to be, and is a number between 0 and 100.
> + *
> + * The following function does the fixed point maths needed to implement the
> + * above formula.
> + */
> +static u64 cie1931(unsigned int lightness, unsigned int scale)
> +{
> +       u64 retval;
> +
> +       lightness *= 100;
> +       if (lightness <= (8 * scale)) {
> +               retval = DIV_ROUND_CLOSEST_ULL(lightness * 10, 9023);
> +       } else {
> +               retval = int_pow((lightness + (16 * scale)) / 116, 3);
> +               retval = DIV_ROUND_CLOSEST_ULL(retval, (scale * scale));
> +       }
> +
> +       return retval;
> +}
> +
> +/*
> + * Create a default correction table for PWM values to create linear brightness
> + * for LED based backlights using the CIE1931 algorithm.
> + */
> +static
> +int pwm_backlight_brightness_default(struct device *dev,
> +                                    struct platform_pwm_backlight_data *data,
> +                                    unsigned int period)
> +{
> +       unsigned int counter = 0;
> +       unsigned int i, n;
> +       u64 retval;
> +
> +       /*
> +        * Count the number of bits needed to represent the period number. The
> +        * number of bits is used to calculate the number of levels used for the
> +        * brightness-levels table, the purpose of this calculation is have a
> +        * pre-computed table with enough levels to get linear brightness
> +        * perception. The period is divided by the number of bits so for a
> +        * 8-bit PWM we have 255 / 8 = 32 brightness levels or for a 16-bit PWM
> +        * we have 65535 / 16 = 4096 brightness levels.
> +        *
> +        * Note that this method is based on empirical testing on different
> +        * devices with PWM of 8 and 16 bits of resolution.
> +        */
> +       n = period;
> +       while (n) {
> +               counter += n % 2;
> +               n >>= 1;
> +       }
> +
> +       data->max_brightness = DIV_ROUND_UP(period, counter);
> +       data->levels = devm_kcalloc(dev, data->max_brightness,
> +                                   sizeof(*data->levels), GFP_KERNEL);
> +       if (!data->levels)
> +               return -ENOMEM;
> +
> +       /* Fill the table using the cie1931 algorithm */
> +       for (i = 0; i < data->max_brightness; i++) {
> +               retval = cie1931((i * PWM_LUMINANCE_SCALE) /
> +                                data->max_brightness, PWM_LUMINANCE_SCALE) *
> +                                period;
> +               retval = DIV_ROUND_CLOSEST_ULL(retval, PWM_LUMINANCE_SCALE);
> +               if (retval > UINT_MAX)
> +                       return -EINVAL;
> +               data->levels[i] = (unsigned int)retval;
> +       }
> +
> +       data->dft_brightness = data->max_brightness / 2;
> +       data->max_brightness--;
> +
> +       return 0;
> +}
> +
>  static int pwm_backlight_parse_dt(struct device *dev,
>                                   struct platform_pwm_backlight_data *data)
>  {
> @@ -161,10 +262,13 @@ static int pwm_backlight_parse_dt(struct device *dev,
>
>         memset(data, 0, sizeof(*data));
>
> -       /* determine the number of brightness levels */
> +       /*
> +        * Determine the number of brightness levels, if this property is not
> +        * set a default table of brightness levels will be used.
> +        */
>         prop = of_find_property(node, "brightness-levels", &length);
>         if (!prop)
> -               return -EINVAL;
> +               return 0;
>
>         data->max_brightness = length / sizeof(u32);
>
> @@ -299,6 +403,14 @@ static int pwm_backlight_parse_dt(struct device *dev,
>  {
>         return -ENODEV;
>  }
> +
> +static
> +int pwm_backlight_brightness_default(struct device *dev,
> +                                    struct platform_pwm_backlight_data *data,
> +                                    unsigned int period)
> +{
> +       return -ENODEV;
> +}
>  #endif
>
>  static int pwm_backlight_initial_power_state(const struct pwm_bl_data *pb)
> @@ -339,7 +451,9 @@ static int pwm_backlight_probe(struct platform_device *pdev)
>         struct backlight_device *bl;
>         struct device_node *node = pdev->dev.of_node;
>         struct pwm_bl_data *pb;
> +       struct pwm_state state;
>         struct pwm_args pargs;
> +       unsigned int i;
>         int ret;
>
>         if (!data) {
> @@ -364,17 +478,6 @@ static int pwm_backlight_probe(struct platform_device *pdev)
>                 goto err_alloc;
>         }
>
> -       if (data->levels) {
> -               unsigned int i;
> -
> -               for (i = 0; i <= data->max_brightness; i++)
> -                       if (data->levels[i] > pb->scale)
> -                               pb->scale = data->levels[i];
> -
> -               pb->levels = data->levels;
> -       } else
> -               pb->scale = data->max_brightness;
> -
>         pb->notify = data->notify;
>         pb->notify_after = data->notify_after;
>         pb->check_fb = data->check_fb;
> @@ -441,6 +544,26 @@ static int pwm_backlight_probe(struct platform_device *pdev)
>
>         dev_dbg(&pdev->dev, "got pwm for backlight\n");
>
> +       if (!data->levels) {
> +               /* Get the PWM period (in nanoseconds) */
> +               pwm_get_state(pb->pwm, &state);
> +
> +               ret = pwm_backlight_brightness_default(&pdev->dev, data,
> +                                                      state.period);
> +               if (ret < 0) {
> +                       dev_err(&pdev->dev,
> +                               "failed to setup default brightness table\n");
> +                       goto err_alloc;
> +               }
> +       }
> +
> +       for (i = 0; i <= data->max_brightness; i++)

Oops, horrible and unjustifiable mistake, missing { here :/

> +               if (data->levels[i] > pb->scale)
> +                       pb->scale = data->levels[i];
> +
> +               pb->levels = data->levels;
> +       }
> +
>         /*
>          * FIXME: pwm_apply_args() should be removed when switching to
>          * the atomic PWM API.
> --
> 2.15.1
>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 3/4] backlight: pwm_bl: compute brightness of LED linearly to human eye.
       [not found]       ` <CAFqH_50zs+TMZaRNegxYPQOcysvwm9EY5iB8DqNeGYN+QaJP6Q-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2018-01-12 11:50         ` Daniel Thompson
  0 siblings, 0 replies; 11+ messages in thread
From: Daniel Thompson @ 2018-01-12 11:50 UTC (permalink / raw)
  To: Enric Balletbo Serra
  Cc: Enric Balletbo i Serra, Doug Anderson, Pavel Machek, Rob Herring,
	Jingoo Han, Richard Purdie, Jacek Anaszewski, Brian Norris,
	Guenter Roeck, Lee Jones, Alexandru Stan,
	linux-leds-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, linux-kernel

On Fri, Jan 12, 2018 at 11:14:54AM +0100, Enric Balletbo Serra wrote:
> > @@ -441,6 +544,26 @@ static int pwm_backlight_probe(struct platform_device *pdev)
> >
> >         dev_dbg(&pdev->dev, "got pwm for backlight\n");
> >
> > +       if (!data->levels) {
> > +               /* Get the PWM period (in nanoseconds) */
> > +               pwm_get_state(pb->pwm, &state);
> > +
> > +               ret = pwm_backlight_brightness_default(&pdev->dev, data,
> > +                                                      state.period);
> > +               if (ret < 0) {
> > +                       dev_err(&pdev->dev,
> > +                               "failed to setup default brightness table\n");
> > +                       goto err_alloc;
> > +               }
> > +       }
> > +
> > +       for (i = 0; i <= data->max_brightness; i++)
> 
> Oops, horrible and unjustifiable mistake, missing { here :/

Well, at least you found it rather than us :-)


Daniel.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 2/4] dt-bindings: pwm-backlight: add a num-interpolation-steps property.
  2018-01-10 22:30 ` [PATCH 2/4] dt-bindings: pwm-backlight: add a num-interpolation-steps property Enric Balletbo i Serra
@ 2018-01-19 20:52   ` Rob Herring
  2018-01-22  9:16     ` Daniel Thompson
  0 siblings, 1 reply; 11+ messages in thread
From: Rob Herring @ 2018-01-19 20:52 UTC (permalink / raw)
  To: Enric Balletbo i Serra
  Cc: Daniel Thompson, Doug Anderson, Pavel Machek, Jingoo Han,
	Richard Purdie, Jacek Anaszewski, Brian Norris, Guenter Roeck,
	Lee Jones, Alexandru Stan, linux-leds, devicetree, linux-kernel

On Wed, Jan 10, 2018 at 11:30:44PM +0100, Enric Balletbo i Serra wrote:
> The num-interpolated-steps property specifies the number of
> interpolated steps between each value of brightness-level table. This is
> useful for high resolution PWMs to not have to list out every possible
> value in the brightness-level array.
> 
> Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
> ---
>  .../bindings/leds/backlight/pwm-backlight.txt       | 21 +++++++++++++++++++++
>  1 file changed, 21 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/leds/backlight/pwm-backlight.txt b/Documentation/devicetree/bindings/leds/backlight/pwm-backlight.txt
> index 310810906613..605432c910c5 100644
> --- a/Documentation/devicetree/bindings/leds/backlight/pwm-backlight.txt
> +++ b/Documentation/devicetree/bindings/leds/backlight/pwm-backlight.txt
> @@ -21,6 +21,11 @@ Optional properties:
>                            and enabling the backlight using GPIO.
>    - pwm-off-delay-ms: Delay in ms between disabling the backlight using GPIO
>                        and setting PWM value to 0.
> +  - num-interpolated-steps: Number of interpolated steps between each value
> +                            of brightness-levels table. This way a high
> +                            resolution pwm duty cycle can be used without
> +                            having to list out every possible value in the
> +                            brightness-level array.
>  
>  [0]: Documentation/devicetree/bindings/pwm/pwm.txt
>  [1]: Documentation/devicetree/bindings/gpio/gpio.txt
> @@ -39,3 +44,19 @@ Example:
>  		post-pwm-on-delay-ms = <10>;
>  		pwm-off-delay-ms = <10>;
>  	};
> +
> +Example using num-interpolation-steps:
> +
> +	backlight {
> +		compatible = "pwm-backlight";
> +		pwms = <&pwm 0 5000000>;
> +
> +		brightness-levels = <0 65535>;
> +		num-interpolated-steps = <4096>;

How does this make sense with only 2 defined levels other than having 
fewer steps? I thought the purpose of this was to have a piecewise 
linear curve. 

> +		default-brightness-level = <6>;

Aren't valid values 0, 16, 32, 48, etc.?

Rob

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 4/4] dt-bindings: pwm-backlight: move brightness-levels to optional.
       [not found]   ` <20180110223046.17696-5-enric.balletbo-ZGY8ohtN/8qB+jHODAdFcQ@public.gmane.org>
@ 2018-01-19 20:57     ` Rob Herring
  0 siblings, 0 replies; 11+ messages in thread
From: Rob Herring @ 2018-01-19 20:57 UTC (permalink / raw)
  To: Enric Balletbo i Serra
  Cc: Daniel Thompson, Doug Anderson, Pavel Machek, Jingoo Han,
	Richard Purdie, Jacek Anaszewski, Brian Norris, Guenter Roeck,
	Lee Jones, Alexandru Stan, linux-leds-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On Wed, Jan 10, 2018 at 11:30:46PM +0100, Enric Balletbo i Serra wrote:
> The patch 'backlight: pwm_bl: compute brightness of LED linearly to
> human eye' introduced a default brightness-levels table that is used
> when brightness-levels is not availablel in the dts so move move

s/availablel/available/

Perhaps "so move..." should be a new sentence.

> brightness-levels and default-brightness-level to be optional.
> 
> Signed-off-by: Enric Balletbo i Serra <enric.balletbo-ZGY8ohtN/8qB+jHODAdFcQ@public.gmane.org>
> ---
>  .../devicetree/bindings/leds/backlight/pwm-backlight.txt  | 15 ++++++++-------
>  1 file changed, 8 insertions(+), 7 deletions(-)

With that,

Reviewed-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 2/4] dt-bindings: pwm-backlight: add a num-interpolation-steps property.
  2018-01-19 20:52   ` Rob Herring
@ 2018-01-22  9:16     ` Daniel Thompson
  2018-01-23 10:21       ` Enric Balletbo Serra
  0 siblings, 1 reply; 11+ messages in thread
From: Daniel Thompson @ 2018-01-22  9:16 UTC (permalink / raw)
  To: Rob Herring
  Cc: Enric Balletbo i Serra, Doug Anderson, Pavel Machek, Jingoo Han,
	Richard Purdie, Jacek Anaszewski, Brian Norris, Guenter Roeck,
	Lee Jones, Alexandru Stan, linux-leds, devicetree, linux-kernel

On Fri, Jan 19, 2018 at 02:52:49PM -0600, Rob Herring wrote:
> On Wed, Jan 10, 2018 at 11:30:44PM +0100, Enric Balletbo i Serra wrote:
> > The num-interpolated-steps property specifies the number of
> > interpolated steps between each value of brightness-level table. This is
> > useful for high resolution PWMs to not have to list out every possible
> > value in the brightness-level array.
> > 
> > Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
> > ---
> >  .../bindings/leds/backlight/pwm-backlight.txt       | 21 +++++++++++++++++++++
> >  1 file changed, 21 insertions(+)
> > 
> > diff --git a/Documentation/devicetree/bindings/leds/backlight/pwm-backlight.txt b/Documentation/devicetree/bindings/leds/backlight/pwm-backlight.txt
> > index 310810906613..605432c910c5 100644
> > --- a/Documentation/devicetree/bindings/leds/backlight/pwm-backlight.txt
> > +++ b/Documentation/devicetree/bindings/leds/backlight/pwm-backlight.txt
> > @@ -21,6 +21,11 @@ Optional properties:
> >                            and enabling the backlight using GPIO.
> >    - pwm-off-delay-ms: Delay in ms between disabling the backlight using GPIO
> >                        and setting PWM value to 0.
> > +  - num-interpolated-steps: Number of interpolated steps between each value
> > +                            of brightness-levels table. This way a high
> > +                            resolution pwm duty cycle can be used without
> > +                            having to list out every possible value in the
> > +                            brightness-level array.
> >  
> >  [0]: Documentation/devicetree/bindings/pwm/pwm.txt
> >  [1]: Documentation/devicetree/bindings/gpio/gpio.txt
> > @@ -39,3 +44,19 @@ Example:
> >  		post-pwm-on-delay-ms = <10>;
> >  		pwm-off-delay-ms = <10>;
> >  	};
> > +
> > +Example using num-interpolation-steps:
> > +
> > +	backlight {
> > +		compatible = "pwm-backlight";
> > +		pwms = <&pwm 0 5000000>;
> > +
> > +		brightness-levels = <0 65535>;
> > +		num-interpolated-steps = <4096>;
> 
> How does this make sense with only 2 defined levels other than having 
> fewer steps? I thought the purpose of this was to have a piecewise 
> linear curve. 

It's not wrong as such, this is how a device with a linear (or nearly
linear) response could be compactly described.

Nevertheless I agree!  An example with a small but realistic curve 
would be better... we know that copy 'n paste exists so I'd rather 
see a simple curve than no curve.


Daniel.


> > +		default-brightness-level = <6>;
> 
> Aren't valid values 0, 16, 32, 48, etc.?
> 
> Rob

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 2/4] dt-bindings: pwm-backlight: add a num-interpolation-steps property.
  2018-01-22  9:16     ` Daniel Thompson
@ 2018-01-23 10:21       ` Enric Balletbo Serra
  0 siblings, 0 replies; 11+ messages in thread
From: Enric Balletbo Serra @ 2018-01-23 10:21 UTC (permalink / raw)
  To: Daniel Thompson
  Cc: Rob Herring, Enric Balletbo i Serra, Doug Anderson, Pavel Machek,
	Jingoo Han, Richard Purdie, Jacek Anaszewski, Brian Norris,
	Guenter Roeck, Lee Jones, Alexandru Stan, linux-leds, devicetree,
	linux-kernel

2018-01-22 10:16 GMT+01:00 Daniel Thompson <daniel.thompson@linaro.org>:
> On Fri, Jan 19, 2018 at 02:52:49PM -0600, Rob Herring wrote:
>> On Wed, Jan 10, 2018 at 11:30:44PM +0100, Enric Balletbo i Serra wrote:
>> > The num-interpolated-steps property specifies the number of
>> > interpolated steps between each value of brightness-level table. This is
>> > useful for high resolution PWMs to not have to list out every possible
>> > value in the brightness-level array.
>> >
>> > Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
>> > ---
>> >  .../bindings/leds/backlight/pwm-backlight.txt       | 21 +++++++++++++++++++++
>> >  1 file changed, 21 insertions(+)
>> >
>> > diff --git a/Documentation/devicetree/bindings/leds/backlight/pwm-backlight.txt b/Documentation/devicetree/bindings/leds/backlight/pwm-backlight.txt
>> > index 310810906613..605432c910c5 100644
>> > --- a/Documentation/devicetree/bindings/leds/backlight/pwm-backlight.txt
>> > +++ b/Documentation/devicetree/bindings/leds/backlight/pwm-backlight.txt
>> > @@ -21,6 +21,11 @@ Optional properties:
>> >                            and enabling the backlight using GPIO.
>> >    - pwm-off-delay-ms: Delay in ms between disabling the backlight using GPIO
>> >                        and setting PWM value to 0.
>> > +  - num-interpolated-steps: Number of interpolated steps between each value
>> > +                            of brightness-levels table. This way a high
>> > +                            resolution pwm duty cycle can be used without
>> > +                            having to list out every possible value in the
>> > +                            brightness-level array.
>> >
>> >  [0]: Documentation/devicetree/bindings/pwm/pwm.txt
>> >  [1]: Documentation/devicetree/bindings/gpio/gpio.txt
>> > @@ -39,3 +44,19 @@ Example:
>> >             post-pwm-on-delay-ms = <10>;
>> >             pwm-off-delay-ms = <10>;
>> >     };
>> > +
>> > +Example using num-interpolation-steps:
>> > +
>> > +   backlight {
>> > +           compatible = "pwm-backlight";
>> > +           pwms = <&pwm 0 5000000>;
>> > +
>> > +           brightness-levels = <0 65535>;
>> > +           num-interpolated-steps = <4096>;
>>
>> How does this make sense with only 2 defined levels other than having
>> fewer steps? I thought the purpose of this was to have a piecewise
>> linear curve.
>
> It's not wrong as such, this is how a device with a linear (or nearly
> linear) response could be compactly described.
>
> Nevertheless I agree!  An example with a small but realistic curve
> would be better... we know that copy 'n paste exists so I'd rather
> see a simple curve than no curve.
>

Makes sense, I'll put a better example on next series. Thanks for the review.

 - Enric

>
> Daniel.
>
>
>> > +           default-brightness-level = <6>;
>>
>> Aren't valid values 0, 16, 32, 48, etc.?
>>
>> Rob

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2018-01-23 10:21 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-01-10 22:30 [PATCH 0/4] backlight: pwm_bl: support linear interpolation and brightness to human eye Enric Balletbo i Serra
2018-01-10 22:30 ` [PATCH 1/4] backlight: pwm_bl: linear interpolation between brightness-levels Enric Balletbo i Serra
2018-01-10 22:30 ` [PATCH 2/4] dt-bindings: pwm-backlight: add a num-interpolation-steps property Enric Balletbo i Serra
2018-01-19 20:52   ` Rob Herring
2018-01-22  9:16     ` Daniel Thompson
2018-01-23 10:21       ` Enric Balletbo Serra
2018-01-10 22:30 ` [PATCH 3/4] backlight: pwm_bl: compute brightness of LED linearly to human eye Enric Balletbo i Serra
     [not found]   ` <20180110223046.17696-4-enric.balletbo-ZGY8ohtN/8qB+jHODAdFcQ@public.gmane.org>
2018-01-12 10:14     ` Enric Balletbo Serra
     [not found]       ` <CAFqH_50zs+TMZaRNegxYPQOcysvwm9EY5iB8DqNeGYN+QaJP6Q-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2018-01-12 11:50         ` Daniel Thompson
2018-01-10 22:30 ` [PATCH 4/4] dt-bindings: pwm-backlight: move brightness-levels to optional Enric Balletbo i Serra
     [not found]   ` <20180110223046.17696-5-enric.balletbo-ZGY8ohtN/8qB+jHODAdFcQ@public.gmane.org>
2018-01-19 20:57     ` Rob Herring

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).