I.MX6 PWM
The PWM controller is accessed through the Linux driver. PWM is available on these pins:
- CN1_19 (channel 1) (LCD Data 8)
- CN1_21 (channel 2) (LCD Data 9)
- CN2_74 (channel 2) (replaces USB_OTG_ID)
- CN1_57 (channel 3)
This will require modifying the kernel or device tree to set up these pins as PWM. See the #Compile the Kernel section to get a build environment working. You will then need to modify either a baseboard specific device tree, or the fallback arch/arm/boot/dts/imx6qdl-ts4900.dtsi. This example will assume the latter.
In this case this is the example PWM channel 3 on the TS-4900 on CN1_57. First the pin must be configured to be PWM and not a GPIO. Add the pinctrl_pwm3 after the imx-ts4900 {:
iomuxc {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_hog>;
imx6-ts4900 {
pinctrl_pwm3: pwm3grp {
fsl,pins = <
MX6QDL_PAD_SD4_DAT1__PWM3_OUT 0x1b088
>;
};
The MX6QDL_PAD_SD4_DAT1__PWM3_OUT pad name comes from imx6q-pinfunc.h (or imx6dl-pinfunc.h). The format follows MX6QDL_PAD_<CPU Pad Name>__<Function of that pad>. This specifies SD4_DAT1 to be used as PWM3's output.
At the end of the file enable the PWM controller, and point at this pinctrl:
&pwm3 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm3>;
status = "okay";
};
This will attach a driver to actually drive that pin that is now configured for PWM. After rebuilding and installing this device tree you will now have a directory "/sys/class/pwm/pwmchip0". This can be used to control the PWM.
# Each PWM controller has "1" pwm which will be pwm channel 0
echo 0 > /sys/class/pwm/pwmchip0/export
This will create a pwm0 directory under pwmchip0 which has these files:
period | Total period, inactive and active time in the PWM cycle specified in nanoseconds. |
duty_cycle | Active time of the PWM signal specified in nanoseconds. Must be less than the period. |
enable | Write 1 to enable, 0 to disable |
polarity | When the pwm is disabled this can be written as "normal" for default behavior or "inversed" to invert the signal. |
As an example, this will set a 50khz signal with 50 percent duty cycle.
# 20us is the period for 50khz
echo 20000 > /sys/class/pwm/pwmchip0/pwm0/period
echo 10000 > /sys/class/pwm/pwmchip0/pwm0/duty_cycle
echo 1 > /sys/class/pwm/pwmchip0/pwm0/enable
A common use of the PWM is for backlight control which is specified in the device tree. Our TS-TPC-8390 baseboard device tree can be used as an example.
In addition to setting up the PWM as demonstrated above, the PWM is connected to the pwm-backlight driver.
backlight_lcd {
compatible = "pwm-backlight";
pwms = <&pwm3 0 5000000>;
brightness-levels = <0 128 140 160 180 200 220 240 255>;
default-brightness-level = <8>;
power-supply = <®_3p3v>;
};
This specifies PWM3 to run with 5000000 ns periods (200hz) with duty cycles specified in brightness-levels up to 255. This example creates 8 levels of brightness for the backlight, but more duty cycles can be added if more levels are needed.