V4L/DVB: ir-core: change duration to be coded as a u32 integer

This patch implements the agreed upon 1:31 integer encoded pulse/duration
struct for ir-core raw decoders. All decoders have been tested after the
change. Comments are welcome.

Signed-off-by: David Härdeman <david@hardeman.nu>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
diff --git a/drivers/media/IR/ir-nec-decoder.c b/drivers/media/IR/ir-nec-decoder.c
index 14609d9..ba79233 100644
--- a/drivers/media/IR/ir-nec-decoder.c
+++ b/drivers/media/IR/ir-nec-decoder.c
@@ -17,13 +17,15 @@
 
 #define NEC_NBITS		32
 #define NEC_UNIT		562500  /* ns */
-#define NEC_HEADER_PULSE	PULSE(16)
-#define NECX_HEADER_PULSE	PULSE(8) /* Less common NEC variant */
-#define NEC_HEADER_SPACE	SPACE(8)
-#define NEC_REPEAT_SPACE	SPACE(4)
-#define NEC_BIT_PULSE		PULSE(1)
-#define NEC_BIT_0_SPACE		SPACE(1)
-#define NEC_BIT_1_SPACE		SPACE(3)
+#define NEC_HEADER_PULSE	(16 * NEC_UNIT)
+#define NECX_HEADER_PULSE	(8  * NEC_UNIT) /* Less common NEC variant */
+#define NEC_HEADER_SPACE	(8  * NEC_UNIT)
+#define NEC_REPEAT_SPACE	(8  * NEC_UNIT)
+#define NEC_BIT_PULSE		(1  * NEC_UNIT)
+#define NEC_BIT_0_SPACE		(1  * NEC_UNIT)
+#define NEC_BIT_1_SPACE		(3  * NEC_UNIT)
+#define	NEC_TRAILER_PULSE	(1  * NEC_UNIT)
+#define	NEC_TRAILER_SPACE	(10 * NEC_UNIT) /* even longer in reality */
 
 /* Used to register nec_decoder clients */
 static LIST_HEAD(decoder_list);
@@ -119,15 +121,14 @@
 /**
  * ir_nec_decode() - Decode one NEC pulse or space
  * @input_dev:	the struct input_dev descriptor of the device
- * @duration:	duration in ns of pulse/space
+ * @duration:	the struct ir_raw_event descriptor of the pulse/space
  *
  * This function returns -EINVAL if the pulse violates the state machine
  */
-static int ir_nec_decode(struct input_dev *input_dev, s64 duration)
+static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev)
 {
 	struct decoder_data *data;
 	struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
-	int u;
 	u32 scancode;
 	u8 address, not_address, command, not_command;
 
@@ -138,59 +139,88 @@
 	if (!data->enabled)
 		return 0;
 
-	if (IS_RESET(duration)) {
+	if (IS_RESET(ev)) {
 		data->state = STATE_INACTIVE;
 		return 0;
 	}
 
-	u = TO_UNITS(duration, NEC_UNIT);
-	if (DURATION(u) == 0)
-		goto out;
-
-	IR_dprintk(2, "NEC decode started at state %d (%i units, %ius)\n",
-		   data->state, u, TO_US(duration));
+	IR_dprintk(2, "NEC decode started at state %d (%uus %s)\n",
+		   data->state, TO_US(ev.duration), TO_STR(ev.pulse));
 
 	switch (data->state) {
 
 	case STATE_INACTIVE:
-		if (u == NEC_HEADER_PULSE || u == NECX_HEADER_PULSE) {
-			data->count = 0;
-			data->state = STATE_HEADER_SPACE;
-		}
+		if (!ev.pulse)
+			break;
+
+		if (!eq_margin(ev.duration, NEC_HEADER_PULSE, NEC_UNIT / 2) &&
+		    !eq_margin(ev.duration, NECX_HEADER_PULSE, NEC_UNIT / 2))
+			break;
+
+		data->count = 0;
+		data->state = STATE_HEADER_SPACE;
 		return 0;
 
 	case STATE_HEADER_SPACE:
-		if (u == NEC_HEADER_SPACE) {
+		if (ev.pulse)
+			break;
+
+		if (eq_margin(ev.duration, NEC_HEADER_SPACE, NEC_UNIT / 2)) {
 			data->state = STATE_BIT_PULSE;
 			return 0;
-		} else if (u == NEC_REPEAT_SPACE) {
+		} else if (eq_margin(ev.duration, NEC_REPEAT_SPACE, NEC_UNIT / 2)) {
 			ir_repeat(input_dev);
 			IR_dprintk(1, "Repeat last key\n");
 			data->state = STATE_TRAILER_PULSE;
 			return 0;
 		}
+
 		break;
 
 	case STATE_BIT_PULSE:
-		if (u == NEC_BIT_PULSE) {
-			data->state = STATE_BIT_SPACE;
-			return 0;
-		}
-		break;
+		if (!ev.pulse)
+			break;
+
+		if (!eq_margin(ev.duration, NEC_BIT_PULSE, NEC_UNIT / 2))
+			break;
+
+		data->state = STATE_BIT_SPACE;
+		return 0;
 
 	case STATE_BIT_SPACE:
-		if (u != NEC_BIT_0_SPACE && u != NEC_BIT_1_SPACE)
+		if (ev.pulse)
 			break;
 
 		data->nec_bits <<= 1;
-		if (u == NEC_BIT_1_SPACE)
+		if (eq_margin(ev.duration, NEC_BIT_1_SPACE, NEC_UNIT / 2))
 			data->nec_bits |= 1;
+		else if (!eq_margin(ev.duration, NEC_BIT_0_SPACE, NEC_UNIT / 2))
+			break;
 		data->count++;
 
-		if (data->count != NEC_NBITS) {
+		if (data->count == NEC_NBITS)
+			data->state = STATE_TRAILER_PULSE;
+		else
 			data->state = STATE_BIT_PULSE;
-			return 0;
-		}
+
+		return 0;
+
+	case STATE_TRAILER_PULSE:
+		if (!ev.pulse)
+			break;
+
+		if (!eq_margin(ev.duration, NEC_TRAILER_PULSE, NEC_UNIT / 2))
+			break;
+
+		data->state = STATE_TRAILER_SPACE;
+		return 0;
+
+	case STATE_TRAILER_SPACE:
+		if (ev.pulse)
+			break;
+
+		if (!geq_margin(ev.duration, NEC_TRAILER_SPACE, NEC_UNIT / 2))
+			break;
 
 		address     = bitrev8((data->nec_bits >> 24) & 0xff);
 		not_address = bitrev8((data->nec_bits >> 16) & 0xff);
@@ -210,34 +240,18 @@
 				   command;
 			IR_dprintk(1, "NEC (Ext) scancode 0x%06x\n", scancode);
 		} else {
-			/* normal NEC */
+			/* Normal NEC */
 			scancode = address << 8 | command;
 			IR_dprintk(1, "NEC scancode 0x%04x\n", scancode);
 		}
 
 		ir_keydown(input_dev, scancode, 0);
-		data->state = STATE_TRAILER_PULSE;
+		data->state = STATE_INACTIVE;
 		return 0;
-
-	case STATE_TRAILER_PULSE:
-		if (u > 0) {
-			data->state = STATE_TRAILER_SPACE;
-			return 0;
-		}
-		break;
-
-	case STATE_TRAILER_SPACE:
-		if (u < 0) {
-			data->state = STATE_INACTIVE;
-			return 0;
-		}
-
-		break;
 	}
 
-out:
-	IR_dprintk(1, "NEC decode failed at state %d (%i units, %ius)\n",
-		   data->state, u, TO_US(duration));
+	IR_dprintk(1, "NEC decode failed at state %d (%uus %s)\n",
+		   data->state, TO_US(ev.duration), TO_STR(ev.pulse));
 	data->state = STATE_INACTIVE;
 	return -EINVAL;
 }