Welcome, Guest

Author Topic: SPI Example: olinuxino GPIO expander  (Read 10987 times)

Fadil Berisha

  • Full Member
  • ***
  • Posts: 124
  • Karma: +7/-0
SPI Example: olinuxino GPIO expander
« on: October 30, 2012, 03:50:33 AM »
SPI driver for imx23 is included in kernel 3.x. To add SPI support on olinuxino needed to patch kernel source with patch available here:

https://www.dropbox.com/s/0v5morn5a4a0mlv/0001-ARM-imx23-olinuxino-Add-spi-support.patch

Following code on file imx23-olinuxino.dts define only master device:
Code: [Select]
ssp1: ssp@80034000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "fsl,imx23-spi";
pinctrl-names = "default";
pinctrl-0 = <&spi2_pins_a>;
status = "okay";
                        };

End user need to update code for slave device.

Example-1:
To add spi flash, previous code is updated with child node[1]:

Code: [Select]
ssp1: ssp@80034000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "fsl,imx23-spi";
pinctrl-names = "default";
pinctrl-0 = <&spi2_pins_a>;
status = "okay";

flash: m25p80@0 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "sst,sst25vf016b";
spi-max-frequency = <40000000>;
        reg = <0>;
};
                        };

Mandatory fields are: compatible, spi-max-frequency and reg. Take a look at Documentation/devicetree/bindings/spi/spi-bus.txt for other supported fields.

Sometimes needed to pass additional data to kernel e.g. platform_data. In this case, spi device driver need to be adapted for device tree support (on old kernel, passing is done with structure spi_board_info defined somewhere on <board>.c file). Following example will show this:

Example-2:
GPIO expander MCP23S08
Code: [Select]
ssp1: ssp@80034000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "fsl,imx23-spi";
pinctrl-names = "default";
pinctrl-0 = <&spi2_pins_a>;
status = "okay";
gpio3: gpio3@0 {
compatible = "microchip,mcp23s08";
addr = <0>;
base = <97>;
reg = <0>;
spi-max-frequency = <100000>;
gpio-controller;
#gpio-cells = <2>;
};
                        };

MCP23S08 is a 8-bit port expander with interrupt output, 2 adddress inputs for up to 4 devices on one bus.
In this code, fields are:
- addr represent address occupied with mcp23s08 chip's (0 - 1st chip, 1 - second chip ...)
- base address. Since imx32 has 3 banks (gpio0,...,gpio2) by 32 GPIO, base address is chosen to be 97, so     extended GPIO numbers are, 97,98,..,104
- gpio-controller define this node as controller.

Driver mcp23s08 does not support device tree. Patch to add device tree is provided here:

 https://www.dropbox.com/s/d4odg11ftls4b04/0001-Add-SPI-device-tree-support.patch

This patch shows how to pass platform_data to kernel in device tree environment.

Test results

Kernel response is:
Code: [Select]
Yocto (Built by Poky 7.0.1) 1.2.1 imx233-olinuxino-maxi ttyAMA0                                                                               
                                                                                                                                               
imx233-olinuxino-maxi login: root                                                                                                             
root@imx233-olinuxino-maxi:~# dmesg | grep spi                                                                                                 
[    0.950000] mxs-spi 80034000.ssp: registered master spi32766 (dynamic)                                                                     
[    0.950000] spi spi32766.0: setup mode 0, 8 bits/w, 100000 Hz max --> 0                                                                     
[    0.950000] mcp23s08 spi32766.0: chip[0].is_present = true                                                                                 
[    0.970000] mxs-spi 80034000.ssp: registered child spi32766.0

You can see that chip 0 is present and registered child spi32766.0.
GPIO  won't show up in the sysfs system until they are 'exported':

echo 97 > /sys/class/gpio/export

Make output direction for gpio pin 97:

echo out > /sys/class/gpio/gpio97/direction

Change value on pin 97:
Code: [Select]
root@imx233-olinuxino-maxi:~# echo 0 > /sys/class/gpio/gpio97/value                                                                           
root@imx233-olinuxino-maxi:~# echo 1 > /sys/class/gpio/gpio97/value                                                                           
root@imx233-olinuxino-maxi:~# echo 0 > /sys/class/gpio/gpio97/value                                                                           
root@imx233-olinuxino-maxi:~# echo 1 > /sys/class/gpio/gpio97/value

I have tested values with oscilloscope and everything working as needed.


Acknowledgements

Fabio Estevam, Freescale; Providing assistance and guidance in development of SPI patch
Tsvetan, Olimex:  Providing hardware for testing of SPI interface

Fadil Berisha
[1] https://patchwork.kernel.org/patch/1377821/
« Last Edit: November 03, 2012, 03:06:39 AM by Fadil Berisha »