For Android underlying development, do the Linux input subsystem need to judge the system sleep status and report the key value?
For Android underlying development, do the Linux input subsystem need to judge the system sleep status and report the key value?
Digress: the first half of the documents recorded over there are basically useless or even incorrect questions after a problem is studied. In the end, the front side is just hypothetical speculation.
When debugging the input driver of the infrared remote control, a semi-finished driver is used to match the device on the top, but some questions about the input subsystem are also encountered.
The buttons are generally in the "press and lift" status, which is expressed by 0 and 1 respectively. Generally, you can complete the collection by pressing and lifting the key values as follows.
Input_event (ddata-> input, EV_KEY, KEY_POWER, 1 );
Input_sync (ddata-> input );
However, a strange problem recently occurs when the KEY_WAKEUP in the kernel uses the above method to wake up the key value for reporting, the user space can only detect the status 0, and the second key will only have status 1. In this way, the Android system does not wake up normally. You need to wake up the system twice.
The current solution is to change the above-mentioned reported KEY_WAKEUP to the KEY_POWER key value. But curiosity tells me how they are.
Experience reports the following status continuously to 1/0 in the user space.
Input_event (ddata-> input, EV_KEY, KEY_WAKEUP, 1 );
Input_sync (ddata-> input );
Input_event (ddata-> input, EV_KEY, KEY_WAKEUP, 0 );
Input_sync (ddata-> input );
Intuition tells me that it can be caused by my lack of understanding of these two APIs. comparison is a result of everything.
Try another key value except KEY_WAKEUP. The result is the same as that of KEY_WAKEUPG. It can be inferred that a non-POWER button cannot be used. This can be related to the code location:
} Else if (get_suspend_state () & (ddata-> keycode = KEY_POWER )){
Input_event (ddata-> input, EV_KEY, KEY_POWER, 1 );
Input_sync (ddata-> input );
}
Further test how all the buttons work in non-PM_SUSPEND_ON power mode. The test result shows that keys cannot be synchronized for all non-POWER buttons. However, the physical buttons connected by GPIO do not have this problem. Therefore, the input subsystem has been ruled out. The problem is solved by the Remote control driver.
The problem is found out. It is indeed in the Remote control driver. The report key value determines the PM status. If
Static void remotectl_timer (unsigned long _ data)
If (ddata-> press! = Ddata-> pre_press ){
Ddata-> pre_press = ddata-> press = 0;
If (get_suspend_state () = 0 ){
// Input_event (ddata-> input, EV_KEY, ddata-> keycode, 1 );
// Input_sync (ddata-> input );
Input_event (ddata-> input, EV_KEY, ddata-> keycode, 0 );
Input_sync (ddata-> input );
} Else if (get_suspend_state () & (ddata-> keycode = KEY_POWER )){
// Input_event (ddata-> input, EV_KEY, KEY_WAKEUP, 1 );
// Input_sync (ddata-> input );
Input_event (ddata-> input, EV_KEY, KEY_WAKEUP, 0 );
Input_sync (ddata-> input );
}
}
After filtering conditions are removed, the effect can be the same as that of the physical buttons connected to GPIO, that is, the key value is uploaded no matter what status the system processes, sleep or wakeup status. At the same time, this also brings me a doubt,Do you need to determine the suspend status in the key-driven drive? Based on the experience in Android, all the statuses must be uploaded. The upper-layer system determines whether to respond or not; however, if the input subsystem uploads a key value during system sleep, the corresponding application layer can directly respond to the key value. Which method is used for implementation is a paradox! Combined with the Android macro, the following functions are implemented:
Diff -- git a/drivers/input/remotectl/rkxx_remotectl.c B/drivers/input/remotectl/rkxx_remotectl.c
Index db91516.201c5dd 100644
--- A/drivers/input/remotectl/rkxx_remotectl.c
++ B/drivers/input/remotectl/rkxx_remotectl.c
@-306,6 + 306,10 @ static void remotectl_do_something (unsigned long data)
If (ddata-> scanData & 0x0ff) = ((~ Ddata-> scanData> 8) & 0x0ff )){
If (remotectl_keycode_lookup (ddata )){
Ddata-> press = 1;
+ # Ifdef CONFIG_ANDROID // Android OS needs input event whatever suspend state
+ Input_event (ddata-> input, EV_KEY, ddata-> keycode, 1 );
+ Input_sync (ddata-> input );
+ # Else
If (ddata-> keycode = KEY_POWER | get_suspend_state () = PM_SUSPEND_ON ){
Input_event (ddata-> input, EV_KEY, ddata-> keycode, 1 );
Input_sync (ddata-> input );
@-314,6 + 318,7 @ static void remotectl_do_something (unsigned long data)
}
// Input_event (ddata-> input, EV_KEY, ddata-> keycode, ddata-> press );
// Input_sync (ddata-> input );
+ # Endif // CONFIG_ANDROID
Ddata-> state = RMC_SEQUENCE;
} Else {
Ddata-> state = RMC_PRELOAD;
@-437,6 + 442,10 @ static void remotectl_timer (unsigned long _ data)
If (ddata-> press! = Ddata-> pre_press ){
Ddata-> pre_press = ddata-> press = 0;
+ # Ifdef CONFIG_ANDROID // Android OS needs input event whatever suspend state
+ Input_event (ddata-> input, EV_KEY, ddata-> keycode, 0 );
+ Input_sync (ddata-> input );
+ # Else
If (get_suspend_state () = 0 ){
// Input_event (ddata-> input, EV_KEY, ddata-> keycode, 1 );
// Input_sync (ddata-> input );
@-448,6 + 457,7 @ static void remotectl_timer (unsigned long _ data)
Input_event (ddata-> input, EV_KEY, KEY_WAKEUP, 0 );
Input_sync (ddata-> input );
}
+ # Endif // CONFIG_ANDROID
}
# Ifdef CONFIG_PM
Remotectl_wakeup (_ data );
For Android systems,Then, no matter what kind of sleep state the kernel processes, the key value is reported in real time. This ensures that the audio size can be controlled during sleep playback. This is exactly how Android phones are implemented..
Another point: the value 0 in the key is not input_sync (ddata-> input); if it is sent, it only emits the current value. It is just a "synchronization", meaning that the data is ready and can be sent. I still don't know much about the driver, and some of my imagination misleads myself. In the Kernel input driver, the POWER key and the WAKEUP key are not differentiated. The problem must be in the driver code.