This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Tool/software: Linux
Hello,
I am trying to connect a GPIO as an interrupt line. The relevant device tree parts are as below:
gpio0_pins_default: gpio0_pins_default {
pinctrl-single,pins = <
0x1a8 ( PIN_INPUT_PULLUP | MUX_MODE9 ) /* (M25) mcasp0_axr1.gpio0[2] */
0x1ac ( PIN_INPUT_PULLUP | MUX_MODE9 ) /* (L24) mcasp0_ahclkx.gpio0[3] */
0x158 ( PIN_INPUT_PULLUP | MUX_MODE7 ) /* (T21) spi0_d1.gpio0[4] */
0x15c ( PIN_INPUT_PULLUP | MUX_MODE7 ) /* (T20) spi0_cs0.gpio0[5] */
0x1a0 ( PIN_INPUT_PULLUP | MUX_MODE9 ) /* (L23) mcasp0_aclkr.gpio0[18] */
0x1a4 ( PIN_INPUT_PULLUP | MUX_MODE9 ) /* (K23) mcasp0_fsr.gpio0[19] */
0x264 ( PIN_INPUT_PULLUP | MUX_MODE9 ) /* (P22) spi2_d0.gpio0[20] */
0x268 ( PIN_INPUT_PULLUP | MUX_MODE9 ) /* (P20) spi2_d1.gpio0[21] */
>;
};
tca8418:tca8418@34{
compatible = "ti,tca8418";
reg = <0x34>;
interrupt-parent = <&gpio0>;
interrupts = <21 0x01>; //gpio0_21 configured as interrupt
keypad,num-rows = <5>;
keypad,num-columns = <4>;
linux,keymap = <
0x0306003b
0x06000111>;
status = "okay";
};
&gpio0 {
pinctrl-names = "default";
pinctrl-0 = <&gpio0_pins_default>;
status = "okay";
};
The driver is configured without any error (checked using printk). And the interrupt gets added in /proc/interrupt
95: 0 48322000.gpio 24 Edge tca8418
But, the interrupt never gets called.
In /sys/kernel/debug/pinctrl/44e10800.pinmux/pinmux-pins, we see that
pin 154 (PIN154): (MUX UNCLAIMED) (GPIO UNCLAIMED)
pin 154 corresponds to GPIO0_21, but it says MUX UNCLAIMED.
In order to rectify this, I added the following in gpio0
p21 {
gpio-hog;
gpios = <21 GPIO_ACTIVE_HIGH>;
input;
line-name = "GPIO0_21";
};
After adding the above lines, the probe function of the driver never got called.
What am I doing wrong?
Thanks,
Rajat Rao
Hi Tsvetolin,
I don't know what you mean exactly. If you're referring to GPIO UNCLAIMED message, then in the GP-EVM as well we see this:
pin 85 (PIN85): matrix_keypad0 (GPIO UNCLAIMED) function matrix_keypad_default
pin 105 (PIN105): matrix_keypad0 (GPIO UNCLAIMED) function matrix_keypad_default
pin 106 (PIN106): matrix_keypad0 (GPIO UNCLAIMED) function matrix_keypad_default
pin 107 (PIN107): matrix_keypad0 (GPIO UNCLAIMED) function matrix_keypad_default
One problem I can see is that the gpio interrupt is not getting configured correctly. In my case, the output of cat /proc/interrupts should show a gpio0 interrupt but it shows
95: 0 48322000.gpio 24 Edge tca8418
which should have been 44e07000.gpio.
I see that this is getting configured correctly in the EVM.
195: 0 44e07000.gpio 3 Edge matrix-keypad
I add printk in the driver as follows:
irq = client->irq;
printk(KERN_ALERT "Irq number %d\n", irq);
irq = gpio_to_irq(irq);
printk(KERN_ALERT "Irq number %d\n", irq);
This prints:
[ 9.374763] [tca8418]: Irq number 56
[ 9.374770] [tca8418]: Irq number 95
How do I verify if these numbers are correct? Which header file has the definitions that map the interrupts into linux space?
Thanks,
Rajat Rao
Hi Rajat,
I think i have the same issue regarding the tca8418 driver.
I am not that experienced with Linux drivers, so could you pleas share the changes you made with me?
Regards,
Andreas Lechner
Hi Andreas,
I can't share the changes as a patch that you can apply, but below are the lines I changed -
struct device_node *np = dev->of_node;
if (!np) {
dev_err(dev, "[tca8418]: device lacks DT data\n");
return ERR_PTR(-ENODEV);
}
irq = of_get_named_gpio(np, "irq-gpio", 0); //Add something like irq-gpio = <gpio0 21 GPIO_ACTIVE_HIGH>;
printk(KERN_DEBUG "[tca8418]: GPIO number %d\n", irq);
error = gpio_request(irq, "i2c_keypad_irq");
if (error) {
dev_err(dev,
"[tca8418]: failed to request GPIO%d for IRQ\n",
irq);
return error;
}
gpio_direction_input(irq);
printk(KERN_DEBUG "[tca8418]: GPIO set as input\n");
irq = gpio_to_irq(irq);
printk(KERN_DEBUG "[tca8418]: IRQ number %d\n", irq);
enable_irq(irq);
error = devm_request_threaded_irq(dev, irq, NULL, tca8418_irq_handler,
IRQF_TRIGGER_RISING |
IRQF_SHARED |
IRQF_ONESHOT,
client->name, keypad_data);
Note that the interrupt may be FALLING edge triggered for you.
Rajat Rao