X-Git-Url: https://git.zerfleddert.de/cgi-bin/gitweb.cgi/ms2-fixes/blobdiff_plain/1e0dcc40cee8b59f87f00f85081ed889609fd62e..6d3e36335a1698d23c626b7c756f2d03fcfd85b9:/debounce.c diff --git a/debounce.c b/debounce.c index 029ff91..d59f10a 100644 --- a/debounce.c +++ b/debounce.c @@ -2,6 +2,10 @@ #include #include #include +#include + +/* hardware debounce: (value + 1) * 31us */ +#define GPIO_DEBOUNCE_TIME 0x1 #define PREFIX "debounce: " @@ -125,9 +129,6 @@ static ssize_t store_flags(struct device *dev, struct device_attribute *attr, co printk(KERN_INFO PREFIX "flags: 0x%x\n", flags); - if (flags & GPIOKPF_DRIVE_INACTIVE) - return count; - gpio_evmi->flags = flags; return count; @@ -263,6 +264,58 @@ static ssize_t store_print_phantom_keys_flag(struct device *dev, struct device_a return count; } +static ssize_t show_active_high_flag(struct device *dev, struct device_attribute *attr, char *buf) +{ + if (!gpio_evmi) + return -ENODEV; + + return snprintf(buf, PAGE_SIZE, "%u\n", (gpio_evmi->flags & GPIOKPF_ACTIVE_HIGH) ? 1 : 0); +} + +static ssize_t store_active_high_flag(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +{ + unsigned flag; + + if (!gpio_evmi) + return -ENODEV; + + sscanf(buf, "%u", &flag); + + if (flag) { + gpio_evmi->flags |= GPIOKPF_ACTIVE_HIGH; + } else { + gpio_evmi->flags &= ~GPIOKPF_ACTIVE_HIGH; + } + + return count; +} + +static ssize_t show_drive_inactive_flag(struct device *dev, struct device_attribute *attr, char *buf) +{ + if (!gpio_evmi) + return -ENODEV; + + return snprintf(buf, PAGE_SIZE, "%u\n", (gpio_evmi->flags & GPIOKPF_DRIVE_INACTIVE) ? 1 : 0); +} + +static ssize_t store_drive_inactive_flag(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +{ + unsigned flag; + + if (!gpio_evmi) + return -ENODEV; + + sscanf(buf, "%u", &flag); + + if (flag) { + gpio_evmi->flags |= GPIOKPF_DRIVE_INACTIVE; + } else { + gpio_evmi->flags &= ~GPIOKPF_DRIVE_INACTIVE; + } + + return count; +} + static DEVICE_ATTR(debounce_delay, (S_IRUGO | S_IWUGO), show_debounce_delay, store_debounce_delay); static DEVICE_ATTR(settle_time, (S_IRUGO | S_IWUGO), show_settle_time, store_settle_time); static DEVICE_ATTR(poll_time, (S_IRUGO | S_IWUGO), show_poll_time, store_poll_time); @@ -272,6 +325,8 @@ static DEVICE_ATTR(remove_some_phantom_keys_flag, (S_IRUGO | S_IWUGO), show_remo static DEVICE_ATTR(print_unmapped_keys_flag, (S_IRUGO | S_IWUGO), show_print_unmapped_keys_flag, store_print_unmapped_keys_flag); static DEVICE_ATTR(print_mapped_keys_flag, (S_IRUGO | S_IWUGO), show_print_mapped_keys_flag, store_print_mapped_keys_flag); static DEVICE_ATTR(print_phantom_keys_flag, (S_IRUGO | S_IWUGO), show_print_phantom_keys_flag, store_print_phantom_keys_flag); +static DEVICE_ATTR(active_high_flag, (S_IRUGO), show_active_high_flag, store_active_high_flag); +static DEVICE_ATTR(drive_inactive_flag, (S_IRUGO | S_IWUGO), show_drive_inactive_flag, store_drive_inactive_flag); static void debounce_release(struct device *dev) { @@ -282,6 +337,28 @@ static struct device debounce_device = { .release = debounce_release, }; +static unsigned int mapphone_col_gpios[] = { 43, 53, 54, 55, 56, 57, 58, 63 }; +static unsigned int mapphone_row_gpios[] = { 34, 35, 36, 37, 38, 39, 40, 41 }; + +static void hw_debounce_pin(int gpio, int enable) { + printk(KERN_INFO PREFIX "%sabling hardware debounce for GPIO %d\n", (enable?"En":"Dis"), gpio); + if (enable) + omap_set_gpio_debounce_time(gpio, GPIO_DEBOUNCE_TIME); + omap_set_gpio_debounce(gpio, enable); +} + +static void hw_debounce(int enable) { + int i; + + for (i = 0; i < (sizeof(mapphone_col_gpios) / sizeof(mapphone_col_gpios[0])); i++) { + hw_debounce_pin(mapphone_col_gpios[i], enable); + } + + for (i = 0; i < (sizeof(mapphone_row_gpios) / sizeof(mapphone_row_gpios[0])); i++) { + hw_debounce_pin(mapphone_row_gpios[i], enable); + } +} + static int __init debounce_init(void) { struct device *event_dev = NULL; @@ -308,6 +385,8 @@ static int __init debounce_init(void) return err; } + hw_debounce(1); + err = device_create_file(&debounce_device, &dev_attr_debounce_delay); err = device_create_file(&debounce_device, &dev_attr_settle_time); err = device_create_file(&debounce_device, &dev_attr_poll_time); @@ -317,6 +396,8 @@ static int __init debounce_init(void) err = device_create_file(&debounce_device, &dev_attr_print_unmapped_keys_flag); err = device_create_file(&debounce_device, &dev_attr_print_mapped_keys_flag); err = device_create_file(&debounce_device, &dev_attr_print_phantom_keys_flag); + err = device_create_file(&debounce_device, &dev_attr_active_high_flag); + err = device_create_file(&debounce_device, &dev_attr_drive_inactive_flag); printk(KERN_INFO PREFIX "settle_time: %u\n", gpio_evmi->settle_time.tv.nsec); printk(KERN_INFO PREFIX "poll_time: %u\n", gpio_evmi->poll_time.tv.nsec); @@ -349,6 +430,7 @@ static void __exit debounce_exit(void) gpio_evmi->settle_time = old_settle_time; gpio_evmi->poll_time = old_poll_time; } + hw_debounce(0); device_remove_file(&debounce_device, &dev_attr_debounce_delay); device_remove_file(&debounce_device, &dev_attr_settle_time); device_remove_file(&debounce_device, &dev_attr_poll_time); @@ -358,6 +440,8 @@ static void __exit debounce_exit(void) device_remove_file(&debounce_device, &dev_attr_print_unmapped_keys_flag); device_remove_file(&debounce_device, &dev_attr_print_mapped_keys_flag); device_remove_file(&debounce_device, &dev_attr_print_phantom_keys_flag); + device_remove_file(&debounce_device, &dev_attr_active_high_flag); + device_remove_file(&debounce_device, &dev_attr_drive_inactive_flag); device_unregister(&debounce_device); }