summaryrefslogtreecommitdiff
path: root/evdevtest/kernel_module/juice_input_test_module.c
diff options
context:
space:
mode:
Diffstat (limited to 'evdevtest/kernel_module/juice_input_test_module.c')
-rw-r--r--evdevtest/kernel_module/juice_input_test_module.c166
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);