1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
/*
* Wakeup assist driver
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
#include <linux/err.h>
#include <linux/input.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <mach/regs-pmu.h>
#define DEV_NAME "wakeup_assist"
static int wakeup_assist_keycode[] = { KEY_POWER };
static int __devinit wakeup_assist_probe(struct platform_device *pdev)
{
int error;
struct input_dev *input_dev;
input_dev = input_allocate_device();
if (!input_dev)
return -ENOMEM;
input_dev->name = DEV_NAME;
input_dev->id.bustype = BUS_HOST;
input_dev->dev.parent = &pdev->dev;
input_dev->evbit[0] = BIT_MASK(EV_KEY);
input_set_capability(input_dev, EV_MSC, MSC_SCAN);
input_dev->keycode = wakeup_assist_keycode;
input_dev->keycodesize = sizeof(wakeup_assist_keycode[0]);
input_dev->keycodemax = ARRAY_SIZE(wakeup_assist_keycode);
__set_bit(wakeup_assist_keycode[0], input_dev->keybit);
__clear_bit(KEY_RESERVED, input_dev->keybit);
error = input_register_device(input_dev);
if (error) {
input_free_device(input_dev);
return error;
}
platform_set_drvdata(pdev, input_dev);
return 0;
}
static int __devexit wakeup_assist_remove(struct platform_device *pdev)
{
struct input_dev *input_dev = platform_get_drvdata(pdev);
platform_set_drvdata(pdev, NULL);
input_unregister_device(input_dev);
input_free_device(input_dev);
return 0;
}
static int wakeup_assist_resume(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct input_dev *input_dev = platform_get_drvdata(pdev);
if (readl(S5P_WAKEUP_STAT) & 0x1) {
input_report_key(input_dev, wakeup_assist_keycode[0], 0x2);
input_sync(input_dev);
input_report_key(input_dev, wakeup_assist_keycode[0], 0x0);
input_sync(input_dev);
}
return 0;
}
static const struct dev_pm_ops wakeup_assist_pm_ops = {
.resume = wakeup_assist_resume,
};
static struct platform_driver wakeup_assist_driver = {
.probe = wakeup_assist_probe,
.remove = __devexit_p(wakeup_assist_remove),
.driver = {
.name = DEV_NAME,
.owner = THIS_MODULE,
.pm = &wakeup_assist_pm_ops,
},
};
static int __init wakeup_assist_init(void)
{
return platform_driver_register(&wakeup_assist_driver);
}
module_init(wakeup_assist_init);
static void __exit wakeup_assist_exit(void)
{
platform_driver_unregister(&wakeup_assist_driver);
}
module_exit(wakeup_assist_exit);
MODULE_DESCRIPTION("Wakeup assist driver");
MODULE_AUTHOR("Eunki Kim <eunki_kim@samsung.com>");
MODULE_LICENSE("GPL");
|