...
CONFIG_GPIO_XILINX=y (for axi_gpio)Devicetree
#gpio-cells = <2>;
compatible = "xlnx,xps-gpio-1.00.a";
...
root@plnx_aarch64:~# cat /sys/class/gpio/gpio497/value – try each switch positionRepeat for 498 - 503
Addition of Dip Switches and Push Buttons to the node to generate interrupts
This section covers process of modifying the device tree (DTS) by adding dip switches and push buttons subnodes to generate interrupts.
These are suitable for more complex applications involving handling interrupts.
Add Dip Switches and Push buttons to the device tree
Kernel Configuration for dip switches and push buttons
In order to use, the kernel must be configured correctly. Configure the kernel as described in Build Kernel, and then make sure the following options are enabled in menuconfig:
Device Drivers
GPIO Support
Memory Mapped GPIO Drivers
Xilinx GPIO support
Xilinx Zynq GPIO support
Input device support
Keyboards
GPIO Buttons
Polled GPIO buttons
The following configs should be present in .config afterwards:
CONFIG_KEYBOARD_GPIO and CONFIG_KEYBOARD_GPIO_POLLED respectively.
Dip Switches to the device tree
Dip Switches are available only for Input GPIO application and are 8 in number.
Each created node controls a single bit of GPIO. Under "gpio-keys" node in the dts file, create 8 subnodes for dip switches with names as shown below:
gpio-keys {
compatible = "gpio-keys";
#address-cells = <1>;
#size-cells = <0>;
autorepeat;
sw19 {
label = "sw19";
gpios = <&gpio 22 0>;
linux,code = <108>; /* down */
gpio-key,wakeup;
autorepeat;
};
GPIO_DIP_SW0 {
label = "GPIO_DIP_SW0";
gpios = <&axi_gpio_0 0x0 0x0>;
linux, code = <108>;
gpio-key,wakeup;
autorepeat;
};
GPIO_DIP_SW1 {
label = "GPIO_DIP_SW1";
gpios = <&axi_gpio_0 0x1 0x0>;
linux,code = <108>;
gpio-key,wakeup;
autorepeat;
};
GPIO_DIP_SW2 {
label = "GPIO_DIP_SW2";
gpios = <&axi_gpio_0 0x2 0x0>;
linux,code = <108>;
gpio-key,wakeup;
autorepeat;
};
GPIO_DIP_SW3 {
label = "GPIO_DIP_SW3";
gpios = <&axi_gpio_0 0x3 0x0>;
linux,code = <108>;
gpio-key,wakeup;
autorepeat;
};
GPIO_DIP_SW4 {
label = "GPIO_DIP_SW4";
gpios = <&axi_gpio_0 0x4 0x0>;
linux,code = <108>;
gpio-key,wakeup;
autorepeat;
};
GPIO_DIP_SW5 {
label = "GPIO_DIP_SW5";
gpios = <&axi_gpio_0 0x5 0x0>;
linux,code = <108>;
gpio-key,wakeup;
autorepeat;
};
GPIO_DIP_SW6 {
label = "GPIO_DIP_SW6";
gpios = <&axi_gpio_0 0x6 0x0>;
linux,code = <108>;
gpio-key,wakeup;
autorepeat;
};
GPIO_DIP_SW7 {
label = "GPIO_DIP_SW7";
gpios = <&axi_gpio_0 0x7 0x0>;
linux,code = <108>;
gpio-key,wakeup;
autorepeat;
};
};
The Label refers to the descriptive name of the dip switch.
The string <&axi_gpio_0 0x0 0x0> references the AXI GPIO 0 controller and states that GPIO_DIP_SW0 is on pin 0, GPIO_DIP_SW1 is on pin 1 and same for remaining dip switches; the 0 states that the device is active high.
The linux,code property determines which key will show up in the event.
A full listing of key events can be found in include/uapi/linux/input.h.
gpio-key,wakeup will enable the GPIO to wake the system from suspend.
The autorepeat property allows holding the key to continuously generate events.
Full documentation can be found here Documentation/devicetree/bindings/input/gpio-keys.txt.
After this, boot the linux. We should able to see the label names of 8 dip switches in cat /proc/interrupts. On and off any of the dip switches and view the trigger count of that dip switch using "cat /proc/interrupts".
Expected Output
root@xilinx-zcu102-zu9-es2-rev1_0-2017:/sys/class/gpio# dmesg | grep gpio
[ 1.337411] XGpio: /amba_pl@0/gpio@a0010000: registered, base is 504
[ 4.127198] input: gpio-keys as /devices/platform/gpio-keys/input/input0
It means AXI GPIO reading the DIP Switches at 0xa0010000 and ist base is 504.
root@xilinx-zcu102-zu9-es2-rev1_0-2017:~# cd /sysc /class/gpio/
root@xilinx-zcu102-zu9-es2-rev1_0-2017:/sys/class/gpio# ls
export gpiochip298 gpiochip314 gpiochip330 gpiochip504 unexport
root@xilinx-zcu102-zu9-es2-rev1_0-2017:~# cat /proc/interrupts
CPU0 CPU1 CPU2 CPU3
3: 0 0 0 0 GICv2 29 Level arch_timer
4: 1115 1701 1909 1106 GICv2 30 Level arch_timer
7: 0 0 0 0 GICv2 187 Level arm-smmu global fault, arm-smmu-context-fault, arm-smmu-context-fault, arm-smmu-context-fault, arm-smmu-context-fault, arm-smmu-context-fault, arm-smmu-context-fault, arm-smmu-context-fault, arm-smmu-context-fault, arm-smmu-context-fault, arm-smmu-context-fault, arm-smmu-context-fault, arm-smmu-context-fault, arm-smmu-context-fault
12: 0 0 0 0 GICv2 67 Level zynqmp_pm
15: 0 0 0 0 GICv2 156 Level zynqmp-dma
16: 0 0 0 0 GICv2 157 Level zynqmp-dma
17: 0 0 0 0 GICv2 158 Level zynqmp-dma
18: 0 0 0 0 GICv2 159 Level zynqmp-dma
19: 0 0 0 0 GICv2 160 Level zynqmp-dma
20: 0 0 0 0 GICv2 161 Level zynqmp-dma
21: 0 0 0 0 GICv2 162 Level zynqmp-dma
22: 0 0 0 0 GICv2 163 Level zynqmp-dma
24: 0 0 0 0 GICv2 109 Level zynqmp-dma
25: 0 0 0 0 GICv2 110 Level zynqmp-dma
26: 0 0 0 0 GICv2 111 Level zynqmp-dma
27: 0 0 0 0 GICv2 112 Level zynqmp-dma
28: 0 0 0 0 GICv2 113 Level zynqmp-dma
29: 0 0 0 0 GICv2 114 Level zynqmp-dma
30: 0 0 0 0 GICv2 115 Level zynqmp-dma
31: 0 0 0 0 GICv2 116 Level zynqmp-dma
33: 0 0 0 0 GICv2 95 Level eth0, eth0
35: 302 0 0 0 GICv2 49 Level cdns-i2c
36: 43 0 0 0 GICv2 50 Level cdns-i2c
37: 0 0 0 0 GICv2 42 Level ff960000.memory-controller
38: 0 0 0 0 GICv2 150 Level nwl_pcie:misc
43: 14 0 0 0 GICv2 47 Level ff0f0000.spi
44: 0 0 0 0 GICv2 58 Level ffa60000.rtc
45: 0 0 0 0 GICv2 59 Level ffa60000.rtc
46: 0 0 0 0 GICv2 165 Level ahci-ceva[fd0c0000.ahci]
47: 192 0 0 0 GICv2 81 Level mmc0
48: 62 0 0 0 GICv2 53 Level xuartps
50: 0 0 0 0 GICv2 145 Edge fd4d0000.watchdog
51: 0 0 0 0 GICv2 88 Level ams-irq
52: 0 0 0 0 GICv2 151 Level fd4a0000.dp
53: 0 0 0 0 GICv2 154 Level fd4c0000.dma
55: 0 0 0 0 Xilinx INTC 1 Level -level a0000000.i2c
**57: 0 0 0 0 xgpio 0 Edge GPIO_DIP_SW0**
**58: 0 0 0 0 xgpio 1 Edge GPIO_DIP_SW1**
**59: 0 0 0 0 xgpio 2 Edge GPIO_DIP_SW2**
**60: 0 0 0 0 xgpio 3 Edge GPIO_DIP_SW3**
**61: 0 0 0 0 xgpio 4 Edge GPIO_DIP_SW4**
87: 0 0 0 0 zynq-gpio 22 Edge sw19
239: 0 0 0 0 GICv2 97 Level xhci-hcd:usb1
IPI0: 2073 972 1065 2191 Rescheduling interrupts
IPI1: 69 49 54 43 Function call interrupts
IPI2: 0 0 0 0 CPU stop interrupts
IPI3: 156 154 29 142 Timer broadcast interrupts
IPI4: 0 0 0 0 IRQ work interrupts
IPI5: 0 0 0 0 CPU wake-up interrupts
After switching on and off any of the dip switches, the trigger count of that dip switch increases as shown below
root@xilinx-zcu102-zu9-es2-rev1_0-2017:/sys/class/gpio# cat /proc/interrupts
CPU0 CPU1 CPU2 CPU3
3: 0 0 0 0 GICv2 29 Level arch_timer
4: 3061 2185 10195 1814 GICv2 30 Level arch_timer
7: 0 0 0 0 GICv2 187 Level arm-smmu global fault, arm-smmu-context-fault, arm-smmu-context-fault, arm-smmu-context-fault, arm-smmu-context-fault, arm-smmu-context-fault, arm-smmu-context-fault, arm-smmu-context-fault, arm-smmu-context-fault, arm-smmu-context-fault, arm-smmu-context-fault, arm-smmu-context-fault, arm-smmu-context-fault, arm-smmu-context-fault
12: 0 0 0 0 GICv2 67 Level zynqmp_pm
15: 0 0 0 0 GICv2 156 Level zynqmp-dma
16: 0 0 0 0 GICv2 157 Level zynqmp-dma
17: 0 0 0 0 GICv2 158 Level zynqmp-dma
18: 0 0 0 0 GICv2 159 Level zynqmp-dma
19: 0 0 0 0 GICv2 160 Level zynqmp-dma
20: 0 0 0 0 GICv2 161 Level zynqmp-dma
21: 0 0 0 0 GICv2 162 Level zynqmp-dma
22: 0 0 0 0 GICv2 163 Level zynqmp-dma
24: 0 0 0 0 GICv2 109 Level zynqmp-dma
25: 0 0 0 0 GICv2 110 Level zynqmp-dma
26: 0 0 0 0 GICv2 111 Level zynqmp-dma
27: 0 0 0 0 GICv2 112 Level zynqmp-dma
28: 0 0 0 0 GICv2 113 Level zynqmp-dma
29: 0 0 0 0 GICv2 114 Level zynqmp-dma
30: 0 0 0 0 GICv2 115 Level zynqmp-dma
31: 0 0 0 0 GICv2 116 Level zynqmp-dma
33: 0 0 0 0 GICv2 95 Level eth0, eth0
35: 302 0 0 0 GICv2 49 Level cdns-i2c
36: 43 0 0 0 GICv2 50 Level cdns-i2c
37: 0 0 0 0 GICv2 42 Level ff960000.memory-controller
38: 0 0 0 0 GICv2 150 Level nwl_pcie:misc
43: 14 0 0 0 GICv2 47 Level ff0f0000.spi
44: 0 0 0 0 GICv2 58 Level ffa60000.rtc
45: 0 0 0 0 GICv2 59 Level ffa60000.rtc
46: 0 0 0 0 GICv2 165 Level ahci-ceva[fd0c0000.ahci]
47: 192 0 0 0 GICv2 81 Level mmc0
48: 733 0 0 0 GICv2 53 Level xuartps
50: 0 0 0 0 GICv2 145 Edge fd4d0000.watchdog
51: 0 0 0 0 GICv2 88 Level ams-irq
52: 0 0 0 0 GICv2 151 Level fd4a0000.dp
53: 0 0 0 0 GICv2 154 Level fd4c0000.dma
55: 0 0 0 0 Xilinx INTC 1 Level -level a0000000.i2c
**57: 18 0 0 0 xgpio 0 Edge GPIO_DIO_SW0**
**58: 19 0 0 0 xgpio 1 Edge GPIO_DIP_SW1**
**59: 16 0 0 0 xgpio 2 Edge GPIO_DIP_SW2**
**60: 10 0 0 0 xgpio 3 Edge GPIO_DIP_SW3**
**61: 6 0 0 0 xgpio 4 Edge GPIO_DIP_SW4**
87: 0 0 0 0 zynq-gpio 22 Edge sw19
239: 0 0 0 0 GICv2 97 Level xhci-hcd:usb1
IPI0: 2106 996 1183 2261 Rescheduling interrupts
IPI1: 69 49 54 43 Function call interrupts
IPI2: 0 0 0 0 CPU stop interrupts
IPI3: 1457 1541 536 1442 Timer broadcast interrupts
IPI4: 0 0 0 0 IRQ work interrupts
IPI5: 0 0 0 0 CPU wake-up interrupts
Push buttons to the device tree
Push buttons are available only for Input GPIO application. They are 5 in number.
Each created node controls a single bit of GPIO. Under "gpio-keys" node in the dts file, create 5 subnodes for Push buttons with names as shown below:
gpio-keys {
compatible = "gpio-keys";
#address-cells = <1>;
#size-cells = <0>;
autorepeat;
sw19 {
label = "sw19";
gpios = <&gpio 22 0>;
linux,code = <108>; /* down */
gpio-key,wakeup;
autorepeat;
};
SW15 {
label = "SW15";
gpios = <&axi_gpio_1 0x0 0x0>;
linux,code = <108>;
gpio-key,wakeup;
autorepeat;
};
SW14 {
label = "SW14";
gpios = <&axi_gpio_1 0x1 0x0>;
linux,code = <108>;
gpio-key,wakeup;
autorepeat;
};
SW16 {
label = "SW16";
gpios = <&axi_gpio_1 0x2 0x0>;
linux,code = <108>;
gpio-key,wakeup;
autorepeat;
};
SW17 {
label = "SW17";
gpios = <&axi_gpio_1 0x3 0x0>;
linux,code = <108>;
gpio-key,wakeup;
autorepeat;
};
SW18 {
label = "SW18";
gpios = <&axi_gpio_1 0x4 0x0>;
linux,code = <108>;
gpio-key,wakeup;
autorepeat;
};
};
The Label refers to the descriptive name of the Push button.
The string <&axi_gpio_1 0x0 0x0> references the AXI GPIO 1 controller and states that SW15 is on pin 0, SW14 is on pin 1 and same for remaining Push buttons; the 0 states that the device is active high.
The linux,code property determines which key will show up in the event.
A full listing of key events can be found in include/uapi/linux/input.h.
gpio-key,wakeup will enable the GPIO to wake the system from suspend.
The autorepeat property allows holding the key to continuously generate events.
Full documentation can be found here Documentation/devicetree/bindings/input/gpio-keys.txt.
After this, boot the linux. We should able to see the label names of 5 push buttons in cat /proc/interrupts. Press any of the push buttons and view the trigger count of those push buttons in cat /proc/interrupts.
Expected Output
root@plnx_aarch64:~# c dmesg | grep gpio
[ 1.329832] XGpio: /amba_pl@0/gpio@b0002000: registered, base is 491
It means AXI GPIO reading the push buttons at b0002000 and its base starts from 491 to 495.
[ 4.680308] input: gpio-keys as /devices/platform/gpio-keys/input/input0
root@plnx_aarch64:~# cat /proc/interrupts
CPU0 CPU1 CPU2 CPU3
2: 0 0 0 0 GICv2 29 Level arch_timer
3: 1765 2701 1206 1053 GICv2 30 Level arch_timer
10: 0 0 0 0 GICv2 67 Level zynqmp_pm
13: 0 0 0 0 GICv2 156 Level zynqmp-dma
14: 0 0 0 0 GICv2 157 Level zynqmp-dma
15: 0 0 0 0 GICv2 158 Level zynqmp-dma
16: 0 0 0 0 GICv2 159 Level zynqmp-dma
17: 0 0 0 0 GICv2 160 Level zynqmp-dma
18: 0 0 0 0 GICv2 161 Level zynqmp-dma
19: 0 0 0 0 GICv2 162 Level zynqmp-dma
20: 0 0 0 0 GICv2 163 Level zynqmp-dma
22: 0 0 0 0 GICv2 109 Level zynqmp-dma
23: 0 0 0 0 GICv2 110 Level zynqmp-dma
24: 0 0 0 0 GICv2 111 Level zynqmp-dma
25: 0 0 0 0 GICv2 112 Level zynqmp-dma
26: 0 0 0 0 GICv2 113 Level zynqmp-dma
27: 0 0 0 0 GICv2 114 Level zynqmp-dma
28: 0 0 0 0 GICv2 115 Level zynqmp-dma
29: 0 0 0 0 GICv2 116 Level zynqmp-dma
31: 0 0 0 0 GICv2 95 Level eth0, eth0
33: 302 0 0 0 GICv2 49 Level cdns-i2c
34: 43 0 0 0 GICv2 50 Level cdns-i2c
35: 0 0 0 0 GICv2 42 Level ff960000.memory-controller
36: 0 0 0 0 GICv2 150 Level nwl_pcie:misc
41: 14 0 0 0 GICv2 47 Level ff0f0000.spi
42: 0 0 0 0 GICv2 58 Level ffa60000.rtc
43: 0 0 0 0 GICv2 59 Level ffa60000.rtc
44: 0 0 0 0 GICv2 165 Level ahci-ceva[fd0c0000.ahci]
45: 174 0 0 0 GICv2 81 Level mmc0
46: 82 0 0 0 GICv2 53 Level xuartps
48: 0 0 0 0 GICv2 145 Edge fd4d0000.watchdog
49: 0 0 0 0 GICv2 88 Level ams-irq
50: 0 0 0 0 GICv2 151 Level fd4a0000.dp
51: 0 0 0 0 GICv2 154 Level fd4c0000.dma
**53: 0 0 0 0 xgpio 0 Edge SW15**
**54: 0 0 0 0 xgpio 1 Edge SW14**
**55: 0 0 0 0 xgpio 2 Edge SW16**
**56: 0 0 0 0 xgpio 3 Edge SW17**
**57: 0 0 0 0 xgpio 4 Edge SW18**
**80: 0 0 0 0 zynq-gpio 22 Edge sw19**
232: 0 0 0 0 GICv2 97 Level xhci-hcd:usb1
IPI0: 1691 1101 1537 1320 Rescheduling interrupts
IPI1: 57 47 64 39 Function call interrupts
IPI2: 0 0 0 0 CPU stop interrupts
IPI3: 93 157 200 215 Timer broadcast interrupts
IPI4: 0 0 0 0 IRQ work interrupts
IPI5: 0 0 0 0 CPU wake-up interrupts
root@plnx_aarch64:/sys/class/gpio#
root@plnx_aarch64:/sys/class/gpio# echo 491 > export
-sh: echo: write error: Device or resource busy
root@plnx_aarch64:/sys/class/gpio# echo 492 > export
-sh: echo: write error: Device or resource busy
root@plnx_aarch64:/sys/class/gpio# echo 493 > export
-sh: echo: write error: Device or resource busy
root@plnx_aarch64:/sys/class/gpio# echo 494 > export
-sh: echo: write error: Device or resource busy
root@plnx_aarch64:/sys/class/gpio# echo 495 > export
-sh: echo: write error: Device or resource busy
root@plnx_aarch64:/sys/class/gpio#
After pressing any of the push buttons, count of that push button increases as shown below.
root@plnx_aarch64:/sys/class/gpio# cat /proc/interrupts
CPU0 CPU1 CPU2 CPU3
2: 0 0 0 0 GICv2 29 Level arch_timer
3: 6915 12365 1875 1126 GICv2 30 Level arch_timer
10: 0 0 0 0 GICv2 67 Level zynqmp_pm
13: 0 0 0 0 GICv2 156 Level zynqmp-dma
14: 0 0 0 0 GICv2 157 Level zynqmp-dma
15: 0 0 0 0 GICv2 158 Level zynqmp-dma
16: 0 0 0 0 GICv2 159 Level zynqmp-dma
17: 0 0 0 0 GICv2 160 Level zynqmp-dma
18: 0 0 0 0 GICv2 161 Level zynqmp-dma
19: 0 0 0 0 GICv2 162 Level zynqmp-dma
20: 0 0 0 0 GICv2 163 Level zynqmp-dma
22: 0 0 0 0 GICv2 109 Level zynqmp-dma
23: 0 0 0 0 GICv2 110 Level zynqmp-dma
24: 0 0 0 0 GICv2 111 Level zynqmp-dma
25: 0 0 0 0 GICv2 112 Level zynqmp-dma
26: 0 0 0 0 GICv2 113 Level zynqmp-dma
27: 0 0 0 0 GICv2 114 Level zynqmp-dma
28: 0 0 0 0 GICv2 115 Level zynqmp-dma
29: 0 0 0 0 GICv2 116 Level zynqmp-dma
31: 0 0 0 0 GICv2 95 Level eth0, eth0
33: 302 0 0 0 GICv2 49 Level cdns-i2c
34: 43 0 0 0 GICv2 50 Level cdns-i2c
35: 0 0 0 0 GICv2 42 Level ff960000.memory-controller
36: 0 0 0 0 GICv2 150 Level nwl_pcie:misc
41: 14 0 0 0 GICv2 47 Level ff0f0000.spi
42: 0 0 0 0 GICv2 58 Level ffa60000.rtc
43: 0 0 0 0 GICv2 59 Level ffa60000.rtc
44: 0 0 0 0 GICv2 165 Level ahci-ceva[fd0c0000.ahci]
45: 174 0 0 0 GICv2 81 Level mmc0
46: 1111 0 0 0 GICv2 53 Level xuartps
48: 0 0 0 0 GICv2 145 Edge fd4d0000.watchdog
49: 0 0 0 0 GICv2 88 Level ams-irq
50: 0 0 0 0 GICv2 151 Level fd4a0000.dp
51: 0 0 0 0 GICv2 154 Level fd4c0000.dma
**53: 12 0 0 0 xgpio 0 Edge SW15**
**54: 9 0 0 0 xgpio 1 Edge SW14**
**55: 9 0 0 0 xgpio 2 Edge SW16**
**56: 6 0 0 0 xgpio 3 Edge SW17**
**57: 8 0 0 0 xgpio 4 Edge SW18**
80: 0 0 0 0 zynq-gpio 22 Edge sw19
232: 0 0 0 0 GICv2 97 Level xhci-hcd:usb1
IPI0: 1733 1223 1649 1340 Rescheduling interrupts
IPI1: 57 47 64 39 Function call interrupts
IPI2: 0 0 0 0 CPU stop interrupts
IPI3: 1720 1344 2083 2149 Timer broadcast interrupts
IPI4: 0 0 0 0 IRQ work interrupts
IPI5: 0 0 0 0 CPU wake-up interrupts
Err: 0
root@plnx_aarch64:/sys/class/gpio#
ChangeLog
2016.3