2 * wakeup_button.c - Power Button which is pushed on resume from standby.
4 * Copyright (c) 2011 Stefan Seidel
6 * This file is released under the GPLv2 or later.
8 #include <linux/module.h>
9 #include <linux/init.h>
10 #include <linux/earlysuspend.h>
11 #include <linux/input.h>
13 MODULE_LICENSE("GPL");
14 MODULE_AUTHOR("Stefan Seidel <android@stefanseidel.info>");
15 MODULE_DESCRIPTION("Sets up a virtual input device and sends a power key event during early resume. Needed for some to make Android on x86 wake up properly.");
17 static struct input_dev *input;
19 static void wakeup_button_early_suspend(struct early_suspend *h)
24 static void wakeup_button_early_resume(struct early_suspend *h)
26 printk("Early resume, push virtual power button!\n");
27 input_report_key(input, KEY_POWER, 1);
29 input_report_key(input, KEY_POWER, 0);
33 static struct early_suspend wakeup_button_early_suspend_handlers = {
34 .level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN - 1, // very late resume
35 .suspend = wakeup_button_early_suspend,
36 .resume = wakeup_button_early_resume
39 static int __init wakeup_button_init(void)
42 printk("Registering Android Wakeup Button.\n");
43 input = input_allocate_device();
44 input->name = "Wakeup Button";
45 input->id.bustype = BUS_USB; // use BUS_USB here so that Android registers this as an external key
46 input->evbit[0] = BIT_MASK(EV_KEY);
47 set_bit(KEY_POWER, input->keybit);
48 error = input_register_device(input);
50 input_free_device(input);
52 register_early_suspend(&wakeup_button_early_suspend_handlers);
57 static void __exit wakeup_button_exit(void)
59 printk("Unregistering Android Wakeup Button.\n");
60 unregister_early_suspend(&wakeup_button_early_suspend_handlers);
61 input_unregister_device(input);
65 module_init(wakeup_button_init);
66 module_exit(wakeup_button_exit);