c138574d81d4a3ce620e3483051a1d75da73a10c
[ms2-fixes] / debounce.c
1 #include <linux/module.h>
2 #include <linux/device.h>
3 #include <linux/platform_device.h>
4 #include <linux/gpio_event.h>
5
6 #define PREFIX "debounce: "
7
8 static int debounce_delay = 15;
9
10 static unsigned old_flags = 0;
11 ktime_t old_debounce_delay;
12 ktime_t old_settle_time;
13 ktime_t old_poll_time;
14 static struct gpio_event_matrix_info *gpio_evmi = NULL;
15
16 module_param(debounce_delay, int, S_IRUSR | S_IRGRP | S_IROTH);
17 MODULE_PARM_DESC(debounce_delay, "debouncing delay (ms), default: 15");
18
19 static int find_ms2_dev(struct device *dev, void *data)
20 {
21 if (!strncmp((char*)data, dev_name(dev), strlen((char*)data))) {
22 printk(KERN_INFO PREFIX "Found it\n");
23 return 1;
24 }
25 return 0;
26 }
27
28 static int __init debounce_init(void)
29 {
30 struct device *event_dev = NULL;
31 struct gpio_event_platform_data *gpio_epd;
32 struct gpio_event_info *gpio_ei;
33
34 printk(KERN_INFO PREFIX "Searching for " GPIO_EVENT_DEV_NAME "...\n");
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;
42 printk(KERN_INFO PREFIX "And there is a %s connected...\n", gpio_epd->name);
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
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);
53
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;
58
59 if (gpio_evmi->debounce_delay.tv.nsec != debounce_delay * NSEC_PER_MSEC) {
60 printk(KERN_INFO PREFIX "Changing debounce_delay\n");
61 gpio_evmi->debounce_delay.tv.nsec = debounce_delay * NSEC_PER_MSEC;
62 printk(KERN_INFO PREFIX "debounce_delay: %u\n", gpio_evmi->debounce_delay.tv.nsec);
63 }
64
65 #if 0
66 gpio_evmi->flags &= ~GPIOKPF_REMOVE_SOME_PHANTOM_KEYS;
67 #endif
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
82 return 0;
83 }
84
85 static void __exit debounce_exit(void)
86 {
87 if (gpio_evmi) {
88 if (gpio_evmi->debounce_delay.tv.nsec != old_debounce_delay.tv.nsec) {
89 printk(KERN_INFO PREFIX "Restoring debounce_delay\n");
90 gpio_evmi->debounce_delay = old_debounce_delay;
91 printk(KERN_INFO PREFIX "debounce_delay: %u\n", gpio_evmi->debounce_delay.tv.nsec);
92 }
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 }
98 gpio_evmi->settle_time = old_settle_time;
99 gpio_evmi->poll_time = old_poll_time;
100 }
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>");
Impressum, Datenschutz