From fd945928d6fd544d2f4bdde718b097b01bafb048 Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Tue, 22 Apr 2014 13:58:14 +0100
Subject: [PATCH 194/196] lirc_rpi: Use read_current_timer to determine
 transmitter delay. Thanks to jjmz and others See:
 https://github.com/raspberrypi/linux/issues/525

---
 drivers/staging/media/lirc/lirc_rpi.c | 32 +++++++++++++++++---------------
 1 file changed, 17 insertions(+), 15 deletions(-)

diff --git a/drivers/staging/media/lirc/lirc_rpi.c b/drivers/staging/media/lirc/lirc_rpi.c
index 8aee83f..57ffacf 100644
--- a/drivers/staging/media/lirc/lirc_rpi.c
+++ b/drivers/staging/media/lirc/lirc_rpi.c
@@ -30,6 +30,7 @@
 #include <linux/sched.h>
 #include <linux/kernel.h>
 #include <linux/time.h>
+#include <linux/timex.h>
 #include <linux/string.h>
 #include <linux/delay.h>
 #include <linux/platform_device.h>
@@ -41,7 +42,7 @@
 
 #define LIRC_DRIVER_NAME "lirc_rpi"
 #define RBUF_LEN 256
-#define LIRC_TRANSMITTER_LATENCY 256
+#define LIRC_TRANSMITTER_LATENCY 50
 
 #ifndef MAX_UDELAY_MS
 #define MAX_UDELAY_US 5000
@@ -107,19 +108,15 @@ static void safe_udelay(unsigned long usecs)
 static int init_timing_params(unsigned int new_duty_cycle,
 	unsigned int new_freq)
 {
-	/*
-	 * period, pulse/space width are kept with 8 binary places -
-	 * IE multiplied by 256.
-	 */
-	if (256 * 1000000L / new_freq * new_duty_cycle / 100 <=
+	if (1000 * 1000000L / new_freq * new_duty_cycle / 100 <=
 	    LIRC_TRANSMITTER_LATENCY)
 		return -EINVAL;
-	if (256 * 1000000L / new_freq * (100 - new_duty_cycle) / 100 <=
+	if (1000 * 1000000L / new_freq * (100 - new_duty_cycle) / 100 <=
 	    LIRC_TRANSMITTER_LATENCY)
 		return -EINVAL;
 	duty_cycle = new_duty_cycle;
 	freq = new_freq;
-	period = 256 * 1000000L / freq;
+	period = 1000 * 1000000L / freq;
 	pulse_width = period * duty_cycle / 100;
 	space_width = period - pulse_width;
 	dprintk("in init_timing_params, freq=%d pulse=%ld, "
@@ -130,11 +127,14 @@ static int init_timing_params(unsigned int new_duty_cycle,
 static long send_pulse_softcarrier(unsigned long length)
 {
 	int flag;
-	unsigned long actual, target, d;
+	unsigned long actual, target;
+	unsigned long actual_us, initial_us, target_us;
 
-	length <<= 8;
+	length *= 1000;
 
 	actual = 0; target = 0; flag = 0;
+	read_current_timer(&actual_us);
+
 	while (actual < length) {
 		if (flag) {
 			gpiochip->set(gpiochip, gpio_out_pin, invert);
@@ -143,17 +143,19 @@ static long send_pulse_softcarrier(unsigned long length)
 			gpiochip->set(gpiochip, gpio_out_pin, !invert);
 			target += pulse_width;
 		}
-		d = (target - actual -
-		     LIRC_TRANSMITTER_LATENCY + 128) >> 8;
+		initial_us = actual_us;
+		target_us = actual_us + (target - actual) / 1000;
 		/*
 		 * Note - we've checked in ioctl that the pulse/space
 		 * widths are big enough so that d is > 0
 		 */
-		udelay(d);
-		actual += (d << 8) + LIRC_TRANSMITTER_LATENCY;
+		if  ((int)(target_us - actual_us) > 0)
+			udelay(target_us - actual_us);
+		read_current_timer(&actual_us);
+		actual += (actual_us - initial_us) * 1000;
 		flag = !flag;
 	}
-	return (actual-length) >> 8;
+	return (actual-length) / 1000;
 }
 
 static long send_pulse(unsigned long length)
-- 
1.9.1

