gpio_keys + pinctrl: pin already requested: failed with error -22 - linux-device-driver

I have an Orange Pi Zero 2 board and I'm trying to add some joystick through GPIO.
I have found an example Device Tree overlay and modified it to my needs (see below attached version). It is also loaded and applied at startup, but yielts an error and no node is found under /dev/input/. Instead it results in the following error message posted to DMESG:
[ 1.533942] sun50i-h616-pinctrl 300b000.pinctrl: pin PC8 already requested by gpio-keys-user; cannot claim for 300b000.pinctrl:72
[ 1.533967] gpio-keys gpio-keys-user: failed to get gpio: -22
[ 1.533975] gpio-keys: probe of gpio-keys-user failed with error -22
It seems as if pinctrl and gpio-keys block each other.
If I remove the pinctrl section, adding the input device works fine, but it doesn' detect useful events, because it seems as if the GPIO pin has not been setup (i.e. pull-up is not configured).
Does anybody have an idea what I'm doing wrong?
Here's my dts file:
/dts-v1/;
/plugin/;
/ {
compatible = "allwinner,sun50i-h616";
fragment#0 {
target = <&pio>;
__overlay__ {
custom-buttons: custom-buttons {
pins = "PC5","PC6","PC8";
function = "gpio_in";
bias-pull-up;
};
};
};
fragment#1 {
target-path = "/";
__overlay__ {
gpio-keys-user {
compatible = "gpio-keys";
pinctrl-names = "default";
pinctrl-0 = <&custom-buttons>;
play_button {
label = "GPIO Key 1";
linux,code = <25>;
gpios = <&pio 0 69 1>;
};
vol_up_button {
label = "GPIO Key 2";
linux,code = <22>;
gpios = <&pio 0 70 1>;
};
vol_down_button {
label = "GPIO Key 3";
linux,code = <32>;
gpios = <&pio 0 72 1>;
};
};
};
};
};

Related

Why MaxTouch amtel_mxt_ts driver can't register interrupt on Yocto BeagleBone am335x?

I need to integrate a Maxtouch Touchpanel (atmel_mxt_ts) Driver to an BeagleBoneBlack based Yocto Dunfell 3.1 with linux-ti-staging Kernel 5.4 system. The driver is set as loadable kernel module. The Yocto project integrates meta-ti and meta-arm from the dunfell branches.
The Interrupt should use gpio0[30] at address 0x870 on the BeagleBones P9 header. For that I set the mode ofthe gpio to 7.
I wrote a DTS to the sources and add the resulting DTB it to be loaded at startup. So far everything is working. The DTB is created and loaded during boot up.
The only problem is that when the driver is loaded by the kernel it complains about to be unable to register the interrupt.
[ 2.823173] atmel_mxt_ts 1-004a: Failed to register interrupt
[ 3.040633] atmel_mxt_ts: probe of 1-004a failed with error -22
Can anyone explain what I'm doing wrong?
This is my main DTS file
/*
* Copyright (C) 2015 Jumpnow Technologies, LLC - http://jumpnowtek.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
/dts-v1/;
#include "am33xx.dtsi"
#include "am335x-bone-common.dtsi"
#include "bbb-i2c1.dtsi"
#include "bbb-dcan1.dtsi"
/ {
model = "TI AM335x BeagleBone Black";
compatible = "ti,am335x-bone-black", "ti,am33xx";
};
&ldo3_reg {
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
};
&mmc1 {
vmmc-supply = <&vmmcsd_fixed>;
};
&mmc2 {
vmmc-supply = <&vmmcsd_fixed>;
pinctrl-names = "default";
pinctrl-0 = <&emmc_pins>;
bus-width = <8>;
status = "okay";
};
&am33xx_pinmux {
touch_pins: touch_pins {
pinctrl-single,pins = <
AM33XX_PADCONF(AM335X_PIN_GPMC_WAIT0, PIN_INPUT_PULLDOWN, MUX_MODE7) /* P9.11 0x870 Touch IRQ */
AM33XX_PADCONF(AM335X_PIN_MCASP0_AXR0, PIN_OUTPUT_PULLUP, MUX_MODE7) /* P9.30 0x998 Touch RST */
>;
};
can_pins: can_pins {
pinctrl-single,pins = <
AM33XX_PADCONF(AM335X_PIN_UART1_TXD, PIN_INPUT_PULLUP, MUX_MODE2) /* P9.24 0x984 CAN rx */
AM33XX_PADCONF(AM335X_PIN_UART1_RXD, PIN_OUTPUT_PULLUP, MUX_MODE2) /* P9.26 0x980 CAN tx */
>;
};
};
&dcan0 {
status = "disabled";
};
&rtc {
system-power-controller;
};
&i2c1 {
status = "okay";
pinctrl-names = "default";
clock-frequency = <100000>;
atmel_mxt_ts#4a {
status = "okay";
compatible = "atmel,atmel_mxt_ts";
reg = <0x4a>;
interrupt-parent = <&gpio0>; /* P9.11 gpio0
interrupts = <30>; /* gpio0[30], Falling edge only 0x02*/
pinctrl-names = "default";
pinctrl-0 = <&touch_pins>;
};
};
&i2c2 {
status = "okay";
};
&dcan1 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&can_pins>;
};
and this is the content of bbb-i2c1.dtsi
&am33xx_pinmux {
i2c1_pins: i2c1_pins {
pinctrl-single,pins = <
AM33XX_IOPAD(0x958, SLEWCTRL_SLOW | PIN_INPUT_PULLUP | MUX_MODE2) /* P9.18, i2c1_sda */
AM33XX_IOPAD(0x95c, SLEWCTRL_SLOW | PIN_INPUT_PULLUP | MUX_MODE2) /* P9.17, i2c1_scl */
>;
};
};
&i2c1 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&i2c1_pins>;
clock-frequency = <100000>;
};
and this is the content of bbb-dcan1.dtsi
&am33xx_pinmux {
dcan1_pins: dcan1_pins {
pinctrl-single,pins = <
AM33XX_IOPAD(0x984, PIN_INPUT_PULLUP | MUX_MODE2) /* P9.24, ddcan1_rx */
AM33XX_IOPAD(0x980, PIN_OUTPUT_PULLUP | MUX_MODE2) /* P9.26, ddcan1_tx */
>;
};
};
&dcan1 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&dcan1_pins>;
};
Thanks for your support
Found the bug by myself. It was a missing closing command tag here
interrupt-parent = <&gpio0>; /* P9.11 gpio0
I opened a multiline comment without closing and all included attributes were not set

How to write down the gpio-expander to the kernel device tree?

I use a GPIO expander (TCA6424) with i.mx8qm. The expander is connected with the processor through I²C. I wrote it down to the *.dts file:
&i2c4 {
pinctrl-0 = <&pinctrl_i2c4>;
status = "okay";
tca6424#22 {
compatible = "ti, tca6424";
reg = <0x22>;
gpio-controller;
#gpio-cells = <2>;
};
};
But the driver outputed the errors:
[ 0.816053] pca953x 8-0020: 8-0020 supply vcc not found, using dummy regulator
[ 0.823139] pca953x 8-0020: failed reading register
[ 0.827936] pca953x: probe of 8-0020 failed with error -5
Do I understand correctly 0x22 is address of device here? But where I should write down the number of I²C bus? What else could I forget to point out?

How can I use mcp2515 & device tree?

My Kernel Source writes platform data to device tree.(kernel version 3.10.9)
The board used is Exynos5422.
So I wrote mcp2515 platform data parameter to .dts
dts:
spi_1: spi#12d30000 {
status = "okay";
spi-src-clk = <0>;
num-cs = <1>;
gpios = <&gpa2 4 0>,
<&gpa2 6 0>,
<&gpa2 7 0>;
can1: mcp251x#0{
compatible ="microchip,mcp2515";
reg = <0>;
spi-max-frequency = <2000000>;
pinctrl-names = "default";
pinctr-0=<&mcp_irq>;
interrupts = < 0 0 0 >;
interrupt-parent = <&gpx1>;
irq_gpio = <&gpx1 5 0>;
reset_gpio = <&gph0 1 0>;
controller-data {
cs-gpio = <&gpa2 5 0>;
samsung,spi-feedback-delay = <0>;
};
};
};
mcp_irq: mcp_irq {
samsung,pins = "gpx1-5";
samsung,pin-function = <0xf>;
samsung,pin-pud = <3>;
samsung,pin-drv = <3>;
};
When the following assignment fails, pdata is null, resulting in fatal error below.
struct mcp251x_platform_data *pdata = spi->dev.platform_data
mcp251x.c:
if (!pdata) {
/* Platform data is required for osc freq */
goto error_out;
}
Settings:
What am I missing?

device tree overlay for heartbeat not working

First of all, hello!
I wrote a device tree overlay for heartbeat function on a gpio (you can see the dts file below).
It is loadad successfully, and I could see the trigger file in userspace:
root#beaglebone:~# cat /sys/devices/platform/bone_capemgr/slots
0: PF---- -1
1: PF---- -1
2: PF---- -1
3: PF---- -1
4: P-O-L- 0 Override Board Name,00A0,Override Manuf,cape-univ-emmc
6: P-O-L- 1 Override Board Name,00A0,Override Manuf,issd-heartbeat
root#beaglebone:~# cat /sys/class/leds/beaglebone\:yellow\:usr0/trigger
none nand-disk usb-gadget usb-host mmc0 mmc1 timer oneshot [heartbeat] backlight gpio default-on
Everything looks ok but I cannot see heartbeat on the pin.
I verified the led is working, I can pull it low and high with no problem when it's configured as output gpio.
I don't know where to look now, so if anyone can direct me, it's enough. Thanks.
DTS file:
/dts-v1/;
/plugin/;
/ {
compatible = "ti,beaglebone", "ti,beaglebone-black";
/* identification */
part-number = "issd-heartbeat";
version = "00A0";
/* state the resources this cape uses */
exclusive-use =
/* the pin header uses */
"P8.8", /* heart beat LED*/
/* the hardware ip uses */
"gpio2_3";
fragment#0 {
target = <&am33xx_pinmux>;
__overlay__ {
indicator_pins: indicator_pins {
pinctrl-single,pins = <
0x094 0x07
>;
};
};
};
fragment#14 {
target = <&ocp>;
__overlay__ {
indicator_pins {
compatible = "gpio-leds";
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&indicator_pins>;
led0 {
label = "beaglebone:yellow:usr0";
gpios = <&gpio3 3 0x00>; /* gpio3 is gpio2*/
linux,default-trigger = "heartbeat";
default-state = "off";
};
};
};
};
};

How to define platform_data in a Linux 3.8 device tree structure (DTS) file

I'm trying to get the at86rf230 kernel driver running on a BeagleBone Black to communicate with my radio. I have confirmed that I am able to interact with the device using some userspace SPI code. Here's the fragment of the DTS file I'm working with:
fragment#0 {
target = <&am33xx_pinmux>;
__overlay__ {
spi1_pins_s0: spi1_pins_s0 {
pinctrl-single,pins = <
0x040 0x37 /* DIG2 GPIO_9.15 I_PULLUP | MODE7-GPIO1_16 */
0x044 0x17 /* SLPTR GPIO_9.23 O_PULLUP | MODE7-GPIO1_17 */
0x1AC 0x17 /* RSTN GPIO_9.25 O_PULLUP | MODE7-GPIO3_21 */
0x1A4 0x37 /* IRQ GPIO_9.26 I_PULLUP | MODE7-GPIO3_19 */
0x190 0x33 /* SCLK mcasp0_aclkx.spi1_sclk, INPUT_PULLUP | MODE3 */
0x194 0x33 /* MISO mcasp0_fsx.spi1_d0, INPUT_PULLUP | MODE3 */
0x198 0x13 /* MOSI mcasp0_axr0.spi1_d1, OUTPUT_PULLUP | MODE3 */
0x19c 0x13 /* SCS0 mcasp0_ahclkr.spi1_cs0, OUTPUT_PULLUP | MODE3 */
>;
};
};
};
fragment#3 {
target = <&spi1>;
__overlay__ {
#address-cells = <1>;
#size-cells = <0>;
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&spi1_pins_s0>;
at86rf230#0 {
spi-max-frequency = <1000000>;
reg = <0>;
compatible = "at86rf230";
interrupts = <19>;
interrupt-parent = <&gpio3>;
};
};
};
On loading the module I get the following error in dmesg:
[ 352.668833] at86rf230 spi1.0: no platform_data
[ 352.668945] at86rf230: probe of spi1.0 failed with error -22
I am trying to work out the right way to attach platform_data to the SPI overlay. Here's what I'd like to attach:
platform_data {
rstn = <&gpio3 21 0>;
slp_tr = <&gpio1 17 0>;
dig2 = <&gpio1 16 0>;
};
Unfortunately, just sticking it in as-is doesn't work so well when I use dtc to compile the DTS. I get the following error:
syntax error: properties must precede subnodes
FATAL ERROR: Unable to parse input tree
I feel that I'm ridiculously close to solving this, and I just need a little shove in the right direction ;)
First of all, the GPIO names in your excerpt are wrong. Accordingly to the latest code in linux-next there are
pdata->rstn = of_get_named_gpio(spi->dev.of_node, "reset-gpio", 0);
pdata->slp_tr = of_get_named_gpio(spi->dev.of_node, "sleep-gpio", 0);
There are only two of them.
Second, you have to adjust the DTS for your exact board. The entire DTS has to be considered as a platform data for all devices found on the board (some supported, some might be not). The section for the specific device should be described as device node.
So, the good start point is to check what is in upstream already exists, namely in arch/arm/boot/dts/am335x-boneblack.dts, don't forget to check included files as well.
And the example for this specific driver is in Documentation/devicetree/bindings/net/ieee802154/at86rf230.txt.