# How to use the PWM lines

<abstract>
This article illustrates how to use the SPI interface on the Acme Systems Linux boards based on Microchip SAMG2x, SAMA5D3x and SAMD2x CPUs
</abstract>

##PWM Kernel modules

Two drivers are provided by Atmel in the Kernel mainstream to generate the PWM signals

* [pwm-atmel.c](http://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/tree/drivers/pwm/pwm-atmel-tcb.c) which uses the PWM controller
* [pwm-atmel-tcb.c](http://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/tree/drivers/pwm/pwm-atmel-tcb.c) which uses the Timer Counter Block

These drivers exposes a sysfs user space interface to manage the PWM signals.

##Driver for Timer Counter Block PWB

	Device Drivers  ---> 
	  [*] Pulse-Width Modulation (PWM) Support  --->
	    <*>   Atmel TC Block PWM support 

##Related links
* [Using PWMs with the sysfs interface](http://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/tree/Documentation/pwm.txt#n48)
* [pwm-atmel.c driver source](http://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/tree/drivers/pwm/pwm-atmel.c)
* [pwm-atmel-tcb.c driver source](http://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/tree/drivers/pwm/pwm-atmel-tcb.c)
* [Device tree binding](http://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/tree/Documentation/devicetree/bindings/pwm/atmel-tcb-pwm.txt)



##Using the PWM sysfs user space interface

The PWM sysfs at startup interface will create a directory called <b>/sys/class/pwm/pwmchip0</b>.

For any PWM line you want to use you have to export it.

<pre class="minicom">
~# echo 0 > /sys/class/pwm/pwmchip0/export
~# echo 1 > /sys/class/pwm/pwmchip0/export
~# echo 2 > /sys/class/pwm/pwmchip0/export
~# echo 3 > /sys/class/pwm/pwmchip0/export
...
</pre>

To use again that line ad generic GPIO you can unexport it:

<pre class="minicom">
~# echo 0 > /sys/class/pwm/pwmchip0/unexport
~# echo 1 > /sys/class/pwm/pwmchip0/unexport
~# echo 2 > /sys/class/pwm/pwmchip0/unexport
~# echo 3 > /sys/class/pwm/pwmchip0/unexport
...
</pre>

For any exported channel a directory called **pwmX** wil be created with
the following structure: 

<pre class="minicom">
/sys/class/pwm/pwmchip0/pwmX/
      |-- duty_cycle (r/w) duty cycle (in nanoseconds)
      |-- enable     (r/w) enable/disable PWM
      |-- period     (r/w) period (in nanoseconds)
      |-- polarity   (r/w) polarity of PWM
      |-- power
      `-- uevent
</pre>

The follow example illustrate how enable a PWM signale with a period 
of 1mS with a 0.5mS of duty cycle:

<pre class="minicom">
~# echo 1000000 > /sys/class/pwm/pwmchip0/pwm0/period
~# echo 500000 > /sys/class/pwm/pwmchip0/pwm0/duty_cycle
~# echo 1 > /sys/class/pwm/pwmchip0/pwm0/enable
</pre>

## PWM

### Acqua

	pwm0: pwm@f002c000 {
		pinctrl-names = "default";
		pinctrl-0 = <   
						&pinctrl_pwm0_pwmh0
						&pinctrl_pwm0_pwml0
						&pinctrl_pwm0_pwmh1 
						&pinctrl_pwm0_pwml1
						&pinctrl_pwm0_pwmh2 
						&pinctrl_pwm0_pwml2
						&pinctrl_pwm0_pwmh3 
						&pinctrl_pwm0_pwml3
						>;
		status = "okay";
	};

	pinctrl@fffff200 {
		board {
			pinctrl_pwm0_pwmh0: pwm0_pwmh0 {
				atmel,pins =
					< AT91_PIOB 0 AT91_PERIPH_B AT91_PINCTRL_NONE >;
			};
			pinctrl_pwm0_pwml0: pwm0_pwml0 {
				atmel,pins =
					< AT91_PIOB 1 AT91_PERIPH_B AT91_PINCTRL_NONE >;
			};
			pinctrl_pwm0_pwmh1: pwm0_pwmh1 {
				atmel,pins =
					< AT91_PIOB 4 AT91_PERIPH_B AT91_PINCTRL_NONE >;
			};
			pinctrl_pwm0_pwml1: pwm0_pwml1 {
				atmel,pins =
					< AT91_PIOB 5 AT91_PERIPH_B AT91_PINCTRL_NONE >;
			};
			pinctrl_pwm0_pwmh2: pwm0_pwmh2 {
				atmel,pins =
					< AT91_PIOB 8 AT91_PERIPH_B AT91_PINCTRL_NONE >;
			};
			pinctrl_pwm0_pwml2: pwm0_pwml2 {
				atmel,pins =
					< AT91_PIOB 9 AT91_PERIPH_B AT91_PINCTRL_NONE >;
			};
			pinctrl_pwm0_pwmh3: pwm0_pwmh3 {
				atmel,pins =
					< AT91_PIOB 12 AT91_PERIPH_B AT91_PINCTRL_NONE >;
			};
			pinctrl_pwm0_pwml3: pwm0_pwml3 {
				atmel,pins =
					< AT91_PIOB 13 AT91_PERIPH_B AT91_PINCTRL_NONE >;
			};
		};
	};

### Aria

	pinctrl@fffff400 {
		pwm0 {
			pinctrl_pwm0: pwm0-0 {
				atmel,pins =
				< AT91_PIOC 18 AT91_PERIPH_C AT91_PINCTRL_NONE
				  AT91_PIOC 19 AT91_PERIPH_C AT91_PINCTRL_NONE
				  AT91_PIOC 20 AT91_PERIPH_C AT91_PINCTRL_NONE
				  AT91_PIOC 21 AT91_PERIPH_C AT91_PINCTRL_NONE >;
			};
		};
	};
				
	pwm0: pwm@f8034000 {
		pinctrl-names = "default";
		pinctrl-0 = <&pinctrl_pwm0>;
		status = "okay";
	};

### Arietta

	pinctrl@fffff400 {
		pwm0 {
			pinctrl_pwm0: pwm0-0 {
				atmel,pins =
				< AT91_PIOB 11 AT91_PERIPH_B AT91_PINCTRL_NONE
				  AT91_PIOB 12 AT91_PERIPH_B AT91_PINCTRL_NONE
				  AT91_PIOB 13 AT91_PERIPH_B AT91_PINCTRL_NONE
				  AT91_PIOB 14 AT91_PERIPH_B AT91_PINCTRL_NONE >;
			};
		};
	};

<!--
<pre class="minicom">
pwm {
        compatible = "atmel,tcb-pwm";
        #pwm-cells = <3>;
        tc-block = <1>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_tcb1_tioa0
                     &pinctrl_tcb1_tioa1
                     &pinctrl_tcb1_tioa2
                     &pinctrl_tcb1_tiob0
                     &pinctrl_tcb1_tiob1
                     &pinctrl_tcb1_tiob2>;
        status = "okay";
};
</pre>
-->


##Credits

Many thanks to Nicolas Ferre and Boris Brezillon for their help.  

@include='bio_tanzilli'
