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>
9 #define PREFIX "debounce: "
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 struct gpio_event_matrix_info
*gpio_evmi
= NULL
;
16 static int hw_debounce
= 0;
17 static int hw_debounce_time
= 0;
19 static int find_ms2_dev(struct device
*dev
, void *data
)
21 if (!strncmp((char*)data
, dev_name(dev
), strlen((char*)data
))) {
22 printk(KERN_INFO PREFIX
"Found it\n");
28 /* hardware debounce: (time + 1) * 31us */
29 static void hw_debounce_set(int enable
, int time
) {
32 if (gpio_evmi
== NULL
)
35 for (i
= 0; i
< gpio_evmi
->ninputs
; i
++) {
36 int gpio
= gpio_evmi
->input_gpios
[i
];
38 if ((time
!= -1) && (time
!= hw_debounce_time
) && hw_debounce
) {
39 printk(KERN_INFO PREFIX
"Setting hardware debounce time for GPIO %d to %d (%dus)\n", gpio
, time
, (time
+1)*31);
40 omap_set_gpio_debounce_time(gpio
, time
);
43 if ((enable
!= -1) && (enable
!= hw_debounce
)) {
44 printk(KERN_INFO PREFIX
"%sabling hardware debounce for GPIO %d\n", (enable
?"En":"Dis"), gpio
);
45 omap_set_gpio_debounce(gpio
, enable
);
50 static void set_irq_types(void) {
56 if (gpio_evmi
== NULL
)
59 switch (gpio_evmi
->flags
& (GPIOKPF_ACTIVE_HIGH
|GPIOKPF_LEVEL_TRIGGERED_IRQ
)) {
61 type
= IRQ_TYPE_EDGE_FALLING
;
63 case GPIOKPF_ACTIVE_HIGH
:
64 type
= IRQ_TYPE_EDGE_RISING
;
66 case GPIOKPF_LEVEL_TRIGGERED_IRQ
:
67 type
= IRQ_TYPE_LEVEL_LOW
;
69 case GPIOKPF_LEVEL_TRIGGERED_IRQ
| GPIOKPF_ACTIVE_HIGH
:
70 type
= IRQ_TYPE_LEVEL_HIGH
;
74 printk(KERN_INFO PREFIX
"Settinhg IRQ type to 0x%lx\n", type
);
76 for (i
= 0; i
< gpio_evmi
->ninputs
; i
++) {
78 err
= irq
= gpio_to_irq(gpio_evmi
->input_gpios
[i
]);
83 err
= set_irq_type(irq
, type
);
87 static ssize_t
show_debounce_delay(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
92 return snprintf(buf
, PAGE_SIZE
, "%ld\n", (gpio_evmi
->debounce_delay
.tv
.nsec
/ NSEC_PER_MSEC
));
95 static void set_debounce_delay(long delay
)
97 if (gpio_evmi
->debounce_delay
.tv
.nsec
!= delay
* NSEC_PER_MSEC
) {
98 printk(KERN_INFO PREFIX
"Changing debounce_delay\n");
99 gpio_evmi
->debounce_delay
.tv
.nsec
= delay
* NSEC_PER_MSEC
;
100 printk(KERN_INFO PREFIX
"debounce_delay: %u\n", gpio_evmi
->debounce_delay
.tv
.nsec
);
104 if (gpio_evmi
->debounce_delay
.tv
.nsec
!= 0) {
105 if (!(gpio_evmi
->flags
& GPIOKPF_DEBOUNCE
)) {
106 printk(KERN_INFO PREFIX
"Activating debounce\n");
107 gpio_evmi
->flags
|= GPIOKPF_DEBOUNCE
;
110 if (gpio_evmi
->flags
& GPIOKPF_DEBOUNCE
) {
111 printk(KERN_INFO PREFIX
"Deactivating debounce\n");
112 gpio_evmi
->flags
&= ~GPIOKPF_DEBOUNCE
;
118 static ssize_t
store_debounce_delay(struct device
*dev
, struct device_attribute
*attr
, const char *buf
, size_t count
)
125 sscanf(buf
, "%ld", &delay
);
126 set_debounce_delay(delay
);
131 static ssize_t
show_settle_time(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
136 return snprintf(buf
, PAGE_SIZE
, "%ld\n", (gpio_evmi
->settle_time
.tv
.nsec
/ NSEC_PER_USEC
));
139 static ssize_t
store_settle_time(struct device
*dev
, struct device_attribute
*attr
, const char *buf
, size_t count
)
146 sscanf(buf
, "%ld", &delay
);
147 gpio_evmi
->settle_time
.tv
.nsec
= delay
* NSEC_PER_USEC
;
152 static ssize_t
show_poll_time(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
157 return snprintf(buf
, PAGE_SIZE
, "%ld\n", (gpio_evmi
->poll_time
.tv
.nsec
/ NSEC_PER_MSEC
));
160 static ssize_t
store_poll_time(struct device
*dev
, struct device_attribute
*attr
, const char *buf
, size_t count
)
167 sscanf(buf
, "%ld", &delay
);
168 gpio_evmi
->poll_time
.tv
.nsec
= delay
* NSEC_PER_MSEC
;
173 static ssize_t
show_flags(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
178 return snprintf(buf
, PAGE_SIZE
, "0x%x\n", gpio_evmi
->flags
);
181 static ssize_t
store_flags(struct device
*dev
, struct device_attribute
*attr
, const char *buf
, size_t count
)
188 sscanf(buf
, "0x%x", &flags
);
190 printk(KERN_INFO PREFIX
"flags: 0x%x\n", flags
);
192 gpio_evmi
->flags
= flags
;
197 static ssize_t
show_debounce_flag(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
202 return snprintf(buf
, PAGE_SIZE
, "%u\n", (gpio_evmi
->flags
& GPIOKPF_DEBOUNCE
) ? 1 : 0);
205 static ssize_t
store_debounce_flag(struct device
*dev
, struct device_attribute
*attr
, const char *buf
, size_t count
)
212 sscanf(buf
, "%u", &flag
);
215 gpio_evmi
->flags
|= GPIOKPF_DEBOUNCE
;
217 gpio_evmi
->flags
&= ~GPIOKPF_DEBOUNCE
;
223 static ssize_t
show_remove_some_phantom_keys_flag(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
228 return snprintf(buf
, PAGE_SIZE
, "%u\n", (gpio_evmi
->flags
& GPIOKPF_REMOVE_SOME_PHANTOM_KEYS
) ? 1 : 0);
231 static ssize_t
store_remove_some_phantom_keys_flag(struct device
*dev
, struct device_attribute
*attr
, const char *buf
, size_t count
)
238 sscanf(buf
, "%u", &flag
);
241 gpio_evmi
->flags
|= GPIOKPF_REMOVE_SOME_PHANTOM_KEYS
;
243 gpio_evmi
->flags
&= ~GPIOKPF_REMOVE_SOME_PHANTOM_KEYS
;
249 static ssize_t
show_print_unmapped_keys_flag(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
254 return snprintf(buf
, PAGE_SIZE
, "%u\n", (gpio_evmi
->flags
& GPIOKPF_PRINT_UNMAPPED_KEYS
) ? 1 : 0);
257 static ssize_t
store_print_unmapped_keys_flag(struct device
*dev
, struct device_attribute
*attr
, const char *buf
, size_t count
)
264 sscanf(buf
, "%u", &flag
);
267 gpio_evmi
->flags
|= GPIOKPF_PRINT_UNMAPPED_KEYS
;
269 gpio_evmi
->flags
&= ~GPIOKPF_PRINT_UNMAPPED_KEYS
;
275 static ssize_t
show_print_mapped_keys_flag(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
280 return snprintf(buf
, PAGE_SIZE
, "%u\n", (gpio_evmi
->flags
& GPIOKPF_PRINT_MAPPED_KEYS
) ? 1 : 0);
283 static ssize_t
store_print_mapped_keys_flag(struct device
*dev
, struct device_attribute
*attr
, const char *buf
, size_t count
)
290 sscanf(buf
, "%u", &flag
);
293 gpio_evmi
->flags
|= GPIOKPF_PRINT_MAPPED_KEYS
;
295 gpio_evmi
->flags
&= ~GPIOKPF_PRINT_MAPPED_KEYS
;
301 static ssize_t
show_print_phantom_keys_flag(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
306 return snprintf(buf
, PAGE_SIZE
, "%u\n", (gpio_evmi
->flags
& GPIOKPF_PRINT_PHANTOM_KEYS
) ? 1 : 0);
309 static ssize_t
store_print_phantom_keys_flag(struct device
*dev
, struct device_attribute
*attr
, const char *buf
, size_t count
)
316 sscanf(buf
, "%u", &flag
);
319 gpio_evmi
->flags
|= GPIOKPF_PRINT_PHANTOM_KEYS
;
321 gpio_evmi
->flags
&= ~GPIOKPF_PRINT_PHANTOM_KEYS
;
327 static ssize_t
show_active_high_flag(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
332 return snprintf(buf
, PAGE_SIZE
, "%u\n", (gpio_evmi
->flags
& GPIOKPF_ACTIVE_HIGH
) ? 1 : 0);
335 static ssize_t
store_active_high_flag(struct device
*dev
, struct device_attribute
*attr
, const char *buf
, size_t count
)
342 sscanf(buf
, "%u", &flag
);
345 gpio_evmi
->flags
|= GPIOKPF_ACTIVE_HIGH
;
347 gpio_evmi
->flags
&= ~GPIOKPF_ACTIVE_HIGH
;
355 static ssize_t
show_level_triggered_irq_flag(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
360 return snprintf(buf
, PAGE_SIZE
, "%u\n", (gpio_evmi
->flags
& GPIOKPF_LEVEL_TRIGGERED_IRQ
) ? 1 : 0);
363 static ssize_t
store_level_triggered_irq_flag(struct device
*dev
, struct device_attribute
*attr
, const char *buf
, size_t count
)
370 sscanf(buf
, "%u", &flag
);
373 gpio_evmi
->flags
|= GPIOKPF_LEVEL_TRIGGERED_IRQ
;
375 gpio_evmi
->flags
&= ~GPIOKPF_LEVEL_TRIGGERED_IRQ
;
383 static ssize_t
show_drive_inactive_flag(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
388 return snprintf(buf
, PAGE_SIZE
, "%u\n", (gpio_evmi
->flags
& GPIOKPF_DRIVE_INACTIVE
) ? 1 : 0);
391 static ssize_t
store_drive_inactive_flag(struct device
*dev
, struct device_attribute
*attr
, const char *buf
, size_t count
)
398 sscanf(buf
, "%u", &flag
);
401 gpio_evmi
->flags
|= GPIOKPF_DRIVE_INACTIVE
;
403 gpio_evmi
->flags
&= ~GPIOKPF_DRIVE_INACTIVE
;
409 static ssize_t
show_hw_debounce(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
411 return snprintf(buf
, PAGE_SIZE
, "%d\n", hw_debounce
);
414 static ssize_t
store_hw_debounce(struct device
*dev
, struct device_attribute
*attr
, const char *buf
, size_t count
)
418 sscanf(buf
, "%d", &enable
);
421 hw_debounce_set(1, -1);
425 hw_debounce_set(-1, 0);
426 hw_debounce_set(0, -1);
428 hw_debounce_time
= 0;
434 static ssize_t
show_hw_debounce_time(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
436 return snprintf(buf
, PAGE_SIZE
, "%d\n", hw_debounce_time
);
439 static ssize_t
store_hw_debounce_time(struct device
*dev
, struct device_attribute
*attr
, const char *buf
, size_t count
)
443 sscanf(buf
, "%d", &time
);
445 if ((time
< 0) || (time
> 0xff))
451 hw_debounce_set(-1, time
);
452 hw_debounce_time
= time
;
457 static DEVICE_ATTR(debounce_delay
, (S_IRUGO
| S_IWUGO
), show_debounce_delay
, store_debounce_delay
);
458 static DEVICE_ATTR(settle_time
, (S_IRUGO
| S_IWUGO
), show_settle_time
, store_settle_time
);
459 static DEVICE_ATTR(poll_time
, (S_IRUGO
| S_IWUGO
), show_poll_time
, store_poll_time
);
460 static DEVICE_ATTR(flags
, (S_IRUGO
), show_flags
, store_flags
);
461 static DEVICE_ATTR(debounce_flag
, (S_IRUGO
| S_IWUGO
), show_debounce_flag
, store_debounce_flag
);
462 static DEVICE_ATTR(remove_some_phantom_keys_flag
, (S_IRUGO
| S_IWUGO
), show_remove_some_phantom_keys_flag
, store_remove_some_phantom_keys_flag
);
463 static DEVICE_ATTR(print_unmapped_keys_flag
, (S_IRUGO
| S_IWUGO
), show_print_unmapped_keys_flag
, store_print_unmapped_keys_flag
);
464 static DEVICE_ATTR(print_mapped_keys_flag
, (S_IRUGO
| S_IWUGO
), show_print_mapped_keys_flag
, store_print_mapped_keys_flag
);
465 static DEVICE_ATTR(print_phantom_keys_flag
, (S_IRUGO
| S_IWUGO
), show_print_phantom_keys_flag
, store_print_phantom_keys_flag
);
466 static DEVICE_ATTR(active_high_flag
, (S_IRUGO
), show_active_high_flag
, store_active_high_flag
);
467 static DEVICE_ATTR(level_triggered_irq_flag
, (S_IRUGO
| S_IWUGO
), show_level_triggered_irq_flag
, store_level_triggered_irq_flag
);
468 static DEVICE_ATTR(drive_inactive_flag
, (S_IRUGO
| S_IWUGO
), show_drive_inactive_flag
, store_drive_inactive_flag
);
469 static DEVICE_ATTR(hw_debounce
, (S_IRUGO
| S_IWUGO
), show_hw_debounce
, store_hw_debounce
);
470 static DEVICE_ATTR(hw_debounce_time
, (S_IRUGO
| S_IWUGO
), show_hw_debounce_time
, store_hw_debounce_time
);
472 static void debounce_release(struct device
*dev
)
476 static struct device debounce_device
= {
477 .init_name
= "debounce",
478 .release
= debounce_release
,
481 static int __init
debounce_init(void)
483 struct device
*event_dev
= NULL
;
484 struct gpio_event_platform_data
*gpio_epd
;
485 struct gpio_event_info
*gpio_ei
;
488 printk(KERN_INFO PREFIX
"Searching for " GPIO_EVENT_DEV_NAME
"...\n");
490 event_dev
= device_find_child(&platform_bus
, GPIO_EVENT_DEV_NAME
, find_ms2_dev
);
491 if (event_dev
== NULL
)
494 gpio_epd
= (struct gpio_event_platform_data
*)event_dev
->platform_data
;
495 printk(KERN_INFO PREFIX
"And there is a %s connected...\n", gpio_epd
->name
);
496 if (strcmp(gpio_epd
->name
, "sholes-keypad"))
499 gpio_ei
= (struct gpio_event_info
*)gpio_epd
->info
[0];
500 gpio_evmi
= container_of(gpio_ei
, struct gpio_event_matrix_info
, info
);
502 err
= device_register(&debounce_device
);
507 err
= device_create_file(&debounce_device
, &dev_attr_debounce_delay
);
508 err
= device_create_file(&debounce_device
, &dev_attr_settle_time
);
509 err
= device_create_file(&debounce_device
, &dev_attr_poll_time
);
510 err
= device_create_file(&debounce_device
, &dev_attr_flags
);
511 err
= device_create_file(&debounce_device
, &dev_attr_debounce_flag
);
512 err
= device_create_file(&debounce_device
, &dev_attr_remove_some_phantom_keys_flag
);
513 err
= device_create_file(&debounce_device
, &dev_attr_print_unmapped_keys_flag
);
514 err
= device_create_file(&debounce_device
, &dev_attr_print_mapped_keys_flag
);
515 err
= device_create_file(&debounce_device
, &dev_attr_print_phantom_keys_flag
);
516 err
= device_create_file(&debounce_device
, &dev_attr_active_high_flag
);
517 err
= device_create_file(&debounce_device
, &dev_attr_level_triggered_irq_flag
);
518 err
= device_create_file(&debounce_device
, &dev_attr_drive_inactive_flag
);
519 err
= device_create_file(&debounce_device
, &dev_attr_hw_debounce
);
520 err
= device_create_file(&debounce_device
, &dev_attr_hw_debounce_time
);
522 printk(KERN_INFO PREFIX
"settle_time: %u\n", gpio_evmi
->settle_time
.tv
.nsec
);
523 printk(KERN_INFO PREFIX
"poll_time: %u\n", gpio_evmi
->poll_time
.tv
.nsec
);
524 printk(KERN_INFO PREFIX
"debounce_delay: %u\n", gpio_evmi
->debounce_delay
.tv
.nsec
);
525 printk(KERN_INFO PREFIX
"flags: 0x%x\n", gpio_evmi
->flags
);
527 old_debounce_delay
= gpio_evmi
->debounce_delay
;
528 old_settle_time
= gpio_evmi
->settle_time
;
529 old_poll_time
= gpio_evmi
->poll_time
;
530 old_flags
= gpio_evmi
->flags
;
532 printk(KERN_INFO PREFIX
"flags: 0x%x\n", gpio_evmi
->flags
);
537 static void __exit
debounce_exit(void)
540 if (gpio_evmi
->debounce_delay
.tv
.nsec
!= old_debounce_delay
.tv
.nsec
) {
541 printk(KERN_INFO PREFIX
"Restoring debounce_delay\n");
542 gpio_evmi
->debounce_delay
= old_debounce_delay
;
543 printk(KERN_INFO PREFIX
"debounce_delay: %u\n", gpio_evmi
->debounce_delay
.tv
.nsec
);
545 if (gpio_evmi
->flags
!= old_flags
) {
546 printk(KERN_INFO PREFIX
"Restoring flags\n");
547 gpio_evmi
->flags
= old_flags
;
548 printk(KERN_INFO PREFIX
"flags: 0x%x\n", gpio_evmi
->flags
);
551 gpio_evmi
->settle_time
= old_settle_time
;
552 gpio_evmi
->poll_time
= old_poll_time
;
554 hw_debounce_set(0, 0);
555 device_remove_file(&debounce_device
, &dev_attr_debounce_delay
);
556 device_remove_file(&debounce_device
, &dev_attr_settle_time
);
557 device_remove_file(&debounce_device
, &dev_attr_poll_time
);
558 device_remove_file(&debounce_device
, &dev_attr_flags
);
559 device_remove_file(&debounce_device
, &dev_attr_debounce_flag
);
560 device_remove_file(&debounce_device
, &dev_attr_remove_some_phantom_keys_flag
);
561 device_remove_file(&debounce_device
, &dev_attr_print_unmapped_keys_flag
);
562 device_remove_file(&debounce_device
, &dev_attr_print_mapped_keys_flag
);
563 device_remove_file(&debounce_device
, &dev_attr_print_phantom_keys_flag
);
564 device_remove_file(&debounce_device
, &dev_attr_active_high_flag
);
565 device_remove_file(&debounce_device
, &dev_attr_level_triggered_irq_flag
);
566 device_remove_file(&debounce_device
, &dev_attr_drive_inactive_flag
);
567 device_remove_file(&debounce_device
, &dev_attr_hw_debounce
);
568 device_remove_file(&debounce_device
, &dev_attr_hw_debounce_time
);
569 device_unregister(&debounce_device
);
572 module_init(debounce_init
);
573 module_exit(debounce_exit
);
575 MODULE_LICENSE("GPL");
576 MODULE_AUTHOR("Michael Gernoth <michael@gernoth.net>");