diff options
Diffstat (limited to 'evdevtest/kernel_module/juice_input_test_module.c')
-rw-r--r-- | evdevtest/kernel_module/juice_input_test_module.c | 166 |
1 files changed, 166 insertions, 0 deletions
diff --git a/evdevtest/kernel_module/juice_input_test_module.c b/evdevtest/kernel_module/juice_input_test_module.c new file mode 100644 index 0000000..6472d7f --- /dev/null +++ b/evdevtest/kernel_module/juice_input_test_module.c @@ -0,0 +1,166 @@ +/******************************************************************************* + * Copyright (c) 2013 Linaro + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Linaro <linaro-dev@lists.linaro.org> + * + * Test module for test new evdev ioctl commands: + * EVIOCGSUSPENDBLOCK, EVIOCSSUSPENDBLOCK, EVIOCSCLOCKID + */ + +#include <linux/module.h> +#include <linux/init.h> +#include <linux/input.h> +#include <linux/delay.h> +#include <linux/workqueue.h> + +MODULE_AUTHOR("Bintian Wang <bintian.wang@linaro.org>"); +MODULE_DESCRIPTION("Linaro Juice ioctl evdev test"); +MODULE_LICENSE("GPL"); + +static unsigned char juice_keycode[10] = { + [0] = KEY_1, + [1] = KEY_2, + [2] = KEY_3, + [3] = KEY_4, + [4] = KEY_5, + [5] = KEY_6, + [6] = KEY_7, + [7] = KEY_8, + [8] = KEY_9, + [9] = KEY_0, +}; + +static struct input_dev *juice_testkbd; + +static unsigned int run = 0; +static unsigned int interval = 500; /*Defualt interval for reporting key to up layer*/ + +struct workqueue_struct *juice_kbd_wq; + +struct kobject *juice_sys; + +static void juice_key_report(struct work_struct *work) +{ + while(1) + { + if(run) + { + /*For test, just report KEY8 and KEY_9 here*/ + input_report_key(juice_testkbd, KEY_8, 1); + input_report_key(juice_testkbd, KEY_8, 0); + input_report_key(juice_testkbd, KEY_9, 1); + input_report_key(juice_testkbd, KEY_9, 0); + input_sync(juice_testkbd); + msleep(interval); + } else { + break; + } + } +} + +static DECLARE_WORK(juice_kbd_wk, &juice_key_report); + +static ssize_t run_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + return sprintf(buf, "%d \n", run); +} + +static ssize_t run_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t count) +{ + int err; + + err = kstrtouint(buf, 10, &run); + if (err) + return err; + + if(1 == run) + queue_work(juice_kbd_wq, &juice_kbd_wk); + + return count; +} + +static ssize_t interval_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + return sprintf(buf, "%d ms \n", interval); +} + +static ssize_t interval_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t count) +{ + int err; + + err = kstrtouint(buf, 10, &interval); + if (err) + return err; + + if (interval > 1000) + interval = 1000; + + return count; +} + +static struct kobj_attribute run_attr = + __ATTR(run, 0777, run_show, run_store); + +static struct kobj_attribute interval_attr = + __ATTR(interval, 0777, interval_show, interval_store); + + +static int __init juice_testkbd_init(void) +{ + int i, error; + + juice_testkbd = input_allocate_device(); + if (!juice_testkbd) + return -ENOMEM; + + juice_testkbd->name = "Juice EVDEV Test Module"; + + juice_testkbd->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); + juice_testkbd->keycode = juice_keycode; + juice_testkbd->keycodesize = sizeof(unsigned char); + juice_testkbd->keycodemax = ARRAY_SIZE(juice_keycode); + + for (i = 0; i < 10; i++) + set_bit(juice_keycode[i], juice_testkbd->keybit); + + error = input_register_device(juice_testkbd); + if (error) { + input_free_device(juice_testkbd); + return error; + } + + juice_kbd_wq = create_workqueue("juice_input_test_wq"); + + juice_sys = kobject_create_and_add("juice_input", NULL); + if (!juice_sys) + return -ENOMEM; + + sysfs_create_file(juice_sys, &run_attr.attr); + + sysfs_create_file(juice_sys, &interval_attr.attr); + + return 0; +} + +static void __exit juice_testkbd_exit(void) +{ + sysfs_remove_file(juice_sys, &run_attr.attr); + sysfs_remove_file(juice_sys, &interval_attr.attr); + kobject_del(juice_sys); + + flush_workqueue(juice_kbd_wq); + destroy_workqueue(juice_kbd_wq); + juice_kbd_wq = NULL; + + input_unregister_device(juice_testkbd); +} + +module_init(juice_testkbd_init); +module_exit(juice_testkbd_exit); |