Backlight Brightness Control

We use PWM_A to control backlight of an LCD. We keep the original device tree for backlight in imx6dl-colibri-eval-v3.dts unchanged as the following:

&backlight {
#if 0 /* PWM polarity: if 1 is brightest */
	pwms = <&pwm3 0 5000000 0>;
#if 0 /* Fusion 7 needs 10kHz PWM frequency */
	pwms = <&pwm3 0 100000 0>;
#endif
#else /* PWM polarity: if 0 is brightest */
	pwms = <&pwm3 0 5000000 1>;
#endif
	brightness-levels = <0 4 8 16 32 64 128 255>;
	default-brightness-level = <6>;
	status = "okay";
};

The max brightness is level 7 and bl_power is set to 0.

root@colibri-imx6:~# cat /sys/class/backlight/backlight/max_brightness
7
root@colibri-imx6:~# echo 0 > /sys/class/backlight/backlight/bl_power

We used command echo x > /sys/class/backlight/backlight/brightness to change the backlight level (x=0,1,2,3,4,5,6,7) and probed the PWM_A with a scope. We found

  1. For x=0 or 7, the duty cycle of PWM_A is 0% (a flat 0V line on the scope)
  2. For x=6, the duty cycle is around 50% (High duration equals low duration of a wave period)
  3. For x=1, the duty cycle is close to 100%
  4. For x from 1 to 6, the duty cycle gradually decreases.

These are conflicting to what this article (High performance, low power Embedded Computing Systems | Toradex Developer Center) says in the following aspects:

  1. Polarity is inverted.
  2. Duty cycles between 0% and 50% are not achievable.
  3. Level 7 should have highest duty cycle (correct?). But it is actually same brightness as level 0 ( 0% duty cycle)

Are these expected? How can we achieve duty cycles between 0% and 50%?

William

  1. Polarity is inverted.

Whatever you mean by inverted. As stated in the device tree as given by you above:

PWM polarity: if 0 is brightest
  1. Duty cycles between 0% and 50% are not achievable.

Yes, according to the device tree you want it to go straight from 128 to 255:

brightness-levels = <0 4 8 16 32 64 128 255>;
  1. Level 7 should have highest duty cycle (correct?). But it is actually same brightness as level 0 ( 0% duty cycle)

Well, no, if a 0 means brightest that’ s what you get at level 7. Plus level 0 actually turns the backlight off.

Are these expected? How can we achieve duty cycles between 0% and 50%?

I would say yes, it behaves just as you configured it via device tree. If that is not what you want you may try changing the polarity and/or the brightness levels in the device tree to suit your needs.

I don’t quite understand what “#if 0” and “pwms = <&pwm3 0 5000000 1>” statements in the device tree mean. Can you explain or refer me to any resources for definitions of these statements?

Did you mean level 0 always has 0% duty cycle and turns the backlight off no matter what polarity is set? Since the polarity is inverted in my case, shouldn’t value 0 (referred by level 0) get highest brightness while last value 255 of the array turns off the backlight? I am confused.

I don’t quite understand what “#if 0” and “pwms = <&pwm3 0 5000000 1>” statements in the device tree mean. Can you explain or refer me to any resources for definitions of these statements?

Well, just as in regular C code the #if 0 part is ignored. If you do want that behaviour aka polarity you would have to #if 1 it.

Did you mean level 0 always has 0% duty cycle and turns the backlight off no matter what polarity is set?

Yes, I believe so.

The first element (value 0) of the brightness array is referred by level 1, not level 0. Right?

No, the array starts with 0 and max’ out at max_brightness being 7 as you saw above.

Since the polarity is inverted in my case, shouldn’t value 0 (referred by level 0) get highest brightness while last value 255 of the array turns off the backlight? I am confused.

No, the polarity is really implemented at the PWM controller level so it gets applied at the very end of the chain.

Then the following relevant statements quoted from that article are incorrect or inappropriate. Right?

The following queries the number of brightness steps, sets the duty cycle to 100% and then to 0%.

cat /sys/class/backlight/backlight/max_brightness

7

echo 0 > /sys/class/backlight/backlight/brightness

echo 7 > /sys/class/backlight/backlight/brightness

Yes, I actually just had that discussion with one of my senior engineers. Sorry about that, we will update that article ASAP.