Interfacing TCA9539 Interrupt to LS1012A

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

Interfacing TCA9539 Interrupt to LS1012A

2,941 Views
alexanderjaiboy
Contributor II

Hi All

I am trying to interface the interrupt from the TCA9539 to FRWY-LS1012A (INT pin on the mickro BUS expander).

INT pin of the micro BUS expander is connected to the 4th pin of the second GPIO bank (i.e. GPIO2[3]).

The DTS entry is -  

gpioexpander@77 {
      compatible = "nxp,pca9539";
      reg = <0x77>;
      vcc-supply = <&reg_3p3v>;
      interrupt-parent = <&gpio1>;
      interrupts = <4 2>;
      interrupt-controller;
      interrupt-cells = <2>;
      gpio-controller;
      gpio-cells = <2>;
};

The below entries in the DTS is meant to setup interupt from the TCA9539 to be interfaced to the 4th pin of the 2nd GPIO bank of LS1012A, with IRQ being triggered on falling edge (IRQ_TYPE_EDGE_FALLING).

      interrupt-parent = <&gpio1>;
      interrupts = <4 2>;

PCA953x driver is enabled in the kernel.

The Kernel Boot up fails with 
[ 0.367933] genirq: Setting trigger mode 8 for irq 29 failed (mpc8xxx_irq_set_type+0x0/0x1a0)
[ 0.376579] pca953x 0-0077: failed to request irq 29
[ 0.381910] pca953x: probe of 0-0077 failed with error -22

During the probe function of the PCA953x driver the irq setup function(pca953x_irq_setup) is called, which triggers at the end mpc8xxx driver irq setup function (mpc8xxx_irq_set_type). In mpc8xxx_irq_set_type the triggering type (driver code variable - flow_type) comes up as "IRQ_TYPE_LEVEL_LOW (8) " (even though the IRQ_TYPE_EDGE_FALLING is set in the DTS).

TCA9539 gpio-expander without the interrupt related entries in the DTS, works fine. I am able to configure the GPIO pins using SYSFS(/sys/class/gpio/).

I am struggling to use TCA9539 gpio expander, with the interupt enabled in the DTS.

Any help is much appreciated.

0 Kudos
Reply
3 Replies

2,354 Views
Pavel
NXP Employee
NXP Employee

See the AN5125 "Introduction to Device Trees" about interrup setting in .dts file:

https://www.nxp.com/docs/en/application-note/AN5125.pdf

 

See also the following document:

https://events.static.linuxfound.org/sites/events/files/slides/petazzoni-device-tree-dummies.pdf

Have a great day,
Pavel Chubakov

 

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos
Reply

2,354 Views
alexanderjaiboy
Contributor II

The DTS entry should be as below to set the interrupt(from GPIO expaner) to GPIO2[3] pin of the FRWY_LS1012A board GPIO pin.

gpioexpander@77 {
      compatible = "nxp,pca9539";
      reg = <0x77>;
      vcc-supply = <&reg_3p3v>;
      interrupt-parent = <&gpio1>;
      interrupts = <3 2>;
      interrupt-controller;
      interrupt-cells = <2>;
      gpio-controller;
      gpio-cells = <2>;
};

0 Kudos
Reply

2,354 Views
alexanderjaiboy
Contributor II

Hi All,

I was able to fix the issue (not a generic fix) of the driver not loading with the IRQ issue.

The reason for the issue is in gpio-pca953x.c
during the probe function of pca953x driver (pca953x_probe), the irq setup function (pca953x_irq_setup) is called.
In the irq setup fucntion, the devm_request_threaded_irq() is called with hard coded value of IRQ trigger for LOW level (IRQF_TRIGGER_LOW)

when the call reaches the driver for the FRWYLS1012A gpio chip i.e gpio-mpc8xxx.c, the IRQ setup function mpc8xxx_irq_set_type() is invoked. The mpc8xxx_irq_set_type() handles only IRQ triggering based on edge (IRQ_TYPE_EDGE_FALLING,IRQ_TYPE_EDGE_BOTH).

The IRQ setup call from pca953x comes with IRQF_TRIGGER_LOW, which causes the driver loading to fail.

The fix is to pass "IRQF_TYPE_EDGE_FALLING" instead of "IRQF_TRIGGER_LOW" from pca953x_irq_setup as parameter for devm_request_threaded_irq().

Original code - 

ret = devm_request_threaded_irq(&client->dev,
 client->irq,
 NULL,
 pca953x_irq_handler,
IRQF_TRIGGER_LOW | IRQF_ONESHOT |
 IRQF_SHARED,
dev_name(&client->dev), chip);‍‍‍‍‍‍‍

 

Modified code - 

ret = devm_request_threaded_irq(&client->dev,
 client->irq,
 NULL,
 pca953x_irq_handler,
 /*IRQF_TRIGGER_LOW | IRQF_ONESHOT |
 IRQF_SHARED,*/
 IRQF_TRIGGER_FALLING | IRQF_ONESHOT |
 IRQF_SHARED,
 dev_name(&client->dev), chip);

 

This is not a generic fix, but this can help to load the driver for the TCA9539 gpio expander.

# i2cdetect -y 0
    0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00: -- -- -- -- -- 08 -- 0a -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- 3c -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- UU -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- UU 
# cd /sys/class/gpio/
# ls
export gpiochip432 gpiochip448 gpiochip480 unexport
# echo 432 > export
# ls
export gpio432 gpiochip432 gpiochip448 gpiochip480 unexport
# cd gpio432
# ls
active_low  direction  power      uevent
device      edge       subsystem  value‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

 

0 Kudos
Reply