]> Pileus Git - ~andy/linux/blobdiff - drivers/media/IR/ir-nec-decoder.c
V4L/DVB: saa7134: don't wait too much to generate an IR event on raw_decode
[~andy/linux] / drivers / media / IR / ir-nec-decoder.c
index a58c717ec6b06694fc58769c4cccbf3169f62dff..104482a6991eddc06980326da1425373d174fba7 100644 (file)
 
 #include <media/ir-core.h>
 
-/* Start time: 4.5 ms  */
-#define MIN_START_TIME 3900000
-#define MAX_START_TIME 5100000
+/* Start time: 4.5 ms + 560 us of the next pulse */
+#define MIN_START_TIME (3900000 + 560000)
+#define MAX_START_TIME (5100000 + 560000)
 
-/* Pulse time: 560 us  */
-#define MIN_PULSE_TIME 460000
-#define MAX_PULSE_TIME 660000
+/* Bit 1 time: 2.25ms us */
+#define MIN_BIT1_TIME  2050000
+#define MAX_BIT1_TIME  2450000
 
-/* Bit 1 space time: 2.25ms-560 us */
-#define MIN_BIT1_TIME  1490000
-#define MAX_BIT1_TIME  1890000
+/* Bit 0 time: 1.12ms us */
+#define MIN_BIT0_TIME  920000
+#define MAX_BIT0_TIME  1320000
 
-/* Bit 0 space time: 1.12ms-560 us */
-#define MIN_BIT0_TIME  360000
-#define MAX_BIT0_TIME  760000
+/* Total IR code is 110 ms, including the 9 ms for the start pulse */
+#define MAX_NEC_TIME   4000000
+
+/* Total IR code is 110 ms, including the 9 ms for the start pulse */
+#define MIN_REPEAT_TIME        99000000
+#define MAX_REPEAT_TIME        112000000
+
+/* Repeat time: 2.25ms us */
+#define MIN_REPEAT_START_TIME  2050000
+#define MAX_REPEAT_START_TIME  3000000
+
+#define REPEAT_TIME    240 /* ms */
+
+/** is_repeat - Check if it is a NEC repeat event
+ * @input_dev: the struct input_dev descriptor of the device
+ * @pos:       the position of the first event
+ * @len:       the length of the buffer
+ */
+static int is_repeat(struct ir_raw_event *evs, int len, int pos)
+{
+       if ((evs[pos].delta.tv_nsec < MIN_REPEAT_START_TIME) ||
+           (evs[pos].delta.tv_nsec > MAX_REPEAT_START_TIME))
+               return 0;
+
+       if (++pos >= len)
+               return 0;
+
+       if ((evs[pos].delta.tv_nsec < MIN_REPEAT_TIME) ||
+           (evs[pos].delta.tv_nsec > MAX_REPEAT_TIME))
+               return 0;
+
+       return 1;
+}
 
 /**
  * __ir_nec_decode() - Decode one NEC pulsecode
  * @evs:       event array with type/duration of pulse/space
  * @len:       length of the array
  * @pos:       position to start seeking for a code
- * This function returns the decoded ircode or -EINVAL if no pulse got decoded
+ * This function returns -EINVAL if no pulse got decoded,
+ * 0 if buffer is empty and 1 if one keycode were handled.
  */
 static int __ir_nec_decode(struct input_dev *input_dev,
                           struct ir_raw_event *evs,
                           int len, int *pos)
 {
+       struct ir_input_dev *ir = input_get_drvdata(input_dev);
        int count = -1;
        int ircode = 0, not_code = 0;
 
        /* Be sure that the first event is an start one and is a pulse */
        for (; *pos < len; (*pos)++) {
-               if (evs[*pos].type & (IR_START_EVENT | IR_PULSE))
+               /* Very long delays are considered as start events */
+               if (evs[*pos].delta.tv_nsec > MAX_NEC_TIME)
                        break;
-       }
-       (*pos)++;       /* First event doesn't contain data */
+               if (evs[*pos].type & IR_START_EVENT)
+                       break;
+               IR_dprintk(1, "%luus: Spurious NEC %s\n",
+                          (evs[*pos].delta.tv_nsec + 500) / 1000,
+                          (evs[*pos].type & IR_SPACE) ? "space" : "pulse");
 
+       }
        if (*pos >= len)
                return 0;
 
-       /* First space should have 4.5 ms otherwise is not NEC protocol */
-       if ((evs[*pos].delta.tv_nsec < MIN_START_TIME) |
-           (evs[*pos].delta.tv_nsec > MAX_START_TIME) |
-           (evs[*pos].type != IR_SPACE))
+       (*pos)++;       /* First event doesn't contain data */
+
+       if (evs[*pos].type != IR_PULSE)
                goto err;
 
-       /*
-        * FIXME: need to implement the repeat sequence
-        */
+       /* Check if it is a NEC repeat event */
+       if (is_repeat(evs, len, *pos)) {
+               *pos += 2;
+               if (ir->keypressed) {
+                       mod_timer(&ir->raw->timer_keyup,
+                               jiffies + msecs_to_jiffies(REPEAT_TIME));
+                       IR_dprintk(1, "NEC repeat event\n");
+                       return 1;
+               } else {
+                       IR_dprintk(1, "missing NEC repeat event\n");
+                       return 0;
+               }
+       }
+
+       /* First space should have 4.5 ms otherwise is not NEC protocol */
+       if ((evs[*pos].delta.tv_nsec < MIN_START_TIME) ||
+           (evs[*pos].delta.tv_nsec > MAX_START_TIME))
+               goto err;
 
        count = 0;
        for ((*pos)++; *pos < len; (*pos)++) {
                int bit;
-
-               if ((evs[*pos].delta.tv_nsec < MIN_PULSE_TIME) |
-                   (evs[*pos].delta.tv_nsec > MAX_PULSE_TIME) |
-                   (evs[*pos].type != IR_PULSE))
-                       goto err;
-
-               if (++*pos >= len)
-                       goto err;
-               if (evs[*pos].type != IR_SPACE)
-                       goto err;
-
                if ((evs[*pos].delta.tv_nsec > MIN_BIT1_TIME) &&
                    (evs[*pos].delta.tv_nsec < MAX_BIT1_TIME))
                        bit = 1;
@@ -107,6 +147,7 @@ static int __ir_nec_decode(struct input_dev *input_dev,
                if (++count == 32)
                        break;
        }
+       *pos++;
 
        /*
         * Fixme: may need to accept Extended NEC protocol?
@@ -119,12 +160,15 @@ static int __ir_nec_decode(struct input_dev *input_dev,
 
        IR_dprintk(1, "NEC scancode 0x%04x\n", ircode);
        ir_keydown(input_dev, ircode);
-       ir_keyup(input_dev);
+       mod_timer(&ir->raw->timer_keyup,
+                 jiffies + msecs_to_jiffies(REPEAT_TIME));
 
-       return ircode;
+       return 1;
 err:
-       IR_dprintk(1, "NEC decoded failed at bit %d while decoding %luus time\n",
-                  count, (evs[*pos].delta.tv_nsec + 500) / 1000);
+       IR_dprintk(1, "NEC decoded failed at bit %d (%s) while decoding %luus time\n",
+                  count,
+                  (evs[*pos].type & IR_SPACE) ? "space" : "pulse",
+                  (evs[*pos].delta.tv_nsec + 500) / 1000);
 
        return -EINVAL;
 }
@@ -145,7 +189,7 @@ int ir_nec_decode(struct input_dev *input_dev,
        int rc = 0;
 
        while (pos < len) {
-               if (__ir_nec_decode(input_dev, evs, len, &pos) >= 0)
+               if (__ir_nec_decode(input_dev, evs, len, &pos) > 0)
                        rc++;
        }