ir-loopback can transmit IR on one rc device and check the correct
scancode and protocol is decoded on a different rc device. This can be
used to check IR transmission between two rc devices. Using rc-loopback,
we use it to check the IR encoders and decoders themselves.
No hardware is required for this test.
Signed-off-by: Sean Young
Cc: Shuah Khan
---
tools/testing/selftests/Makefile | 1 +
tools/testing/selftests/ir/.gitignore | 1 +
tools/testing/selftests/ir/Makefile | 5 +
tools/testing/selftests/ir/ir_loopback.c | 199 ++
tools/testing/selftests/ir/ir_loopback.sh | 20 +++
5 files changed, 226 insertions(+)
create mode 100644 tools/testing/selftests/ir/.gitignore
create mode 100644 tools/testing/selftests/ir/Makefile
create mode 100644 tools/testing/selftests/ir/ir_loopback.c
create mode 100755 tools/testing/selftests/ir/ir_loopback.sh
diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
index f1fe492c8e17..995034ea5546 100644
--- a/tools/testing/selftests/Makefile
+++ b/tools/testing/selftests/Makefile
@@ -15,6 +15,7 @@ TARGETS += futex
TARGETS += gpio
TARGETS += intel_pstate
TARGETS += ipc
+TARGETS += ir
TARGETS += kcmp
TARGETS += kvm
TARGETS += lib
diff --git a/tools/testing/selftests/ir/.gitignore
b/tools/testing/selftests/ir/.gitignore
new file mode 100644
index ..070ea0c75fb8
--- /dev/null
+++ b/tools/testing/selftests/ir/.gitignore
@@ -0,0 +1 @@
+ir_loopback
diff --git a/tools/testing/selftests/ir/Makefile
b/tools/testing/selftests/ir/Makefile
new file mode 100644
index ..f4ba8eb84b95
--- /dev/null
+++ b/tools/testing/selftests/ir/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+TEST_PROGS := ir_loopback.sh
+TEST_GEN_PROGS_EXTENDED := ir_loopback
+
+include ../lib.mk
diff --git a/tools/testing/selftests/ir/ir_loopback.c
b/tools/testing/selftests/ir/ir_loopback.c
new file mode 100644
index ..858c19caf224
--- /dev/null
+++ b/tools/testing/selftests/ir/ir_loopback.c
@@ -0,0 +1,199 @@
+// SPDX-License-Identifier: GPL-2.0
+// test ir decoder
+//
+// Copyright (C) 2018 Sean Young
+
+// When sending LIRC_MODE_SCANCODE, the IR will be encoded. rc-loopback
+// will send this IR to the receiver side, where we try to read the decoded
+// IR. Decoding happens in a separate kernel thread, so we will need to
+// wait until that is scheduled, hence we use poll to check for read
+// readiness.
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "../kselftest.h"
+
+#define TEST_SCANCODES 10
+#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
+
+static const struct {
+ enum rc_proto proto;
+ const char *name;
+ unsigned int mask;
+ const char *decoder;
+} protocols[] = {
+ { RC_PROTO_RC5, "rc-5", 0x1f7f, "rc-5" },
+ { RC_PROTO_RC5X_20, "rc-5x-20", 0x1f7f3f, "rc-5" },
+ { RC_PROTO_RC5_SZ, "rc-5-sz", 0x2fff, "rc-5-sz" },
+ { RC_PROTO_JVC, "jvc", 0x, "jvc" },
+ { RC_PROTO_SONY12, "sony-12", 0x1f007f, "sony" },
+ { RC_PROTO_SONY15, "sony-15", 0xff007f, "sony" },
+ { RC_PROTO_SONY20, "sony-20", 0x1fff7f, "sony" },
+ { RC_PROTO_NEC, "nec", 0x, "nec" },
+ { RC_PROTO_NECX, "nec-x", 0xff, "nec" },
+ { RC_PROTO_NEC32, "nec-32", 0x, "nec" },
+ { RC_PROTO_SANYO, "sanyo", 0x1f, "sanyo" },
+ { RC_PROTO_RC6_0, "rc-6-0", 0x, "rc-6" },
+ { RC_PROTO_RC6_6A_20, "rc-6-6a-20", 0xf, "rc-6" },
+ { RC_PROTO_RC6_6A_24, "rc-6-6a-24", 0xff, "rc-6" },
+ { RC_PROTO_RC6_6A_32, "rc-6-6a-32", 0x, "rc-6" },
+ { RC_PROTO_RC6_MCE, "rc-6-mce", 0x7fff, "rc-6" },
+ { RC_PROTO_SHARP, "sharp", 0x1fff, "sharp" },
+};
+
+int lirc_open(const char *rc)
+{
+ struct dirent *dent;
+ char buf[100];
+ DIR *d;
+ int fd;
+
+ snprintf(buf, sizeof(buf), "/sys/class/rc/%s", rc);
+
+ d = opendir(buf);
+ if (!d)
+ ksft_exit_fail_msg("cannot open %s: %m\n", buf);
+
+ while ((dent = readdir(d)) != NULL) {
+ if (!strncmp(dent->d_name, "lirc", 4)) {
+ snprintf(buf, sizeof(buf), "/dev/%s", dent->d_name);
+ break;
+ }
+ }
+
+ if (!dent)
+ ksft_exit_fail_msg("cannot find lirc device for %s\n", rc);
+
+ closedir(d);
+
+ fd = open(buf, O_RDWR | O_NONBLOCK);
+ if (fd == -1)
+ ksft_exit_fail_msg("cannot open: %s: %m\n", buf);
+
+ return fd;
+}
+
+int main(int argc, char **argv)
+{
+ unsigned int mode;
+ char buf[100];
+ int rlircfd, wlircfd, protocolfd, i, n;
+
+ srand(time(NULL));
+
+ if (argc != 3)
+ ksft_exit_fail_msg("Usage: %s \n",
+ argv[0]);
+
+ rlircfd =