Search by Tags

PWM (Linux)

 

Compare with Revision




Subscribe for this article updates

The Colibri and Apalis standard define four PWM channels by default (Colibri: PWM<A> through PWM<D>, Apalis: PWM1 through PWM4). In the Colibri standard, PWM<A> is traditionally reserved for display backlight brightness. The Linux kernel supports PWM display back-light brightness using a dedicated driver, hence this PWM channel is made available to user-space in a different manner then the other PWM channels. See Backlight PWM (Linux) for more information about PWM backlight usage.

Up until around Linux Kernel version ~3.6 there has not been a dedicated PWM interface to user-space. Instead our BSP made use of the PWM LED interface to export the PWM channels to user-space.

Colibri T20/T30 and Apalis T30

For our Tegra based modules, the PWM LED interface is used to export the PWM channels PWM<B> through PWM<D>, located at /sys/class/leds/.

To control the duty cycle, the sysfs brightness file can be used. Value is within the range 0 to 255, where 0 means 0% duty cycle while 255 means 100% duty cycle.

echo [value] > /sys/class/leds/[pwm_instance]/brightness
e.g.:
echo 127 > /sys/class/leds/PWM<B>/brightness

Note: leds-pwm driver has only support for controlling the duty cycle through sysfs, period is fixed and cannot be configured through sysfs.

Apalis/Colibri iMX6

Starting with BSP version V2.7 we use the generic sysfs PWM framework to give access to PWMs from userspace.

Apalis iMX6

Toradex Name NXP/Freescale Name sysfs path Note
PWM1 PWM1 /sys/class/pwm/pwmchip0/ -
PWM2 PWM2 /sys/class/pwm/pwmchip1/ -
PWM3 PWM3 /sys/class/pwm/pwmchip2/ -
PWM4 PWM4 /sys/class/backlight/backlight.17/ Used for backlight control

Colibri iMX6

Toradex Name NXP/Freescale Name sysfs path Note
PWM_A PWM3 /sys/class/backlight/backlight/ Used for backlight control
PWM_B PWM1 /sys/class/pwm/pwmchip0/ -
PWM_C PWM4 /sys/class/pwm/pwmchip3/ -
PWM_D PWM2 /sys/class/pwm/pwmchip1/ -

Note: In older BSP versions the PWM3 backlight sysfs path was as follows: /sys/class/backlight/backlight.15/.

Export PWM channel for user control.

cd /sys/class/pwm/pwmchip1
echo 0 > export

Select the period of PWM signal. Value is in nanoseconds.

echo 1000000 > pwm0/period

Select the duty cycle. Value is in nanoseconds and must be less than the period.

echo 250000 > pwm0/duty_cycle

Enable/disable the PWM signal.

echo 1 > pwm0/enable

Possible values:

  • 1: Enable
  • 0: Disable

BSP version older than V2.7

The PWM LED interface is used to export the PWM channels.

To control the duty cycle, the sysfs brightness file can be used. Value is within the range 0 to 255, where 0 means 0% duty cycle while 255 means 100% duty cycle.

Apalis iMX6

Toradex Name NXP/Freescale Name sysfs path Note
PWM1 PWM1 /sys/class/leds/PWM1/ -
PWM2 PWM2 /sys/class/leds/PWM2/ -
PWM3 PWM3 /sys/class/leds/PWM3/ -
PWM4 PWM4 /sys/class/backlight/backlight.17/ Used for backlight control

Colibri iMX6

Toradex Name NXP/Freescale Name sysfs path Note
PWM_A PWM3 /sys/class/backlight/backlight.15/ Used for backlight control
PWM_B PWM1 /sys/class/leds/PWM<B>/ -
PWM_C PWM4 /sys/class/leds/PWM<C>/ -
PWM_D PWM2 /sys/class/leds/PWM<D>/ -

root@apalis-imx6:/sys/class/leds# ls
PWM1 PWM2 PWM3 mmc0:: mmc1:: mmc2::
root@apalis-imx6:/sys/class/leds# cd PWM1/
root@apalis-imx6:/sys/class/leds/PWM1# ls
brightness device max_brightness power subsystem uevent
root@apalis-imx6:/sys/class/leds/PWM1# echo 127 > brightness

Note: leds-pwm driver has only support for controlling the duty cycle through sysfs, period is fixed and cannot be configured through sysfs.

Colibri iMX7

Toradex Name NXP/Freescale Name sysfs path Note
PWM_A PWM1 /sys/class/pwm/pwmchip0/ Used for backlight control (/sys/class/backlight/backlight/)
PWM_B PWM2 /sys/class/pwm/pwmchip1/ -
PWM_C PWM3 /sys/class/pwm/pwmchip2/ -
PWM_D PWM4 /sys/class/pwm/pwmchip3/ -

Export PWM channel for user control:

root@colibri-imx7:~# cd /sys/class/pwm/pwmchip1/
root@colibri-imx7:~# echo 0 > export

Select the period of PWM signal. Value is in nanoseconds.

root@colibri-imx7:~# echo 1000000 > pwmchip1/pwm0/period

Select the duty cycle. Value is in nanoseconds and must be less than the period.

root@colibri-imx7:~# echo 500000 > pwm0/duty_cycle

Enable/disable the PWM signal.

root@colibri-imx7:~# echo 1 > pwm0/enable

Possible values:

  • 1: Enable
  • 0: Disable

Note that PWM1 is used by the PWM backlight driver by default. If you want to use that PWM channel as regular PWM, you have to alter the device tree and disable the pwm-backlight driver (see Device Tree Customization). To control the backlight, one can use the backlight sysfs interface:

root@colibri-imx7:~# cd /sys/class/backlight/backlight/
root@colibri-imx7:~# echo 6 > brightness

For more information refer: pwm.txt

Colibri VFxx

The Vybrid BSP is making use of the kernel's PWM framework. PWMs are exposed at /sys/class/pwm/

Toradex Name NXP/Freescale Name sysfs path Note
PWM_A FTM0_0 /sys/class/backlight/backlight/ Used for backlight control
PWM_B FTM1_0 /sys/class/pwm/pwmchip8/pwm0/ -
PWM_C FTM0_1 /sys/class/pwm/pwmchip0/pwm1/ -
PWM_D FTM1_1 /sys/class/pwm/pwmchip8/pwm1/ -

Export PWM channel for user control.

root@colibri-vf:~# cd /sys/class/pwm/pwmchip8/
root@colibri-vf:~# echo 0 > export

Select the period of PWM signal. Value is in nanoseconds.

root@colibri-vf:~# echo 1000000 > pwm0/period

Select the duty cycle. Value is in nanoseconds and must be less than the period.

root@colibri-vf:~# echo 500000 > pwm0/duty_cycle

Enable/disable the PWM signal.

root@colibri-vf:~# echo 1 > pwm0/enable

Possible values

  • 1: Enable
  • 0: Disable

Change the polarity of the PWM signal. The polarity can only be changed if the PWM is not enabled.

root@colibri-vf:~# echo "normal" > pwm0/polarity

Possible strings

  • normal
  • inversed

Note: By default PWM_A is consumed by the backlight driver, hence exporting PWM0_0 fails with an error:

root@colibri-vf:~# echo 0 > export
-sh: echo: write error: Device or resource busy

If you don't use the backlight capabilities and want to use PWM_A through the PWM interface, you have to remove the backlight node in the board level device tree (see also the Device Tree Customization article). For temporarily purposes, you can unbind the driver using

root@colibri-vf:~# echo backlight > /sys/bus/platform/drivers/pwm-backlight/unbind

Note 2: The NXP/Freescale FTM controller supports only a single period for all PWM channels, we cannot use different period values for channels on same FTM controller.

By default, the backlight PWM channel (PWM_A, FTM0_0) is used with a period of 1000000 nsec, so PWM_C (FTM0_1) cannot be configured with a different period.

For more information refer: pwm.txt

Colibri iMX6ULL

Toradex Name NXP/Freescale Name sysfs path Note
PWM_A PWM4 /sys/class/pwm/pwmchip0/ Used for backlight control (/sys/class/backlight/backlight/)
PWM_B PWM5 /sys/class/pwm/pwmchip1/ -
PWM_C PWM6 /sys/class/pwm/pwmchip2/ -
PWM_D PWM7 /sys/class/pwm/pwmchip3/ -

Export PWM channel for user control.

root@colibri-imx6ull:~# cd /sys/class/pwm/pwmchip1/
root@colibri-imx6ull:/sys/class/pwm/pwmchip1# echo 0 > export

Select the period of PWM signal. Value is in nanoseconds.

root@colibri-imx6ull:/sys/class/pwm/pwmchip1# echo 1000000 > pwm0/period

Select the duty cycle. Value is in nanoseconds and must be less than the period.

root@colibri-imx6ull:/sys/class/pwm/pwmchip1# echo 500000 > pwm0/duty_cycle

Enable/disable the PWM signal.

echo 1 > pwm0/enable

Possible values:

  • 1: Enable
  • 0: Disable

Note that PWM_A is used by the PWM backlight driver by default. If you want to use PWM_A channel as regular PWM, you have to alter the device tree and disable the pwm-backlight driver (see Device Tree Customization). To control the backlight, one can use the backlight sysfs interface:

root@colibri-imx6ull:~# cd /sys/class/backlight/backlight/
root@colibri-imx6ull:/sys/class/backlight/backlight# echo 0 > brightness
root@colibri-imx6ull:/sys/class/backlight/backlight# echo 7 > brightness

For more information refer: pwm.txt

Apalis TK1

On TK1 all PWM instances are covered by one single PWM chip abstraction.

Toradex Name NXP/Freescale Name sysfs path Note
PWM1 PWM0 /sys/class/pwm/pwmchip0/ -
PWM2 PWM1 /sys/class/pwm/pwmchip0/ -
PWM3 PWM2 /sys/class/pwm/pwmchip0/ -
PWM4 PWM3 /sys/class/pwm/pwmchip0/ Used for backlight control (sys/class/backlight/pwm-backlight/)

Export PWM instance for user control.

root@apalis-tk1:~# cd /sys/class/pwm/pwmchip0
root@apalis-tk1:/sys/class/pwm/pwmchip0# echo 0 > export

Select the period of PWM signal. Value is in nanoseconds.

root@apalis-tk1:/sys/class/pwm/pwmchip0# echo 1000000 > pwm0/period

Select the duty cycle. Value is in nanoseconds and must be less than the period.

root@apalis-tk1:/sys/class/pwm/pwmchip0# echo 250000 > pwm0/duty_cycle

Enable/disable the PWM signal.

root@apalis-tk1:/sys/class/pwm/pwmchip0# echo 1 > pwm0/enable

Possible values:

  • 1: Enable
  • 0: Disable

Note that PWM3 is used by the PWM backlight driver by default. If you want to use PWM3 instance as regular PWM, you have to alter the device tree and disable the pwm-backlight driver (see Device Tree Customization). To control the backlight, one can use the backlight sysfs interface:

root@apalis-tk1:~# cd /sys/class/backlight/pwm-backlight
root@apalis-tk1:/sys/class/backlight/pwm-backlight# echo 0 > brightness
root@apalis-tk1:/sys/class/backlight/pwm-backlight# echo 255 > brightness

PWM LED's

You can use the PWM LED driver which allows to control LED's brightness through PWM. The LED framework has also advantage that triggers can be configured. Triggers allow to let a LED be controlled by kernel events such as NAND flash access.

Make sure the kernel configuration CONFIG_LEDS_PWM resp. CONFIG_LEDS_GPIO is enabled.

To configure PWM, add the following node to the device tree (see Device Tree Customization for more information on device trees):

    pwmleds {
        compatible = "pwm-leds";
        led1 {
            label = "vf610:green:led1";
            pwms = <&pwm1 1 5000000 0>;
            max-brightness = <255>;
        };
    };

The brightness can then be configured using sysfs:

echo 120 > /sys/class/leds/vf610\:green\:led1/brightness

To let the LED be controlled by the kernel itself, triggers can be used to control the LED:

echo nand-disk > /sys/class/leds/vf610\:green\:led1/trigger

Note: There is also a GPIO LED driver, which might be more appropriate for LED's which are only used in a on/off configuration (e.g. triggers).