]> cvs.zerfleddert.de Git - ms2-fixes/blob - debounce.c
add support for switching between edge and level triggered IRQs
[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 struct gpio_event_matrix_info *gpio_evmi = NULL;
16 static int hw_debounce = 0;
17 static int hw_debounce_time = 0;
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 /* hardware debounce: (time + 1) * 31us */
29 static void hw_debounce_set(int enable, int time) {
30 int i;
31
32 if (gpio_evmi == NULL)
33 return;
34
35 for (i = 0; i < gpio_evmi->ninputs; i++) {
36 int gpio = gpio_evmi->input_gpios[i];
37
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);
41 }
42
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);
46 }
47 }
48 }
49
50 static void set_irq_types(void) {
51 int err;
52 unsigned int irq;
53 unsigned long type;
54 int i;
55
56 if (gpio_evmi == NULL)
57 return;
58
59 switch (gpio_evmi->flags & (GPIOKPF_ACTIVE_HIGH|GPIOKPF_LEVEL_TRIGGERED_IRQ)) {
60 default:
61 type = IRQ_TYPE_EDGE_FALLING;
62 break;
63 case GPIOKPF_ACTIVE_HIGH:
64 type = IRQ_TYPE_EDGE_RISING;
65 break;
66 case GPIOKPF_LEVEL_TRIGGERED_IRQ:
67 type = IRQ_TYPE_LEVEL_LOW;
68 break;
69 case GPIOKPF_LEVEL_TRIGGERED_IRQ | GPIOKPF_ACTIVE_HIGH:
70 type = IRQ_TYPE_LEVEL_HIGH;
71 break;
72 }
73
74 printk(KERN_INFO PREFIX "Settinhg IRQ type to 0x%lx\n", type);
75
76 for (i = 0; i < gpio_evmi->ninputs; i++) {
77
78 err = irq = gpio_to_irq(gpio_evmi->input_gpios[i]);
79
80 if (err < 0)
81 return;
82
83 err = set_irq_type(irq, type);
84 }
85 }
86
87 static ssize_t show_debounce_delay(struct device *dev, struct device_attribute *attr, char *buf)
88 {
89 if (!gpio_evmi)
90 return -ENODEV;
91
92 return snprintf(buf, PAGE_SIZE, "%ld\n", (gpio_evmi->debounce_delay.tv.nsec / NSEC_PER_MSEC));
93 }
94
95 static void set_debounce_delay(long delay)
96 {
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);
101 }
102
103 #if 0
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;
108 }
109 } else {
110 if (gpio_evmi->flags & GPIOKPF_DEBOUNCE) {
111 printk(KERN_INFO PREFIX "Deactivating debounce\n");
112 gpio_evmi->flags &= ~GPIOKPF_DEBOUNCE;
113 }
114 }
115 #endif
116 }
117
118 static ssize_t store_debounce_delay(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
119 {
120 long int delay;
121
122 if (!gpio_evmi)
123 return -ENODEV;
124
125 sscanf(buf, "%ld", &delay);
126 set_debounce_delay(delay);
127
128 return count;
129 }
130
131 static ssize_t show_settle_time(struct device *dev, struct device_attribute *attr, char *buf)
132 {
133 if (!gpio_evmi)
134 return -ENODEV;
135
136 return snprintf(buf, PAGE_SIZE, "%ld\n", (gpio_evmi->settle_time.tv.nsec / NSEC_PER_USEC));
137 }
138
139 static ssize_t store_settle_time(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
140 {
141 long int delay;
142
143 if (!gpio_evmi)
144 return -ENODEV;
145
146 sscanf(buf, "%ld", &delay);
147 gpio_evmi->settle_time.tv.nsec = delay * NSEC_PER_USEC;
148
149 return count;
150 }
151
152 static ssize_t show_poll_time(struct device *dev, struct device_attribute *attr, char *buf)
153 {
154 if (!gpio_evmi)
155 return -ENODEV;
156
157 return snprintf(buf, PAGE_SIZE, "%ld\n", (gpio_evmi->poll_time.tv.nsec / NSEC_PER_MSEC));
158 }
159
160 static ssize_t store_poll_time(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
161 {
162 long int delay;
163
164 if (!gpio_evmi)
165 return -ENODEV;
166
167 sscanf(buf, "%ld", &delay);
168 gpio_evmi->poll_time.tv.nsec = delay * NSEC_PER_MSEC;
169
170 return count;
171 }
172
173 static ssize_t show_flags(struct device *dev, struct device_attribute *attr, char *buf)
174 {
175 if (!gpio_evmi)
176 return -ENODEV;
177
178 return snprintf(buf, PAGE_SIZE, "0x%x\n", gpio_evmi->flags);
179 }
180
181 static ssize_t store_flags(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
182 {
183 unsigned flags;
184
185 if (!gpio_evmi)
186 return -ENODEV;
187
188 sscanf(buf, "0x%x", &flags);
189
190 printk(KERN_INFO PREFIX "flags: 0x%x\n", flags);
191
192 gpio_evmi->flags = flags;
193
194 return count;
195 }
196
197 static ssize_t show_debounce_flag(struct device *dev, struct device_attribute *attr, char *buf)
198 {
199 if (!gpio_evmi)
200 return -ENODEV;
201
202 return snprintf(buf, PAGE_SIZE, "%u\n", (gpio_evmi->flags & GPIOKPF_DEBOUNCE) ? 1 : 0);
203 }
204
205 static ssize_t store_debounce_flag(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
206 {
207 unsigned flag;
208
209 if (!gpio_evmi)
210 return -ENODEV;
211
212 sscanf(buf, "%u", &flag);
213
214 if (flag) {
215 gpio_evmi->flags |= GPIOKPF_DEBOUNCE;
216 } else {
217 gpio_evmi->flags &= ~GPIOKPF_DEBOUNCE;
218 }
219
220 return count;
221 }
222
223 static ssize_t show_remove_some_phantom_keys_flag(struct device *dev, struct device_attribute *attr, char *buf)
224 {
225 if (!gpio_evmi)
226 return -ENODEV;
227
228 return snprintf(buf, PAGE_SIZE, "%u\n", (gpio_evmi->flags & GPIOKPF_REMOVE_SOME_PHANTOM_KEYS) ? 1 : 0);
229 }
230
231 static ssize_t store_remove_some_phantom_keys_flag(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
232 {
233 unsigned flag;
234
235 if (!gpio_evmi)
236 return -ENODEV;
237
238 sscanf(buf, "%u", &flag);
239
240 if (flag) {
241 gpio_evmi->flags |= GPIOKPF_REMOVE_SOME_PHANTOM_KEYS;
242 } else {
243 gpio_evmi->flags &= ~GPIOKPF_REMOVE_SOME_PHANTOM_KEYS;
244 }
245
246 return count;
247 }
248
249 static ssize_t show_print_unmapped_keys_flag(struct device *dev, struct device_attribute *attr, char *buf)
250 {
251 if (!gpio_evmi)
252 return -ENODEV;
253
254 return snprintf(buf, PAGE_SIZE, "%u\n", (gpio_evmi->flags & GPIOKPF_PRINT_UNMAPPED_KEYS) ? 1 : 0);
255 }
256
257 static ssize_t store_print_unmapped_keys_flag(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
258 {
259 unsigned flag;
260
261 if (!gpio_evmi)
262 return -ENODEV;
263
264 sscanf(buf, "%u", &flag);
265
266 if (flag) {
267 gpio_evmi->flags |= GPIOKPF_PRINT_UNMAPPED_KEYS;
268 } else {
269 gpio_evmi->flags &= ~GPIOKPF_PRINT_UNMAPPED_KEYS;
270 }
271
272 return count;
273 }
274
275 static ssize_t show_print_mapped_keys_flag(struct device *dev, struct device_attribute *attr, char *buf)
276 {
277 if (!gpio_evmi)
278 return -ENODEV;
279
280 return snprintf(buf, PAGE_SIZE, "%u\n", (gpio_evmi->flags & GPIOKPF_PRINT_MAPPED_KEYS) ? 1 : 0);
281 }
282
283 static ssize_t store_print_mapped_keys_flag(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
284 {
285 unsigned flag;
286
287 if (!gpio_evmi)
288 return -ENODEV;
289
290 sscanf(buf, "%u", &flag);
291
292 if (flag) {
293 gpio_evmi->flags |= GPIOKPF_PRINT_MAPPED_KEYS;
294 } else {
295 gpio_evmi->flags &= ~GPIOKPF_PRINT_MAPPED_KEYS;
296 }
297
298 return count;
299 }
300
301 static ssize_t show_print_phantom_keys_flag(struct device *dev, struct device_attribute *attr, char *buf)
302 {
303 if (!gpio_evmi)
304 return -ENODEV;
305
306 return snprintf(buf, PAGE_SIZE, "%u\n", (gpio_evmi->flags & GPIOKPF_PRINT_PHANTOM_KEYS) ? 1 : 0);
307 }
308
309 static ssize_t store_print_phantom_keys_flag(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
310 {
311 unsigned flag;
312
313 if (!gpio_evmi)
314 return -ENODEV;
315
316 sscanf(buf, "%u", &flag);
317
318 if (flag) {
319 gpio_evmi->flags |= GPIOKPF_PRINT_PHANTOM_KEYS;
320 } else {
321 gpio_evmi->flags &= ~GPIOKPF_PRINT_PHANTOM_KEYS;
322 }
323
324 return count;
325 }
326
327 static ssize_t show_active_high_flag(struct device *dev, struct device_attribute *attr, char *buf)
328 {
329 if (!gpio_evmi)
330 return -ENODEV;
331
332 return snprintf(buf, PAGE_SIZE, "%u\n", (gpio_evmi->flags & GPIOKPF_ACTIVE_HIGH) ? 1 : 0);
333 }
334
335 static ssize_t store_active_high_flag(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
336 {
337 unsigned flag;
338
339 if (!gpio_evmi)
340 return -ENODEV;
341
342 sscanf(buf, "%u", &flag);
343
344 if (flag) {
345 gpio_evmi->flags |= GPIOKPF_ACTIVE_HIGH;
346 } else {
347 gpio_evmi->flags &= ~GPIOKPF_ACTIVE_HIGH;
348 }
349
350 set_irq_types();
351
352 return count;
353 }
354
355 static ssize_t show_level_triggered_irq_flag(struct device *dev, struct device_attribute *attr, char *buf)
356 {
357 if (!gpio_evmi)
358 return -ENODEV;
359
360 return snprintf(buf, PAGE_SIZE, "%u\n", (gpio_evmi->flags & GPIOKPF_LEVEL_TRIGGERED_IRQ) ? 1 : 0);
361 }
362
363 static ssize_t store_level_triggered_irq_flag(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
364 {
365 unsigned flag;
366
367 if (!gpio_evmi)
368 return -ENODEV;
369
370 sscanf(buf, "%u", &flag);
371
372 if (flag) {
373 gpio_evmi->flags |= GPIOKPF_LEVEL_TRIGGERED_IRQ;
374 } else {
375 gpio_evmi->flags &= ~GPIOKPF_LEVEL_TRIGGERED_IRQ;
376 }
377
378 set_irq_types();
379
380 return count;
381 }
382
383 static ssize_t show_drive_inactive_flag(struct device *dev, struct device_attribute *attr, char *buf)
384 {
385 if (!gpio_evmi)
386 return -ENODEV;
387
388 return snprintf(buf, PAGE_SIZE, "%u\n", (gpio_evmi->flags & GPIOKPF_DRIVE_INACTIVE) ? 1 : 0);
389 }
390
391 static ssize_t store_drive_inactive_flag(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
392 {
393 unsigned flag;
394
395 if (!gpio_evmi)
396 return -ENODEV;
397
398 sscanf(buf, "%u", &flag);
399
400 if (flag) {
401 gpio_evmi->flags |= GPIOKPF_DRIVE_INACTIVE;
402 } else {
403 gpio_evmi->flags &= ~GPIOKPF_DRIVE_INACTIVE;
404 }
405
406 return count;
407 }
408
409 static ssize_t show_hw_debounce(struct device *dev, struct device_attribute *attr, char *buf)
410 {
411 return snprintf(buf, PAGE_SIZE, "%d\n", hw_debounce);
412 }
413
414 static ssize_t store_hw_debounce(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
415 {
416 int enable;
417
418 sscanf(buf, "%d", &enable);
419
420 if (enable) {
421 hw_debounce_set(1, -1);
422 hw_debounce = 1;
423 }
424 else {
425 hw_debounce_set(-1, 0);
426 hw_debounce_set(0, -1);
427 hw_debounce = 0;
428 hw_debounce_time = 0;
429 }
430
431 return count;
432 }
433
434 static ssize_t show_hw_debounce_time(struct device *dev, struct device_attribute *attr, char *buf)
435 {
436 return snprintf(buf, PAGE_SIZE, "%d\n", hw_debounce_time);
437 }
438
439 static ssize_t store_hw_debounce_time(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
440 {
441 int time;
442
443 sscanf(buf, "%d", &time);
444
445 if ((time < 0) || (time > 0xff))
446 return count;
447
448 if (!hw_debounce)
449 return count;
450
451 hw_debounce_set(-1, time);
452 hw_debounce_time = time;
453
454 return count;
455 }
456
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);
471
472 static void debounce_release(struct device *dev)
473 {
474 }
475
476 static struct device debounce_device = {
477 .init_name = "debounce",
478 .release = debounce_release,
479 };
480
481 static int __init debounce_init(void)
482 {
483 struct device *event_dev = NULL;
484 struct gpio_event_platform_data *gpio_epd;
485 struct gpio_event_info *gpio_ei;
486 int err = 0;
487
488 printk(KERN_INFO PREFIX "Searching for " GPIO_EVENT_DEV_NAME "...\n");
489
490 event_dev = device_find_child(&platform_bus, GPIO_EVENT_DEV_NAME, find_ms2_dev);
491 if (event_dev == NULL)
492 return -ENODEV;
493
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"))
497 return -ENODEV;
498
499 gpio_ei = (struct gpio_event_info*)gpio_epd->info[0];
500 gpio_evmi = container_of(gpio_ei, struct gpio_event_matrix_info, info);
501
502 err = device_register(&debounce_device);
503 if (err) {
504 return err;
505 }
506
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);
521
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);
526
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;
531
532 printk(KERN_INFO PREFIX "flags: 0x%x\n", gpio_evmi->flags);
533
534 return 0;
535 }
536
537 static void __exit debounce_exit(void)
538 {
539 if (gpio_evmi) {
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);
544 }
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);
549 set_irq_types();
550 }
551 gpio_evmi->settle_time = old_settle_time;
552 gpio_evmi->poll_time = old_poll_time;
553 }
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);
570 }
571
572 module_init(debounce_init);
573 module_exit(debounce_exit);
574
575 MODULE_LICENSE("GPL");
576 MODULE_AUTHOR("Michael Gernoth <michael@gernoth.net>");
Impressum, Datenschutz