From 7707a0a68579bc45f2698a08f85b0cfe71a18816 Mon Sep 17 00:00:00 2001 From: MilhouseVH Date: Wed, 3 Apr 2019 13:10:43 +0100 Subject: [PATCH] linux (Generic/RPi): drop backported rcmm-ir-decoder patches --- .../linux-903-backport-rcmm-ir-decoder.patch | 506 ------------------ .../linux-903-backport-rcmm-ir-decoder.patch | 506 ------------------ 2 files changed, 1012 deletions(-) delete mode 100644 packages/linux/patches/default/linux-903-backport-rcmm-ir-decoder.patch delete mode 100644 packages/linux/patches/raspberrypi/linux-903-backport-rcmm-ir-decoder.patch diff --git a/packages/linux/patches/default/linux-903-backport-rcmm-ir-decoder.patch b/packages/linux/patches/default/linux-903-backport-rcmm-ir-decoder.patch deleted file mode 100644 index ae2cba8494..0000000000 --- a/packages/linux/patches/default/linux-903-backport-rcmm-ir-decoder.patch +++ /dev/null @@ -1,506 +0,0 @@ -From da8a71104dda4a85a9d9546ff462542347f8efa6 Mon Sep 17 00:00:00 2001 -From: Matthias Reichl -Date: Wed, 20 Mar 2019 09:11:53 +0100 -Subject: [PATCH] media: rc: rcmm decoder and encoder - -commit 721074b03411327e7bf41555d4cc7c18f49313f7 upstream. - -media: add support for RCMM infrared remote controls. - -Signed-off-by: Patrick Lerda -Signed-off-by: Sean Young -Signed-off-by: Mauro Carvalho Chehab -Signed-off-by: Matthias Reichl ---- - Documentation/media/lirc.h.rst.exceptions | 3 + - MAINTAINERS | 5 + - drivers/media/rc/Kconfig | 13 ++ - drivers/media/rc/Makefile | 1 + - drivers/media/rc/ir-rcmm-decoder.c | 254 ++++++++++++++++++++++ - drivers/media/rc/rc-core-priv.h | 5 + - drivers/media/rc/rc-main.c | 9 + - include/media/rc-map.h | 14 +- - include/uapi/linux/lirc.h | 6 + - tools/include/uapi/linux/lirc.h | 12 + - 10 files changed, 319 insertions(+), 3 deletions(-) - create mode 100644 drivers/media/rc/ir-rcmm-decoder.c - -diff --git a/Documentation/media/lirc.h.rst.exceptions b/Documentation/media/lirc.h.rst.exceptions -index 984b61dc3f2e..e7a41d4b3d46 100644 ---- a/Documentation/media/lirc.h.rst.exceptions -+++ b/Documentation/media/lirc.h.rst.exceptions -@@ -58,6 +58,9 @@ ignore symbol RC_PROTO_SHARP - ignore symbol RC_PROTO_XMP - ignore symbol RC_PROTO_CEC - ignore symbol RC_PROTO_IMON -+ignore symbol RC_PROTO_RCMM12 -+ignore symbol RC_PROTO_RCMM24 -+ignore symbol RC_PROTO_RCMM32 - - # Undocumented macros - -diff --git a/MAINTAINERS b/MAINTAINERS -index 9e9b19ecf6f7..57b60dd42729 100644 ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -15837,6 +15837,11 @@ M: David Härdeman - S: Maintained - F: drivers/media/rc/winbond-cir.c - -+RCMM REMOTE CONTROLS DECODER -+M: Patrick Lerda -+S: Maintained -+F: drivers/media/rc/ir-rcmm-decoder.c -+ - WINSYSTEMS EBC-C384 WATCHDOG DRIVER - M: William Breathitt Gray - L: linux-watchdog@vger.kernel.org -diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig -index 1021c08a9ba4..8164a889011a 100644 ---- a/drivers/media/rc/Kconfig -+++ b/drivers/media/rc/Kconfig -@@ -133,6 +133,19 @@ config IR_IMON_DECODER - remote control and you would like to use it with a raw IR - receiver, or if you wish to use an encoder to transmit this IR. - -+config IR_RCMM_DECODER -+ tristate "Enable IR raw decoder for the RC-MM protocol" -+ depends on RC_CORE -+ help -+ Enable this option when you have IR with RC-MM protocol, and -+ you need the software decoder. The driver supports 12, -+ 24 and 32 bits RC-MM variants. You can enable or disable the -+ different modes using the following RC protocol keywords: -+ 'rc-mm-12', 'rc-mm-24' and 'rc-mm-32'. -+ -+ To compile this driver as a module, choose M here: the module -+ will be called ir-rcmm-decoder. -+ - endif #RC_DECODERS - - menuconfig RC_DEVICES -diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile -index e0340d043fe8..fc4058013234 100644 ---- a/drivers/media/rc/Makefile -+++ b/drivers/media/rc/Makefile -@@ -16,6 +16,7 @@ obj-$(CONFIG_IR_SHARP_DECODER) += ir-sharp-decoder.o - obj-$(CONFIG_IR_MCE_KBD_DECODER) += ir-mce_kbd-decoder.o - obj-$(CONFIG_IR_XMP_DECODER) += ir-xmp-decoder.o - obj-$(CONFIG_IR_IMON_DECODER) += ir-imon-decoder.o -+obj-$(CONFIG_IR_RCMM_DECODER) += ir-rcmm-decoder.o - - # stand-alone IR receivers/transmitters - obj-$(CONFIG_RC_ATI_REMOTE) += ati_remote.o -diff --git a/drivers/media/rc/ir-rcmm-decoder.c b/drivers/media/rc/ir-rcmm-decoder.c -new file mode 100644 -index 000000000000..f1096ac1e5c5 ---- /dev/null -+++ b/drivers/media/rc/ir-rcmm-decoder.c -@@ -0,0 +1,254 @@ -+// SPDX-License-Identifier: GPL-2.0+ -+// ir-rcmm-decoder.c - A decoder for the RCMM IR protocol -+// -+// Copyright (C) 2018 by Patrick Lerda -+ -+#include "rc-core-priv.h" -+#include -+#include -+ -+#define RCMM_UNIT 166667 /* nanosecs */ -+#define RCMM_PREFIX_PULSE 416666 /* 166666.666666666*2.5 */ -+#define RCMM_PULSE_0 277777 /* 166666.666666666*(1+2/3) */ -+#define RCMM_PULSE_1 444444 /* 166666.666666666*(2+2/3) */ -+#define RCMM_PULSE_2 611111 /* 166666.666666666*(3+2/3) */ -+#define RCMM_PULSE_3 777778 /* 166666.666666666*(4+2/3) */ -+ -+enum rcmm_state { -+ STATE_INACTIVE, -+ STATE_LOW, -+ STATE_BUMP, -+ STATE_VALUE, -+ STATE_FINISHED, -+}; -+ -+static bool rcmm_mode(const struct rcmm_dec *data) -+{ -+ return !((0x000c0000 & data->bits) == 0x000c0000); -+} -+ -+static int rcmm_miscmode(struct rc_dev *dev, struct rcmm_dec *data) -+{ -+ switch (data->count) { -+ case 24: -+ if (dev->enabled_protocols & RC_PROTO_BIT_RCMM24) { -+ rc_keydown(dev, RC_PROTO_RCMM24, data->bits, 0); -+ data->state = STATE_INACTIVE; -+ return 0; -+ } -+ return -1; -+ -+ case 12: -+ if (dev->enabled_protocols & RC_PROTO_BIT_RCMM12) { -+ rc_keydown(dev, RC_PROTO_RCMM12, data->bits, 0); -+ data->state = STATE_INACTIVE; -+ return 0; -+ } -+ return -1; -+ } -+ -+ return -1; -+} -+ -+/** -+ * ir_rcmm_decode() - Decode one RCMM pulse or space -+ * @dev: the struct rc_dev descriptor of the device -+ * @ev: the struct ir_raw_event descriptor of the pulse/space -+ * -+ * This function returns -EINVAL if the pulse violates the state machine -+ */ -+static int ir_rcmm_decode(struct rc_dev *dev, struct ir_raw_event ev) -+{ -+ struct rcmm_dec *data = &dev->raw->rcmm; -+ u32 scancode; -+ u8 toggle; -+ int value; -+ -+ if (!(dev->enabled_protocols & (RC_PROTO_BIT_RCMM32 | -+ RC_PROTO_BIT_RCMM24 | -+ RC_PROTO_BIT_RCMM12))) -+ return 0; -+ -+ if (!is_timing_event(ev)) { -+ if (ev.reset) -+ data->state = STATE_INACTIVE; -+ return 0; -+ } -+ -+ switch (data->state) { -+ case STATE_INACTIVE: -+ if (!ev.pulse) -+ break; -+ -+ if (!eq_margin(ev.duration, RCMM_PREFIX_PULSE, RCMM_UNIT / 2)) -+ break; -+ -+ data->state = STATE_LOW; -+ data->count = 0; -+ data->bits = 0; -+ return 0; -+ -+ case STATE_LOW: -+ if (ev.pulse) -+ break; -+ -+ if (!eq_margin(ev.duration, RCMM_PULSE_0, RCMM_UNIT / 2)) -+ break; -+ -+ data->state = STATE_BUMP; -+ return 0; -+ -+ case STATE_BUMP: -+ if (!ev.pulse) -+ break; -+ -+ if (!eq_margin(ev.duration, RCMM_UNIT, RCMM_UNIT / 2)) -+ break; -+ -+ data->state = STATE_VALUE; -+ return 0; -+ -+ case STATE_VALUE: -+ if (ev.pulse) -+ break; -+ -+ if (eq_margin(ev.duration, RCMM_PULSE_0, RCMM_UNIT / 2)) -+ value = 0; -+ else if (eq_margin(ev.duration, RCMM_PULSE_1, RCMM_UNIT / 2)) -+ value = 1; -+ else if (eq_margin(ev.duration, RCMM_PULSE_2, RCMM_UNIT / 2)) -+ value = 2; -+ else if (eq_margin(ev.duration, RCMM_PULSE_3, RCMM_UNIT / 2)) -+ value = 3; -+ else -+ value = -1; -+ -+ if (value == -1) { -+ if (!rcmm_miscmode(dev, data)) -+ return 0; -+ break; -+ } -+ -+ data->bits <<= 2; -+ data->bits |= value; -+ -+ data->count += 2; -+ -+ if (data->count < 32) -+ data->state = STATE_BUMP; -+ else -+ data->state = STATE_FINISHED; -+ -+ return 0; -+ -+ case STATE_FINISHED: -+ if (!ev.pulse) -+ break; -+ -+ if (!eq_margin(ev.duration, RCMM_UNIT, RCMM_UNIT / 2)) -+ break; -+ -+ if (rcmm_mode(data)) { -+ toggle = !!(0x8000 & data->bits); -+ scancode = data->bits & ~0x8000; -+ } else { -+ toggle = 0; -+ scancode = data->bits; -+ } -+ -+ if (dev->enabled_protocols & RC_PROTO_BIT_RCMM32) { -+ rc_keydown(dev, RC_PROTO_RCMM32, scancode, toggle); -+ data->state = STATE_INACTIVE; -+ return 0; -+ } -+ -+ break; -+ } -+ -+ data->state = STATE_INACTIVE; -+ return -EINVAL; -+} -+ -+static const int rcmmspace[] = { -+ RCMM_PULSE_0, -+ RCMM_PULSE_1, -+ RCMM_PULSE_2, -+ RCMM_PULSE_3, -+}; -+ -+static int ir_rcmm_rawencoder(struct ir_raw_event **ev, unsigned int max, -+ unsigned int n, u32 data) -+{ -+ int i; -+ int ret; -+ -+ ret = ir_raw_gen_pulse_space(ev, &max, RCMM_PREFIX_PULSE, RCMM_PULSE_0); -+ if (ret) -+ return ret; -+ -+ for (i = n - 2; i >= 0; i -= 2) { -+ const unsigned int space = rcmmspace[(data >> i) & 3]; -+ -+ ret = ir_raw_gen_pulse_space(ev, &max, RCMM_UNIT, space); -+ if (ret) -+ return ret; -+ } -+ -+ return ir_raw_gen_pulse_space(ev, &max, RCMM_UNIT, RCMM_PULSE_3 * 2); -+} -+ -+static int ir_rcmm_encode(enum rc_proto protocol, u32 scancode, -+ struct ir_raw_event *events, unsigned int max) -+{ -+ struct ir_raw_event *e = events; -+ int ret; -+ -+ switch (protocol) { -+ case RC_PROTO_RCMM32: -+ ret = ir_rcmm_rawencoder(&e, max, 32, scancode); -+ break; -+ case RC_PROTO_RCMM24: -+ ret = ir_rcmm_rawencoder(&e, max, 24, scancode); -+ break; -+ case RC_PROTO_RCMM12: -+ ret = ir_rcmm_rawencoder(&e, max, 12, scancode); -+ break; -+ default: -+ ret = -EINVAL; -+ } -+ -+ if (ret < 0) -+ return ret; -+ -+ return e - events; -+} -+ -+static struct ir_raw_handler rcmm_handler = { -+ .protocols = RC_PROTO_BIT_RCMM32 | -+ RC_PROTO_BIT_RCMM24 | -+ RC_PROTO_BIT_RCMM12, -+ .decode = ir_rcmm_decode, -+ .encode = ir_rcmm_encode, -+ .carrier = 36000, -+ .min_timeout = RCMM_PULSE_3 + RCMM_UNIT, -+}; -+ -+static int __init ir_rcmm_decode_init(void) -+{ -+ ir_raw_handler_register(&rcmm_handler); -+ -+ pr_info("IR RCMM protocol handler initialized\n"); -+ return 0; -+} -+ -+static void __exit ir_rcmm_decode_exit(void) -+{ -+ ir_raw_handler_unregister(&rcmm_handler); -+} -+ -+module_init(ir_rcmm_decode_init); -+module_exit(ir_rcmm_decode_exit); -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Patrick Lerda"); -+MODULE_DESCRIPTION("RCMM IR protocol decoder"); -diff --git a/drivers/media/rc/rc-core-priv.h b/drivers/media/rc/rc-core-priv.h -index e847bdad5c51..59c252f24194 100644 ---- a/drivers/media/rc/rc-core-priv.h -+++ b/drivers/media/rc/rc-core-priv.h -@@ -136,6 +136,11 @@ struct ir_raw_event_ctrl { - struct input_dev *idev; - char name[64]; - } imon; -+ struct rcmm_dec { -+ int state; -+ unsigned int count; -+ u32 bits; -+ } rcmm; - }; - - /* Mutex for locking raw IR processing and handler change */ -diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c -index 0f218afdadaa..78e79c37f208 100644 ---- a/drivers/media/rc/rc-main.c -+++ b/drivers/media/rc/rc-main.c -@@ -70,6 +70,12 @@ static const struct { - [RC_PROTO_CEC] = { .name = "cec", .repeat_period = 0 }, - [RC_PROTO_IMON] = { .name = "imon", - .scancode_bits = 0x7fffffff, .repeat_period = 114 }, -+ [RC_PROTO_RCMM12] = { .name = "rc-mm-12", -+ .scancode_bits = 0x00000fff, .repeat_period = 114 }, -+ [RC_PROTO_RCMM24] = { .name = "rc-mm-24", -+ .scancode_bits = 0x00ffffff, .repeat_period = 114 }, -+ [RC_PROTO_RCMM32] = { .name = "rc-mm-32", -+ .scancode_bits = 0xffffffff, .repeat_period = 114 }, - }; - - /* Used to keep track of known keymaps */ -@@ -1018,6 +1024,9 @@ static const struct { - { RC_PROTO_BIT_XMP, "xmp", "ir-xmp-decoder" }, - { RC_PROTO_BIT_CEC, "cec", NULL }, - { RC_PROTO_BIT_IMON, "imon", "ir-imon-decoder" }, -+ { RC_PROTO_BIT_RCMM12 | -+ RC_PROTO_BIT_RCMM24 | -+ RC_PROTO_BIT_RCMM32, "rc-mm", "ir-rcmm-decoder" }, - }; - - /** -diff --git a/include/media/rc-map.h b/include/media/rc-map.h -index bfa3017cecba..cf308b73edae 100644 ---- a/include/media/rc-map.h -+++ b/include/media/rc-map.h -@@ -37,6 +37,9 @@ - #define RC_PROTO_BIT_XMP BIT_ULL(RC_PROTO_XMP) - #define RC_PROTO_BIT_CEC BIT_ULL(RC_PROTO_CEC) - #define RC_PROTO_BIT_IMON BIT_ULL(RC_PROTO_IMON) -+#define RC_PROTO_BIT_RCMM12 BIT_ULL(RC_PROTO_RCMM12) -+#define RC_PROTO_BIT_RCMM24 BIT_ULL(RC_PROTO_RCMM24) -+#define RC_PROTO_BIT_RCMM32 BIT_ULL(RC_PROTO_RCMM32) - - #define RC_PROTO_BIT_ALL \ - (RC_PROTO_BIT_UNKNOWN | RC_PROTO_BIT_OTHER | \ -@@ -51,7 +54,8 @@ - RC_PROTO_BIT_RC6_6A_24 | RC_PROTO_BIT_RC6_6A_32 | \ - RC_PROTO_BIT_RC6_MCE | RC_PROTO_BIT_SHARP | \ - RC_PROTO_BIT_XMP | RC_PROTO_BIT_CEC | \ -- RC_PROTO_BIT_IMON) -+ RC_PROTO_BIT_IMON | RC_PROTO_BIT_RCMM12 | \ -+ RC_PROTO_BIT_RCMM24 | RC_PROTO_BIT_RCMM32) - /* All rc protocols for which we have decoders */ - #define RC_PROTO_BIT_ALL_IR_DECODER \ - (RC_PROTO_BIT_RC5 | RC_PROTO_BIT_RC5X_20 | \ -@@ -64,7 +68,9 @@ - RC_PROTO_BIT_RC6_0 | RC_PROTO_BIT_RC6_6A_20 | \ - RC_PROTO_BIT_RC6_6A_24 | RC_PROTO_BIT_RC6_6A_32 | \ - RC_PROTO_BIT_RC6_MCE | RC_PROTO_BIT_SHARP | \ -- RC_PROTO_BIT_XMP | RC_PROTO_BIT_IMON) -+ RC_PROTO_BIT_XMP | RC_PROTO_BIT_IMON | \ -+ RC_PROTO_BIT_RCMM12 | RC_PROTO_BIT_RCMM24 | \ -+ RC_PROTO_BIT_RCMM32) - - #define RC_PROTO_BIT_ALL_IR_ENCODER \ - (RC_PROTO_BIT_RC5 | RC_PROTO_BIT_RC5X_20 | \ -@@ -77,7 +83,9 @@ - RC_PROTO_BIT_RC6_0 | RC_PROTO_BIT_RC6_6A_20 | \ - RC_PROTO_BIT_RC6_6A_24 | \ - RC_PROTO_BIT_RC6_6A_32 | RC_PROTO_BIT_RC6_MCE | \ -- RC_PROTO_BIT_SHARP | RC_PROTO_BIT_IMON) -+ RC_PROTO_BIT_SHARP | RC_PROTO_BIT_IMON | \ -+ RC_PROTO_BIT_RCMM12 | RC_PROTO_BIT_RCMM24 | \ -+ RC_PROTO_BIT_RCMM32) - - #define RC_SCANCODE_UNKNOWN(x) (x) - #define RC_SCANCODE_OTHER(x) (x) -diff --git a/include/uapi/linux/lirc.h b/include/uapi/linux/lirc.h -index 6b319581882f..45fcbf99d72e 100644 ---- a/include/uapi/linux/lirc.h -+++ b/include/uapi/linux/lirc.h -@@ -192,6 +192,9 @@ struct lirc_scancode { - * @RC_PROTO_XMP: XMP protocol - * @RC_PROTO_CEC: CEC protocol - * @RC_PROTO_IMON: iMon Pad protocol -+ * @RC_PROTO_RCMM12: RC-MM protocol 12 bits -+ * @RC_PROTO_RCMM24: RC-MM protocol 24 bits -+ * @RC_PROTO_RCMM32: RC-MM protocol 32 bits - */ - enum rc_proto { - RC_PROTO_UNKNOWN = 0, -@@ -218,6 +221,9 @@ enum rc_proto { - RC_PROTO_XMP = 21, - RC_PROTO_CEC = 22, - RC_PROTO_IMON = 23, -+ RC_PROTO_RCMM12 = 24, -+ RC_PROTO_RCMM24 = 25, -+ RC_PROTO_RCMM32 = 26, - }; - - #endif -diff --git a/tools/include/uapi/linux/lirc.h b/tools/include/uapi/linux/lirc.h -index f189931042a7..45fcbf99d72e 100644 ---- a/tools/include/uapi/linux/lirc.h -+++ b/tools/include/uapi/linux/lirc.h -@@ -133,6 +133,12 @@ - - #define LIRC_SET_WIDEBAND_RECEIVER _IOW('i', 0x00000023, __u32) - -+/* -+ * Return the recording timeout, which is either set by -+ * the ioctl LIRC_SET_REC_TIMEOUT or by the kernel after setting the protocols. -+ */ -+#define LIRC_GET_REC_TIMEOUT _IOR('i', 0x00000024, __u32) -+ - /* - * struct lirc_scancode - decoded scancode with protocol for use with - * LIRC_MODE_SCANCODE -@@ -186,6 +192,9 @@ struct lirc_scancode { - * @RC_PROTO_XMP: XMP protocol - * @RC_PROTO_CEC: CEC protocol - * @RC_PROTO_IMON: iMon Pad protocol -+ * @RC_PROTO_RCMM12: RC-MM protocol 12 bits -+ * @RC_PROTO_RCMM24: RC-MM protocol 24 bits -+ * @RC_PROTO_RCMM32: RC-MM protocol 32 bits - */ - enum rc_proto { - RC_PROTO_UNKNOWN = 0, -@@ -212,6 +221,9 @@ enum rc_proto { - RC_PROTO_XMP = 21, - RC_PROTO_CEC = 22, - RC_PROTO_IMON = 23, -+ RC_PROTO_RCMM12 = 24, -+ RC_PROTO_RCMM24 = 25, -+ RC_PROTO_RCMM32 = 26, - }; - - #endif --- -2.20.1 - diff --git a/packages/linux/patches/raspberrypi/linux-903-backport-rcmm-ir-decoder.patch b/packages/linux/patches/raspberrypi/linux-903-backport-rcmm-ir-decoder.patch deleted file mode 100644 index ae2cba8494..0000000000 --- a/packages/linux/patches/raspberrypi/linux-903-backport-rcmm-ir-decoder.patch +++ /dev/null @@ -1,506 +0,0 @@ -From da8a71104dda4a85a9d9546ff462542347f8efa6 Mon Sep 17 00:00:00 2001 -From: Matthias Reichl -Date: Wed, 20 Mar 2019 09:11:53 +0100 -Subject: [PATCH] media: rc: rcmm decoder and encoder - -commit 721074b03411327e7bf41555d4cc7c18f49313f7 upstream. - -media: add support for RCMM infrared remote controls. - -Signed-off-by: Patrick Lerda -Signed-off-by: Sean Young -Signed-off-by: Mauro Carvalho Chehab -Signed-off-by: Matthias Reichl ---- - Documentation/media/lirc.h.rst.exceptions | 3 + - MAINTAINERS | 5 + - drivers/media/rc/Kconfig | 13 ++ - drivers/media/rc/Makefile | 1 + - drivers/media/rc/ir-rcmm-decoder.c | 254 ++++++++++++++++++++++ - drivers/media/rc/rc-core-priv.h | 5 + - drivers/media/rc/rc-main.c | 9 + - include/media/rc-map.h | 14 +- - include/uapi/linux/lirc.h | 6 + - tools/include/uapi/linux/lirc.h | 12 + - 10 files changed, 319 insertions(+), 3 deletions(-) - create mode 100644 drivers/media/rc/ir-rcmm-decoder.c - -diff --git a/Documentation/media/lirc.h.rst.exceptions b/Documentation/media/lirc.h.rst.exceptions -index 984b61dc3f2e..e7a41d4b3d46 100644 ---- a/Documentation/media/lirc.h.rst.exceptions -+++ b/Documentation/media/lirc.h.rst.exceptions -@@ -58,6 +58,9 @@ ignore symbol RC_PROTO_SHARP - ignore symbol RC_PROTO_XMP - ignore symbol RC_PROTO_CEC - ignore symbol RC_PROTO_IMON -+ignore symbol RC_PROTO_RCMM12 -+ignore symbol RC_PROTO_RCMM24 -+ignore symbol RC_PROTO_RCMM32 - - # Undocumented macros - -diff --git a/MAINTAINERS b/MAINTAINERS -index 9e9b19ecf6f7..57b60dd42729 100644 ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -15837,6 +15837,11 @@ M: David Härdeman - S: Maintained - F: drivers/media/rc/winbond-cir.c - -+RCMM REMOTE CONTROLS DECODER -+M: Patrick Lerda -+S: Maintained -+F: drivers/media/rc/ir-rcmm-decoder.c -+ - WINSYSTEMS EBC-C384 WATCHDOG DRIVER - M: William Breathitt Gray - L: linux-watchdog@vger.kernel.org -diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig -index 1021c08a9ba4..8164a889011a 100644 ---- a/drivers/media/rc/Kconfig -+++ b/drivers/media/rc/Kconfig -@@ -133,6 +133,19 @@ config IR_IMON_DECODER - remote control and you would like to use it with a raw IR - receiver, or if you wish to use an encoder to transmit this IR. - -+config IR_RCMM_DECODER -+ tristate "Enable IR raw decoder for the RC-MM protocol" -+ depends on RC_CORE -+ help -+ Enable this option when you have IR with RC-MM protocol, and -+ you need the software decoder. The driver supports 12, -+ 24 and 32 bits RC-MM variants. You can enable or disable the -+ different modes using the following RC protocol keywords: -+ 'rc-mm-12', 'rc-mm-24' and 'rc-mm-32'. -+ -+ To compile this driver as a module, choose M here: the module -+ will be called ir-rcmm-decoder. -+ - endif #RC_DECODERS - - menuconfig RC_DEVICES -diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile -index e0340d043fe8..fc4058013234 100644 ---- a/drivers/media/rc/Makefile -+++ b/drivers/media/rc/Makefile -@@ -16,6 +16,7 @@ obj-$(CONFIG_IR_SHARP_DECODER) += ir-sharp-decoder.o - obj-$(CONFIG_IR_MCE_KBD_DECODER) += ir-mce_kbd-decoder.o - obj-$(CONFIG_IR_XMP_DECODER) += ir-xmp-decoder.o - obj-$(CONFIG_IR_IMON_DECODER) += ir-imon-decoder.o -+obj-$(CONFIG_IR_RCMM_DECODER) += ir-rcmm-decoder.o - - # stand-alone IR receivers/transmitters - obj-$(CONFIG_RC_ATI_REMOTE) += ati_remote.o -diff --git a/drivers/media/rc/ir-rcmm-decoder.c b/drivers/media/rc/ir-rcmm-decoder.c -new file mode 100644 -index 000000000000..f1096ac1e5c5 ---- /dev/null -+++ b/drivers/media/rc/ir-rcmm-decoder.c -@@ -0,0 +1,254 @@ -+// SPDX-License-Identifier: GPL-2.0+ -+// ir-rcmm-decoder.c - A decoder for the RCMM IR protocol -+// -+// Copyright (C) 2018 by Patrick Lerda -+ -+#include "rc-core-priv.h" -+#include -+#include -+ -+#define RCMM_UNIT 166667 /* nanosecs */ -+#define RCMM_PREFIX_PULSE 416666 /* 166666.666666666*2.5 */ -+#define RCMM_PULSE_0 277777 /* 166666.666666666*(1+2/3) */ -+#define RCMM_PULSE_1 444444 /* 166666.666666666*(2+2/3) */ -+#define RCMM_PULSE_2 611111 /* 166666.666666666*(3+2/3) */ -+#define RCMM_PULSE_3 777778 /* 166666.666666666*(4+2/3) */ -+ -+enum rcmm_state { -+ STATE_INACTIVE, -+ STATE_LOW, -+ STATE_BUMP, -+ STATE_VALUE, -+ STATE_FINISHED, -+}; -+ -+static bool rcmm_mode(const struct rcmm_dec *data) -+{ -+ return !((0x000c0000 & data->bits) == 0x000c0000); -+} -+ -+static int rcmm_miscmode(struct rc_dev *dev, struct rcmm_dec *data) -+{ -+ switch (data->count) { -+ case 24: -+ if (dev->enabled_protocols & RC_PROTO_BIT_RCMM24) { -+ rc_keydown(dev, RC_PROTO_RCMM24, data->bits, 0); -+ data->state = STATE_INACTIVE; -+ return 0; -+ } -+ return -1; -+ -+ case 12: -+ if (dev->enabled_protocols & RC_PROTO_BIT_RCMM12) { -+ rc_keydown(dev, RC_PROTO_RCMM12, data->bits, 0); -+ data->state = STATE_INACTIVE; -+ return 0; -+ } -+ return -1; -+ } -+ -+ return -1; -+} -+ -+/** -+ * ir_rcmm_decode() - Decode one RCMM pulse or space -+ * @dev: the struct rc_dev descriptor of the device -+ * @ev: the struct ir_raw_event descriptor of the pulse/space -+ * -+ * This function returns -EINVAL if the pulse violates the state machine -+ */ -+static int ir_rcmm_decode(struct rc_dev *dev, struct ir_raw_event ev) -+{ -+ struct rcmm_dec *data = &dev->raw->rcmm; -+ u32 scancode; -+ u8 toggle; -+ int value; -+ -+ if (!(dev->enabled_protocols & (RC_PROTO_BIT_RCMM32 | -+ RC_PROTO_BIT_RCMM24 | -+ RC_PROTO_BIT_RCMM12))) -+ return 0; -+ -+ if (!is_timing_event(ev)) { -+ if (ev.reset) -+ data->state = STATE_INACTIVE; -+ return 0; -+ } -+ -+ switch (data->state) { -+ case STATE_INACTIVE: -+ if (!ev.pulse) -+ break; -+ -+ if (!eq_margin(ev.duration, RCMM_PREFIX_PULSE, RCMM_UNIT / 2)) -+ break; -+ -+ data->state = STATE_LOW; -+ data->count = 0; -+ data->bits = 0; -+ return 0; -+ -+ case STATE_LOW: -+ if (ev.pulse) -+ break; -+ -+ if (!eq_margin(ev.duration, RCMM_PULSE_0, RCMM_UNIT / 2)) -+ break; -+ -+ data->state = STATE_BUMP; -+ return 0; -+ -+ case STATE_BUMP: -+ if (!ev.pulse) -+ break; -+ -+ if (!eq_margin(ev.duration, RCMM_UNIT, RCMM_UNIT / 2)) -+ break; -+ -+ data->state = STATE_VALUE; -+ return 0; -+ -+ case STATE_VALUE: -+ if (ev.pulse) -+ break; -+ -+ if (eq_margin(ev.duration, RCMM_PULSE_0, RCMM_UNIT / 2)) -+ value = 0; -+ else if (eq_margin(ev.duration, RCMM_PULSE_1, RCMM_UNIT / 2)) -+ value = 1; -+ else if (eq_margin(ev.duration, RCMM_PULSE_2, RCMM_UNIT / 2)) -+ value = 2; -+ else if (eq_margin(ev.duration, RCMM_PULSE_3, RCMM_UNIT / 2)) -+ value = 3; -+ else -+ value = -1; -+ -+ if (value == -1) { -+ if (!rcmm_miscmode(dev, data)) -+ return 0; -+ break; -+ } -+ -+ data->bits <<= 2; -+ data->bits |= value; -+ -+ data->count += 2; -+ -+ if (data->count < 32) -+ data->state = STATE_BUMP; -+ else -+ data->state = STATE_FINISHED; -+ -+ return 0; -+ -+ case STATE_FINISHED: -+ if (!ev.pulse) -+ break; -+ -+ if (!eq_margin(ev.duration, RCMM_UNIT, RCMM_UNIT / 2)) -+ break; -+ -+ if (rcmm_mode(data)) { -+ toggle = !!(0x8000 & data->bits); -+ scancode = data->bits & ~0x8000; -+ } else { -+ toggle = 0; -+ scancode = data->bits; -+ } -+ -+ if (dev->enabled_protocols & RC_PROTO_BIT_RCMM32) { -+ rc_keydown(dev, RC_PROTO_RCMM32, scancode, toggle); -+ data->state = STATE_INACTIVE; -+ return 0; -+ } -+ -+ break; -+ } -+ -+ data->state = STATE_INACTIVE; -+ return -EINVAL; -+} -+ -+static const int rcmmspace[] = { -+ RCMM_PULSE_0, -+ RCMM_PULSE_1, -+ RCMM_PULSE_2, -+ RCMM_PULSE_3, -+}; -+ -+static int ir_rcmm_rawencoder(struct ir_raw_event **ev, unsigned int max, -+ unsigned int n, u32 data) -+{ -+ int i; -+ int ret; -+ -+ ret = ir_raw_gen_pulse_space(ev, &max, RCMM_PREFIX_PULSE, RCMM_PULSE_0); -+ if (ret) -+ return ret; -+ -+ for (i = n - 2; i >= 0; i -= 2) { -+ const unsigned int space = rcmmspace[(data >> i) & 3]; -+ -+ ret = ir_raw_gen_pulse_space(ev, &max, RCMM_UNIT, space); -+ if (ret) -+ return ret; -+ } -+ -+ return ir_raw_gen_pulse_space(ev, &max, RCMM_UNIT, RCMM_PULSE_3 * 2); -+} -+ -+static int ir_rcmm_encode(enum rc_proto protocol, u32 scancode, -+ struct ir_raw_event *events, unsigned int max) -+{ -+ struct ir_raw_event *e = events; -+ int ret; -+ -+ switch (protocol) { -+ case RC_PROTO_RCMM32: -+ ret = ir_rcmm_rawencoder(&e, max, 32, scancode); -+ break; -+ case RC_PROTO_RCMM24: -+ ret = ir_rcmm_rawencoder(&e, max, 24, scancode); -+ break; -+ case RC_PROTO_RCMM12: -+ ret = ir_rcmm_rawencoder(&e, max, 12, scancode); -+ break; -+ default: -+ ret = -EINVAL; -+ } -+ -+ if (ret < 0) -+ return ret; -+ -+ return e - events; -+} -+ -+static struct ir_raw_handler rcmm_handler = { -+ .protocols = RC_PROTO_BIT_RCMM32 | -+ RC_PROTO_BIT_RCMM24 | -+ RC_PROTO_BIT_RCMM12, -+ .decode = ir_rcmm_decode, -+ .encode = ir_rcmm_encode, -+ .carrier = 36000, -+ .min_timeout = RCMM_PULSE_3 + RCMM_UNIT, -+}; -+ -+static int __init ir_rcmm_decode_init(void) -+{ -+ ir_raw_handler_register(&rcmm_handler); -+ -+ pr_info("IR RCMM protocol handler initialized\n"); -+ return 0; -+} -+ -+static void __exit ir_rcmm_decode_exit(void) -+{ -+ ir_raw_handler_unregister(&rcmm_handler); -+} -+ -+module_init(ir_rcmm_decode_init); -+module_exit(ir_rcmm_decode_exit); -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Patrick Lerda"); -+MODULE_DESCRIPTION("RCMM IR protocol decoder"); -diff --git a/drivers/media/rc/rc-core-priv.h b/drivers/media/rc/rc-core-priv.h -index e847bdad5c51..59c252f24194 100644 ---- a/drivers/media/rc/rc-core-priv.h -+++ b/drivers/media/rc/rc-core-priv.h -@@ -136,6 +136,11 @@ struct ir_raw_event_ctrl { - struct input_dev *idev; - char name[64]; - } imon; -+ struct rcmm_dec { -+ int state; -+ unsigned int count; -+ u32 bits; -+ } rcmm; - }; - - /* Mutex for locking raw IR processing and handler change */ -diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c -index 0f218afdadaa..78e79c37f208 100644 ---- a/drivers/media/rc/rc-main.c -+++ b/drivers/media/rc/rc-main.c -@@ -70,6 +70,12 @@ static const struct { - [RC_PROTO_CEC] = { .name = "cec", .repeat_period = 0 }, - [RC_PROTO_IMON] = { .name = "imon", - .scancode_bits = 0x7fffffff, .repeat_period = 114 }, -+ [RC_PROTO_RCMM12] = { .name = "rc-mm-12", -+ .scancode_bits = 0x00000fff, .repeat_period = 114 }, -+ [RC_PROTO_RCMM24] = { .name = "rc-mm-24", -+ .scancode_bits = 0x00ffffff, .repeat_period = 114 }, -+ [RC_PROTO_RCMM32] = { .name = "rc-mm-32", -+ .scancode_bits = 0xffffffff, .repeat_period = 114 }, - }; - - /* Used to keep track of known keymaps */ -@@ -1018,6 +1024,9 @@ static const struct { - { RC_PROTO_BIT_XMP, "xmp", "ir-xmp-decoder" }, - { RC_PROTO_BIT_CEC, "cec", NULL }, - { RC_PROTO_BIT_IMON, "imon", "ir-imon-decoder" }, -+ { RC_PROTO_BIT_RCMM12 | -+ RC_PROTO_BIT_RCMM24 | -+ RC_PROTO_BIT_RCMM32, "rc-mm", "ir-rcmm-decoder" }, - }; - - /** -diff --git a/include/media/rc-map.h b/include/media/rc-map.h -index bfa3017cecba..cf308b73edae 100644 ---- a/include/media/rc-map.h -+++ b/include/media/rc-map.h -@@ -37,6 +37,9 @@ - #define RC_PROTO_BIT_XMP BIT_ULL(RC_PROTO_XMP) - #define RC_PROTO_BIT_CEC BIT_ULL(RC_PROTO_CEC) - #define RC_PROTO_BIT_IMON BIT_ULL(RC_PROTO_IMON) -+#define RC_PROTO_BIT_RCMM12 BIT_ULL(RC_PROTO_RCMM12) -+#define RC_PROTO_BIT_RCMM24 BIT_ULL(RC_PROTO_RCMM24) -+#define RC_PROTO_BIT_RCMM32 BIT_ULL(RC_PROTO_RCMM32) - - #define RC_PROTO_BIT_ALL \ - (RC_PROTO_BIT_UNKNOWN | RC_PROTO_BIT_OTHER | \ -@@ -51,7 +54,8 @@ - RC_PROTO_BIT_RC6_6A_24 | RC_PROTO_BIT_RC6_6A_32 | \ - RC_PROTO_BIT_RC6_MCE | RC_PROTO_BIT_SHARP | \ - RC_PROTO_BIT_XMP | RC_PROTO_BIT_CEC | \ -- RC_PROTO_BIT_IMON) -+ RC_PROTO_BIT_IMON | RC_PROTO_BIT_RCMM12 | \ -+ RC_PROTO_BIT_RCMM24 | RC_PROTO_BIT_RCMM32) - /* All rc protocols for which we have decoders */ - #define RC_PROTO_BIT_ALL_IR_DECODER \ - (RC_PROTO_BIT_RC5 | RC_PROTO_BIT_RC5X_20 | \ -@@ -64,7 +68,9 @@ - RC_PROTO_BIT_RC6_0 | RC_PROTO_BIT_RC6_6A_20 | \ - RC_PROTO_BIT_RC6_6A_24 | RC_PROTO_BIT_RC6_6A_32 | \ - RC_PROTO_BIT_RC6_MCE | RC_PROTO_BIT_SHARP | \ -- RC_PROTO_BIT_XMP | RC_PROTO_BIT_IMON) -+ RC_PROTO_BIT_XMP | RC_PROTO_BIT_IMON | \ -+ RC_PROTO_BIT_RCMM12 | RC_PROTO_BIT_RCMM24 | \ -+ RC_PROTO_BIT_RCMM32) - - #define RC_PROTO_BIT_ALL_IR_ENCODER \ - (RC_PROTO_BIT_RC5 | RC_PROTO_BIT_RC5X_20 | \ -@@ -77,7 +83,9 @@ - RC_PROTO_BIT_RC6_0 | RC_PROTO_BIT_RC6_6A_20 | \ - RC_PROTO_BIT_RC6_6A_24 | \ - RC_PROTO_BIT_RC6_6A_32 | RC_PROTO_BIT_RC6_MCE | \ -- RC_PROTO_BIT_SHARP | RC_PROTO_BIT_IMON) -+ RC_PROTO_BIT_SHARP | RC_PROTO_BIT_IMON | \ -+ RC_PROTO_BIT_RCMM12 | RC_PROTO_BIT_RCMM24 | \ -+ RC_PROTO_BIT_RCMM32) - - #define RC_SCANCODE_UNKNOWN(x) (x) - #define RC_SCANCODE_OTHER(x) (x) -diff --git a/include/uapi/linux/lirc.h b/include/uapi/linux/lirc.h -index 6b319581882f..45fcbf99d72e 100644 ---- a/include/uapi/linux/lirc.h -+++ b/include/uapi/linux/lirc.h -@@ -192,6 +192,9 @@ struct lirc_scancode { - * @RC_PROTO_XMP: XMP protocol - * @RC_PROTO_CEC: CEC protocol - * @RC_PROTO_IMON: iMon Pad protocol -+ * @RC_PROTO_RCMM12: RC-MM protocol 12 bits -+ * @RC_PROTO_RCMM24: RC-MM protocol 24 bits -+ * @RC_PROTO_RCMM32: RC-MM protocol 32 bits - */ - enum rc_proto { - RC_PROTO_UNKNOWN = 0, -@@ -218,6 +221,9 @@ enum rc_proto { - RC_PROTO_XMP = 21, - RC_PROTO_CEC = 22, - RC_PROTO_IMON = 23, -+ RC_PROTO_RCMM12 = 24, -+ RC_PROTO_RCMM24 = 25, -+ RC_PROTO_RCMM32 = 26, - }; - - #endif -diff --git a/tools/include/uapi/linux/lirc.h b/tools/include/uapi/linux/lirc.h -index f189931042a7..45fcbf99d72e 100644 ---- a/tools/include/uapi/linux/lirc.h -+++ b/tools/include/uapi/linux/lirc.h -@@ -133,6 +133,12 @@ - - #define LIRC_SET_WIDEBAND_RECEIVER _IOW('i', 0x00000023, __u32) - -+/* -+ * Return the recording timeout, which is either set by -+ * the ioctl LIRC_SET_REC_TIMEOUT or by the kernel after setting the protocols. -+ */ -+#define LIRC_GET_REC_TIMEOUT _IOR('i', 0x00000024, __u32) -+ - /* - * struct lirc_scancode - decoded scancode with protocol for use with - * LIRC_MODE_SCANCODE -@@ -186,6 +192,9 @@ struct lirc_scancode { - * @RC_PROTO_XMP: XMP protocol - * @RC_PROTO_CEC: CEC protocol - * @RC_PROTO_IMON: iMon Pad protocol -+ * @RC_PROTO_RCMM12: RC-MM protocol 12 bits -+ * @RC_PROTO_RCMM24: RC-MM protocol 24 bits -+ * @RC_PROTO_RCMM32: RC-MM protocol 32 bits - */ - enum rc_proto { - RC_PROTO_UNKNOWN = 0, -@@ -212,6 +221,9 @@ enum rc_proto { - RC_PROTO_XMP = 21, - RC_PROTO_CEC = 22, - RC_PROTO_IMON = 23, -+ RC_PROTO_RCMM12 = 24, -+ RC_PROTO_RCMM24 = 25, -+ RC_PROTO_RCMM32 = 26, - }; - - #endif --- -2.20.1 -