Waking from deep sleep not working from GPIO

I decompiled my dtb into a dts with dtc and then added the following lines at the end of the gpio-keys section, however after reflashing the Jetson, the code changes didnt work to wake the jetson with the GPIO9_MOTION_INT pin, and now my power button wont even wake the Jetson (only keyboard keystrokes will wake it). Can anyone provide some input by chance? I got the address of the GPIO9_MOTION_INT pin for the gpios = <0x1c 0x12a 0x1> line from the Jetson hacks page https://www.jetsonhacks.com/nvidia-jetson-tx2-j21-header-pinout/ for the TX2 J21 where the GPIO9_MOTION_INT address is gpio298 = 0x12a.

gpio-keys {
		compatible = "gpio-keys";
		gpio-keys,name = "gpio-keys";

		power {
			label = "Power";
			gpios = <0x1c 0x38 0x1>;
			linux,code = <0x74>;
			gpio-key,wakeup;
		};

		volume_up {
			label = "Volume Up";
			gpios = <0x1c 0x39 0x1>;
			linux,code = <0x73>;
		};

		volume_down {
			label = "Volume Down";
			gpios = <0x1c 0x3a 0x1>;
			linux,code = <0x72>;
		};

		
[b]		motion_wake {
			label = "Motion Wake";
			gpios = <0x1c 0x12a 0x1>;
			linux,code = <0x8f>;
			gpio-key,wakeup;[/b]
		};
	};

hello electric27,

it’s due to hardware design, GPIO9/MOTION_INT is not able to configure as normal GPIO.
you may also refer to Topic 1048540 for details.
thanks

I decided to try the “GPIO_GEN5 - Modem Wake AP GPIO” pin on the J21 header, which connects to GPIO16_MDM_WAKE_AP pin on the Jetson. I followed the steps from this post: TX2 GPIO Wake issues - Jetson TX2 - NVIDIA Developer Forums

I updated my .dts file to include the following bolded sections:

common {
			linux,phandle = <0x15>;
			phandle = <0x15>;

			gpio_edp2_pp5 {
				nvidia,pins = "gpio_edp2_pp5";
				nvidia,pull = <0x2>;
				nvidia,tristate = <0x1>;
				nvidia,enable-input = <0x1>;
				status = "okay";
			};

			gpio_edp3_pp6 {
				nvidia,pins = "gpio_edp3_pp6";
				nvidia,pull = <0x0>;
				nvidia,tristate = <0x0>;
				nvidia,enable-input = <0x0>;
				status = "okay";
			};

[b]			gpio_mdm2_py1 {
				nvidia,pins = "gpio_mdm2_py1";
				nvidia,function = "rsvd0"
				nvidia,pull = <0x1>;
				nvidia,tristate = <0x1>;
				nvidia,enable-input = <0x1>;
				nvidia,lpdr = <0x0>
				status = "okay";
			};[/b]
		};

and

gpio-keys {
		compatible = "gpio-keys";
		gpio-keys,name = "gpio-keys";

		power {
			label = "Power";
			gpios = <0x1c 0x38 0x1>;
			linux,code = <0x74>;
			gpio-key,wakeup;
		};

		volume_up {
			label = "Volume Up";
			gpios = <0x1c 0x39 0x1>;
			linux,code = <0x73>;
		};

		volume_down {
			label = "Volume Down";
			gpios = <0x1c 0x3a 0x1>;
			linux,code = <0x72>;
		};

[b]		modem_wake{
			label = "Modem Wake";
			gpios = <&tegra_main_gpio TEGRA_MAIN_GPIO(Y, 1) GPIO_ACTIVE_HIGH>;
			linux,code = <0x8f>;
			gpio-key,wakeup;
		};[/b]
			
	};

however, when I try to use dtc to compile to a dtb, I get an error that it cannot parse the following line:

gpios = <&tegra_main_gpio TEGRA_MAIN_GPIO(Y, 1) GPIO_ACTIVE_HIGH>;

I tried updating this line just use the raw hex (where TEGRA_MAIN_GPIO(Y, 1)=161=0xa1 and GPIO_ACTIVE_HIGH is 0x0), however I am not sure what the hex value should be for “&tegra_main_gpio”.

It appears that the “Power” “Volume Up” and “Volume Down” gpios just above the code I added use “0x1c” to specify the AON ports, and then use 0x38, 0x39, and 0x40 to specify pins PFF1, PFF2, and PFF3.

Could someone share what the hex address is to take the place of “&tegra_main_gpio”?

Hi JerryChang, do you happen to know the answer to my previous post by chance?

hello electric27,

sorry for late reply.
please don’t use dtc to compile to a dtb for device usage.
please refer to TX2 Configuring Pinmux GPIO and PAD for your GPIO customization steps.
thanks

electric27, did you figure this out? “RTFM” is not very helpful advice. It would help the community by giving a tutorial on this- numerous threads have been created on this topic and not a single one contains a solution.

Hi Kpbower,

No I have not figured it out yet.

I was able to confirm that GPIO9_MOTION_INT (GPIO AA.02/gpio298) is able to wake up the Jetson TX2 with the signal driven low.

Here is the patch file that I used to modify and rebuild by dtbs:

diff -ur a/hardware/nvidia/platform/t18x/common/kernel-dts/t18x-common-platforms/tegra186-cvb-prod-p2597-b00-p3310-1000-a00-00.dtsi b/hardware/nvidia/platform/t18x/common/kernel-dts/t18x-common-platforms/tegra186-cvb-prod-p2597-b00-p3310-1000-a00-00.dtsi
--- a/hardware/nvidia/platform/t18x/common/kernel-dts/t18x-common-platforms/tegra186-cvb-prod-p2597-b00-p3310-1000-a00-00.dtsi	2019-08-12 23:11:25.000000000 -0500
+++ b/hardware/nvidia/platform/t18x/common/kernel-dts/t18x-common-platforms/tegra186-cvb-prod-p2597-b00-p3310-1000-a00-00.dtsi	2019-09-30 11:00:15.470004928 -0500
@@ -329,5 +329,12 @@
 			gpios = <&tegra_aon_gpio TEGRA_AON_GPIO(FF, 2) GPIO_ACTIVE_LOW>;
 			linux,code = <KEY_VOLUMEDOWN>;
 		};
+
+		motion_wake {
+			label = "Motion Wake";
+			gpios = <&tegra_aon_gpio TEGRA_AON_GPIO(AA, 2) GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WAKEUP>;
+			gpio-key,wakeup;
+		};
 	};
 };

With this change I was able to see the KEY_WAKEUP events on /dev/input/event2 whenever J21 pin 31 (MOTION_INT_AP_L_LVL) was forced low to ground. Also, when I suspended my system, forcing the signal low would wake up the system from suspend properly.

A couple things you can check after you modify your .dtsi file. First, boot the system and see that your /sys/firmware/devicetree/base/gpio-keys/motion_wake (/proc/device-tree/gpio-keys/motion_wake) exists and that you properly flashed, loaded, and booted your kernel with the new gpio-keys addition in the kernel DTB. Second, read the GPIO AA.02 registers to make sure they are properly configured.

root@nvtegra:~# devmem2 0xC2F1C40
Read at address  0x0C2F1C40 (0x7f9c479c40): 0x0000006D
root@nvtegra:~# devmem2 0xC2F1C4C
Read at address  0x0C2F1C4C (0x7f9f3c4c4c): 0x00000001

Next, read the GPIO AA.02 INPUT value at 0xC2F1C48 and make sure it reads 0x1 when J21 pin 31 is floating (3.3V) and it reads 0x0 when J21 pin 31 is grounded (0.0V). Finally, if everything checks out “cat /dev/input/event2” and see if you get events for changes on the J21 pin 31.

gpio298-wakup.patch.txt (894 Bytes)

In order to make A10/GPIO_MDM2 (GPIO Y.01) work properly I patched the .dtsi as such:

diff -ur a/hardware/nvidia/platform/t18x/common/kernel-dts/t18x-common-platforms/tegra186-cvb-prod-p2597-b00-p3310-1000-a00-00.dtsi b/hardware/nvidia/platform/t18x/common/kernel-dts/t18x-common-platforms/tegra186-cvb-prod-p2597-b00-p3310-1000-a00-00.dtsi
--- a/hardware/nvidia/platform/t18x/common/kernel-dts/t18x-common-platforms/tegra186-cvb-prod-p2597-b00-p3310-1000-a00-00.dtsi	2019-08-12 23:11:25.000000000 -0500
+++ b/hardware/nvidia/platform/t18x/common/kernel-dts/t18x-common-platforms/tegra186-cvb-prod-p2597-b00-p3310-1000-a00-00.dtsi	2019-09-30 14:17:23.939978693 -0500
@@ -329,5 +329,12 @@
 			gpios = <&tegra_aon_gpio TEGRA_AON_GPIO(FF, 2) GPIO_ACTIVE_LOW>;
 			linux,code = <KEY_VOLUMEDOWN>;
 		};
+
+		modem_wake {
+			label = "Modem Wake";
+			gpios = <&tegra_main_gpio TEGRA_MAIN_GPIO(Y, 1) GPIO_ACTIVE_HIGH>;
+			linux,code = <KEY_WAKEUP>;
+			gpio-key,wakeup;
+		};
 	};
 };

Once I patched the dtsi file, rebuilt the dtbs, flashed kernel-dtb, and booted the system J21 pin 18 was able to wake up the system from suspend by either being set HIGH (3.3V) or cleared LOW (0.0V). It does not appear that you need to change the pinmux setting @ 0x243D068 from the default value in order to make it work.

If you have your DTB properly configured with the new gpio-key for the modem_wake then if you try to export gpio481 (echo 481 > /sys/class/gpio/export) it will give you an error “write error: Device or resource busy” since the gpio-keys driver has already claimed the GPIO Y.01 (#481) for itself. If you don’t get an error on the export then you probably have your handle/addresses wrong and you should compile the DTB from the original sources instead of trying to reverse compile the dtb, make changes, and recompile them back to the dtb.
gpio481-wakup.patch.txt (894 Bytes)

Cool! Thanks for sharing!