Difference between revisions of "Linux PWM Pulse Width Modulator"

From RidgeRun Developer Connection
Jump to: navigation, search
m (Add API header)
m (Get the PWM resource)
Line 121: Line 121:
 
In the driver, use the devm_pwm_get() function to pass to it the consumer device.
 
In the driver, use the devm_pwm_get() function to pass to it the consumer device.
  
<pre>
+
<pre style="background:#d6e4f1">
 
priv->pwm_dev = devm_pwm_get(&client->dev, NULL);
 
priv->pwm_dev = devm_pwm_get(&client->dev, NULL);
 
if (IS_ERR(priv->pwm_dev)) {
 
if (IS_ERR(priv->pwm_dev)) {

Revision as of 12:45, 28 May 2019

Introduction

The following document has information about the Pulse Width Modulators available for the TX2 and how to control them.

There are eight PWMs available for the TX2:

OTPM TX2 PWMs

Activating TX2 PWM

The TX2's pulse width modulators can be controlled at user space level using sysfs interface or at driver level using the PWM API.

Control PWM through sysfs

There are available 4 PWMs to be controlled at user space level. This interface allow the user to set the desired period and duty cycle and then activate or disable the PWM selected.

In /sys/class/pwm, you will find four directories corresponding to the first fourth PWMs available:

pwmchip0 --> GP_PWM1
pwmchip1 --> GP_PWM2
pwmchip2 --> GP_PWM3
pwmchip3 --> GP_PWM4 (Fan)

In order to set the configuration of one of the PWMs, you should export it first. Then, set the period, duty cycle and enable state as the following:

echo 0 > /sys/class/pwm/pwmchip0/export
cd /sys/class/pwm/pwmchip0/pwm0
echo 20000 > period
echo 10000 > duty_cycle
echo 1 > enable

In the example above, the pulse activated (PWM1) has a frequency of 50 KHz (1/20us) and 50% of duty cycle (10000/20000 * 100).

Control Fan PWM (sysfs)

Jetson EVM only has pins exposed for the PWM signal that controls the fan, so in order to verify that the PWM is working correctly use the pin 4 on J15 Connector.

Disable Fan driver

As the PWM4 is already used by a driver that controls the fan, you should disable this driver in order to control the PWM manually.

Apply below change on hardware/nvidia/platform/t18x/common/kernel-dts/t18x-common-platforms/tegra186-quill-power-tree-p3489-1000-a00-00.dtsi

pwm-fan {
+ 	status = "disabled";
 	vdd-fan-supply = <&vdd_fan>;
 };

Fix vdd_fan regulator state

The Fan controller has a GPIO that has to be set to low in order to allow the PWM activation, so you can modify the device-tree to set the initial value to low and keep this state to reduce complexity regarding PWM activation.

Apply below change on hardware/nvidia/platform/t18x/common/kernel-dts/t18x-common-platforms/tegra186-cvb-prod-p2597-b00-p3310-1000-a00-00.dtsi

vdd_fan: regulator@13 {
	compatible = "regulator-fixed-sync";
	reg = <13>;
	regulator-name = "vdd-fan";
	regulator-min-microvolt = <5000000>;
	regulator-max-microvolt = <5000000>;
	gpio = <&gpio_i2c_0_74 4 0>;
+	enable-active-high;
};

Note: You can also, disable this regulator and control manually vdd_fan GPIO (244) according to your needs.

Configure and Enable Fan PWM

Fan is controlled by GP_PWM4, so you in order to configure this PWM, you should apply the configuration to pwmchip3.

echo 0 > /sys/class/pwm/pwmchip3/export
cd /sys/class/pwm/pwmchip3/pwm0
echo 20000 > period
echo 10000 > duty_cycle
echo 1 > enable

Verify PWM activation

Measure the PWM output on pin 4 of J15 Connector using an oscilloscope. You should see the pulse when you enable the PWM and you could measure frequency and duty cycle to validate this procedure.

Enable PWM using the API

A driver can configure and activate a PWM in a similar way to a the GPIOs are set. In order to do this, you should define the desired PWM in your corresponding driver node in your device-tree and implement the logic to parse and control this PWM in the driver.

Control Fan PWM (API)

In the following example, we are going to control the GP_PWM4 so, make sure you have the fan driver disabled and fix vdd_fan regulator to be in low state as explained in Control Fan PWM (sysfs)

Define the PWM in the Device-Tree

In the example below, the GP_PWM4 is defined in the AR1335 sensor node to start in low state and with a period of 45334 (~45 us).

ar1335_a@37 {
	compatible = "nvidia,ar1335";
	reg = <0x37>;
	:
        #pwm-cells = <1>;
	pwms = <&tegra_pwm4 0 45334>;
	:
};

Add API header

In the driver, add the following include:

#include <linux/pwm.h>

Get the PWM resource

In the driver, use the devm_pwm_get() function to pass to it the consumer device.

priv->pwm_dev = devm_pwm_get(&client->dev, NULL);
if (IS_ERR(priv->pwm_dev)) {
	err = PTR_ERR(priv->pwm_dev);
	if (err != -EPROBE_DEFER)
		dev_err(&client->dev,
			"Unable to request PWM for fan\n");
	return -EFAULT;
} else {
	dev_info(&client->dev, "Got PWM for fan\n");
}

Configure PWM

Use pwm_config() method to set the duty cycle and period, in the example below the pulse is configured with a frequency of 60 Hz and 50% of duty cycle.

pwm_config(priv->pwm_dev, 8333333, 16666667);

Enable PWM

Once the PWM is configured, activate it like this:

pwm_enable(priv->pwm_dev);

Disable PWM

In order to disable PWM, use the following method:

pwm_diable(priv->pwm_dev);

Verify PWM

Using this methods you should be able to control the PWM and you can verify the output measuring pin 4 (J15 Connector).