]> git.zerfleddert.de Git - ms2-fixes/blob - debounce.c
399e97bbdb28fdecf0b572fced0dc995487f5cb3
[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 #include <linux/interrupt.h>
6 #include <linux/irq.h>
7 #include <mach/gpio.h>
8
9 #define PREFIX "debounce: "
10
11 static unsigned old_flags = 0;
12 static ktime_t old_debounce_delay;
13 static ktime_t old_settle_time;
14 static ktime_t old_poll_time;
15 static int (*old_sw_fixup)(int index);
16 static struct gpio_event_matrix_info *gpio_evmi = NULL;
17 static int hw_debounce = 0;
18 static int hw_debounce_time = 0;
19
20 static int find_ms2_dev(struct device *dev, void *data)
21 {
22 if (!strncmp((char*)data, dev_name(dev), strlen((char*)data))) {
23 printk(KERN_INFO PREFIX "Found it\n");
24 return 1;
25 }
26 return 0;
27 }
28
29 /* hardware debounce: (time + 1) * 31us */
30 static void hw_debounce_set(int enable, int time) {
31 int i;
32
33 if (gpio_evmi == NULL)
34 return;
35
36 for (i = 0; i < gpio_evmi->ninputs; i++) {
37 int gpio = gpio_evmi->input_gpios[i];
38
39 if ((time != -1) && (time != hw_debounce_time) && hw_debounce) {
40 printk(KERN_INFO PREFIX "Setting hardware debounce time for GPIO %d to %d (%dus)\n", gpio, time, (time+1)*31);
41 omap_set_gpio_debounce_time(gpio, time);
42 }
43
44 if ((enable != -1) && (enable != hw_debounce)) {
45 printk(KERN_INFO PREFIX "%sabling hardware debounce for GPIO %d\n", (enable?"En":"Dis"), gpio);
46 omap_set_gpio_debounce(gpio, enable);
47 }
48 }
49 }
50
51 static void set_irq_types(void) {
52 int err;
53 unsigned int irq;
54 unsigned long type;
55 int i;
56
57 if (gpio_evmi == NULL)
58 return;
59
60 switch (gpio_evmi->flags & (GPIOKPF_ACTIVE_HIGH|GPIOKPF_LEVEL_TRIGGERED_IRQ)) {
61 default:
62 type = IRQ_TYPE_EDGE_FALLING;
63 break;
64 case GPIOKPF_ACTIVE_HIGH:
65 type = IRQ_TYPE_EDGE_RISING;
66 break;
67 case GPIOKPF_LEVEL_TRIGGERED_IRQ:
68 type = IRQ_TYPE_LEVEL_LOW;
69 break;
70 case GPIOKPF_LEVEL_TRIGGERED_IRQ | GPIOKPF_ACTIVE_HIGH:
71 type = IRQ_TYPE_LEVEL_HIGH;
72 break;
73 }
74
75 printk(KERN_INFO PREFIX "Settinhg IRQ type to 0x%lx\n", type);
76
77 for (i = 0; i < gpio_evmi->ninputs; i++) {
78
79 err = irq = gpio_to_irq(gpio_evmi->input_gpios[i]);
80
81 if (err < 0)
82 return;
83
84 err = set_irq_type(irq, type);
85 }
86 }
87
88 static ssize_t show_debounce_delay(struct device *dev, struct device_attribute *attr, char *buf)
89 {
90 if (!gpio_evmi)
91 return -ENODEV;
92
93 return snprintf(buf, PAGE_SIZE, "%ld\n", (gpio_evmi->debounce_delay.tv.nsec / NSEC_PER_MSEC));
94 }
95
96 static void set_debounce_delay(long delay)
97 {
98 if (gpio_evmi->debounce_delay.tv.nsec != delay * NSEC_PER_MSEC) {
99 printk(KERN_INFO PREFIX "Changing debounce_delay\n");
100 gpio_evmi->debounce_delay.tv.nsec = delay * NSEC_PER_MSEC;
101 printk(KERN_INFO PREFIX "debounce_delay: %u\n", gpio_evmi->debounce_delay.tv.nsec);
102 }
103
104 #if 0
105 if (gpio_evmi->debounce_delay.tv.nsec != 0) {
106 if (!(gpio_evmi->flags & GPIOKPF_DEBOUNCE)) {
107 printk(KERN_INFO PREFIX "Activating debounce\n");
108 gpio_evmi->flags |= GPIOKPF_DEBOUNCE;
109 }
110 } else {
111 if (gpio_evmi->flags & GPIOKPF_DEBOUNCE) {
112 printk(KERN_INFO PREFIX "Deactivating debounce\n");
113 gpio_evmi->flags &= ~GPIOKPF_DEBOUNCE;
114 }
115 }
116 #endif
117 }
118
119 static ssize_t store_debounce_delay(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
120 {
121 long int delay;
122
123 if (!gpio_evmi)
124 return -ENODEV;
125
126 sscanf(buf, "%ld", &delay);
127 set_debounce_delay(delay);
128
129 return count;
130 }
131
132 static ssize_t show_settle_time(struct device *dev, struct device_attribute *attr, char *buf)
133 {
134 if (!gpio_evmi)
135 return -ENODEV;
136
137 return snprintf(buf, PAGE_SIZE, "%ld\n", (gpio_evmi->settle_time.tv.nsec / NSEC_PER_USEC));
138 }
139
140 static ssize_t store_settle_time(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
141 {
142 long int delay;
143
144 if (!gpio_evmi)
145 return -ENODEV;
146
147 sscanf(buf, "%ld", &delay);
148 gpio_evmi->settle_time.tv.nsec = delay * NSEC_PER_USEC;
149
150 return count;
151 }
152
153 static ssize_t show_poll_time(struct device *dev, struct device_attribute *attr, char *buf)
154 {
155 if (!gpio_evmi)
156 return -ENODEV;
157
158 return snprintf(buf, PAGE_SIZE, "%ld\n", (gpio_evmi->poll_time.tv.nsec / NSEC_PER_MSEC));
159 }
160
161 static ssize_t store_poll_time(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
162 {
163 long int delay;
164
165 if (!gpio_evmi)
166 return -ENODEV;
167
168 sscanf(buf, "%ld", &delay);
169 gpio_evmi->poll_time.tv.nsec = delay * NSEC_PER_MSEC;
170
171 return count;
172 }
173
174 static ssize_t show_flags(struct device *dev, struct device_attribute *attr, char *buf)
175 {
176 if (!gpio_evmi)
177 return -ENODEV;
178
179 return snprintf(buf, PAGE_SIZE, "0x%x\n", gpio_evmi->flags);
180 }
181
182 static ssize_t store_flags(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
183 {
184 unsigned flags;
185
186 if (!gpio_evmi)
187 return -ENODEV;
188
189 sscanf(buf, "0x%x", &flags);
190
191 printk(KERN_INFO PREFIX "flags: 0x%x\n", flags);
192
193 gpio_evmi->flags = flags;
194
195 return count;
196 }
197
198 static ssize_t show_debounce_flag(struct device *dev, struct device_attribute *attr, char *buf)
199 {
200 if (!gpio_evmi)
201 return -ENODEV;
202
203 return snprintf(buf, PAGE_SIZE, "%u\n", (gpio_evmi->flags & GPIOKPF_DEBOUNCE) ? 1 : 0);
204 }
205
206 static ssize_t store_debounce_flag(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
207 {
208 unsigned flag;
209
210 if (!gpio_evmi)
211 return -ENODEV;
212
213 sscanf(buf, "%u", &flag);
214
215 if (flag) {
216 gpio_evmi->flags |= GPIOKPF_DEBOUNCE;
217 } else {
218 gpio_evmi->flags &= ~GPIOKPF_DEBOUNCE;
219 }
220
221 return count;
222 }
223
224 static ssize_t show_remove_some_phantom_keys_flag(struct device *dev, struct device_attribute *attr, char *buf)
225 {
226 if (!gpio_evmi)
227 return -ENODEV;
228
229 return snprintf(buf, PAGE_SIZE, "%u\n", (gpio_evmi->flags & GPIOKPF_REMOVE_SOME_PHANTOM_KEYS) ? 1 : 0);
230 }
231
232 static ssize_t store_remove_some_phantom_keys_flag(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
233 {
234 unsigned flag;
235
236 if (!gpio_evmi)
237 return -ENODEV;
238
239 sscanf(buf, "%u", &flag);
240
241 if (flag) {
242 gpio_evmi->flags |= GPIOKPF_REMOVE_SOME_PHANTOM_KEYS;
243 } else {
244 gpio_evmi->flags &= ~GPIOKPF_REMOVE_SOME_PHANTOM_KEYS;
245 }
246
247 return count;
248 }
249
250 static ssize_t show_print_unmapped_keys_flag(struct device *dev, struct device_attribute *attr, char *buf)
251 {
252 if (!gpio_evmi)
253 return -ENODEV;
254
255 return snprintf(buf, PAGE_SIZE, "%u\n", (gpio_evmi->flags & GPIOKPF_PRINT_UNMAPPED_KEYS) ? 1 : 0);
256 }
257
258 static ssize_t store_print_unmapped_keys_flag(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
259 {
260 unsigned flag;
261
262 if (!gpio_evmi)
263 return -ENODEV;
264
265 sscanf(buf, "%u", &flag);
266
267 if (flag) {
268 gpio_evmi->flags |= GPIOKPF_PRINT_UNMAPPED_KEYS;
269 } else {
270 gpio_evmi->flags &= ~GPIOKPF_PRINT_UNMAPPED_KEYS;
271 }
272
273 return count;
274 }
275
276 static ssize_t show_print_mapped_keys_flag(struct device *dev, struct device_attribute *attr, char *buf)
277 {
278 if (!gpio_evmi)
279 return -ENODEV;
280
281 return snprintf(buf, PAGE_SIZE, "%u\n", (gpio_evmi->flags & GPIOKPF_PRINT_MAPPED_KEYS) ? 1 : 0);
282 }
283
284 static ssize_t store_print_mapped_keys_flag(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
285 {
286 unsigned flag;
287
288 if (!gpio_evmi)
289 return -ENODEV;
290
291 sscanf(buf, "%u", &flag);
292
293 if (flag) {
294 gpio_evmi->flags |= GPIOKPF_PRINT_MAPPED_KEYS;
295 } else {
296 gpio_evmi->flags &= ~GPIOKPF_PRINT_MAPPED_KEYS;
297 }
298
299 return count;
300 }
301
302 static ssize_t show_print_phantom_keys_flag(struct device *dev, struct device_attribute *attr, char *buf)
303 {
304 if (!gpio_evmi)
305 return -ENODEV;
306
307 return snprintf(buf, PAGE_SIZE, "%u\n", (gpio_evmi->flags & GPIOKPF_PRINT_PHANTOM_KEYS) ? 1 : 0);
308 }
309
310 static ssize_t store_print_phantom_keys_flag(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
311 {
312 unsigned flag;
313
314 if (!gpio_evmi)
315 return -ENODEV;
316
317 sscanf(buf, "%u", &flag);
318
319 if (flag) {
320 gpio_evmi->flags |= GPIOKPF_PRINT_PHANTOM_KEYS;
321 } else {
322 gpio_evmi->flags &= ~GPIOKPF_PRINT_PHANTOM_KEYS;
323 }
324
325 return count;
326 }
327
328 static ssize_t show_active_high_flag(struct device *dev, struct device_attribute *attr, char *buf)
329 {
330 if (!gpio_evmi)
331 return -ENODEV;
332
333 return snprintf(buf, PAGE_SIZE, "%u\n", (gpio_evmi->flags & GPIOKPF_ACTIVE_HIGH) ? 1 : 0);
334 }
335
336 static ssize_t store_active_high_flag(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
337 {
338 unsigned flag;
339
340 if (!gpio_evmi)
341 return -ENODEV;
342
343 sscanf(buf, "%u", &flag);
344
345 if (flag) {
346 gpio_evmi->flags |= GPIOKPF_ACTIVE_HIGH;
347 } else {
348 gpio_evmi->flags &= ~GPIOKPF_ACTIVE_HIGH;
349 }
350
351 set_irq_types();
352
353 return count;
354 }
355
356 static ssize_t show_level_triggered_irq_flag(struct device *dev, struct device_attribute *attr, char *buf)
357 {
358 if (!gpio_evmi)
359 return -ENODEV;
360
361 return snprintf(buf, PAGE_SIZE, "%u\n", (gpio_evmi->flags & GPIOKPF_LEVEL_TRIGGERED_IRQ) ? 1 : 0);
362 }
363
364 static ssize_t store_level_triggered_irq_flag(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
365 {
366 unsigned flag;
367
368 if (!gpio_evmi)
369 return -ENODEV;
370
371 sscanf(buf, "%u", &flag);
372
373 if (flag) {
374 gpio_evmi->flags |= GPIOKPF_LEVEL_TRIGGERED_IRQ;
375 } else {
376 gpio_evmi->flags &= ~GPIOKPF_LEVEL_TRIGGERED_IRQ;
377 }
378
379 set_irq_types();
380
381 return count;
382 }
383
384 static ssize_t show_drive_inactive_flag(struct device *dev, struct device_attribute *attr, char *buf)
385 {
386 if (!gpio_evmi)
387 return -ENODEV;
388
389 return snprintf(buf, PAGE_SIZE, "%u\n", (gpio_evmi->flags & GPIOKPF_DRIVE_INACTIVE) ? 1 : 0);
390 }
391
392 static ssize_t store_drive_inactive_flag(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
393 {
394 unsigned flag;
395
396 if (!gpio_evmi)
397 return -ENODEV;
398
399 sscanf(buf, "%u", &flag);
400
401 if (flag) {
402 gpio_evmi->flags |= GPIOKPF_DRIVE_INACTIVE;
403 } else {
404 gpio_evmi->flags &= ~GPIOKPF_DRIVE_INACTIVE;
405 }
406
407 return count;
408 }
409
410 static ssize_t show_hw_debounce(struct device *dev, struct device_attribute *attr, char *buf)
411 {
412 return snprintf(buf, PAGE_SIZE, "%d\n", hw_debounce);
413 }
414
415 static ssize_t store_hw_debounce(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
416 {
417 int enable;
418
419 sscanf(buf, "%d", &enable);
420
421 if (enable) {
422 hw_debounce_set(1, -1);
423 hw_debounce = 1;
424 }
425 else {
426 hw_debounce_set(-1, 0);
427 hw_debounce_set(0, -1);
428 hw_debounce = 0;
429 hw_debounce_time = 0;
430 }
431
432 return count;
433 }
434
435 static ssize_t show_hw_debounce_time(struct device *dev, struct device_attribute *attr, char *buf)
436 {
437 return snprintf(buf, PAGE_SIZE, "%d\n", hw_debounce_time);
438 }
439
440 static ssize_t store_hw_debounce_time(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
441 {
442 int time;
443
444 sscanf(buf, "%d", &time);
445
446 if ((time < 0) || (time > 0xff))
447 return count;
448
449 if (!hw_debounce)
450 return count;
451
452 hw_debounce_set(-1, time);
453 hw_debounce_time = time;
454
455 return count;
456 }
457
458 static DEVICE_ATTR(debounce_delay, (S_IRUGO | S_IWUGO), show_debounce_delay, store_debounce_delay);
459 static DEVICE_ATTR(settle_time, (S_IRUGO | S_IWUGO), show_settle_time, store_settle_time);
460 static DEVICE_ATTR(poll_time, (S_IRUGO | S_IWUGO), show_poll_time, store_poll_time);
461 static DEVICE_ATTR(flags, (S_IRUGO), show_flags, store_flags);
462 static DEVICE_ATTR(debounce_flag, (S_IRUGO | S_IWUGO), show_debounce_flag, store_debounce_flag);
463 static DEVICE_ATTR(remove_some_phantom_keys_flag, (S_IRUGO | S_IWUGO), show_remove_some_phantom_keys_flag, store_remove_some_phantom_keys_flag);
464 static DEVICE_ATTR(print_unmapped_keys_flag, (S_IRUGO | S_IWUGO), show_print_unmapped_keys_flag, store_print_unmapped_keys_flag);
465 static DEVICE_ATTR(print_mapped_keys_flag, (S_IRUGO | S_IWUGO), show_print_mapped_keys_flag, store_print_mapped_keys_flag);
466 static DEVICE_ATTR(print_phantom_keys_flag, (S_IRUGO | S_IWUGO), show_print_phantom_keys_flag, store_print_phantom_keys_flag);
467 static DEVICE_ATTR(active_high_flag, (S_IRUGO | S_IWUGO), show_active_high_flag, store_active_high_flag);
468 static DEVICE_ATTR(level_triggered_irq_flag, (S_IRUGO | S_IWUGO), show_level_triggered_irq_flag, store_level_triggered_irq_flag);
469 static DEVICE_ATTR(drive_inactive_flag, (S_IRUGO | S_IWUGO), show_drive_inactive_flag, store_drive_inactive_flag);
470 static DEVICE_ATTR(hw_debounce, (S_IRUGO | S_IWUGO), show_hw_debounce, store_hw_debounce);
471 static DEVICE_ATTR(hw_debounce_time, (S_IRUGO | S_IWUGO), show_hw_debounce_time, store_hw_debounce_time);
472
473 #if 0
474 static int debounce_fixup(int index)
475 {
476 int ret;
477
478 printk(KERN_INFO PREFIX "0x%x\n", index);
479
480 ret = old_sw_fixup(index);
481 if (!ret)
482 printk(KERN_INFO PREFIX "IGNORED!\n");
483
484 return ret;
485 }
486 #endif
487
488 static void debounce_release(struct device *dev)
489 {
490 }
491
492 static struct device debounce_device = {
493 .init_name = "debounce",
494 .release = debounce_release,
495 };
496
497 static int __init debounce_init(void)
498 {
499 struct device *event_dev = NULL;
500 struct gpio_event_platform_data *gpio_epd;
501 struct gpio_event_info *gpio_ei;
502 int err = 0;
503
504 printk(KERN_INFO PREFIX "Searching for " GPIO_EVENT_DEV_NAME "...\n");
505
506 event_dev = device_find_child(&platform_bus, GPIO_EVENT_DEV_NAME, find_ms2_dev);
507 if (event_dev == NULL)
508 return -ENODEV;
509
510 gpio_epd = (struct gpio_event_platform_data*)event_dev->platform_data;
511 printk(KERN_INFO PREFIX "And there is a %s connected...\n", gpio_epd->name);
512 if (strcmp(gpio_epd->name, "sholes-keypad"))
513 return -ENODEV;
514
515 gpio_ei = (struct gpio_event_info*)gpio_epd->info[0];
516 gpio_evmi = container_of(gpio_ei, struct gpio_event_matrix_info, info);
517
518 err = device_register(&debounce_device);
519 if (err) {
520 return err;
521 }
522
523 err = device_create_file(&debounce_device, &dev_attr_debounce_delay);
524 err = device_create_file(&debounce_device, &dev_attr_settle_time);
525 err = device_create_file(&debounce_device, &dev_attr_poll_time);
526 err = device_create_file(&debounce_device, &dev_attr_flags);
527 err = device_create_file(&debounce_device, &dev_attr_debounce_flag);
528 err = device_create_file(&debounce_device, &dev_attr_remove_some_phantom_keys_flag);
529 err = device_create_file(&debounce_device, &dev_attr_print_unmapped_keys_flag);
530 err = device_create_file(&debounce_device, &dev_attr_print_mapped_keys_flag);
531 err = device_create_file(&debounce_device, &dev_attr_print_phantom_keys_flag);
532 err = device_create_file(&debounce_device, &dev_attr_active_high_flag);
533 err = device_create_file(&debounce_device, &dev_attr_level_triggered_irq_flag);
534 err = device_create_file(&debounce_device, &dev_attr_drive_inactive_flag);
535 err = device_create_file(&debounce_device, &dev_attr_hw_debounce);
536 err = device_create_file(&debounce_device, &dev_attr_hw_debounce_time);
537
538 printk(KERN_INFO PREFIX "settle_time: %u\n", gpio_evmi->settle_time.tv.nsec);
539 printk(KERN_INFO PREFIX "poll_time: %u\n", gpio_evmi->poll_time.tv.nsec);
540 printk(KERN_INFO PREFIX "debounce_delay: %u\n", gpio_evmi->debounce_delay.tv.nsec);
541 printk(KERN_INFO PREFIX "flags: 0x%x\n", gpio_evmi->flags);
542
543 old_debounce_delay = gpio_evmi->debounce_delay;
544 old_settle_time = gpio_evmi->settle_time;
545 old_poll_time = gpio_evmi->poll_time;
546 old_flags = gpio_evmi->flags;
547 old_sw_fixup = gpio_evmi->sw_fixup;
548
549 #if 0
550 printk(KERN_INFO PREFIX "Registering fixup handler\n");
551 gpio_evmi->sw_fixup = debounce_fixup;
552 #endif
553
554 return 0;
555 }
556
557 static void __exit debounce_exit(void)
558 {
559 if (gpio_evmi) {
560 if (gpio_evmi->debounce_delay.tv.nsec != old_debounce_delay.tv.nsec) {
561 printk(KERN_INFO PREFIX "Restoring debounce_delay\n");
562 gpio_evmi->debounce_delay = old_debounce_delay;
563 printk(KERN_INFO PREFIX "debounce_delay: %u\n", gpio_evmi->debounce_delay.tv.nsec);
564 }
565 if (gpio_evmi->flags != old_flags) {
566 printk(KERN_INFO PREFIX "Restoring flags\n");
567 gpio_evmi->flags = old_flags;
568 printk(KERN_INFO PREFIX "flags: 0x%x\n", gpio_evmi->flags);
569 set_irq_types();
570 }
571 gpio_evmi->settle_time = old_settle_time;
572 gpio_evmi->poll_time = old_poll_time;
573
574 if (gpio_evmi->sw_fixup != old_sw_fixup) {
575 printk(KERN_INFO PREFIX "Restoring fixup handler\n");
576 gpio_evmi->sw_fixup = old_sw_fixup;
577 }
578 }
579 hw_debounce_set(0, 0);
580 device_remove_file(&debounce_device, &dev_attr_debounce_delay);
581 device_remove_file(&debounce_device, &dev_attr_settle_time);
582 device_remove_file(&debounce_device, &dev_attr_poll_time);
583 device_remove_file(&debounce_device, &dev_attr_flags);
584 device_remove_file(&debounce_device, &dev_attr_debounce_flag);
585 device_remove_file(&debounce_device, &dev_attr_remove_some_phantom_keys_flag);
586 device_remove_file(&debounce_device, &dev_attr_print_unmapped_keys_flag);
587 device_remove_file(&debounce_device, &dev_attr_print_mapped_keys_flag);
588 device_remove_file(&debounce_device, &dev_attr_print_phantom_keys_flag);
589 device_remove_file(&debounce_device, &dev_attr_active_high_flag);
590 device_remove_file(&debounce_device, &dev_attr_level_triggered_irq_flag);
591 device_remove_file(&debounce_device, &dev_attr_drive_inactive_flag);
592 device_remove_file(&debounce_device, &dev_attr_hw_debounce);
593 device_remove_file(&debounce_device, &dev_attr_hw_debounce_time);
594 device_unregister(&debounce_device);
595 }
596
597 module_init(debounce_init);
598 module_exit(debounce_exit);
599
600 MODULE_LICENSE("GPL");
601 MODULE_AUTHOR("Michael Gernoth <michael@gernoth.net>");
Impressum, Datenschutz