]>
Commit | Line | Data |
---|---|---|
b422e333 | 1 | #include <linux/module.h> |
d1ff9643 MG |
2 | #include <linux/device.h> |
3 | #include <linux/platform_device.h> | |
4 | #include <linux/gpio_event.h> | |
5 | ||
ab5ed215 MG |
6 | #define PREFIX "debounce: " |
7 | ||
a4838b14 | 8 | static int debounce_delay = 15; |
ab5ed215 | 9 | |
a4838b14 | 10 | static unsigned old_flags = 0; |
bb65757a MG |
11 | ktime_t old_debounce_delay; |
12 | ktime_t old_settle_time; | |
13 | ktime_t old_poll_time; | |
1e65c113 MG |
14 | static struct gpio_event_matrix_info *gpio_evmi = NULL; |
15 | ||
b2b792eb | 16 | module_param(debounce_delay, int, S_IRUSR | S_IRGRP | S_IROTH); |
a4838b14 | 17 | MODULE_PARM_DESC(debounce_delay, "debouncing delay (ms), default: 15"); |
ab5ed215 MG |
18 | |
19 | static int find_ms2_dev(struct device *dev, void *data) | |
d1ff9643 MG |
20 | { |
21 | if (!strncmp((char*)data, dev_name(dev), strlen((char*)data))) { | |
ab5ed215 | 22 | printk(KERN_INFO PREFIX "Found it\n"); |
d1ff9643 MG |
23 | return 1; |
24 | } | |
25 | return 0; | |
26 | } | |
b422e333 MG |
27 | |
28 | static int __init debounce_init(void) | |
29 | { | |
d1ff9643 MG |
30 | struct device *event_dev = NULL; |
31 | struct gpio_event_platform_data *gpio_epd; | |
32 | struct gpio_event_info *gpio_ei; | |
d1ff9643 | 33 | |
ab5ed215 | 34 | printk(KERN_INFO PREFIX "Searching for " GPIO_EVENT_DEV_NAME "...\n"); |
d1ff9643 MG |
35 | |
36 | ||
37 | event_dev = device_find_child(&platform_bus, GPIO_EVENT_DEV_NAME, find_ms2_dev); | |
38 | if (event_dev == NULL) | |
39 | return -ENODEV; | |
40 | ||
41 | gpio_epd = (struct gpio_event_platform_data*)event_dev->platform_data; | |
ab5ed215 | 42 | printk(KERN_INFO PREFIX "And there is a %s connected...\n", gpio_epd->name); |
d1ff9643 MG |
43 | if (strcmp(gpio_epd->name, "sholes-keypad")) |
44 | return -ENODEV; | |
45 | ||
46 | gpio_ei = (struct gpio_event_info*)gpio_epd->info[0]; | |
47 | gpio_evmi = container_of(gpio_ei, struct gpio_event_matrix_info, info); | |
48 | ||
ab5ed215 MG |
49 | printk(KERN_INFO PREFIX "settle_time: %u\n", gpio_evmi->settle_time.tv.nsec); |
50 | printk(KERN_INFO PREFIX "poll_time: %u\n", gpio_evmi->poll_time.tv.nsec); | |
51 | printk(KERN_INFO PREFIX "debounce_delay: %u\n", gpio_evmi->debounce_delay.tv.nsec); | |
52 | printk(KERN_INFO PREFIX "flags: 0x%x\n", gpio_evmi->flags); | |
20bf1c9e | 53 | |
bb65757a MG |
54 | old_debounce_delay = gpio_evmi->debounce_delay; |
55 | old_settle_time = gpio_evmi->settle_time; | |
56 | old_poll_time = gpio_evmi->poll_time; | |
57 | old_flags = gpio_evmi->flags; | |
1e65c113 | 58 | |
b2b792eb | 59 | if (gpio_evmi->debounce_delay.tv.nsec != debounce_delay * NSEC_PER_MSEC) { |
ab5ed215 | 60 | printk(KERN_INFO PREFIX "Changing debounce_delay\n"); |
b2b792eb | 61 | gpio_evmi->debounce_delay.tv.nsec = debounce_delay * NSEC_PER_MSEC; |
ab5ed215 | 62 | printk(KERN_INFO PREFIX "debounce_delay: %u\n", gpio_evmi->debounce_delay.tv.nsec); |
d1ff9643 MG |
63 | } |
64 | ||
bb65757a MG |
65 | #if 0 |
66 | gpio_evmi->flags &= ~GPIOKPF_REMOVE_SOME_PHANTOM_KEYS; | |
67 | #endif | |
a4838b14 MG |
68 | |
69 | if (gpio_evmi->debounce_delay.tv.nsec != 0) { | |
70 | /* GPIOKPF_DEBOUNCE should already be set by GPIOKPF_REMOVE_PHANTOM_KEYS */ | |
71 | if (!(gpio_evmi->flags & GPIOKPF_DEBOUNCE)) { | |
72 | printk(KERN_INFO PREFIX "Activating debounce\n"); | |
73 | gpio_evmi->flags |= GPIOKPF_DEBOUNCE; | |
74 | } | |
75 | } else { | |
76 | /* Deactivating GPIOKPF_DEBOUNCE */ | |
77 | printk(KERN_INFO PREFIX "Deactivating debounce\n"); | |
78 | gpio_evmi->flags &= ~GPIOKPF_DEBOUNCE; | |
79 | } | |
80 | printk(KERN_INFO PREFIX "flags: 0x%x\n", gpio_evmi->flags); | |
81 | ||
b422e333 MG |
82 | return 0; |
83 | } | |
84 | ||
85 | static void __exit debounce_exit(void) | |
86 | { | |
1e65c113 | 87 | if (gpio_evmi) { |
bb65757a | 88 | if (gpio_evmi->debounce_delay.tv.nsec != old_debounce_delay.tv.nsec) { |
1e65c113 | 89 | printk(KERN_INFO PREFIX "Restoring debounce_delay\n"); |
bb65757a | 90 | gpio_evmi->debounce_delay = old_debounce_delay; |
1e65c113 MG |
91 | printk(KERN_INFO PREFIX "debounce_delay: %u\n", gpio_evmi->debounce_delay.tv.nsec); |
92 | } | |
a4838b14 MG |
93 | if (gpio_evmi->flags != old_flags) { |
94 | printk(KERN_INFO PREFIX "Restoring flags\n"); | |
95 | gpio_evmi->flags = old_flags; | |
96 | printk(KERN_INFO PREFIX "flags: 0x%x\n", gpio_evmi->flags); | |
97 | } | |
bb65757a MG |
98 | gpio_evmi->settle_time = old_settle_time; |
99 | gpio_evmi->poll_time = old_poll_time; | |
1e65c113 | 100 | } |
b422e333 MG |
101 | } |
102 | ||
103 | module_init(debounce_init); | |
104 | module_exit(debounce_exit); | |
105 | ||
106 | MODULE_LICENSE("GPL"); | |
107 | MODULE_AUTHOR("Michael Gernoth <michael@gernoth.net>"); |