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