Power Off and Wake Up using GPIO Key Button

This section describes how to set up GPIO key button for power off and wake up purpose.

The brief set-up flow is as following.

  1. Connect a tab button to the pin port you want to use
  2. Set GPIO number using boot.ini
  3. Compiling and flash the modified kernel dts : This part is only needed on ANDROID.

First, You need to prepare a tab switch that are connected to two lines.
Red line is for Power Button and another Gray line is for the active level line (Ground or 3.3V Power).

For example, we will use Pin#29 of 40pin expansion connector.

The pin is assigned to GPIOX.BIT0 and its GPIO number is #228.
Connect the red line to Pin#29.

Its default pin pulled status is high and switch active will be Low, so you should connect the gray line of tab switch to Ground (GND), Pin#30.

Pin Number
(Red Line)
GPIO Number Active Level
(Gray Line)
29 GPIO#228 Active Low (Pin 30)

Here are the available key examples using 40-pin connector and 7-pin connector.
You can find the pin assign examples for Red Line and Gray Line.

(1) J2 - 2×20 pins

Active Level
(Gray Line)
GPIO Number Pin Number
(Red Line)
Pin Number
(Red Line)
GPIO Number Active Level
(Gray Line)
- 3.3V Power 1 2 - -
- - 3 4 - -
- - 5 6 Ground -
Active Low (Pin 9) GPIO#249 7 8 - -
- Ground 9 10 - -
Active Low (Pin 14) GPIO#247 11 12 GPIO#238 Active Low (Pin 14)
Active Low (Pin 14) GPIO#239 13 14 Ground -
Active Low (Pin 14) GPIO#237 15 16 GPIO#236 Active Low (Pin 14)
- 3.3V Power 17 18 GPIO#233 Active Low (Pin 20)
Active Low (Pin 20) GPIO#235 19 20 Ground -
Active Low (Pin 20) GPIO#232 21 22 GPIO#231 Active Low (Pin 20)
Active Low (Pin 25) GPIO#230 23 24 GPIO#229 Active Low (Pin 25)
- Ground 25 26 GPIO#225 Active High (Pin 17)
- - 27 28 - -
Active Low (Pin 30) GPIO#228 29 30 Ground -
Active Low (Pin 30) GPIO#219 31 32 GPIO#224 Active Low (Pin 34)
Active High (Pin 17) GPIO#234 33 34 Ground
Active Low (Pin 34) GPIO#214 35 36 GPIO#218 Active Low (Pin 34)
- - 37 38 - -
- Ground 39 40 - -

(2) J7 - 1×7 pins

Pin Number
(Red Line)
GPIO Number Active Level
(Gray Line)
1 Ground -
2 GPIO#128 Active Low (Pin 1)
3 5.0V Power -
4 GPIO#130 Active Low (Pin 1)
5 GPIO#132 Active Low (Pin 1)
6 GPIO#131 Active Low (Pin 1)
7 GPIO#133 Active Low (Pin 1)

You can find the detailed information about 40-pin and 7-pin connectors in the following link.
Expansion Connectors

  • Ubuntu : The release version should be 3.14.79-107 (Feb 26, 2017) or higher.

(1) Setting boot.ini

You can assign GPIO number with env gpiopower in boot.ini.

## gpio power key : J2 (2x20) Pin#29 , GPIOX.BIT0
setenv gpiopower "228"
...
...
 
## Add gpiopower like "setenv bootargs ${bootargs} gpiopower=${gpiopower}"
setenv bootargs "root=UUID=e139ce78-9841-40fe-8823-96a304a09859 rootwait ro ${condev} no_console_suspend hdmimode=${m} ${cmode} m_bpp=${m_bpp} vout=${vout} fsck.repair=yes net.ifnames=0 elevator=noop disablehpd=${hpd} max_freq=${max_freq} maxcpus=${maxcpus} monitor_onoff=${monitor_onoff} disableuhs=${disableuhs} mmc_removable=${mmc_removable} usbmulticam=${usbmulticam} ${hid_quirks} gpiopower=${gpiopower}"

(2) Setting Power Button Action for Power Off

To set poweroff event with this GPIO power button, acpi service is used.

a. Install acpi
$ sudo apt-get install acpid
b. Modify powerbtn.sh

After acpid installation, a default file of powerbtn.sh under /etc/acpi/ will be generated.
You need to replace it with a new powerbtn.sh as following.

$ sudo mv /etc/acpi/powerbtn.sh /etc/acpi/powerbtn.sh.bak
$ sudo vi /etc/acpi/powerbtn.sh
#!/bin/sh
# /etc/acpi/powerbtn.sh
# Initiates a shutdown when the power putton has been
# pressed.
 
# Shuts down as soon as power button is pressed on NUC
/sbin/shutdown -h now "Power button pressed"
exit 0
$ sudo chmod a+x /etc/acpi/powerbtn.sh
c. Register the service
$ sudo systemctl enable acpid.service
$ sudo systemctl start acpid.service
d. Edit logind.conf

Please uncomment the line, HandlePowerKey=poweroff.

$ sudo vi /etc/systemd/logind.conf

Here are the samples for Ubuntu 16.04 and Ubuntu 18.04.

  • logind.conf with Ubuntu 16.04
#  This file is part of systemd.
#
#  systemd is free software; you can redistribute it and/or modify it
#  under the terms of the GNU Lesser General Public License as published by
#  the Free Software Foundation; either version 2.1 of the License, or
#  (at your option) any later version.
#
# Entries in this file show the compile time defaults.
# You can change settings by editing this file.
# Defaults can be restored by simply deleting this file.
#
# See logind.conf(5) for details.
 
[Login]
#NAutoVTs=6
#ReserveVT=6
#KillUserProcesses=no
#KillOnlyUsers=
#KillExcludeUsers=root
#InhibitDelayMaxSec=5
HandlePowerKey=poweroff
#HandleSuspendKey=suspend
#HandleHibernateKey=hibernate
#HandleLidSwitch=suspend
#HandleLidSwitchDocked=ignore
#PowerKeyIgnoreInhibited=no
#SuspendKeyIgnoreInhibited=no
#HibernateKeyIgnoreInhibited=no
#LidSwitchIgnoreInhibited=yes
#HoldoffTimeoutSec=30s
#IdleAction=ignore
#IdleActionSec=30min
#RuntimeDirectorySize=10%
#RemoveIPC=yes
#UserTasksMax=12288
  • logind.conf with Ubuntu 18.04
#  This file is part of systemd.
#
#  systemd is free software; you can redistribute it and/or modify it
#  under the terms of the GNU Lesser General Public License as published by
#  the Free Software Foundation; either version 2.1 of the License, or
#  (at your option) any later version.
#
# Entries in this file show the compile time defaults.
# You can change settings by editing this file.
# Defaults can be restored by simply deleting this file.
#
# See logind.conf(5) for details.
 
[Login]
#NAutoVTs=6
#ReserveVT=6
#KillUserProcesses=no
#KillOnlyUsers=
#KillExcludeUsers=root
#InhibitDelayMaxSec=5
HandlePowerKey=poweroff
#HandleSuspendKey=suspend
#HandleHibernateKey=hibernate
#HandleLidSwitch=suspend
#HandleLidSwitchDocked=ignore
#PowerKeyIgnoreInhibited=no
#SuspendKeyIgnoreInhibited=no
#HibernateKeyIgnoreInhibited=no
#LidSwitchIgnoreInhibited=yes
#HoldoffTimeoutSec=30s
#IdleAction=ignore
#IdleActionSec=30min
#RuntimeDirectorySize=10%
#RemoveIPC=yes
#InhibitorsMax=8192
#SessionsMax=8192
#UserTasksMax=33%

(3) Wake up Action

To wake-up after power off, long-pressing over 2 seconds is needed.

  • Android : You have to modify the dts file in Android Marshmallow (v2.4) and higher version to using this functionality.

(1) Modifying and Flashing Kernel dts

In case of Android, you have to modify the dts file to activate gpio key functionality.

C2 Android DTS

<kernel_path>/arch/arm64/boot/dts/meson64_odroidc2.dts

...
gpio_keypad{
    .
    status = "okay";
    .
};
...

After compiling the dts file, you can flash the dtb file to the board.

In kernel:

$ make odroidc2_defconfig
$ make dtbs
$ fastboot flash dtb arch/arm64/boot/dts/meson64_odroidc2.dtb
$ fastboot reboot

You have to flash dtbs file when board it is in u-boot fastboot mode.

In board:

$ reboot fastboot

(2) Setting boot.ini

In Android boot.ini, you can find a “gpiopower” example. Uncomment “gpiopower” part and modify the number with the number you want to use.

## gpio power key : J2 (2x20) Pin#29 , GPIOX.BIT0
setenv gpiopower "228"

(3) Setting Power Button Action for Power Off

In Android, you don't need to set any menu for power button actions but it's already defined as following.

One short power key event is used for sleep, and with long key event, you can handle options of power off/reboot.
With Android Marshmallow v2.4 or higher version, it's available to enter power off using long-pressing (5 sec).

(4) Wake up Action

And to wake-up after power off, long-pressing over 2 seconds is needed.

It's needed to modify and re-build dts file to use some ports that acts as Active High.
Please add gpio_high_z in gpio_keypad part.

<kernel_path>/arch/arm64/boot/dts/meson64_odroidc2.dts

gpio_keypad{
    .
    gpio_high_z = <1>;
    .
};