media: lirc: report ir receiver overflow
authorSean Young <sean@mess.org>
Sat, 15 Jan 2022 10:19:11 +0000 (11:19 +0100)
committerMauro Carvalho Chehab <mchehab@kernel.org>
Fri, 28 Jan 2022 18:32:50 +0000 (19:32 +0100)
If the driver reports that the hardware had an overflow, report this to
userspace. It would be nice to know when this happens, and not just get
a long space.

This change has been tested with lircd, ir-ctl, and ir-keytable.

Signed-off-by: Sean Young <sean@mess.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
Documentation/userspace-api/media/lirc.h.rst.exceptions
Documentation/userspace-api/media/rc/lirc-dev-intro.rst
drivers/media/rc/lirc_dev.c
drivers/media/rc/rc-loopback.c
include/uapi/linux/lirc.h

index ec86e82d026dfb9787c72c8f5a3955e74c985842..5f31e967bc50e2eba7a5f5d468cdc117216df03e 100644 (file)
@@ -11,12 +11,14 @@ ignore define LIRC_SPACE
 ignore define LIRC_PULSE
 ignore define LIRC_FREQUENCY
 ignore define LIRC_TIMEOUT
+ignore define LIRC_OVERFLOW
 ignore define LIRC_VALUE
 ignore define LIRC_MODE2
 ignore define LIRC_IS_SPACE
 ignore define LIRC_IS_PULSE
 ignore define LIRC_IS_FREQUENCY
 ignore define LIRC_IS_TIMEOUT
+ignore define LIRC_IS_OVERFLOW
 
 ignore define LIRC_MODE2SEND
 ignore define LIRC_SEND2MODE
@@ -75,6 +77,7 @@ ignore define PULSE_MASK
 ignore define LIRC_MODE2_SPACE
 ignore define LIRC_MODE2_PULSE
 ignore define LIRC_MODE2_TIMEOUT
+ignore define LIRC_MODE2_OVERFLOW
 
 ignore define LIRC_VALUE_MASK
 ignore define LIRC_MODE2_MASK
index 9a5e5f0aae11609b0f6a1cd51ac0690cc6421f1f..d899331b943f33dfafa4517063e849f1f91b16a5 100644 (file)
@@ -103,11 +103,11 @@ on the following table.
 
     ``LIRC_MODE2_PULSE``
 
-        Signifies the presence of IR in microseconds.
+        Signifies the presence of IR in microseconds, also known as *flash*.
 
     ``LIRC_MODE2_SPACE``
 
-        Signifies absence of IR in microseconds.
+        Signifies absence of IR in microseconds, also known as *gap*.
 
     ``LIRC_MODE2_FREQUENCY``
 
@@ -121,6 +121,13 @@ on the following table.
         to no IR being detected, this packet will be sent, with the number
         of microseconds with no IR.
 
+    ``LIRC_MODE2_OVERFLOW``
+
+        Signifies that the IR receiver encounter an overflow, and some IR
+        is missing. The IR data after this should be correct again. The
+        actual value is not important, but this is set to 0xffffff by the
+        kernel for compatibility with lircd.
+
 .. _lirc-mode-pulse:
 
 ``LIRC_MODE_PULSE``
index fa4671fc92be2f1965cd0c3baf54b075ab9f1335..765375bda0c6e902c809892b24336799ab324107 100644 (file)
@@ -44,14 +44,13 @@ void lirc_raw_event(struct rc_dev *dev, struct ir_raw_event ev)
        /* Receiver overflow, data missing */
        if (ev.overflow) {
                /*
-                * Userspace expects a long space event before the start of
-                * the signal to use as a sync.  This may be done with repeat
-                * packets and normal samples.  But if an overflow has been sent
-                * then we assume that a long time has passed, so we send a
-                * space with the maximum time value.
+                * Send lirc overflow message. This message is unknown to
+                * lircd, but it will interpret this as a long space as
+                * long as the value is set to high value. This resets its
+                * decoder state.
                 */
-               sample = LIRC_SPACE(LIRC_VALUE_MASK);
-               dev_dbg(&dev->dev, "delivering overflow space to lirc_dev\n");
+               sample = LIRC_OVERFLOW(LIRC_VALUE_MASK);
+               dev_dbg(&dev->dev, "delivering overflow to lirc_dev\n");
 
        /* Carrier reports */
        } else if (ev.carrier_report) {
index 6441879fcba1a4717b1b0d7e62f1ce679d977151..b356041c5c00e718dcfde82cc374681da46b1276 100644 (file)
@@ -112,7 +112,11 @@ static int loop_tx_ir(struct rc_dev *dev, unsigned *txbuf, unsigned count)
                rawir.pulse = i % 2 ? false : true;
                rawir.duration = txbuf[i];
 
-               ir_raw_event_store_with_filter(dev, &rawir);
+               /* simulate overflow if ridiculously long pulse was sent */
+               if (rawir.pulse && rawir.duration > MS_TO_US(50))
+                       ir_raw_event_overflow(dev);
+               else
+                       ir_raw_event_store_with_filter(dev, &rawir);
        }
 
        if (lodev->carrierreport) {
index a1f9c26ea537bc2e836655e84cf516daa48d997d..21c69a6a100db52cec66efc60acdf6ece1548da9 100644 (file)
 #define LIRC_MODE2_PULSE     0x01000000
 #define LIRC_MODE2_FREQUENCY 0x02000000
 #define LIRC_MODE2_TIMEOUT   0x03000000
+#define LIRC_MODE2_OVERFLOW  0x04000000
 
 #define LIRC_VALUE_MASK      0x00FFFFFF
 #define LIRC_MODE2_MASK      0xFF000000
 
-#define LIRC_SPACE(val) (((val)&LIRC_VALUE_MASK) | LIRC_MODE2_SPACE)
-#define LIRC_PULSE(val) (((val)&LIRC_VALUE_MASK) | LIRC_MODE2_PULSE)
-#define LIRC_FREQUENCY(val) (((val)&LIRC_VALUE_MASK) | LIRC_MODE2_FREQUENCY)
-#define LIRC_TIMEOUT(val) (((val)&LIRC_VALUE_MASK) | LIRC_MODE2_TIMEOUT)
+#define LIRC_SPACE(val) (((val) & LIRC_VALUE_MASK) | LIRC_MODE2_SPACE)
+#define LIRC_PULSE(val) (((val) & LIRC_VALUE_MASK) | LIRC_MODE2_PULSE)
+#define LIRC_FREQUENCY(val) (((val) & LIRC_VALUE_MASK) | LIRC_MODE2_FREQUENCY)
+#define LIRC_TIMEOUT(val) (((val) & LIRC_VALUE_MASK) | LIRC_MODE2_TIMEOUT)
+#define LIRC_OVERFLOW(val) (((val) & LIRC_VALUE_MASK) | LIRC_MODE2_OVERFLOW)
 
 #define LIRC_VALUE(val) ((val)&LIRC_VALUE_MASK)
 #define LIRC_MODE2(val) ((val)&LIRC_MODE2_MASK)
@@ -32,6 +34,7 @@
 #define LIRC_IS_PULSE(val) (LIRC_MODE2(val) == LIRC_MODE2_PULSE)
 #define LIRC_IS_FREQUENCY(val) (LIRC_MODE2(val) == LIRC_MODE2_FREQUENCY)
 #define LIRC_IS_TIMEOUT(val) (LIRC_MODE2(val) == LIRC_MODE2_TIMEOUT)
+#define LIRC_IS_OVERFLOW(val) (LIRC_MODE2(val) == LIRC_MODE2_OVERFLOW)
 
 /* used heavily by lirc userspace */
 #define lirc_t int