Possible Fix for Power Button s2idle Resume on Dell 5175

226 views
Skip to first unread message

tristin....@gmail.com

unread,
Apr 14, 2018, 9:55:46 AM4/14/18
to Android-x86
Summary:

My Dell Latitude 5175 doesn't resume after transitioning to s2idle. I think the culprit is the intel-hid driver that makes the power button function. Attached is a patch that addresses this for my device.

I'm trying to confirm:

- if this patch works on other devices that use the intel-hid driver to make the power button function
- if this is the right solution; sparse_keymap_report_event() can trigger a key-down and key-up signal on a single event. Is this a case where it would be used?

However, I think this patch will only work on 4.15+ kernels

Background:

I am running Android x86 7.1 with a 4.16 kernel on a Dell Latitude 5175. This device originally came with Windows 10 and supported Microsoft's Connected Standby standard, also known as s2idle and Low Power S0. This device doesn't support suspending the to S3 state, as is traditional for laptops.

Since the 4.15 kernel, patches have been submitted that enabled this machine to successfully transition to and from the s2idle (Low Power S0) state. I can confirm that things work in a traditional Linux distribution (Fedora 27) by short-pressing the power button to suspend and resume. However, in Android x86, even with newer kernels, resuming by pressing the power button did not work.

What I I could do was confirm that I could suspend/resume in software by running the command:

input keyevent KEYCODE_POWER

I found that the power button on this device is driven by the intel-hid.ko module. After adding a number of dev_dbg() statements to the module, ssh'ing to the device, and viewing the output of both /proc/kmsg and getevent, I think I found why power button s2idle resume wasn't working, and a fix.

In the intel-hid driver, located in kernel/drivers/platform/x86/intel-hid.ko, in the function

static void notify_handler(acpi_handle handle, u32 event, void *context)

 there's this block:

        /*
         * Needed for suspend to work on some platforms that don't expose
         * the 5-button array, but still send notifies with power button
         * event code to this device object on power button actions.
         *
         * Report the power button press; catch and ignore the button release.
         */
        if (!priv->array) {
                if (event == 0xce) {
                        input_report_key(priv->input_dev, KEY_POWER, 1);
                        input_sync(priv->input_dev);
                        return;
                }

                if (event == 0xcf)
                        return;
        }


0xce is the event that is sent by the device when the power button is pressed down. I think this is dictated by the ACPI firmware and can be confirmed in the DSDT. 0xcf is sent when the power button is released. The input_report_key/input_sync functions propogate the signal to user space by transforming the event into a keycode that userspace understands. The code only performs that propogation when pressing the power button down. This seems to be enough for Fedora 27/GNOME; I think s2idle is started on the "down" signal in that case.

However, in Androidx86, it seems like Android expects the "down" signal to be followed by an "up" signal. Subsequent short presses of the power button, which can only send the "down" signal, are unrecognized by getevent.

For instance, suppose the Intel HID device is mapped to /dev/input/event19. Then when I press the power button while running getevent, I'd see 1 occurrence of a line like:

/dev/input/event19: EV_KEY       KEY_POWER            DOWN               
/dev/input/event19: EV_SYN       SYN_REPORT           00000000

which would correspond to the first time I pressed the button. I also see a power menu displayed on short press. However, on subsequent presses, I would never see the menu or this event again

To fix, I changed the block to:

        /*
         * Needed for suspend to work on some platforms that don't expose
         * the 5-button array, but still send notifies with power button
         * event code to this device object on power button actions.
         *
         * Report the power button press; catch and ignore the button release.
         */
        if (!priv->array) {
                if (event == 0xce) {
                        input_report_key(priv->input_dev, KEY_POWER, 1);
                        input_sync(priv->input_dev);
                        return;
                }

                if (event == 0xcf)
                        input_report_key(priv->input_dev, KEY_POWER, 0);
                        input_sync(priv->input_dev);
                        return;
        }

        /* 0xC0 is for HID events, other values are for 5 button array */
        if (event != 0xc0) {
                if (!priv->array ||
                    !sparse_keymap_report_event(priv->array, event, 1, true))
                        dev_dbg(&device->dev, "unknown event 0x%x\n", event);
                return;
        }

When I rebooted, Androidx86 would respond to repeated short presses of the power button.
0001-intel-hid-power-button-up-fix.patch

youling 257

unread,
Apr 14, 2018, 1:09:12 PM4/14/18
to Android-x86
only has s2idle(deep) and s2idle(s0i3)

the s2idle(deep) is suspend to RAM,is s3

s3 vs s0i3

tristin....@gmail.com

unread,
Apr 14, 2018, 2:21:46 PM4/14/18
to Android-x86
Yes, I don't even try to use suspend to RAM/s3, as it doesn't work on this device. Only s2idle(s0i3) does. I've only tested this fix for allowing the power button to resume from s2idle(s0i3).

Chih-Wei Huang

unread,
Dec 13, 2018, 7:17:54 PM12/13/18
to Android-x86
Sorry for reply late.
I queued your patch but forgot it until now.

Thank you for the patch. It looks reasonable.
I'll ask the author of the specified block in intel-hid.c
for comment.

<tristin....@gmail.com> 於 2018年4月14日 週六 下午9:55寫道:
> --
> You received this message because you are subscribed to the Google Groups "Android-x86" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to android-x86...@googlegroups.com.
> To post to this group, send email to andro...@googlegroups.com.
> Visit this group at https://groups.google.com/group/android-x86.
> For more options, visit https://groups.google.com/d/optout.



--
Chih-Wei
Android-x86 project
http://www.android-x86.org

youling 257

unread,
Dec 13, 2018, 9:14:33 PM12/13/18
to Android-x86
This is not a special problem for special device, this is generic Androidx86 userspace.

android_x86:/ $ su
android_x86:/ # getevent -l
add device 1: /dev/input/event3
  name: "USB USB Keyboard Consumer Control"
add device 2: /dev/input/event2
  name: "USB USB Keyboard System Control"
add device 3: /dev/input/event1
  name: "USB USB Keyboard Mouse"
could not get driver version for /dev/input/mouse0, Not a typewriter
add device 4: /dev/input/event0
  name: "USB USB Keyboard"
could not get driver version for /dev/input/mice, Not a typewriter
add device 5: /dev/input/event9
  name: "Video Bus"
add device 6: /dev/input/event8
  name: "axp20x-pek"
add device 7: /dev/input/event7
  name: "gpio-keys"
add device 8: /dev/input/event6
  name: "gpio-keys"
add device 9: /dev/input/event5
  name: "silead_ts"
could not get driver version for /dev/input/mouse1, Not a typewriter
add device 10: /dev/input/event4
  name: "bytcr-rt5640 Headset"
/dev/input/event8: EV_KEY KEY_POWER DOWN
/dev/input/event8: EV_SYN SYN_REPORT 00000000
/dev/input/event8: EV_KEY KEY_POWER UP
/dev/input/event8: EV_SYN SYN_REPORT 00000000
/dev/input/event8: EV_KEY KEY_POWER DOWN
/dev/input/event8: EV_SYN SYN_REPORT 00000000
/dev/input/event8: EV_KEY KEY_POWER UP
/dev/input/event8: EV_SYN SYN_REPORT 00000000
/dev/input/event0: EV_MSC MSC_SCAN 000700e0
/dev/input/event0: EV_KEY KEY_LEFTCTRL DOWN
/dev/input/event0: EV_SYN SYN_REPORT 00000000
/dev/input/event0: EV_MSC MSC_SCAN 00070006
/dev/input/event0: EV_KEY KEY_C DOWN
/dev/input/event0: EV_SYN SYN_REPORT 00000000
^C
130|android_x86:/ #

youling 257

unread,
Dec 13, 2018, 9:51:19 PM12/13/18
to Android-x86
never see again? i don't have this problem.

在 2018年4月14日星期六 UTC+8下午9:55:46,tristin....@gmail.com写道:
 
which would correspond to the first time I pressed the button. I also see a power menu displayed on short press. However, on subsequent presses, I would never see the menu or this event again


press power button once to suspend(make sure suspended, 7.1 can sleep.earlysuspend=1, 8.1 removed earlysuspend)
generic problem is need press twice to wakeup, press once resume from suspend, keep black screen but has backlight, press twice to wakeup screen.

press power button once to suspend, response these event:
/dev/input/event8: EV_KEY KEY_POWER DOWN
/dev/input/event8: EV_SYN SYN_REPORT 00000000
/dev/input/event8: EV_KEY KEY_POWER UP

press power button once to resume, no android event, of course must resume then can response Android event, have to press power button twice, happen Android event:
/dev/input/event8: EV_SYN SYN_REPORT 00000000
/dev/input/event8: EV_KEY KEY_POWER DOWN
/dev/input/event8: EV_SYN SYN_REPORT 00000000
/dev/input/event8: EV_KEY KEY_POWER UP

echo mem > /sys/power/state to suspend, press power button once to resume and wakeup screen, no android event.

youling 257

unread,
Dec 13, 2018, 10:08:23 PM12/13/18
to Android-x86
still has this problem never fixed: suspend long time, resume keep blackscreen has backlight, not response Android event wakeup screen.
Linux kernel no any suspend/resume wakeup problem, Android terminal echo mem to suspend long time can resume wakeup screen.
what is Android userspace wakeup screen problem? power.x86.so ? need remove cpu offline?
when suspend,intel cpu keep c7、c8、c9、c10 c-state and s0i3 state(4.20 rc and 4.19-footrail has full s0i3 support for most BYT/CHT device).

Reply all
Reply to author
Forward
0 new messages