brcm2708: update 3.10 patches with raspberrypi/rpi-3.10.y of 27 Apr. 2014
[openwrt.git] / target / linux / brcm2708 / patches-3.10 / 0194-lirc_rpi-Use-read_current_timer-to-determine-transmi.patch
diff --git a/target/linux/brcm2708/patches-3.10/0194-lirc_rpi-Use-read_current_timer-to-determine-transmi.patch b/target/linux/brcm2708/patches-3.10/0194-lirc_rpi-Use-read_current_timer-to-determine-transmi.patch
new file mode 100644 (file)
index 0000000..66cd4a4
--- /dev/null
@@ -0,0 +1,100 @@
+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
+