I.MX6 PWM

From Technologic Systems Manuals

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 = <&reg_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.