This is an automatic generated email to let you know that the following patch 
were queued at the 
http://git.linuxtv.org/cgit.cgi/v4l-utils.git tree:

Subject: ir-keytable: show lirc device and make test show lirc scancodes
Author:  Sean Young <s...@mess.org>
Date:    Mon Sep 25 09:09:24 2017 +0100

Now you can see what protocol any remote is using the following command.

$ ir-keytable -c -p all -t
Old keytable cleared
Protocols changed to lirc rc-5 rc-5-sz jvc sony nec sanyo mce_kbd rc-6 sharp xmp
Testing events. Please, press CTRL-C to abort.
2124.576099: lirc protocol(rc5): scancode = 0x1e11
2124.576143: event type EV_MSC(0x04): scancode = 0x1e11
2124.576143: event type EV_SYN(0x00).
2125.601002: lirc protocol(rc6_mce): scancode = 0x800f0410
2125.601051: event type EV_MSC(0x04): scancode = 0x800f0410
2125.601051: event type EV_SYN(0x00).

Signed-off-by: Sean Young <s...@mess.org>

 utils/common/ir-encode.c   | 453 +++++++++++++++++++++++++++++++++++++++++++++
 utils/common/ir-encode.h   |  15 ++
 utils/ir-ctl/ir-encode.c   | 450 +-------------------------------------------
 utils/ir-ctl/ir-encode.h   |  16 +-
 utils/keytable/Makefile.am |   2 +-
 utils/keytable/ir-encode.c |   1 +
 utils/keytable/ir-encode.h |   1 +
 utils/keytable/keytable.c  | 122 +++++++++++-
 8 files changed, 589 insertions(+), 471 deletions(-)

---

http://git.linuxtv.org/cgit.cgi/v4l-utils.git/commit/?id=f0b56a9ed19e29e358161112b081ca1605f2517a
diff --git a/utils/common/ir-encode.c b/utils/common/ir-encode.c
new file mode 100644
index 000000000000..8f486dacfa3b
--- /dev/null
+++ b/utils/common/ir-encode.c
@@ -0,0 +1,453 @@
+/*
+ * ir-encode.c - encodes IR scancodes in different protocols
+ *
+ * Copyright (C) 2016 Sean Young <s...@mess.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 2 of the License.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+/*
+ * TODO: XMP protocol and MCE keyboard
+ */
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#include <linux/lirc.h>
+
+#include "ir-encode.h"
+
+#define NS_TO_US(x) (((x)+500)/1000)
+
+static int nec_encode(enum rc_proto proto, unsigned scancode, unsigned *buf)
+{
+       const int nec_unit = 562500;
+       int n = 0;
+
+       void add_byte(unsigned bits)
+       {
+               int i;
+               for (i=0; i<8; i++) {
+                       buf[n++] = NS_TO_US(nec_unit);
+                       if (bits & (1 << i))
+                               buf[n++] = NS_TO_US(nec_unit * 3);
+                       else
+                               buf[n++] = NS_TO_US(nec_unit);
+               }
+       }
+
+       buf[n++] = NS_TO_US(nec_unit * 16);
+       buf[n++] = NS_TO_US(nec_unit * 8);
+
+       switch (proto) {
+       default:
+               return 0;
+       case RC_PROTO_NEC:
+               add_byte(scancode >> 8);
+               add_byte(~(scancode >> 8));
+               add_byte(scancode);
+               add_byte(~scancode);
+               break;
+       case RC_PROTO_NECX:
+               add_byte(scancode >> 16);
+               add_byte(scancode >> 8);
+               add_byte(scancode);
+               add_byte(~scancode);
+               break;
+       case RC_PROTO_NEC32:
+               /*
+                * At the time of writing kernel software nec decoder
+                * reverses the bit order so it will not match. Hardware
+                * decoders do not have this issue.
+                */
+               add_byte(scancode >> 24);
+               add_byte(scancode >> 16);
+               add_byte(scancode >> 8);
+               add_byte(scancode);
+               break;
+       }
+
+       buf[n++] = NS_TO_US(nec_unit);
+
+       return n;
+}
+
+static int jvc_encode(enum rc_proto proto, unsigned scancode, unsigned *buf)
+{
+       const int jvc_unit = 525000;
+       int i;
+
+       /* swap bytes so address comes first */
+       scancode = ((scancode << 8) & 0xff00) | ((scancode >> 8) & 0x00ff);
+
+       *buf++ = NS_TO_US(jvc_unit * 16);
+       *buf++ = NS_TO_US(jvc_unit * 8);
+
+       for (i=0; i<16; i++) {
+               *buf++ = NS_TO_US(jvc_unit);
+
+               if (scancode & 1)
+                       *buf++ = NS_TO_US(jvc_unit * 3);
+               else
+                       *buf++ = NS_TO_US(jvc_unit);
+
+               scancode >>= 1;
+       }
+
+       *buf = NS_TO_US(jvc_unit);
+
+       return 35;
+}
+
+static int sanyo_encode(enum rc_proto proto, unsigned scancode, unsigned *buf)
+{
+       const int sanyo_unit = 562500;
+
+       void add_bits(int bits, int count)
+       {
+               int i;
+               for (i=0; i<count; i++) {
+                       *buf++ = NS_TO_US(sanyo_unit);
+
+                       if (bits & (1 << i))
+                               *buf++ = NS_TO_US(sanyo_unit * 3);
+                       else
+                               *buf++ = NS_TO_US(sanyo_unit);
+               }
+       }
+
+       *buf++ = NS_TO_US(sanyo_unit * 16);
+       *buf++ = NS_TO_US(sanyo_unit * 8);
+
+       add_bits(scancode >> 8, 13);
+       add_bits(~(scancode >> 8), 13);
+       add_bits(scancode, 8);
+       add_bits(~scancode, 8);
+
+       *buf = NS_TO_US(sanyo_unit);
+
+       return 87;
+}
+
+static int sharp_encode(enum rc_proto proto, unsigned scancode, unsigned *buf)
+{
+       const int sharp_unit = 40000;
+
+       void add_bits(int bits, int count)
+       {
+               int i;
+               for (i=0; i<count; i++) {
+                       *buf++ = NS_TO_US(sharp_unit * 8);
+
+                       if (bits & (1 << i))
+                               *buf++ = NS_TO_US(sharp_unit * 50);
+                       else
+                               *buf++ = NS_TO_US(sharp_unit * 25);
+               }
+       }
+
+       add_bits(scancode >> 8, 5);
+       add_bits(scancode, 8);
+       add_bits(1, 2);
+
+       *buf++ = NS_TO_US(sharp_unit * 8);
+       *buf++ = NS_TO_US(sharp_unit * 1000);
+
+       add_bits(scancode >> 8, 5);
+       add_bits(~scancode, 8);
+       add_bits(~1, 2);
+       *buf++ = NS_TO_US(sharp_unit * 8);
+
+       return (13 + 2) * 4 + 3;
+}
+
+static int sony_encode(enum rc_proto proto, unsigned scancode, unsigned *buf)
+{
+       const int sony_unit = 600000;
+       int n = 0;
+
+       void add_bits(int bits, int count)
+       {
+               int i;
+               for (i=0; i<count; i++) {
+                       if (bits & (1 << i))
+                               buf[n++] = NS_TO_US(sony_unit * 2);
+                       else
+                               buf[n++] = NS_TO_US(sony_unit);
+
+                       buf[n++] = NS_TO_US(sony_unit);
+               }
+       }
+
+       buf[n++] = NS_TO_US(sony_unit * 4);
+       buf[n++] = NS_TO_US(sony_unit);
+
+       switch (proto) {
+       case RC_PROTO_SONY12:
+               add_bits(scancode, 7);
+               add_bits(scancode >> 16, 5);
+               break;
+       case RC_PROTO_SONY15:
+               add_bits(scancode, 7);
+               add_bits(scancode >> 16, 8);
+               break;
+       case RC_PROTO_SONY20:
+               add_bits(scancode, 7);
+               add_bits(scancode >> 16, 5);
+               add_bits(scancode >> 8, 8);
+               break;
+       default:
+               return 0;
+       }
+
+       /* ignore last space */
+       return n - 1;
+}
+
+static int rc5_encode(enum rc_proto proto, unsigned scancode, unsigned *buf)
+{
+       const unsigned int rc5_unit = 888888;
+       unsigned n = 0;
+
+       void advance_space(unsigned length)
+       {
+               if (n % 2)
+                       buf[n] += length;
+               else
+                       buf[++n] = length;
+       }
+
+       void advance_pulse(unsigned length)
+       {
+               if (n % 2)
+                       buf[++n] = length;
+               else
+                       buf[n] += length;
+       }
+
+       void add_bits(int bits, int count)
+       {
+               while (count--) {
+                       if (bits & (1 << count)) {
+                               advance_space(NS_TO_US(rc5_unit));
+                               advance_pulse(NS_TO_US(rc5_unit));
+                       } else {
+                               advance_pulse(NS_TO_US(rc5_unit));
+                               advance_space(NS_TO_US(rc5_unit));
+                       }
+               }
+       }
+
+       buf[n] = NS_TO_US(rc5_unit);
+
+       switch (proto) {
+       default:
+               return 0;
+       case RC_PROTO_RC5:
+               add_bits(!(scancode & 0x40), 1);
+               add_bits(0, 1);
+               add_bits(scancode >> 8, 5);
+               add_bits(scancode, 6);
+               break;
+       case RC_PROTO_RC5_SZ:
+               add_bits(!!(scancode & 0x2000), 1);
+               add_bits(0, 1);
+               add_bits(scancode >> 6, 6);
+               add_bits(scancode, 6);
+               break;
+       case RC_PROTO_RC5X_20:
+               add_bits(!(scancode & 0x4000), 1);
+               add_bits(0, 1);
+               add_bits(scancode >> 16, 5);
+               advance_space(NS_TO_US(rc5_unit * 4));
+               add_bits(scancode >> 8, 6);
+               add_bits(scancode, 6);
+               break;
+       }
+
+       /* drop any trailing pulse */
+       return (n % 2) ? n : n + 1;
+}
+
+static int rc6_encode(enum rc_proto proto, unsigned scancode, unsigned *buf)
+{
+       const unsigned int rc6_unit = 444444;
+       unsigned n = 0;
+
+       void advance_space(unsigned length)
+       {
+               if (n % 2)
+                       buf[n] += length;
+               else
+                       buf[++n] = length;
+       }
+
+       void advance_pulse(unsigned length)
+       {
+               if (n % 2)
+                       buf[++n] = length;
+               else
+                       buf[n] += length;
+       }
+
+       void add_bits(unsigned bits, unsigned count, unsigned length)
+       {
+               while (count--) {
+                       if (bits & (1 << count)) {
+                               advance_pulse(length);
+                               advance_space(length);
+                       } else {
+                               advance_space(length);
+                               advance_pulse(length);
+                       }
+               }
+       }
+
+       buf[n++] = NS_TO_US(rc6_unit * 6);
+       buf[n++] = NS_TO_US(rc6_unit * 2);
+       buf[n] = 0;
+
+       switch (proto) {
+       default:
+               return 0;
+       case RC_PROTO_RC6_0:
+               add_bits(8, 4, NS_TO_US(rc6_unit));
+               add_bits(0, 1, NS_TO_US(rc6_unit * 2));
+               add_bits(scancode, 16, NS_TO_US(rc6_unit));
+               break;
+       case RC_PROTO_RC6_6A_20:
+               add_bits(14, 4, NS_TO_US(rc6_unit));
+               add_bits(0, 1, NS_TO_US(rc6_unit * 2));
+               add_bits(scancode, 20, NS_TO_US(rc6_unit));
+               break;
+       case RC_PROTO_RC6_6A_24:
+               add_bits(14, 4, NS_TO_US(rc6_unit));
+               add_bits(0, 1, NS_TO_US(rc6_unit * 2));
+               add_bits(scancode, 24, NS_TO_US(rc6_unit));
+               break;
+       case RC_PROTO_RC6_6A_32:
+       case RC_PROTO_RC6_MCE:
+               add_bits(14, 4, NS_TO_US(rc6_unit));
+               add_bits(0, 1, NS_TO_US(rc6_unit * 2));
+               add_bits(scancode, 32, NS_TO_US(rc6_unit));
+               break;
+       }
+
+       /* drop any trailing pulse */
+       return (n % 2) ? n : n + 1;
+}
+
+static const struct {
+       char name[10];
+       unsigned scancode_mask;
+       unsigned max_edges;
+       unsigned carrier;
+       int (*encode)(enum rc_proto proto, unsigned scancode, unsigned *buf);
+} encoders[] = {
+       [RC_PROTO_RC5] = { "rc5", 0x1f7f, 24, 36000, rc5_encode },
+       [RC_PROTO_RC5X_20] = { "rc5x_20", 0x1f7f3f, 40, 36000, rc5_encode },
+       [RC_PROTO_RC5_SZ] = { "rc5_sz", 0x2fff, 26, 36000, rc5_encode },
+       [RC_PROTO_SONY12] = { "sony12", 0x1f007f, 25, 40000, sony_encode },
+       [RC_PROTO_SONY15] = { "sony15", 0xff007f, 31, 40000, sony_encode },
+       [RC_PROTO_SONY20] = { "sony20", 0x1fff7f, 41, 40000, sony_encode },
+       [RC_PROTO_JVC] = { "jvc", 0xffff, 35, 38000, jvc_encode },
+       [RC_PROTO_NEC] = { "nec", 0xffff, 67, 38000, nec_encode },
+       [RC_PROTO_NECX] = { "necx", 0xffffff, 67, 38000, nec_encode },
+       [RC_PROTO_NEC32] = { "nec32", 0xffffffff, 67, 38000, nec_encode },
+       [RC_PROTO_SANYO] = { "sanyo", 0x1fffff, 87, 38000, sanyo_encode },
+       [RC_PROTO_RC6_0] = { "rc6_0", 0xffff, 24, 36000, rc6_encode },
+       [RC_PROTO_RC6_6A_20] = { "rc6_6a_20", 0xfffff, 52, 36000, rc6_encode },
+       [RC_PROTO_RC6_6A_24] = { "rc6_6a_24", 0xffffff, 60, 36000, rc6_encode },
+       [RC_PROTO_RC6_6A_32] = { "rc6_6a_32", 0xffffffff, 76, 36000, rc6_encode 
},
+       [RC_PROTO_RC6_MCE] = { "rc6_mce", 0xffff7fff, 76, 36000, rc6_encode },
+       [RC_PROTO_SHARP] = { "sharp", 0x1fff, 63, 38000, sharp_encode },
+};
+
+static bool str_like(const char *a, const char *b)
+{
+       while (*a && *b) {
+               while (*a == ' ' || *a == '-' || *a == '_')
+                       a++;
+               while (*b == ' ' || *b == '-' || *b == '_')
+                       b++;
+
+               if (*a >= 0x7f || *b >= 0x7f)
+                       return false;
+
+               if (tolower(*a) != tolower(*b))
+                       return false;
+
+               a++; b++;
+       }
+
+       return !*a && !*b;
+}
+
+bool protocol_match(const char *name, enum rc_proto *proto)
+{
+       enum rc_proto p;
+
+       for (p=0; p<ARRAY_SIZE(encoders); p++) {
+               if (str_like(encoders[p].name, name)) {
+                       *proto = p;
+                       return true;
+               }
+       }
+
+       return false;
+}
+
+unsigned protocol_carrier(enum rc_proto proto)
+{
+       return encoders[proto].carrier;
+}
+
+unsigned protocol_max_size(enum rc_proto proto)
+{
+       return encoders[proto].max_edges;
+}
+
+unsigned protocol_scancode_mask(enum rc_proto proto)
+{
+       return encoders[proto].scancode_mask;
+}
+
+bool protocol_scancode_valid(enum rc_proto p, unsigned s)
+{
+       if (s & ~encoders[p].scancode_mask)
+               return false;
+
+       if (p == RC_PROTO_NECX) {
+               return (((s >> 16) ^ ~(s >> 8)) & 0xff) != 0;
+       } else if (p == RC_PROTO_NEC32) {
+               return (((s >> 24) ^ ~(s >> 16)) & 0xff) != 0;
+       } else if (p == RC_PROTO_RC6_MCE) {
+               return (s & 0xffff0000) == 0x800f0000;
+       } else if (p == RC_PROTO_RC6_6A_32) {
+               return (s & 0xffff0000) != 0x800f0000;
+       }
+
+       return true;
+}
+
+unsigned protocol_encode(enum rc_proto proto, unsigned scancode, unsigned *buf)
+{
+       return encoders[proto].encode(proto, scancode, buf);
+}
+
+const char* protocol_name(enum rc_proto proto)
+{
+       if (proto >= ARRAY_SIZE(encoders))
+               return NULL;
+
+       return encoders[proto].name;
+}
diff --git a/utils/common/ir-encode.h b/utils/common/ir-encode.h
new file mode 100644
index 000000000000..6e9c623e3548
--- /dev/null
+++ b/utils/common/ir-encode.h
@@ -0,0 +1,15 @@
+
+#ifndef __IR_ENCODE_H__
+#define __IR_ENCODE_H__
+
+#define ARRAY_SIZE(x)     (sizeof(x)/sizeof((x)[0]))
+
+bool protocol_match(const char *name, enum rc_proto *proto);
+unsigned protocol_carrier(enum rc_proto proto);
+unsigned protocol_max_size(enum rc_proto proto);
+bool protocol_scancode_valid(enum rc_proto proto, unsigned scancode);
+unsigned protocol_scancode_mask(enum rc_proto proto);
+unsigned protocol_encode(enum rc_proto proto, unsigned scancode, unsigned 
*buf);
+const char *protocol_name(enum rc_proto proto);
+
+#endif
diff --git a/utils/ir-ctl/ir-encode.c b/utils/ir-ctl/ir-encode.c
deleted file mode 100644
index 8a12562868a7..000000000000
--- a/utils/ir-ctl/ir-encode.c
+++ /dev/null
@@ -1,449 +0,0 @@
-/*
- * ir-encode.c - encodes IR scancodes in different protocols
- *
- * Copyright (C) 2016 Sean Young <s...@mess.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, version 2 of the License.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-/*
- * TODO: XMP protocol and MCE keyboard
- */
-
-#include <stdbool.h>
-#include <stdint.h>
-#include <ctype.h>
-
-#include <linux/lirc.h>
-
-#include "ir-encode.h"
-
-#define NS_TO_US(x) (((x)+500)/1000)
-
-static int nec_encode(enum rc_proto proto, unsigned scancode, unsigned *buf)
-{
-       const int nec_unit = 562500;
-       int n = 0;
-
-       void add_byte(unsigned bits)
-       {
-               int i;
-               for (i=0; i<8; i++) {
-                       buf[n++] = NS_TO_US(nec_unit);
-                       if (bits & (1 << i))
-                               buf[n++] = NS_TO_US(nec_unit * 3);
-                       else
-                               buf[n++] = NS_TO_US(nec_unit);
-               }
-       }
-
-       buf[n++] = NS_TO_US(nec_unit * 16);
-       buf[n++] = NS_TO_US(nec_unit * 8);
-
-       switch (proto) {
-       default:
-               return 0;
-       case RC_PROTO_NEC:
-               add_byte(scancode >> 8);
-               add_byte(~(scancode >> 8));
-               add_byte(scancode);
-               add_byte(~scancode);
-               break;
-       case RC_PROTO_NECX:
-               add_byte(scancode >> 16);
-               add_byte(scancode >> 8);
-               add_byte(scancode);
-               add_byte(~scancode);
-               break;
-       case RC_PROTO_NEC32:
-               /*
-                * At the time of writing kernel software nec decoder
-                * reverses the bit order so it will not match. Hardware
-                * decoders do not have this issue.
-                */
-               add_byte(scancode >> 24);
-               add_byte(scancode >> 16);
-               add_byte(scancode >> 8);
-               add_byte(scancode);
-               break;
-       }
-
-       buf[n++] = NS_TO_US(nec_unit);
-
-       return n;
-}
-
-static int jvc_encode(enum rc_proto proto, unsigned scancode, unsigned *buf)
-{
-       const int jvc_unit = 525000;
-       int i;
-
-       /* swap bytes so address comes first */
-       scancode = ((scancode << 8) & 0xff00) | ((scancode >> 8) & 0x00ff);
-
-       *buf++ = NS_TO_US(jvc_unit * 16);
-       *buf++ = NS_TO_US(jvc_unit * 8);
-
-       for (i=0; i<16; i++) {
-               *buf++ = NS_TO_US(jvc_unit);
-
-               if (scancode & 1)
-                       *buf++ = NS_TO_US(jvc_unit * 3);
-               else
-                       *buf++ = NS_TO_US(jvc_unit);
-
-               scancode >>= 1;
-       }
-
-       *buf = NS_TO_US(jvc_unit);
-
-       return 35;
-}
-
-static int sanyo_encode(enum rc_proto proto, unsigned scancode, unsigned *buf)
-{
-       const int sanyo_unit = 562500;
-
-       void add_bits(int bits, int count)
-       {
-               int i;
-               for (i=0; i<count; i++) {
-                       *buf++ = NS_TO_US(sanyo_unit);
-
-                       if (bits & (1 << i))
-                               *buf++ = NS_TO_US(sanyo_unit * 3);
-                       else
-                               *buf++ = NS_TO_US(sanyo_unit);
-               }
-       }
-
-       *buf++ = NS_TO_US(sanyo_unit * 16);
-       *buf++ = NS_TO_US(sanyo_unit * 8);
-
-       add_bits(scancode >> 8, 13);
-       add_bits(~(scancode >> 8), 13);
-       add_bits(scancode, 8);
-       add_bits(~scancode, 8);
-
-       *buf = NS_TO_US(sanyo_unit);
-
-       return 87;
-}
-
-static int sharp_encode(enum rc_proto proto, unsigned scancode, unsigned *buf)
-{
-       const int sharp_unit = 40000;
-
-       void add_bits(int bits, int count)
-       {
-               int i;
-               for (i=0; i<count; i++) {
-                       *buf++ = NS_TO_US(sharp_unit * 8);
-
-                       if (bits & (1 << i))
-                               *buf++ = NS_TO_US(sharp_unit * 50);
-                       else
-                               *buf++ = NS_TO_US(sharp_unit * 25);
-               }
-       }
-
-       add_bits(scancode >> 8, 5);
-       add_bits(scancode, 8);
-       add_bits(1, 2);
-
-       *buf++ = NS_TO_US(sharp_unit * 8);
-       *buf++ = NS_TO_US(sharp_unit * 1000);
-
-       add_bits(scancode >> 8, 5);
-       add_bits(~scancode, 8);
-       add_bits(~1, 2);
-       *buf++ = NS_TO_US(sharp_unit * 8);
-
-       return (13 + 2) * 4 + 3;
-}
-
-static int sony_encode(enum rc_proto proto, unsigned scancode, unsigned *buf)
-{
-       const int sony_unit = 600000;
-       int n = 0;
-
-       void add_bits(int bits, int count)
-       {
-               int i;
-               for (i=0; i<count; i++) {
-                       if (bits & (1 << i))
-                               buf[n++] = NS_TO_US(sony_unit * 2);
-                       else
-                               buf[n++] = NS_TO_US(sony_unit);
-
-                       buf[n++] = NS_TO_US(sony_unit);
-               }
-       }
-
-       buf[n++] = NS_TO_US(sony_unit * 4);
-       buf[n++] = NS_TO_US(sony_unit);
-
-       switch (proto) {
-       case RC_PROTO_SONY12:
-               add_bits(scancode, 7);
-               add_bits(scancode >> 16, 5);
-               break;
-       case RC_PROTO_SONY15:
-               add_bits(scancode, 7);
-               add_bits(scancode >> 16, 8);
-               break;
-       case RC_PROTO_SONY20:
-               add_bits(scancode, 7);
-               add_bits(scancode >> 16, 5);
-               add_bits(scancode >> 8, 8);
-               break;
-       default:
-               return 0;
-       }
-
-       /* ignore last space */
-       return n - 1;
-}
-
-static int rc5_encode(enum rc_proto proto, unsigned scancode, unsigned *buf)
-{
-       const unsigned int rc5_unit = 888888;
-       unsigned n = 0;
-
-       void advance_space(unsigned length)
-       {
-               if (n % 2)
-                       buf[n] += length;
-               else
-                       buf[++n] = length;
-       }
-
-       void advance_pulse(unsigned length)
-       {
-               if (n % 2)
-                       buf[++n] = length;
-               else
-                       buf[n] += length;
-       }
-
-       void add_bits(int bits, int count)
-       {
-               while (count--) {
-                       if (bits & (1 << count)) {
-                               advance_space(NS_TO_US(rc5_unit));
-                               advance_pulse(NS_TO_US(rc5_unit));
-                       } else {
-                               advance_pulse(NS_TO_US(rc5_unit));
-                               advance_space(NS_TO_US(rc5_unit));
-                       }
-               }
-       }
-
-       buf[n] = NS_TO_US(rc5_unit);
-
-       switch (proto) {
-       default:
-               return 0;
-       case RC_PROTO_RC5:
-               add_bits(!(scancode & 0x40), 1);
-               add_bits(0, 1);
-               add_bits(scancode >> 8, 5);
-               add_bits(scancode, 6);
-               break;
-       case RC_PROTO_RC5_SZ:
-               add_bits(!!(scancode & 0x2000), 1);
-               add_bits(0, 1);
-               add_bits(scancode >> 6, 6);
-               add_bits(scancode, 6);
-               break;
-       case RC_PROTO_RC5X_20:
-               add_bits(!(scancode & 0x4000), 1);
-               add_bits(0, 1);
-               add_bits(scancode >> 16, 5);
-               advance_space(NS_TO_US(rc5_unit * 4));
-               add_bits(scancode >> 8, 6);
-               add_bits(scancode, 6);
-               break;
-       }
-
-       /* drop any trailing pulse */
-       return (n % 2) ? n : n + 1;
-}
-
-static int rc6_encode(enum rc_proto proto, unsigned scancode, unsigned *buf)
-{
-       const unsigned int rc6_unit = 444444;
-       unsigned n = 0;
-
-       void advance_space(unsigned length)
-       {
-               if (n % 2)
-                       buf[n] += length;
-               else
-                       buf[++n] = length;
-       }
-
-       void advance_pulse(unsigned length)
-       {
-               if (n % 2)
-                       buf[++n] = length;
-               else
-                       buf[n] += length;
-       }
-
-       void add_bits(unsigned bits, unsigned count, unsigned length)
-       {
-               while (count--) {
-                       if (bits & (1 << count)) {
-                               advance_pulse(length);
-                               advance_space(length);
-                       } else {
-                               advance_space(length);
-                               advance_pulse(length);
-                       }
-               }
-       }
-
-       buf[n++] = NS_TO_US(rc6_unit * 6);
-       buf[n++] = NS_TO_US(rc6_unit * 2);
-       buf[n] = 0;
-
-       switch (proto) {
-       default:
-               return 0;
-       case RC_PROTO_RC6_0:
-               add_bits(8, 4, NS_TO_US(rc6_unit));
-               add_bits(0, 1, NS_TO_US(rc6_unit * 2));
-               add_bits(scancode, 16, NS_TO_US(rc6_unit));
-               break;
-       case RC_PROTO_RC6_6A_20:
-               add_bits(14, 4, NS_TO_US(rc6_unit));
-               add_bits(0, 1, NS_TO_US(rc6_unit * 2));
-               add_bits(scancode, 20, NS_TO_US(rc6_unit));
-               break;
-       case RC_PROTO_RC6_6A_24:
-               add_bits(14, 4, NS_TO_US(rc6_unit));
-               add_bits(0, 1, NS_TO_US(rc6_unit * 2));
-               add_bits(scancode, 24, NS_TO_US(rc6_unit));
-               break;
-       case RC_PROTO_RC6_6A_32:
-       case RC_PROTO_RC6_MCE:
-               add_bits(14, 4, NS_TO_US(rc6_unit));
-               add_bits(0, 1, NS_TO_US(rc6_unit * 2));
-               add_bits(scancode, 32, NS_TO_US(rc6_unit));
-               break;
-       }
-
-       /* drop any trailing pulse */
-       return (n % 2) ? n : n + 1;
-}
-
-static const struct {
-       char name[10];
-       unsigned scancode_mask;
-       unsigned max_edges;
-       unsigned carrier;
-       int (*encode)(enum rc_proto proto, unsigned scancode, unsigned *buf);
-} encoders[] = {
-       [RC_PROTO_RC5] = { "rc5", 0x1f7f, 24, 36000, rc5_encode },
-       [RC_PROTO_RC5X_20] = { "rc5x_20", 0x1f7f3f, 40, 36000, rc5_encode },
-       [RC_PROTO_RC5_SZ] = { "rc5_sz", 0x2fff, 26, 36000, rc5_encode },
-       [RC_PROTO_SONY12] = { "sony12", 0x1f007f, 25, 40000, sony_encode },
-       [RC_PROTO_SONY15] = { "sony15", 0xff007f, 31, 40000, sony_encode },
-       [RC_PROTO_SONY20] = { "sony20", 0x1fff7f, 41, 40000, sony_encode },
-       [RC_PROTO_JVC] = { "jvc", 0xffff, 35, 38000, jvc_encode },
-       [RC_PROTO_NEC] = { "nec", 0xffff, 67, 38000, nec_encode },
-       [RC_PROTO_NECX] = { "necx", 0xffffff, 67, 38000, nec_encode },
-       [RC_PROTO_NEC32] = { "nec32", 0xffffffff, 67, 38000, nec_encode },
-       [RC_PROTO_SANYO] = { "sanyo", 0x1fffff, 87, 38000, sanyo_encode },
-       [RC_PROTO_RC6_0] = { "rc6_0", 0xffff, 24, 36000, rc6_encode },
-       [RC_PROTO_RC6_6A_20] = { "rc6_6a_20", 0xfffff, 52, 36000, rc6_encode },
-       [RC_PROTO_RC6_6A_24] = { "rc6_6a_24", 0xffffff, 60, 36000, rc6_encode },
-       [RC_PROTO_RC6_6A_32] = { "rc6_6a_32", 0xffffffff, 76, 36000, rc6_encode 
},
-       [RC_PROTO_RC6_MCE] = { "rc6_mce", 0xffff7fff, 76, 36000, rc6_encode },
-       [RC_PROTO_SHARP] = { "sharp", 0x1fff, 63, 38000, sharp_encode },
-};
-
-static bool str_like(const char *a, const char *b)
-{
-       while (*a && *b) {
-               while (*a == ' ' || *a == '-' || *a == '_')
-                       a++;
-               while (*b == ' ' || *b == '-' || *b == '_')
-                       b++;
-
-               if (*a >= 0x7f || *b >= 0x7f)
-                       return false;
-
-               if (tolower(*a) != tolower(*b))
-                       return false;
-
-               a++; b++;
-       }
-
-       return !*a && !*b;
-}
-
-bool protocol_match(const char *name, enum rc_proto *proto)
-{
-       enum rc_proto p;
-
-       for (p=0; p<ARRAY_SIZE(encoders); p++) {
-               if (str_like(encoders[p].name, name)) {
-                       *proto = p;
-                       return true;
-               }
-       }
-
-       return false;
-}
-
-unsigned protocol_carrier(enum rc_proto proto)
-{
-       return encoders[proto].carrier;
-}
-
-unsigned protocol_max_size(enum rc_proto proto)
-{
-       return encoders[proto].max_edges;
-}
-
-unsigned protocol_scancode_mask(enum rc_proto proto)
-{
-       return encoders[proto].scancode_mask;
-}
-
-bool protocol_scancode_valid(enum rc_proto p, unsigned s)
-{
-       if (s & ~encoders[p].scancode_mask)
-               return false;
-
-       if (p == RC_PROTO_NECX) {
-               return (((s >> 16) ^ ~(s >> 8)) & 0xff) != 0;
-       } else if (p == RC_PROTO_NEC32) {
-               return (((s >> 24) ^ ~(s >> 16)) & 0xff) != 0;
-       } else if (p == RC_PROTO_RC6_MCE) {
-               return (s & 0xffff0000) == 0x800f0000;
-       } else if (p == RC_PROTO_RC6_6A_32) {
-               return (s & 0xffff0000) != 0x800f0000;
-       }
-
-       return true;
-}
-
-unsigned protocol_encode(enum rc_proto proto, unsigned scancode, unsigned *buf)
-{
-       return encoders[proto].encode(proto, scancode, buf);
-}
-
-const char* protocol_name(enum rc_proto proto)
-{
-       return encoders[proto].name;
-}
diff --git a/utils/ir-ctl/ir-encode.c b/utils/ir-ctl/ir-encode.c
new file mode 120000
index 000000000000..d973a0df0b0f
--- /dev/null
+++ b/utils/ir-ctl/ir-encode.c
@@ -0,0 +1 @@
+../common/ir-encode.c
\ No newline at end of file
diff --git a/utils/ir-ctl/ir-encode.h b/utils/ir-ctl/ir-encode.h
deleted file mode 100644
index 6e9c623e3548..000000000000
--- a/utils/ir-ctl/ir-encode.h
+++ /dev/null
@@ -1,15 +0,0 @@
-
-#ifndef __IR_ENCODE_H__
-#define __IR_ENCODE_H__
-
-#define ARRAY_SIZE(x)     (sizeof(x)/sizeof((x)[0]))
-
-bool protocol_match(const char *name, enum rc_proto *proto);
-unsigned protocol_carrier(enum rc_proto proto);
-unsigned protocol_max_size(enum rc_proto proto);
-bool protocol_scancode_valid(enum rc_proto proto, unsigned scancode);
-unsigned protocol_scancode_mask(enum rc_proto proto);
-unsigned protocol_encode(enum rc_proto proto, unsigned scancode, unsigned 
*buf);
-const char *protocol_name(enum rc_proto proto);
-
-#endif
diff --git a/utils/ir-ctl/ir-encode.h b/utils/ir-ctl/ir-encode.h
new file mode 120000
index 000000000000..39853214d203
--- /dev/null
+++ b/utils/ir-ctl/ir-encode.h
@@ -0,0 +1 @@
+../common/ir-encode.h
\ No newline at end of file
diff --git a/utils/keytable/Makefile.am b/utils/keytable/Makefile.am
index 62b90ad5c073..9eec51ae2249 100644
--- a/utils/keytable/Makefile.am
+++ b/utils/keytable/Makefile.am
@@ -4,7 +4,7 @@ sysconf_DATA = rc_maps.cfg
 keytablesystem_DATA = $(srcdir)/rc_keymaps/*
 udevrules_DATA = 70-infrared.rules
 
-ir_keytable_SOURCES = keytable.c parse.h
+ir_keytable_SOURCES = keytable.c parse.h ir-encode.c
 ir_keytable_LDADD = @LIBINTL@
 ir_keytable_LDFLAGS = $(ARGP_LIBS)
 
diff --git a/utils/keytable/ir-encode.c b/utils/keytable/ir-encode.c
new file mode 120000
index 000000000000..d973a0df0b0f
--- /dev/null
+++ b/utils/keytable/ir-encode.c
@@ -0,0 +1 @@
+../common/ir-encode.c
\ No newline at end of file
diff --git a/utils/keytable/ir-encode.h b/utils/keytable/ir-encode.h
new file mode 120000
index 000000000000..39853214d203
--- /dev/null
+++ b/utils/keytable/ir-encode.h
@@ -0,0 +1 @@
+../common/ir-encode.h
\ No newline at end of file
diff --git a/utils/keytable/keytable.c b/utils/keytable/keytable.c
index 988e98570c30..712830e8295a 100644
--- a/utils/keytable/keytable.c
+++ b/utils/keytable/keytable.c
@@ -18,16 +18,20 @@
 #include <fcntl.h>
 #include <stdio.h>
 #include <unistd.h>
+#include <poll.h>
 #include <stdlib.h>
 #include <string.h>
 #include <linux/input.h>
+#include <linux/lirc.h>
 #include <sys/ioctl.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <dirent.h>
 #include <argp.h>
+#include <time.h>
 #include <stdbool.h>
 
+#include "ir-encode.h"
 #include "parse.h"
 
 #ifdef ENABLE_NLS
@@ -271,6 +275,7 @@ static int sysfs = 0;
 struct rc_device {
        char *sysfs_name;       /* Device sysfs node name */
        char *input_name;       /* Input device file name */
+       char *lirc_name;        /* Lirc device file name */
        char *drv_name;         /* Kernel driver that implements it */
        char *dev_name;         /* Kernel device name */
        char *keytable_name;    /* Keycode table name */
@@ -1031,15 +1036,33 @@ static int v2_set_protocols(struct rc_device *rc_dev)
 static int get_attribs(struct rc_device *rc_dev, char *sysfs_name)
 {
        struct uevents  *uevent;
-       char            *input = "input", *event = "event";
+       char            *input = "input", *event = "event", *lirc = "lirc";
        char            *DEV = "/dev/";
-       static struct sysfs_names *input_names, *event_names, *attribs, *cur;
+       static struct sysfs_names *input_names, *event_names, *attribs, *cur, 
*lirc_names;
 
        /* Clean the attributes */
        memset(rc_dev, 0, sizeof(*rc_dev));
 
        rc_dev->sysfs_name = sysfs_name;
 
+       lirc_names = seek_sysfs_dir(rc_dev->sysfs_name, lirc);
+       if (lirc_names) {
+               uevent = read_sysfs_uevents(lirc_names->name);
+               free_names(lirc_names);
+               if (uevent) {
+                       while (uevent->next) {
+                               if (!strcmp(uevent->key, "DEVNAME")) {
+                                       rc_dev->lirc_name = 
malloc(strlen(uevent->value) + strlen(DEV) + 1);
+                                       strcpy(rc_dev->lirc_name, DEV);
+                                       strcat(rc_dev->lirc_name, 
uevent->value);
+                                       break;
+                               }
+                               uevent = uevent->next;
+                       }
+                       free_uevent(uevent);
+               }
+       }
+
        input_names = seek_sysfs_dir(rc_dev->sysfs_name, input);
        if (!input_names)
                return EINVAL;
@@ -1281,16 +1304,100 @@ static char *get_event_name(struct parse_event *event, 
u_int16_t code)
        return "";
 }
 
-static void test_event(int fd)
+static void print_scancodes(const struct lirc_scancode *scancodes, unsigned 
count)
+{
+       unsigned i;
+
+       for (i=0; i< count; i++)  {
+               const char *p = protocol_name(scancodes[i].rc_proto);
+
+               printf(_("%llu.%06llu: "),
+                       scancodes[i].timestamp / 1000000000ull,
+                       (scancodes[i].timestamp % 1000000000ull) / 1000ull);
+
+               if (p)
+                       printf(_("lirc protocol(%s): scancode = 0x%llx"),
+                               p, scancodes[i].scancode);
+               else
+                       printf(_("lirc protocol(%d): scancode = 0x%llx"),
+                               scancodes[i].rc_proto, scancodes[i].scancode);
+
+               if (scancodes[i].flags & LIRC_SCANCODE_FLAG_REPEAT)
+                       printf(_(" repeat"));
+               if (scancodes[i].flags & LIRC_SCANCODE_FLAG_TOGGLE)
+                       printf(_(" toggle=1"));
+
+               printf("\n");
+       }
+}
+
+static void test_event(struct rc_device *rc_dev, int fd)
 {
        struct input_event ev[64];
-       int rd, i;
+       struct lirc_scancode sc[64];
+       int rd, i, lircfd = -1;
+       unsigned mode;
+
+       /* LIRC reports time in monotonic, set event to same */
+       mode = CLOCK_MONOTONIC;
+       ioctl(fd, EVIOCSCLOCKID, &mode);
+
+       if (rc_dev->lirc_name) {
+               lircfd = open(rc_dev->lirc_name, O_RDONLY | O_NONBLOCK);
+               if (lircfd == -1) {
+                       perror(_("Can't open lirc device"));
+                       return;
+               }
+               unsigned features;
+               if (ioctl(lircfd, LIRC_GET_FEATURES, &features)) {
+                       perror(_("Can't get lirc features"));
+                       return;
+               }
+
+               if (!(features & LIRC_CAN_REC_SCANCODE)) {
+                       close(lircfd);
+                       lircfd = -1;
+               }
+               else {
+                       unsigned mode = LIRC_MODE_SCANCODE;
+                       if (ioctl(lircfd, LIRC_SET_REC_MODE, &mode)) {
+                               perror(_("Can't set lirc scancode mode"));
+                               return;
+                       }
+               }
+       }
 
        printf (_("Testing events. Please, press CTRL-C to abort.\n"));
        while (1) {
+               struct pollfd pollstruct[2] = {
+                       { .fd = fd, .events = POLLIN },
+                       { .fd = lircfd, .events = POLLIN },
+               };
+
+               if (poll(pollstruct, 2, -1) < 0) {
+                       if (errno == EINTR)
+                               continue;
+
+                       perror(_("poll returned error"));
+               }
+
+               if (lircfd != -1) {
+                       rd = read(lircfd, sc, sizeof(sc));
+
+                       if (rd != -1) {
+                               print_scancodes(sc, rd / sizeof(struct 
lirc_scancode));
+                       } else if (errno != EAGAIN) {
+                               perror(_("Error reading lirc scancode"));
+                               return;
+                       }
+               }
+
                rd = read(fd, ev, sizeof(ev));
 
                if (rd < (int) sizeof(struct input_event)) {
+                       if (errno == EAGAIN)
+                               continue;
+
                        perror(_("Error reading event"));
                        return;
                }
@@ -1482,6 +1589,9 @@ static int show_sysfs_attribs(struct rc_device *rc_dev, 
char *name)
                        fprintf(stderr, _("\tDriver: %s, table: %s\n"),
                                rc_dev->drv_name,
                                rc_dev->keytable_name);
+                       if (rc_dev->lirc_name)
+                               fprintf(stderr, _("\tlirc device: %s\n"),
+                                       rc_dev->lirc_name);
                        fprintf(stderr, _("\tSupported protocols: "));
                        write_sysfs_protocols(rc_dev->supported, stderr, "%s ");
                        fprintf(stderr, "\n\t");
@@ -1615,7 +1725,7 @@ int main(int argc, char *argv[])
 
        if (debug)
                fprintf(stderr, _("Opening %s\n"), devicename);
-       fd = open(devicename, O_RDONLY);
+       fd = open(devicename, O_RDONLY | O_NONBLOCK);
        if (fd < 0) {
                perror(devicename);
                return -1;
@@ -1674,7 +1784,7 @@ int main(int argc, char *argv[])
        }
 
        if (test)
-               test_event(fd);
+               test_event(&rc_dev, fd);
 
        return 0;
 }

_______________________________________________
linuxtv-commits mailing list
linuxtv-commits@linuxtv.org
https://www.linuxtv.org/cgi-bin/mailman/listinfo/linuxtv-commits

Reply via email to