summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBintian Wang <bintian.wang@linaro.org>2013-07-17 00:37:53 +0800
committerBintian Wang <bintian.wang@linaro.org>2013-07-17 00:37:53 +0800
commit199e6f6bed4b08f4f20f7e9a8587e7cbd339630f (patch)
treefb2f009de702b56aa856780257a3060796c448a4
parent96a4aa362c19afb29a56b6f134fc7c94e363f1da (diff)
downloadlinaro-android-kernel-test-199e6f6bed4b08f4f20f7e9a8587e7cbd339630f.tar.gz
Add input evdev test cases
Signed-off-by: Bintian Wang <bintian.wang@linaro.org>
-rw-r--r--Makefile2
-rw-r--r--evdevtest/Android.mk9
-rw-r--r--evdevtest/Makefile26
-rw-r--r--evdevtest/juice_evtest.c458
-rw-r--r--evdevtest/juice_evtest.sh27
-rw-r--r--evdevtest/kernel_module/Makefile11
-rw-r--r--evdevtest/kernel_module/juice_input_test_module.c166
-rwxr-xr-xlinaro-android-kernel-tests.sh11
-rw-r--r--product.mk4
9 files changed, 711 insertions, 3 deletions
diff --git a/Makefile b/Makefile
index b8d222e..e10781e 100644
--- a/Makefile
+++ b/Makefile
@@ -9,7 +9,7 @@
# Linaro <linaro-dev@lists.linaro.org>
#############################################################################
-DIRS = alarmdevtest ashmemtest-basic ashmemtest-expanded logger #sync-basic does not build atm
+DIRS = alarmdevtest ashmemtest-basic ashmemtest-expanded logger evdevtest #sync-basic does not build atm
CLEANDIRS = $(foreach dir,$(DIRS),clean-$(dir))
.PHONY: all clean $(DIRS) $(CLEANDIRS)
diff --git a/evdevtest/Android.mk b/evdevtest/Android.mk
new file mode 100644
index 0000000..1d74d14
--- /dev/null
+++ b/evdevtest/Android.mk
@@ -0,0 +1,9 @@
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+include $(LOCAL_PATH)/kernel_module/Makefile
+$(PRODUCT_OUT)/system/bin/juice_evtest: evdevtest_driver
+LOCAL_SRC_FILES := juice_evtest.c
+LOCAL_MODULE := juice_evtest
+LOCAL_MODULE_TAGS := optional tests
+
+include $(BUILD_EXECUTABLE)
diff --git a/evdevtest/Makefile b/evdevtest/Makefile
new file mode 100644
index 0000000..e006ac9
--- /dev/null
+++ b/evdevtest/Makefile
@@ -0,0 +1,26 @@
+#############################################################################
+# 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>
+#############################################################################
+
+CC = $(CROSS_COMPILE)gcc
+CFLAGS = -O2 -g
+EXE = juice_evtest
+Q = @
+
+$(EXE): juice_evtest.c
+ @echo -ne "\tCC\t"
+ @echo $<
+ $(Q)$(CC) $(CFLAGS) -I. -o $@ $< -lrt
+ $(MAKE) -C kernel_module
+
+clean:
+ @echo -ne "\tRM\t"
+ @echo $(EXE)
+ $(Q)$(RM) $(EXE)
diff --git a/evdevtest/juice_evtest.c b/evdevtest/juice_evtest.c
new file mode 100644
index 0000000..f421a61
--- /dev/null
+++ b/evdevtest/juice_evtest.c
@@ -0,0 +1,458 @@
+#include <linux/input.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <getopt.h>
+#include <errno.h>
+#include <time.h>
+
+#define DELAY 10
+#define CLOCK_REALTIME_ALARM 8
+#define CLOCK_BOOTTIME_ALARM 9
+
+static int suspend_resume_test(int seconds)
+{
+// struct timespec now, target, latest;
+ int ret;
+ int pm_state_fd;
+ int len, n;
+ char buf[32];
+ timer_t timerid;
+ struct itimerspec its;
+ struct timespec t1, t2;
+
+ if (seconds < 6) {
+ printf("Please input suspend time more than 4 seconds!\n");
+ return -1;
+ }
+
+ ret = timer_create(CLOCK_REALTIME_ALARM, NULL, &timerid);
+ if (-1 == ret) {
+// printf("Create alarm timer failed!\n");
+ return -1;
+ }
+
+ if(clock_gettime(CLOCK_REALTIME_ALARM, &its.it_value))
+ return -1;
+
+ its.it_value.tv_sec += seconds;
+
+ ret = timer_settime(timerid, TIMER_ABSTIME, &its, NULL);
+ if (-1 == ret) {
+// perror("Set alarm timer failed!\n");
+ return -1;
+ }
+
+ ret = clock_gettime(CLOCK_REALTIME, &t1);
+ if (-1 == ret) {
+// perror("Get the suspend start time failed\n");
+ return -1;
+ }
+
+#if 0
+ fd = open("/dev/alarm", O_RDWR);
+ if (fd < 0) {
+ printf("Open /dev/alarm failed!\n");
+ return -1;
+ }
+
+ ret = ioctl(fd, ANDROID_ALARM_GET_TIME(ANDROID_ALARM_RTC_WAKEUP), &now);
+ if (ret < 0) {
+ printf("Get time failed!\n");
+ close(fd);
+ return -1;
+ }
+
+ target = now;
+ target.tv_sec += seconds;
+
+ ret = ioctl(fd, ANDROID_ALARM_SET(ANDROID_ALARM_RTC_WAKEUP), &target);
+ if (ret < 0) {
+ printf("Set time failed:");
+ if (errno == EBUSY)
+ printf("Android using this alarm ANDROID_ALARM_RTC_WAKEUP!\n");
+ close(fd);
+ return -1;
+ }
+#endif
+
+ /*start suspend the system now*/
+ pm_state_fd = open("/sys/power/state", O_WRONLY);
+ if (pm_state_fd < 0) {
+// printf("Open /sys/power/state failed!\n");
+ return -1;
+ }
+ sprintf(buf, "%s\n", "mem");
+ len = strlen(buf);
+ n = write(pm_state_fd, buf, len);
+ if (n < 0 || n != len) {
+// printf("Write /sys/power/state failed!\n");
+ close(pm_state_fd);
+ return -1;
+ }
+#if 0
+ /*Get the time after the system resume*/
+ ret = ioctl(fd, ANDROID_ALARM_GET_TIME(ANDROID_ALARM_RTC_WAKEUP), &latest);
+ if (ret < 0) {
+ printf("Get time again failed!\n");
+ close(fd);
+ close(pm_state_fd);
+ return -1;
+ }
+
+ /*judge if the system suspend/resume works well */
+ if (latest.tv_sec - now.tv_sec >= seconds) {
+ close(fd);
+ close(pm_state_fd);
+ return 0;
+ } else {
+ close(fd);
+ close(pm_state_fd);
+ return 1;
+ }
+#endif
+ close(pm_state_fd);
+ /*Maybe need sleep here for several seconds to wait system to suspend itself!!!!*/
+ /*
+ *
+ *
+ */
+ ret = clock_gettime(CLOCK_REALTIME, &t2);
+ if (-1 == ret) {
+// printf("Get the suspend start time failed\n");
+ return -1;
+ }
+
+ if (t2.tv_sec - t1.tv_sec >= seconds)
+ return 0;
+ else
+ return 1;
+}
+
+int main (int argc, char **argv)
+{
+ struct option lopt[] = {
+ { "path", required_argument, NULL, 'p' },
+ { "help", no_argument, NULL, 'h' },
+ { NULL, 0, NULL, 0 },
+ };
+
+ char parameter1=0;
+ int parameter2=0;
+ long long parameter3=0;
+
+ char * shopt = "p:h";
+ char *evdevice = NULL;
+ long enable_lock=1, disable_lock=0, lockvalue = -1;
+ int fd, fd_evdev_run;
+ int c, opti = 0;
+ int ret, len, n;
+ char buf[32];
+ unsigned int clk;
+ struct input_event ev[64];
+ struct timespec tp1, tp2;
+
+ if(getuid()) {
+ perror("Need run this test as root!\n");
+ return -1;
+ }
+
+ while ((c = getopt_long(argc, argv, shopt, lopt, &opti)) != -1 ) {
+ switch (c) {
+ case 'h':
+ fprintf(stdout, "Userage:\n" "juice_evtest -p /dev/input/eventX \n");
+ break;
+ case 'p':
+ evdevice = strdup(optarg);
+ break;
+ default:
+ perror("Warning, unknown option!\n");
+ break;
+ }
+ }
+
+ if (!evdevice) {
+ perror("You need to input the event input device!\n");
+ return -1;
+ }
+
+ /*Open the evdev input device*/
+ if ((fd = open(evdevice, O_RDONLY)) < 0) {
+ perror("Open input device failed, please check it!\n");
+ return -1;
+ }
+
+
+ printf("===========================\n");
+ printf("Starting evdev ioctl cmd EVIOCGSUSPENDBLOCK/EVIOCCSUSPENDBLOCK test:\n");
+ /* Read lock command */
+ if (ioctl(fd, EVIOCGSUSPENDBLOCK, &lockvalue))
+ printf("[EVDEV EVIOCGSUSPENDBLOCK READ TEST1] FAIL\n");
+ else
+ printf("[EVDEV EVIOCGSUSPENDBLOCK READ TEST1] PASS\n");
+
+ if (0 == lockvalue) /*default lock value*/
+ printf("[EVDEV TEST2] PASS\n");
+ else
+ printf("[EVDEV TEST2] FAIL\n");
+
+ /*Set user_wake_lock*/
+ if (ioctl(fd, EVIOCSSUSPENDBLOCK, enable_lock))
+ printf("[EVDEV EVIOCSSUSPENDBLOCK SET TEST3] FAIL\n");
+ else
+ printf("[EVDEV EVIOCSSUSPENDBLOCK SET TEST3] PASS\n");
+
+ /*Verfify the lock value equals what we set before*/
+ if (ioctl(fd, EVIOCGSUSPENDBLOCK, &lockvalue))
+ perror("[EVDEV READ user_wake_lock value] FAIL\n");
+
+ if (enable_lock == lockvalue)
+ printf("[EVDEV TEST4] PASS\n");
+ else {
+ printf("[EVDEV TEST4] FAIL\n");
+ goto para_test;
+ }
+
+ if ((fd_evdev_run = open("/sys/juice_input/run", O_WRONLY)) < 0) {
+ perror("[EVDEV OPEN SYS RUN] FAIL\n");
+ perror("Please check input kernel test module!\n");
+ goto para_test;
+ } else {
+ sprintf(buf, "%d\n", 1);
+ len = strlen(buf);
+ n = write(fd_evdev_run, buf, len);
+ if (n < 0 || n != len)
+ perror("Write /sys/juice_input/run failed!\n");
+
+ close(fd_evdev_run);
+ }
+ /*Judge the system can not be suspend*/
+ ret = suspend_resume_test(DELAY);
+ if (1 == ret)
+ printf("[EVDEV CMD DISABLE SUSPEND TEST5] PASS\n");
+ else
+ printf("[EVDEV CMD DISABLE SUSPEND TEST5] FAIL\n");
+
+ /*Disable evdev usr_wake_lock*/
+ ioctl(fd, EVIOCSSUSPENDBLOCK, disable_lock);
+ ioctl(fd, EVIOCGSUSPENDBLOCK, &lockvalue);
+ if ( disable_lock == lockvalue)
+ printf("[EVDEV TEST6] PASS\n");
+ else
+ printf("[EVDEV TEST6] FAIL\n");
+
+ /*Judge the system can be suspend resume*/
+ ret = suspend_resume_test(DELAY);
+ if (0 == ret)
+ printf("[EVDEV ENABLE SUSPEND/RESUME TEST7] PASS\n");
+ else
+ printf("[EVDEV ENABLE SUSPEND/RESUME TEST7] FAIL\n");
+
+ if ((fd_evdev_run = open("/sys/juice_input/run", O_WRONLY)) < 0) {
+ perror("[EVDEV OPEN SYS RUN] FAIL\n");
+ goto para_test;
+ } else {
+ sprintf(buf, "%d\n", 0);
+ len = strlen(buf);
+ n = write(fd_evdev_run, buf, len);
+ if (n < 0 || n != len)
+ perror("Write /sys/juice_input/run failed!\n");
+
+ close(fd_evdev_run);
+ }
+
+
+para_test:
+ /*The following is the test cases for verifying different parameters*/
+ /* Null parameters test!*/
+ printf("Starting test EVIOCGSUSPENDBLOCK/EVIOCSSUSPENDBLOCK with different parameters:\n");
+ ret = ioctl(fd, EVIOCGSUSPENDBLOCK);
+ if (ret == -1)
+ printf("[EVDEV TEST8] PASS\n");
+ else
+ printf("[EVDEV TEST8] FAIL\n");
+
+ ret = ioctl(fd, EVIOCSSUSPENDBLOCK);
+ if (!ret)
+ printf("[EVDEV TEST9] PASS\n");
+ else
+ printf("[EVDEV TEST9] FAIL\n");
+
+ /* byte parameters test*/
+ ret = ioctl(fd, EVIOCGSUSPENDBLOCK, &parameter1);
+ if (!ret)
+ printf("[EVDEV TEST10] PASS\n");
+ else
+ printf("[EVDEV TEST10] FAIL\n");
+
+ ret = ioctl(fd, EVIOCSSUSPENDBLOCK, parameter1);
+ if (!ret)
+ printf("[EVDEV TEST11] PASS\n");
+ else
+ printf("[EVDEV TEST11] FAIL\n");
+
+ /* int parameters test*/
+ ret = ioctl(fd, EVIOCGSUSPENDBLOCK, &parameter2);
+ if (!ret)
+ printf("[EVDEV TEST12] PASS\n");
+ else
+ printf("[EVDEV TEST12] FAIL\n");
+
+ ret = ioctl(fd, EVIOCSSUSPENDBLOCK, parameter2);
+ if (!ret)
+ printf("[EVDEV TEST13] PASS\n");
+ else
+ printf("[EVDEV TEST13] FAIL\n");
+
+ /* 64bit parameters test*/
+ ret = ioctl(fd, EVIOCGSUSPENDBLOCK, &parameter3);
+ if (!ret)
+ printf("[EVDEV TEST14] PASS\n");
+ else
+ printf("[EVDEV TEST14] FAIL\n");
+
+ ret = ioctl(fd, EVIOCSSUSPENDBLOCK, parameter3);
+ if (!ret)
+ printf("[EVDEV TEST15] PASS\n");
+ else
+ printf("[EVDEV TEST15] FAIL\n");
+
+
+/*EVIOCSCLOCKID test*/
+ printf("Starting EVIOCSCLOCKID test:\n");
+ clk = CLOCK_REALTIME_ALARM;
+ ret = ioctl(fd, EVIOCSCLOCKID, &clk);
+ if (ret < 0)
+ printf("[EVDEV TEST16] PASS\n");
+ else
+ printf("[EVDEV TEST16] FAIL\n");
+ clk = CLOCK_BOOTTIME;
+ ret = ioctl(fd, EVIOCSCLOCKID, &clk);
+ if (ret < 0)
+ printf("[EVDEV TEST17] PASS\n");
+ else
+ printf("[EVDEV TEST17] FAIL\n");
+
+ ret = ioctl(fd, EVIOCSCLOCKID);
+ if (ret < 0)
+ printf("[EVDEV TEST18] PASS\n");
+ else
+ printf("[EVDEV TEST18] FAIL\n");
+
+/*EVIOCSCLOCKID & CLOCK_REALTIME test*/
+ clk = CLOCK_REALTIME;
+ ret = ioctl(fd, EVIOCSCLOCKID, &clk);
+ if (ret < 0)
+ printf("[EVDEV TEST19] FAIL\n");
+ else
+ printf("[EVDEV TEST19] PASS\n");
+
+ /*Start generate event here!*/
+ if ((fd_evdev_run = open("/sys/juice_input/run", O_WRONLY)) < 0) {
+ perror("[EVDEV OPEN SYS RUN] FAIL\n");
+ goto finish;
+ } else {
+ sprintf(buf, "%d\n", 1);
+ len = strlen(buf);
+ n = write(fd_evdev_run, buf, len);
+ if (n < 0 || n != len)
+ perror("Write /sys/juice_input/run failed!\n");
+
+ close(fd_evdev_run);
+ }
+
+ ret = clock_gettime(CLOCK_REALTIME, &tp1);
+ if (ret < 0)
+ perror("Clock MONOTONIC gettime1 FAILED\n");
+
+ /*Get event here!*/
+ ret = read(fd, ev, sizeof(struct input_event));
+ if (ret < (int) sizeof(struct input_event))
+ perror("evtest: error reading\n");
+
+ ret = clock_gettime(CLOCK_REALTIME, &tp2);
+ if (ret < 0)
+ perror("Clock MONOTONIC gettime2 FAILED\n");
+
+ if (tp1.tv_sec <= ev[0].time.tv_sec && ev[0].time.tv_sec <= tp2.tv_sec)
+ printf("[EVDEV TEST20] PASS\n");
+ else
+ printf("[EVDEV TEST20] FAIL\n");
+
+ if ((fd_evdev_run = open("/sys/juice_input/run", O_WRONLY)) < 0) {
+ perror("[EVDEV OPEN SYS RUN] FAIL\n");
+ goto finish;
+ } else {
+ sprintf(buf, "%d\n", 0);
+ len = strlen(buf);
+ n = write(fd_evdev_run, buf, len);
+ if (n < 0 || n != len)
+ perror("Write /sys/juice_input/run failed!\n");
+ close(fd_evdev_run);
+ }
+
+/*EVIOCSCLOCKID & CLOCK_MONOTONIC test*/
+ close(fd);
+ if ((fd = open(evdevice, O_RDONLY)) < 0) {
+ perror("Test is not finished but exit!\n");
+ return -1;
+ }
+
+ clk = CLOCK_MONOTONIC;
+ ret = ioctl(fd, EVIOCSCLOCKID, &clk);
+ if (ret < 0)
+ printf("[EVDEV TEST21] FAIL\n");
+ else
+ printf("[EVDEV TEST21] PASS\n");
+
+ if ((fd_evdev_run = open("/sys/juice_input/run", O_WRONLY)) < 0) {
+ perror("[EVDEV OPEN SYS RUN] FAIL\n");
+ goto finish;
+ } else {
+ sprintf(buf, "%d\n", 1);
+ len = strlen(buf);
+ n = write(fd_evdev_run, buf, len);
+ if (n < 0 || n != len)
+ perror("Write /sys/juice_input/run failed!\n");
+ close(fd_evdev_run);
+ }
+
+ ret = clock_gettime(CLOCK_MONOTONIC, &tp1);
+ if (ret < 0)
+ perror("Clock MONOTONIC gettime1 FAIL\n");
+
+ /*Get event here!*/
+ ret = read(fd, ev, sizeof(struct input_event));
+ if (ret < (int) sizeof(struct input_event))
+ perror("evtest: error reading\n");
+
+ ret = clock_gettime(CLOCK_MONOTONIC, &tp2);
+ if (ret < 0)
+ perror("Clock MONOTONIC gettime2 FAILED\n");
+
+ if (tp1.tv_sec <= ev[0].time.tv_sec && ev[0].time.tv_sec<= tp2.tv_sec)
+ printf("[EVDEV TEST22] PASS\n");
+ else
+ printf("[EVDEV TEST22] FAIL\n");
+
+ /*Stop generate input dev event here!*/
+ if ((fd_evdev_run = open("/sys/juice_input/run", O_WRONLY)) < 0) {
+ perror("[EVDEV OPEN SYS RUN] FAIL\n");
+ goto finish;
+ } else {
+ sprintf(buf, "%d\n", 0);
+ len = strlen(buf);
+ n = write(fd_evdev_run, buf, len);
+ if (n < 0 || n != len)
+ perror("Write /sys/juice_input/run failed!\n");
+ close(fd_evdev_run);
+ }
+
+finish:
+ close(fd);
+ printf("===========================\n");
+ return -1;
+}
diff --git a/evdevtest/juice_evtest.sh b/evdevtest/juice_evtest.sh
new file mode 100644
index 0000000..2654ec1
--- /dev/null
+++ b/evdevtest/juice_evtest.sh
@@ -0,0 +1,27 @@
+#!/system/bin/sh
+
+rc=0
+
+insmod /system/modules/juice_input_test_module.ko
+rc=$?
+if [ $rc -ne 0 ]; then
+ echo "Insmod juice input kernel module failed!"
+fi
+
+N=`dmesg |grep Juice|awk -F '' '{print $NF}'`
+
+echo "Evdev IOCTL CMD TEST START"
+juice_evtest -p /dev/input/event$N
+rc=$?
+if [ $rc -ne 0 ]; then
+ echo "Evdev IOCTL CMD TEST FAIL!"
+else
+ echo "EVDEV IOCTL CMD TEST FINISH"
+fi
+
+rmmod juice_input_test_module
+rc=$?
+if [ $rc -ne 0 ]; then
+ echo "Remove juice input kernel module failed!"
+fi
+
diff --git a/evdevtest/kernel_module/Makefile b/evdevtest/kernel_module/Makefile
new file mode 100644
index 0000000..cd62ba4
--- /dev/null
+++ b/evdevtest/kernel_module/Makefile
@@ -0,0 +1,11 @@
+obj-m := juice_input_test_module.o
+
+KERNELDIR ?= $(PRODUCT_OUT)/obj/kernel/
+
+evdevtest_driver: android_kernel_modules $(INSTALLED_KERNEL_TARGET) $(ACP)
+ export PATH=$(KERNEL_COMPILER_PATHS):$(PATH) &&\
+ cd $(TOP)/external/linaro-android-kernel-test/evdevtest/kernel_module &&\
+ if [ -e $(KERNEL_TOOLS_PREFIX)ld.bfd ]; then LD=$(KERNEL_TOOLS_PREFIX)ld.bfd; else LD=$(KERNEL_TOOLS_PREFIX)ld; fi && \
+ $(MAKE) O=$(KERNEL_OUT) ARCH=$(ARCH) CROSS_COMPILE=$(KERNEL_TOOLS_PREFIX) LD=$$LD KCFLAGS="$(TARGET_EXTRA_CFLAGS) -fno-pic $(LOCAL_CFLAGS)" -C $(KERNEL_PATH) M=`pwd` modules
+ mkdir -p $(TARGET_OUT)/modules
+ find $(TOP)/external/linaro-android-kernel-test/evdevtest/kernel_module -name "*.ko" -exec $(ACP) -fpt {} $(TARGET_OUT)/modules/ \;
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);
diff --git a/linaro-android-kernel-tests.sh b/linaro-android-kernel-tests.sh
index 8e83574..d35cb90 100755
--- a/linaro-android-kernel-tests.sh
+++ b/linaro-android-kernel-tests.sh
@@ -25,6 +25,7 @@ usage() {
echo " binder"
echo " sync"
echo " vfat"
+ echo " evdev"
echo ""
echo "example:"
echo "$ linaro-android-kernel-tests -t \"logger binder\""
@@ -111,9 +112,14 @@ run_vfat_test() {
vfat-volid-test.sh
}
+run_evdev_test() {
+ echo "Running evdev test."
+ juice_evtest.sh
+}
+
run_all() {
echo "Running all tests"
- TESTS="ashmem ashmem_expanded alarmdev logger binder sync vfat"
+ TESTS="ashmem ashmem_expanded alarmdev logger binder sync vfat evdev"
run_tests
}
@@ -142,6 +148,9 @@ run_tests() {
vfat)
run_vfat_test
;;
+ evdev)
+ run_evdev_test
+ ;;
*)
echo ""
echo "Unrecognized test $TEST."
diff --git a/product.mk b/product.mk
index 5f14a9f..9388fac 100644
--- a/product.mk
+++ b/product.mk
@@ -17,12 +17,14 @@ PRODUCT_PACKAGES += alarm-dev-test \
sync-basic \
nl-listener \
vfat-volid dosfstools \
- mkfs.vfat
+ mkfs.vfat \
+ juice_evtest
PRODUCT_COPY_FILES += external/linaro-android-kernel-test/binder/bindertest.sh:system/bin/bindertest.sh
PRODUCT_COPY_FILES += external/linaro-android-kernel-test/linaro-android-kernel-tests.sh:system/bin/linaro-android-kernel-tests.sh
PRODUCT_COPY_FILES += external/linaro-android-kernel-test/netfilter/ipt-idletimer.sh:system/bin/ipt-idletimer.sh
PRODUCT_COPY_FILES += external/linaro-android-kernel-test/vfat-volid/test.sh:system/bin/vfat-volid-test.sh
+PRODUCT_COPY_FILES += external/linaro-android-kernel-test/evdevtest/juice_evtest.sh:system/bin/juice_evtest.sh
# put expanded ashmemtest in/out files on the device filesystem
PRODUCT_COPY_FILES += \