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 new file mode 100644 index 0000000000..ae2cba8494 --- /dev/null +++ b/packages/linux/patches/default/linux-903-backport-rcmm-ir-decoder.patch @@ -0,0 +1,506 @@ +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/default/linux-904-improve-xbox-dvd-remote-performance.patch b/packages/linux/patches/default/linux-904-improve-xbox-dvd-remote-performance.patch new file mode 100644 index 0000000000..5ec182064e --- /dev/null +++ b/packages/linux/patches/default/linux-904-improve-xbox-dvd-remote-performance.patch @@ -0,0 +1,158 @@ +From 55096db50d8cdbf777c67f672b493ef565a12c38 Mon Sep 17 00:00:00 2001 +From: Matthias Reichl +Date: Fri, 22 Mar 2019 12:26:17 +0100 +Subject: [PATCH] media: rc: xbox_remote: add protocol and set timeout + +The timestamps in ir-keytable -t output showed that the Xbox DVD +IR dongle decodes scancodes every 64ms. The last scancode of a +longer button press is decodes 64ms after the last-but-one which +indicates the decoder doesn't use a timeout but decodes on the last +edge of the signal. + +267.042629: lirc protocol(unknown): scancode = 0xace +267.042665: event type EV_MSC(0x04): scancode = 0xace +267.042665: event type EV_KEY(0x01) key_down: KEY_1(0x0002) +267.042665: event type EV_SYN(0x00). +267.106625: lirc protocol(unknown): scancode = 0xace +267.106643: event type EV_MSC(0x04): scancode = 0xace +267.106643: event type EV_SYN(0x00). +267.170623: lirc protocol(unknown): scancode = 0xace +267.170638: event type EV_MSC(0x04): scancode = 0xace +267.170638: event type EV_SYN(0x00). +267.234621: lirc protocol(unknown): scancode = 0xace +267.234636: event type EV_MSC(0x04): scancode = 0xace +267.234636: event type EV_SYN(0x00). +267.298623: lirc protocol(unknown): scancode = 0xace +267.298638: event type EV_MSC(0x04): scancode = 0xace +267.298638: event type EV_SYN(0x00). +267.543345: event type EV_KEY(0x01) key_down: KEY_1(0x0002) +267.543345: event type EV_SYN(0x00). +267.570015: event type EV_KEY(0x01) key_up: KEY_1(0x0002) +267.570015: event type EV_SYN(0x00). + +Add a protocol with the repeat value and set the timeout in the +driver to 10ms (to have a bit of headroom for delays) so the Xbox +DVD remote performs more responsive. + +Signed-off-by: Matthias Reichl +--- + Documentation/media/lirc.h.rst.exceptions | 1 + + drivers/media/rc/keymaps/rc-xbox-dvd.c | 2 +- + drivers/media/rc/rc-main.c | 2 ++ + drivers/media/rc/xbox_remote.c | 4 +++- + include/media/rc-map.h | 4 +++- + include/uapi/linux/lirc.h | 2 ++ + 6 files changed, 12 insertions(+), 3 deletions(-) + +diff --git a/Documentation/media/lirc.h.rst.exceptions b/Documentation/media/lirc.h.rst.exceptions +index e7a41d4b3d46..f8b5f1a32b7d 100644 +--- a/Documentation/media/lirc.h.rst.exceptions ++++ b/Documentation/media/lirc.h.rst.exceptions +@@ -61,6 +61,7 @@ ignore symbol RC_PROTO_IMON + ignore symbol RC_PROTO_RCMM12 + ignore symbol RC_PROTO_RCMM24 + ignore symbol RC_PROTO_RCMM32 ++ignore symbol RC_PROTO_XBOX_DVD + + # Undocumented macros + +diff --git a/drivers/media/rc/keymaps/rc-xbox-dvd.c b/drivers/media/rc/keymaps/rc-xbox-dvd.c +index af387244636b..42815ab57bff 100644 +--- a/drivers/media/rc/keymaps/rc-xbox-dvd.c ++++ b/drivers/media/rc/keymaps/rc-xbox-dvd.c +@@ -42,7 +42,7 @@ static struct rc_map_list xbox_dvd_map = { + .map = { + .scan = xbox_dvd, + .size = ARRAY_SIZE(xbox_dvd), +- .rc_proto = RC_PROTO_UNKNOWN, ++ .rc_proto = RC_PROTO_XBOX_DVD, + .name = RC_MAP_XBOX_DVD, + } + }; +diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c +index 78e79c37f208..7f1d5b226f68 100644 +--- a/drivers/media/rc/rc-main.c ++++ b/drivers/media/rc/rc-main.c +@@ -76,6 +76,7 @@ static const struct { + .scancode_bits = 0x00ffffff, .repeat_period = 114 }, + [RC_PROTO_RCMM32] = { .name = "rc-mm-32", + .scancode_bits = 0xffffffff, .repeat_period = 114 }, ++ [RC_PROTO_XBOX_DVD] = { .name = "xbox-dvd", .repeat_period = 64 }, + }; + + /* Used to keep track of known keymaps */ +@@ -1027,6 +1028,7 @@ static const struct { + { RC_PROTO_BIT_RCMM12 | + RC_PROTO_BIT_RCMM24 | + RC_PROTO_BIT_RCMM32, "rc-mm", "ir-rcmm-decoder" }, ++ { RC_PROTO_BIT_XBOX_DVD, "xbox-dvd", NULL }, + }; + + /** +diff --git a/drivers/media/rc/xbox_remote.c b/drivers/media/rc/xbox_remote.c +index f959cbb94744..79470c09989e 100644 +--- a/drivers/media/rc/xbox_remote.c ++++ b/drivers/media/rc/xbox_remote.c +@@ -148,7 +148,7 @@ static void xbox_remote_rc_init(struct xbox_remote *xbox_remote) + struct rc_dev *rdev = xbox_remote->rdev; + + rdev->priv = xbox_remote; +- rdev->allowed_protocols = RC_PROTO_BIT_UNKNOWN; ++ rdev->allowed_protocols = RC_PROTO_BIT_XBOX_DVD; + rdev->driver_name = "xbox_remote"; + + rdev->open = xbox_remote_rc_open; +@@ -157,6 +157,8 @@ static void xbox_remote_rc_init(struct xbox_remote *xbox_remote) + rdev->device_name = xbox_remote->rc_name; + rdev->input_phys = xbox_remote->rc_phys; + ++ rdev->timeout = MS_TO_NS(10); ++ + usb_to_input_id(xbox_remote->udev, &rdev->input_id); + rdev->dev.parent = &xbox_remote->interface->dev; + } +diff --git a/include/media/rc-map.h b/include/media/rc-map.h +index e5e86d595645..a0000f392362 100644 +--- a/include/media/rc-map.h ++++ b/include/media/rc-map.h +@@ -40,6 +40,7 @@ + #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_XBOX_DVD BIT_ULL(RC_PROTO_XBOX_DVD) + + #define RC_PROTO_BIT_ALL \ + (RC_PROTO_BIT_UNKNOWN | RC_PROTO_BIT_OTHER | \ +@@ -55,7 +56,8 @@ + RC_PROTO_BIT_RC6_MCE | RC_PROTO_BIT_SHARP | \ + RC_PROTO_BIT_XMP | RC_PROTO_BIT_CEC | \ + RC_PROTO_BIT_IMON | RC_PROTO_BIT_RCMM12 | \ +- RC_PROTO_BIT_RCMM24 | RC_PROTO_BIT_RCMM32) ++ RC_PROTO_BIT_RCMM24 | RC_PROTO_BIT_RCMM32 | \ ++ RC_PROTO_BIT_XBOX_DVD) + /* All rc protocols for which we have decoders */ + #define RC_PROTO_BIT_ALL_IR_DECODER \ + (RC_PROTO_BIT_RC5 | RC_PROTO_BIT_RC5X_20 | \ +diff --git a/include/uapi/linux/lirc.h b/include/uapi/linux/lirc.h +index 45fcbf99d72e..f99d9dcae667 100644 +--- a/include/uapi/linux/lirc.h ++++ b/include/uapi/linux/lirc.h +@@ -195,6 +195,7 @@ struct lirc_scancode { + * @RC_PROTO_RCMM12: RC-MM protocol 12 bits + * @RC_PROTO_RCMM24: RC-MM protocol 24 bits + * @RC_PROTO_RCMM32: RC-MM protocol 32 bits ++ * @RC_PROTO_XBOX_DVD: Xbox DVD Movie Playback Kit protocol + */ + enum rc_proto { + RC_PROTO_UNKNOWN = 0, +@@ -224,6 +225,7 @@ enum rc_proto { + RC_PROTO_RCMM12 = 24, + RC_PROTO_RCMM24 = 25, + RC_PROTO_RCMM32 = 26, ++ RC_PROTO_XBOX_DVD = 27, + }; + + #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 new file mode 100644 index 0000000000..ae2cba8494 --- /dev/null +++ b/packages/linux/patches/raspberrypi/linux-903-backport-rcmm-ir-decoder.patch @@ -0,0 +1,506 @@ +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-904-improve-xbox-dvd-remote-performance.patch b/packages/linux/patches/raspberrypi/linux-904-improve-xbox-dvd-remote-performance.patch new file mode 100644 index 0000000000..5ec182064e --- /dev/null +++ b/packages/linux/patches/raspberrypi/linux-904-improve-xbox-dvd-remote-performance.patch @@ -0,0 +1,158 @@ +From 55096db50d8cdbf777c67f672b493ef565a12c38 Mon Sep 17 00:00:00 2001 +From: Matthias Reichl +Date: Fri, 22 Mar 2019 12:26:17 +0100 +Subject: [PATCH] media: rc: xbox_remote: add protocol and set timeout + +The timestamps in ir-keytable -t output showed that the Xbox DVD +IR dongle decodes scancodes every 64ms. The last scancode of a +longer button press is decodes 64ms after the last-but-one which +indicates the decoder doesn't use a timeout but decodes on the last +edge of the signal. + +267.042629: lirc protocol(unknown): scancode = 0xace +267.042665: event type EV_MSC(0x04): scancode = 0xace +267.042665: event type EV_KEY(0x01) key_down: KEY_1(0x0002) +267.042665: event type EV_SYN(0x00). +267.106625: lirc protocol(unknown): scancode = 0xace +267.106643: event type EV_MSC(0x04): scancode = 0xace +267.106643: event type EV_SYN(0x00). +267.170623: lirc protocol(unknown): scancode = 0xace +267.170638: event type EV_MSC(0x04): scancode = 0xace +267.170638: event type EV_SYN(0x00). +267.234621: lirc protocol(unknown): scancode = 0xace +267.234636: event type EV_MSC(0x04): scancode = 0xace +267.234636: event type EV_SYN(0x00). +267.298623: lirc protocol(unknown): scancode = 0xace +267.298638: event type EV_MSC(0x04): scancode = 0xace +267.298638: event type EV_SYN(0x00). +267.543345: event type EV_KEY(0x01) key_down: KEY_1(0x0002) +267.543345: event type EV_SYN(0x00). +267.570015: event type EV_KEY(0x01) key_up: KEY_1(0x0002) +267.570015: event type EV_SYN(0x00). + +Add a protocol with the repeat value and set the timeout in the +driver to 10ms (to have a bit of headroom for delays) so the Xbox +DVD remote performs more responsive. + +Signed-off-by: Matthias Reichl +--- + Documentation/media/lirc.h.rst.exceptions | 1 + + drivers/media/rc/keymaps/rc-xbox-dvd.c | 2 +- + drivers/media/rc/rc-main.c | 2 ++ + drivers/media/rc/xbox_remote.c | 4 +++- + include/media/rc-map.h | 4 +++- + include/uapi/linux/lirc.h | 2 ++ + 6 files changed, 12 insertions(+), 3 deletions(-) + +diff --git a/Documentation/media/lirc.h.rst.exceptions b/Documentation/media/lirc.h.rst.exceptions +index e7a41d4b3d46..f8b5f1a32b7d 100644 +--- a/Documentation/media/lirc.h.rst.exceptions ++++ b/Documentation/media/lirc.h.rst.exceptions +@@ -61,6 +61,7 @@ ignore symbol RC_PROTO_IMON + ignore symbol RC_PROTO_RCMM12 + ignore symbol RC_PROTO_RCMM24 + ignore symbol RC_PROTO_RCMM32 ++ignore symbol RC_PROTO_XBOX_DVD + + # Undocumented macros + +diff --git a/drivers/media/rc/keymaps/rc-xbox-dvd.c b/drivers/media/rc/keymaps/rc-xbox-dvd.c +index af387244636b..42815ab57bff 100644 +--- a/drivers/media/rc/keymaps/rc-xbox-dvd.c ++++ b/drivers/media/rc/keymaps/rc-xbox-dvd.c +@@ -42,7 +42,7 @@ static struct rc_map_list xbox_dvd_map = { + .map = { + .scan = xbox_dvd, + .size = ARRAY_SIZE(xbox_dvd), +- .rc_proto = RC_PROTO_UNKNOWN, ++ .rc_proto = RC_PROTO_XBOX_DVD, + .name = RC_MAP_XBOX_DVD, + } + }; +diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c +index 78e79c37f208..7f1d5b226f68 100644 +--- a/drivers/media/rc/rc-main.c ++++ b/drivers/media/rc/rc-main.c +@@ -76,6 +76,7 @@ static const struct { + .scancode_bits = 0x00ffffff, .repeat_period = 114 }, + [RC_PROTO_RCMM32] = { .name = "rc-mm-32", + .scancode_bits = 0xffffffff, .repeat_period = 114 }, ++ [RC_PROTO_XBOX_DVD] = { .name = "xbox-dvd", .repeat_period = 64 }, + }; + + /* Used to keep track of known keymaps */ +@@ -1027,6 +1028,7 @@ static const struct { + { RC_PROTO_BIT_RCMM12 | + RC_PROTO_BIT_RCMM24 | + RC_PROTO_BIT_RCMM32, "rc-mm", "ir-rcmm-decoder" }, ++ { RC_PROTO_BIT_XBOX_DVD, "xbox-dvd", NULL }, + }; + + /** +diff --git a/drivers/media/rc/xbox_remote.c b/drivers/media/rc/xbox_remote.c +index f959cbb94744..79470c09989e 100644 +--- a/drivers/media/rc/xbox_remote.c ++++ b/drivers/media/rc/xbox_remote.c +@@ -148,7 +148,7 @@ static void xbox_remote_rc_init(struct xbox_remote *xbox_remote) + struct rc_dev *rdev = xbox_remote->rdev; + + rdev->priv = xbox_remote; +- rdev->allowed_protocols = RC_PROTO_BIT_UNKNOWN; ++ rdev->allowed_protocols = RC_PROTO_BIT_XBOX_DVD; + rdev->driver_name = "xbox_remote"; + + rdev->open = xbox_remote_rc_open; +@@ -157,6 +157,8 @@ static void xbox_remote_rc_init(struct xbox_remote *xbox_remote) + rdev->device_name = xbox_remote->rc_name; + rdev->input_phys = xbox_remote->rc_phys; + ++ rdev->timeout = MS_TO_NS(10); ++ + usb_to_input_id(xbox_remote->udev, &rdev->input_id); + rdev->dev.parent = &xbox_remote->interface->dev; + } +diff --git a/include/media/rc-map.h b/include/media/rc-map.h +index e5e86d595645..a0000f392362 100644 +--- a/include/media/rc-map.h ++++ b/include/media/rc-map.h +@@ -40,6 +40,7 @@ + #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_XBOX_DVD BIT_ULL(RC_PROTO_XBOX_DVD) + + #define RC_PROTO_BIT_ALL \ + (RC_PROTO_BIT_UNKNOWN | RC_PROTO_BIT_OTHER | \ +@@ -55,7 +56,8 @@ + RC_PROTO_BIT_RC6_MCE | RC_PROTO_BIT_SHARP | \ + RC_PROTO_BIT_XMP | RC_PROTO_BIT_CEC | \ + RC_PROTO_BIT_IMON | RC_PROTO_BIT_RCMM12 | \ +- RC_PROTO_BIT_RCMM24 | RC_PROTO_BIT_RCMM32) ++ RC_PROTO_BIT_RCMM24 | RC_PROTO_BIT_RCMM32 | \ ++ RC_PROTO_BIT_XBOX_DVD) + /* All rc protocols for which we have decoders */ + #define RC_PROTO_BIT_ALL_IR_DECODER \ + (RC_PROTO_BIT_RC5 | RC_PROTO_BIT_RC5X_20 | \ +diff --git a/include/uapi/linux/lirc.h b/include/uapi/linux/lirc.h +index 45fcbf99d72e..f99d9dcae667 100644 +--- a/include/uapi/linux/lirc.h ++++ b/include/uapi/linux/lirc.h +@@ -195,6 +195,7 @@ struct lirc_scancode { + * @RC_PROTO_RCMM12: RC-MM protocol 12 bits + * @RC_PROTO_RCMM24: RC-MM protocol 24 bits + * @RC_PROTO_RCMM32: RC-MM protocol 32 bits ++ * @RC_PROTO_XBOX_DVD: Xbox DVD Movie Playback Kit protocol + */ + enum rc_proto { + RC_PROTO_UNKNOWN = 0, +@@ -224,6 +225,7 @@ enum rc_proto { + RC_PROTO_RCMM12 = 24, + RC_PROTO_RCMM24 = 25, + RC_PROTO_RCMM32 = 26, ++ RC_PROTO_XBOX_DVD = 27, + }; + + #endif +-- +2.20.1 + diff --git a/packages/sysutils/v4l-utils/keymaps/xbox_dvd b/packages/sysutils/v4l-utils/keymaps/xbox_dvd index 582c921c98..22c9f7026b 100644 --- a/packages/sysutils/v4l-utils/keymaps/xbox_dvd +++ b/packages/sysutils/v4l-utils/keymaps/xbox_dvd @@ -1,4 +1,4 @@ -# table xbox_dvd, type: unknown +# table xbox_dvd, type: xbox-dvd 0xa0b KEY_OK 0xaa6 KEY_UP 0xaa7 KEY_DOWN diff --git a/packages/sysutils/v4l-utils/patches/v4l-utils-0002-backport-imon-and-rcmm-protocol-support.patch b/packages/sysutils/v4l-utils/patches/v4l-utils-0002-backport-imon-and-rcmm-protocol-support.patch new file mode 100644 index 0000000000..9b04950ee0 --- /dev/null +++ b/packages/sysutils/v4l-utils/patches/v4l-utils-0002-backport-imon-and-rcmm-protocol-support.patch @@ -0,0 +1,35 @@ +From dc70f6cdfa9980b707a958cfca9a3820d51af8f6 Mon Sep 17 00:00:00 2001 +From: Matthias Reichl +Date: Sat, 23 Mar 2019 10:11:55 +0100 +Subject: [PATCH] keytable: backport imon and rc-mm protocols + +Signed-off-by: Matthias Reichl +--- + utils/keytable/keytable.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/utils/keytable/keytable.c b/utils/keytable/keytable.c +index 34a1522e..67c6f92c 100644 +--- a/utils/keytable/keytable.c ++++ b/utils/keytable/keytable.c +@@ -112,6 +112,8 @@ enum sysfs_protocols { + SYSFS_SHARP = (1 << 11), + SYSFS_XMP = (1 << 12), + SYSFS_CEC = (1 << 13), ++ SYSFS_IMON = (1 << 14), ++ SYSFS_RCMM = (1 << 15), + SYSFS_INVALID = 0, + }; + +@@ -145,6 +147,8 @@ const struct protocol_map_entry protocol_map[] = { + { "sharp", NULL, SYSFS_SHARP }, + { "xmp", "/xmp_decoder", SYSFS_XMP }, + { "cec", NULL, SYSFS_CEC }, ++ { "imon", NULL, SYSFS_IMON }, ++ { "rc-mm", NULL, SYSFS_RCMM }, + { NULL, NULL, SYSFS_INVALID }, + }; + +-- +2.20.1 + diff --git a/packages/sysutils/v4l-utils/patches/v4l-utils-0003-add-xbox-dvd-protocol.patch b/packages/sysutils/v4l-utils/patches/v4l-utils-0003-add-xbox-dvd-protocol.patch new file mode 100644 index 0000000000..1bbfabae7a --- /dev/null +++ b/packages/sysutils/v4l-utils/patches/v4l-utils-0003-add-xbox-dvd-protocol.patch @@ -0,0 +1,33 @@ +From dbf64abf9eed823b35a2931d4882905b6106461e Mon Sep 17 00:00:00 2001 +From: Matthias Reichl +Date: Sat, 23 Mar 2019 10:19:48 +0100 +Subject: [PATCH] keytable: add xbox-dvd protocol + +Signed-off-by: Matthias Reichl +--- + utils/keytable/keytable.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/utils/keytable/keytable.c b/utils/keytable/keytable.c +index 67c6f92c..4ee280cc 100644 +--- a/utils/keytable/keytable.c ++++ b/utils/keytable/keytable.c +@@ -114,6 +114,7 @@ enum sysfs_protocols { + SYSFS_CEC = (1 << 13), + SYSFS_IMON = (1 << 14), + SYSFS_RCMM = (1 << 15), ++ SYSFS_XBOX_DVD = (1 << 16), + SYSFS_INVALID = 0, + }; + +@@ -149,6 +150,7 @@ const struct protocol_map_entry protocol_map[] = { + { "cec", NULL, SYSFS_CEC }, + { "imon", NULL, SYSFS_IMON }, + { "rc-mm", NULL, SYSFS_RCMM }, ++ { "xbox-dvd", NULL, SYSFS_XBOX_DVD }, + { NULL, NULL, SYSFS_INVALID }, + }; + +-- +2.20.1 + diff --git a/projects/Generic/linux/linux.x86_64.conf b/projects/Generic/linux/linux.x86_64.conf index 68346a4c6e..fe13951474 100644 --- a/projects/Generic/linux/linux.x86_64.conf +++ b/projects/Generic/linux/linux.x86_64.conf @@ -3102,6 +3102,7 @@ CONFIG_IR_SHARP_DECODER=m CONFIG_IR_MCE_KBD_DECODER=m CONFIG_IR_XMP_DECODER=m CONFIG_IR_IMON_DECODER=m +CONFIG_IR_RCMM_DECODER=m CONFIG_RC_DEVICES=y CONFIG_RC_ATI_REMOTE=m CONFIG_IR_ENE=m diff --git a/projects/RPi/devices/RPi/linux/linux.arm.conf b/projects/RPi/devices/RPi/linux/linux.arm.conf index 8a250ec127..df3e00608f 100644 --- a/projects/RPi/devices/RPi/linux/linux.arm.conf +++ b/projects/RPi/devices/RPi/linux/linux.arm.conf @@ -2489,6 +2489,7 @@ CONFIG_IR_SHARP_DECODER=m CONFIG_IR_MCE_KBD_DECODER=m CONFIG_IR_XMP_DECODER=m CONFIG_IR_IMON_DECODER=m +CONFIG_IR_RCMM_DECODER=m CONFIG_RC_DEVICES=y CONFIG_RC_ATI_REMOTE=m # CONFIG_IR_HIX5HD2 is not set diff --git a/projects/RPi/devices/RPi2/linux/linux.arm.conf b/projects/RPi/devices/RPi2/linux/linux.arm.conf index 8877bf55f1..69246dc43a 100644 --- a/projects/RPi/devices/RPi2/linux/linux.arm.conf +++ b/projects/RPi/devices/RPi2/linux/linux.arm.conf @@ -2608,6 +2608,7 @@ CONFIG_IR_SHARP_DECODER=m CONFIG_IR_MCE_KBD_DECODER=m CONFIG_IR_XMP_DECODER=m CONFIG_IR_IMON_DECODER=m +CONFIG_IR_RCMM_DECODER=m CONFIG_RC_DEVICES=y CONFIG_RC_ATI_REMOTE=m # CONFIG_IR_HIX5HD2 is not set