add access to struct gpio_kp
[ms2-fixes] / debounce.c
CommitLineData
b422e333 1#include <linux/module.h>
d1ff9643
MG
2#include <linux/device.h>
3#include <linux/platform_device.h>
4#include <linux/gpio_event.h>
f4286301
MG
5#include <linux/interrupt.h>
6#include <linux/irq.h>
62a453fc 7#include <mach/gpio.h>
e2cecc6a
MG
8#include <linux/earlysuspend.h>
9#include <linux/wakelock.h>
62a453fc 10
ab5ed215
MG
11#define PREFIX "debounce: "
12
a4838b14 13static unsigned old_flags = 0;
29bad272
MG
14static ktime_t old_debounce_delay;
15static ktime_t old_settle_time;
16static ktime_t old_poll_time;
e063f9d5 17static int (*old_sw_fixup)(int index);
1e65c113 18static struct gpio_event_matrix_info *gpio_evmi = NULL;
29bad272
MG
19static int hw_debounce = 0;
20static int hw_debounce_time = 0;
1e65c113 21
e2cecc6a
MG
22struct 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
29struct 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
42static struct gpio_kp *gpio_kp_state = NULL;
43
ab5ed215 44static int find_ms2_dev(struct device *dev, void *data)
d1ff9643
MG
45{
46 if (!strncmp((char*)data, dev_name(dev), strlen((char*)data))) {
ab5ed215 47 printk(KERN_INFO PREFIX "Found it\n");
d1ff9643
MG
48 return 1;
49 }
50 return 0;
51}
b422e333 52
29bad272
MG
53/* hardware debounce: (time + 1) * 31us */
54static 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
308fc1a5 63 if ((time != -1) && (time != hw_debounce_time) && hw_debounce) {
5df3a8e0 64 printk(KERN_INFO PREFIX "Setting hardware debounce time for GPIO %d to %d (%dus)\n", gpio, time, (time+1)*31);
29bad272
MG
65 omap_set_gpio_debounce_time(gpio, time);
66 }
308fc1a5
MG
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 }
29bad272
MG
72 }
73}
74
f4286301
MG
75static 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}
29bad272 111
f7cb07b2
MG
112static 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
120static 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;
f7cb07b2
MG
125 printk(KERN_INFO PREFIX "debounce_delay: %u\n", gpio_evmi->debounce_delay.tv.nsec);
126 }
127
fc215caa 128#if 0
f7cb07b2
MG
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 }
fc215caa 140#endif
f7cb07b2
MG
141}
142
143static 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
fc215caa 153 return count;
f7cb07b2
MG
154}
155
156static 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
164static 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
fc215caa 174 return count;
f7cb07b2
MG
175}
176
177static 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
185static 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
fc215caa 195 return count;
f7cb07b2
MG
196}
197
198static 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
206static 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);
fc215caa
MG
214
215 printk(KERN_INFO PREFIX "flags: 0x%x\n", flags);
216
f7cb07b2
MG
217 gpio_evmi->flags = flags;
218
fc215caa
MG
219 return count;
220}
221
222static 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);
f7cb07b2
MG
228}
229
fc215caa
MG
230static 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
248static 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
256static 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
274static 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
282static 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
300static 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
308static 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
326static 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
334static 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
a2485674
MG
352static 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
360static 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
f4286301
MG
375 set_irq_types();
376
377 return count;
378}
379
380static 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
388static 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
a2485674
MG
405 return count;
406}
407
408static 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
416static 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
29bad272
MG
434static 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
439static 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 {
c0cd650e 450 hw_debounce_set(-1, 0);
29bad272
MG
451 hw_debounce_set(0, -1);
452 hw_debounce = 0;
c0cd650e 453 hw_debounce_time = 0;
29bad272
MG
454 }
455
456 return count;
457}
458
459static 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
464static 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
8440ec7c
MG
473 if (!hw_debounce)
474 return count;
475
29bad272
MG
476 hw_debounce_set(-1, time);
477 hw_debounce_time = time;
478
479 return count;
480}
481
fc215caa
MG
482static DEVICE_ATTR(debounce_delay, (S_IRUGO | S_IWUGO), show_debounce_delay, store_debounce_delay);
483static DEVICE_ATTR(settle_time, (S_IRUGO | S_IWUGO), show_settle_time, store_settle_time);
484static DEVICE_ATTR(poll_time, (S_IRUGO | S_IWUGO), show_poll_time, store_poll_time);
485static DEVICE_ATTR(flags, (S_IRUGO), show_flags, store_flags);
486static DEVICE_ATTR(debounce_flag, (S_IRUGO | S_IWUGO), show_debounce_flag, store_debounce_flag);
487static DEVICE_ATTR(remove_some_phantom_keys_flag, (S_IRUGO | S_IWUGO), show_remove_some_phantom_keys_flag, store_remove_some_phantom_keys_flag);
488static DEVICE_ATTR(print_unmapped_keys_flag, (S_IRUGO | S_IWUGO), show_print_unmapped_keys_flag, store_print_unmapped_keys_flag);
489static DEVICE_ATTR(print_mapped_keys_flag, (S_IRUGO | S_IWUGO), show_print_mapped_keys_flag, store_print_mapped_keys_flag);
490static DEVICE_ATTR(print_phantom_keys_flag, (S_IRUGO | S_IWUGO), show_print_phantom_keys_flag, store_print_phantom_keys_flag);
60fe4255 491static DEVICE_ATTR(active_high_flag, (S_IRUGO | S_IWUGO), show_active_high_flag, store_active_high_flag);
f4286301 492static DEVICE_ATTR(level_triggered_irq_flag, (S_IRUGO | S_IWUGO), show_level_triggered_irq_flag, store_level_triggered_irq_flag);
a2485674 493static DEVICE_ATTR(drive_inactive_flag, (S_IRUGO | S_IWUGO), show_drive_inactive_flag, store_drive_inactive_flag);
29bad272
MG
494static DEVICE_ATTR(hw_debounce, (S_IRUGO | S_IWUGO), show_hw_debounce, store_hw_debounce);
495static DEVICE_ATTR(hw_debounce_time, (S_IRUGO | S_IWUGO), show_hw_debounce_time, store_hw_debounce_time);
f7cb07b2 496
e063f9d5
MG
497#if 0
498static int debounce_fixup(int index)
499{
500 int ret;
501
e2cecc6a
MG
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);
e063f9d5
MG
506
507 ret = old_sw_fixup(index);
508 if (!ret)
e2cecc6a 509 printk(KERN_INFO PREFIX "Index 0x%x ignored!\n", index);
e063f9d5
MG
510
511 return ret;
512}
513#endif
514
f7cb07b2
MG
515static void debounce_release(struct device *dev)
516{
517}
518
519static struct device debounce_device = {
520 .init_name = "debounce",
521 .release = debounce_release,
522};
523
b422e333
MG
524static int __init debounce_init(void)
525{
d1ff9643 526 struct device *event_dev = NULL;
e2cecc6a 527 struct platform_device *pdev = NULL;
d1ff9643
MG
528 struct gpio_event_platform_data *gpio_epd;
529 struct gpio_event_info *gpio_ei;
e2cecc6a 530 struct gpio_event *gpio_e;
f7cb07b2 531 int err = 0;
e2cecc6a 532 int i;
d1ff9643 533
ab5ed215 534 printk(KERN_INFO PREFIX "Searching for " GPIO_EVENT_DEV_NAME "...\n");
d1ff9643
MG
535
536 event_dev = device_find_child(&platform_bus, GPIO_EVENT_DEV_NAME, find_ms2_dev);
537 if (event_dev == NULL)
538 return -ENODEV;
e2cecc6a
MG
539
540 pdev = container_of(event_dev, struct platform_device, dev);
541 if (pdev == NULL)
542 return -ENODEV;
543
d1ff9643 544 gpio_epd = (struct gpio_event_platform_data*)event_dev->platform_data;
ab5ed215 545 printk(KERN_INFO PREFIX "And there is a %s connected...\n", gpio_epd->name);
d1ff9643
MG
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
e2cecc6a
MG
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
f7cb07b2
MG
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);
fc215caa
MG
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);
a2485674 589 err = device_create_file(&debounce_device, &dev_attr_active_high_flag);
f4286301 590 err = device_create_file(&debounce_device, &dev_attr_level_triggered_irq_flag);
a2485674 591 err = device_create_file(&debounce_device, &dev_attr_drive_inactive_flag);
29bad272
MG
592 err = device_create_file(&debounce_device, &dev_attr_hw_debounce);
593 err = device_create_file(&debounce_device, &dev_attr_hw_debounce_time);
f7cb07b2 594
ab5ed215
MG
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);
20bf1c9e 599
bb65757a
MG
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;
e063f9d5 604 old_sw_fixup = gpio_evmi->sw_fixup;
1e65c113 605
e063f9d5
MG
606#if 0
607 printk(KERN_INFO PREFIX "Registering fixup handler\n");
608 gpio_evmi->sw_fixup = debounce_fixup;
609#endif
a4838b14 610
b422e333
MG
611 return 0;
612}
613
614static void __exit debounce_exit(void)
615{
1e65c113 616 if (gpio_evmi) {
bb65757a 617 if (gpio_evmi->debounce_delay.tv.nsec != old_debounce_delay.tv.nsec) {
1e65c113 618 printk(KERN_INFO PREFIX "Restoring debounce_delay\n");
bb65757a 619 gpio_evmi->debounce_delay = old_debounce_delay;
1e65c113
MG
620 printk(KERN_INFO PREFIX "debounce_delay: %u\n", gpio_evmi->debounce_delay.tv.nsec);
621 }
a4838b14
MG
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);
f4286301 626 set_irq_types();
a4838b14 627 }
bb65757a
MG
628 gpio_evmi->settle_time = old_settle_time;
629 gpio_evmi->poll_time = old_poll_time;
e063f9d5
MG
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 }
1e65c113 635 }
29bad272 636 hw_debounce_set(0, 0);
f7cb07b2
MG
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);
fc215caa
MG
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);
a2485674 646 device_remove_file(&debounce_device, &dev_attr_active_high_flag);
f4286301 647 device_remove_file(&debounce_device, &dev_attr_level_triggered_irq_flag);
a2485674 648 device_remove_file(&debounce_device, &dev_attr_drive_inactive_flag);
29bad272
MG
649 device_remove_file(&debounce_device, &dev_attr_hw_debounce);
650 device_remove_file(&debounce_device, &dev_attr_hw_debounce_time);
f7cb07b2 651 device_unregister(&debounce_device);
b422e333
MG
652}
653
654module_init(debounce_init);
655module_exit(debounce_exit);
656
657MODULE_LICENSE("GPL");
658MODULE_AUTHOR("Michael Gernoth <michael@gernoth.net>");
Impressum, Datenschutz