Skip to content

Instantly share code, notes, and snippets.

@ivanbrennan
Created February 10, 2018 22:09
Show Gist options
  • Save ivanbrennan/680c69ac311a4f2b6826b86a12b0c8a4 to your computer and use it in GitHub Desktop.
Save ivanbrennan/680c69ac311a4f2b6826b86a12b0c8a4 to your computer and use it in GitHub Desktop.
#include <linux/module.h>
#include <linux/serio.h>
#include <linux/vmalloc.h>
#include <linux/i8042.h>
// Simplified i8042 key filter for example purposes
struct key_data {
bool is_pressed;
unsigned long updated_at;
};
#define NUM_KEYS 128
#define SIZEOF_KEYS (sizeof(struct key_data) * NUM_KEYS)
static struct key_data *keys;
#define KEYUP_MASK 0x80 // High bit: 1 (keyup), 0 (keydown)
#define KEYID_MASK 0x7f // Remaining 7 bits: which key
static bool foo_filter(unsigned char data, unsigned char str, struct serio *serio) {
struct key_data *key;
key = keys + (data & KEYID_MASK);
key->is_pressed = !(data & KEYUP_MASK);
key->updated_at = jiffies;
return false; // let event flow through
}
static int __init foo_init(void) {
int ret, err;
ret = i8042_install_filter(foo_filter);
if (ret) {
pr_err("Unable to install key filter\n");
err = -EBUSY;
goto err_filter;
}
keys = vmalloc(SIZEOF_KEYS);
if (!keys) {
pr_err("Unable to allocate memory\n");
err = -ENOMEM;
goto err_mem;
}
memset(keys, 0x00, SIZEOF_KEYS);
pr_info("foo init\n");
return 0;
err_mem:
i8042_remove_filter(foo_filter);
err_filter:
return err;
}
static void __exit foo_exit(void) {
i8042_remove_filter(foo_filter);
vfree(keys);
pr_info("foo exit\n");
}
module_init(i8042_debounce_init);
module_exit(i8042_debounce_exit);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment