Configure GPIO as interrupt source

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Configure GPIO as interrupt source

Jump to solution
38,716 Views
lategoodbye
Senior Contributor I

Hello Freescale Community,

i'm using Linux Kernel 3.10 on i.MX28 EVK and have some problems with dts definition.

I want to use MX28_PAD_I2C0_SDA__GPIO_3_25 as an GPIO (direction: input), who generates interrupts if the input value goes from 0 to 1 (rising edge). Finally, the interrupts should trigger an Kernel module and call it's irq handler. I should mention the Kernel module doesn't have support for Device Tree.

In my dts file, i have the following entry:

gpio_intr: gpio_intr@0 {
                    reg = <0>;
                    fsl,pinmux-ids = <
                        0x3193 /* MX28_PAD_I2C0_SDA__GPIO_3_25 */
                    >;
                    fsl,drive-strength = <0>;
                    fsl,voltage = <1>;
                    fsl,pull-up = <0>;

                };

Here are my questions:

Is the dts entry above correct?

What needs to be added, that the GPIO generates interrupts?

Where should be the GPIO direction configured (GPIO section of dts file or init function of mach-mxs/mach-mxs.c)?

Where should be the IRQ event (rising edge) configured (mach-mxs.c, dts file or Kernel module)?

Thanks in advance.

Stefan

Labels (2)
Tags (3)
0 Kudos
Reply
1 Solution
11,189 Views
lategoodbye
Senior Contributor I

Finally i've successful ported the driver and got the it running. The main problem was the inconsistent and out-dated documentation.

The advice to use a different driver as template was good, but the example wasn't really helpful. The Xilinx SPI controller driver did help me more.

For everbody who has the problem like me, here are some very helpful links:

http://devicetree.org/Device_Tree_Usage - General information about Device Tree

http://www.jumpnowtek.com/index.php?option=com_content&view=article&id=57&Itemid=62 - Tutorial how to write a SPI protocol driver (unfortunately without device tree support)

http://xillybus.com/tutorials/device-tree-zynq-1 - Tutorial how to write a SPI master driver (fortunately with Device Tree support)

View solution in original post

0 Kudos
Reply
8 Replies
11,189 Views
francescoaru
Contributor I

Hello Stefan,

I've got the same problem, the external SPI device (slave) provides an interrupt line that is connected to a GPIO.

From what I understand I have to write a new driver (on top of the spi-mxs driver) supporting dts and managing the GPIO irq.

Is that correct?

Thanks,

Francesco

0 Kudos
Reply
11,189 Views
lategoodbye
Senior Contributor I

Hi Francesco,

if you want to use the external SPI device in a new kernel and there is no device driver, then you will need to implement a spi device driver.

Here is a little bit prototype stuff you will need to implement:

static int my_spi_probe(struct spi_device *spi_device);


static int my_spi_remove(struct spi_device *spi_device);

static struct spi_driver my_spi_driver = {

.driver = {

.name = "myspi",

.owner = THIS_MODULE,

.of_match_table = my_spi_of_match,

},

.id_table = my_spi_ids,

.probe   = my_spi_probe,

.remove   = my_spi_remove,

};

module_spi_driver(my_spi_driver);


There is also a helpful funktion gpio_to_irq() to get the irq from a GPIO.


Finally the implementation of this device should use the spi driver interface and not the specific of spi-mxs driver.


I hope this helps.


BR Stefan

0 Kudos
Reply
11,189 Views
francescoaru
Contributor I

Hi Stefan,

thanks for your reply.

I would like to extend the spi-mxs.c driver adding the GPIO interrupt routine.

For that purpose I think I will use the gpio_to_irq() function you suggested me.

 

I also presume I have to extend the spi section of the dts file accordingly.

Did you use the dts as shown in your previous post?

My concern is that if I define a parent interrupt controller (e.g. &gpio3) for the driver it will not inherit the SSP interrupts.

Indeed I also need the DMA transfers (imx28.dtsi specifies two interrupts for the SSP, the SSP error and the DMA).

Does your driver implement the DMA transfers?

Francesco

0 Kudos
Reply
11,189 Views
lategoodbye
Senior Contributor I

Hi Francesco,

i think you are a little bit confused about spi drivers under Linux. There are two driver layers. The lower layer is specific to the Host CPU (i.MX28 in your case) and is called SPI master controller driver. This driver is already implemented it's the spi-mxs.c. The upper layer is specific to the SPI slave and is called SPI protocol driver. This is explained in the Kernel documentation Documentation/spi/spi-summary. The problem is that document does explain nothing about device trees, so forget all about board specific from this document.

Extending spi-mxs.c as a SPI protocol driver won't work. You will need to implement a different interface. The advantage of this approach is that the protocol driver doesn't need to care about DMA transfer, because the spi-mxs does this for you.

Our SPI protocol driver will goes to mainline in the near future.

Here is the public repository: https://github.com/I2SE/qca7000/tree/linux-mainline

In the README file, you will find a helpful dts usage example. It's so simple.

BR Stefan

0 Kudos
Reply
11,189 Views
francescoaru
Contributor I

Going into details, the SPI slave reads a data block sent by the master and processes it.

The GPIO interrupt notifies the master when the slave can accept another data block.

My idea is to modify the DMA transfer routine in order to check and wait the slave ready state.

I think spidev is ok as SPI protocol driver.

Thanks for your support. It's time to try.

Bye,

Francesco

0 Kudos
Reply
11,190 Views
lategoodbye
Senior Contributor I

Finally i've successful ported the driver and got the it running. The main problem was the inconsistent and out-dated documentation.

The advice to use a different driver as template was good, but the example wasn't really helpful. The Xilinx SPI controller driver did help me more.

For everbody who has the problem like me, here are some very helpful links:

http://devicetree.org/Device_Tree_Usage - General information about Device Tree

http://www.jumpnowtek.com/index.php?option=com_content&view=article&id=57&Itemid=62 - Tutorial how to write a SPI protocol driver (unfortunately without device tree support)

http://xillybus.com/tutorials/device-tree-zynq-1 - Tutorial how to write a SPI master driver (fortunately with Device Tree support)

0 Kudos
Reply
11,189 Views
fabio_estevam
NXP Employee
NXP Employee

First of all you need to add device tree support to the driver you want to use.

You can see an example of a mx28 that uses a GPIO (GPIO2_19) as IRQ at arch/arm/boot/dts/imx28-cfa10049.dts:

   i2c@3 {
   reg = <3>;
   #address-cells = <1>;
   #size-cells = <0>;

   pca9555: pca9555@20 {
   compatible = "nxp,pca9555";
   pinctrl-names = "default";
   pinctrl-0 = <&pca_pins_cfa10049>;
   interrupt-parent = <&gpio2>;
   interrupts = <19 0x2>;
   gpio-controller;
   #gpio-cells = <2>;
   interrupt-controller;
   #interrupt-cells = <2>;
   reg = <0x20>;
   };
   };

The 0x2 from the interrupts node is explained at:

Documentation/devicetree/bindings/interrupt-controller/interrupts.txt

  "The #interrupt-cells property is set to 2 and the first cell defines the

  index of the interrupt within the controller, while the second cell is used

  to specify any of the following flags:

    - bits[3:0] trigger type and level flags

        1 = low-to-high edge triggered

        2 = high-to-low edge triggered

        4 = active high level-sensitive

        8 = active low level-sensitive"

11,189 Views
lategoodbye
Senior Contributor I

Hello Fabio,

thanks for your advice. But i'm pretty new to kernel hacking and need more information. The device tree support for Linux device driver isn't much documented, especially for newbies.

The kernel driver represent an IC connected as SPI slave to the MX28 and acts as an network device.

I need more information about your example:

Which C file do you mean gpio-pca953x.c or i2c-mux-954x.c?

What does device tree support means in detail?

In both files i didn't find a access to the interrupt settings of the device tree.

Isn't it necessary to implement the irq mapping (GPIO => IRQ), because the device tree and the spi driver from the parent node handle that?

Now i have extended the device tree with the spi device and i can find it under /sys/devices.

ssp2: ssp@80014000 {

                #address-cells = <1>;

                #size-cells = <0>;

                compatible = "fsl,imx28-spi";

                pinctrl-names = "default";

                pinctrl-0 = <&spi2_pins_a>;

                status = "okay";

               

                spi-device: spi-device@0 {   

                       compatible = "spi-device";

                       interrupt-parent = <&gpio3>;

                       interrupts = <25 0x1>;

                       spi-max-frequency = <2000000>;

                       reg = <0x0>;

                   };

            };

Do i need to place the input GPIO 3_25 as child of pinctrl?

Are there any checkpoints, where i can see that i'm on the right way of implementation?

Stefan

0 Kudos
Reply