I'm improving the integration of a custom C4 Hat with the tobetter kernel 5.16. The hat consists of a number of devices which are all confirmed working via userspace drivers and kernel integration (IE CAN bus transceiver/driver as network interface, RTC module/PPS setting disciplined clock via crony and GPIO expanders recognized as gpiochips). I also use this hat on separate projects using microcontroller so have 100% confidence in the hardware. I am cross compiling DTBs w/full source tree.
I have two mcp23008s on i2c0. For simplicity, I am only working with one for now. Wiring is as follows
INT - PIN16/GPIOX_0
RST - PIN18/GPIOX_1
I2c0-SDA - PIN3
I2c0-SCL - PIN5
To following is stripped down dts
Code: Select all
#include <dt-bindings/gpio/meson-g12a-gpio.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
/dts-v1/;
/plugin/;
/ {
fragment@0 {
// i2c2 aliased with i2c0.
target = <&i2c2>;
__overlay__ {
status = "okay";
#address-cells = <1>;
#size-cells = <0>;
mcp23008: mcp23008@21 {
status = "okay";
compatible = "microchip,mcp23008";
reg = <0x21>;
#gpio-cells = <2>;
gpio-controller;
interrupt-parent = <&gpio_intc>; // MUST be gpio_intc
interrupts = <GPIOX_0 IRQ_TYPE_LEVEL_LOW>;
// irq-gpios works with gpio_intc OR gpio..hmm or not at all...
// perhaps details from interrupt-parent and interrupts is sufficient
irq-gpios = <&gpio_intc GPIOX_0 GPIO_ACTIVE_LOW>;
interrupt-controller;
#interrupt-cells=<2>;
reset-gpios = <&gpio GPIOX_1 GPIO_ACTIVE_LOW>;
};
};
};
};
What works:
mcp23008 chip registered as gpiochip
kernel registers an interrupt for the mcp23008 on the expected gpiochip0 line on the 40 pin header (65)
GPIO pins can be toggled/read as expected using libgpiod
monitoring i2c bus traffic, when interrupt is detected, ISR services the gpiochip by inquring for the pin states/CAPVEC to determine interrupt source,.
What doesn't
GPIOX_0 state has no correlation to interrupt firing (ie by monitoring /proc/interrupts).
In the above dts configuration, interrupt should fire when low. With a scope on PIN16 confirming that the level is HIGH, /proc/interrupts is firing continuously.
If I modify DTS by adding/changing interrupts line to
Code: Select all
microchip,irq-active-high
interrupts = <GPIOX_0 IRQ_TYPE_LEVEL_LOW>;
2. Interrupts do not fire continuously
3. Manually connecting 3.3V to PIN16 does not cause the interrupt to fire according to /proc/interrupts or by monitoring i2c traffic for the isr's activity
If I migrate the pin on the 40 pin header to something unused/disconnected from the Hat, I see the same behavior (ruling out interaction between the pin on the odroid and the hat circuitry).
My conclusion is that my DTS/DTBO is not correctly configuring the interrupt, or linking the interrupt controller to the gpio.
I appreciate any help
Thanks,
-J