changed Makefile and profiles, added patches for kernel 2.6.24
[openwrt.git] / target / linux / s3c24xx / patches-2.6.26 / 0141-fix-motion-sensor-corruption.patch.patch
diff --git a/target/linux/s3c24xx/patches-2.6.26/0141-fix-motion-sensor-corruption.patch.patch b/target/linux/s3c24xx/patches-2.6.26/0141-fix-motion-sensor-corruption.patch.patch
new file mode 100755 (executable)
index 0000000..a9b7243
--- /dev/null
@@ -0,0 +1,88 @@
+From 18a3bda7bf72a36c3e3164402cd0e4dfa2ff4687 Mon Sep 17 00:00:00 2001
+From: Andy Green <agreen@localhost.localdomain>
+Date: Fri, 25 Jul 2008 23:06:09 +0100
+Subject: [PATCH] fix-motion-sensor-corruption.patch
+
+---
+ arch/arm/mach-s3c2440/mach-gta02.c |   35 ++++++++++++++++++++++++++++++++---
+ 1 files changed, 32 insertions(+), 3 deletions(-)
+
+diff --git a/arch/arm/mach-s3c2440/mach-gta02.c b/arch/arm/mach-s3c2440/mach-gta02.c
+index e1984a9..9e8fae7 100644
+--- a/arch/arm/mach-s3c2440/mach-gta02.c
++++ b/arch/arm/mach-s3c2440/mach-gta02.c
+@@ -905,31 +905,58 @@ static struct platform_device gta02_vibrator_dev = {
+ /* #define DEBUG_SPEW_MS */
+ #define MG_PER_SAMPLE 18
++struct lis302dl_platform_data lis302_pdata[];
++
+ void gat02_lis302dl_bitbang_read(struct lis302dl_info *lis)
+ {
+       struct lis302dl_platform_data *pdata = lis->pdata;
+       u8 shifter = 0xc0 | LIS302DL_REG_OUT_X; /* read, autoincrement */
+       int n, n1;
++      unsigned long other_cs;
+       unsigned long flags;
+ #ifdef DEBUG_SPEW_MS
+       s8 x, y, z;
+ #endif
+-      spin_lock_irqsave(&motion_irq_lock, flags);
++      local_save_flags(flags);
++
++      /*
++       * Huh.. "quirk"... CS on this device is not really "CS" like you can
++       * expect.  Instead when 1 it selects I2C interface mode.  Because we
++       * have 2 devices on one interface, the "disabled" device when we talk
++       * to an "enabled" device sees the clocks as I2C clocks, creating
++       * havoc.
++       * I2C sees MOSI going LOW while CLK HIGH as a START action, we must
++       * ensure this is never issued.
++       */
++
++      if (&lis302_pdata[0] == pdata)
++              other_cs = lis302_pdata[1].pin_chip_select;
++      else
++              other_cs = lis302_pdata[0].pin_chip_select;
++
++      s3c2410_gpio_setpin(other_cs, 1);
++      s3c2410_gpio_setpin(pdata->pin_chip_select, 1);
++      s3c2410_gpio_setpin(pdata->pin_clk, 1);
+       s3c2410_gpio_setpin(pdata->pin_chip_select, 0);
+       for (n = 0; n < 8; n++) { /* write the r/w, inc and address */
+               s3c2410_gpio_setpin(pdata->pin_clk, 0);
+               s3c2410_gpio_setpin(pdata->pin_mosi, (shifter >> 7) & 1);
++              s3c2410_gpio_setpin(pdata->pin_clk, 0);
++              s3c2410_gpio_setpin(pdata->pin_clk, 1);
+               s3c2410_gpio_setpin(pdata->pin_clk, 1);
+               shifter <<= 1;
+       }
++
+       for (n = 0; n < 5; n++) { /* 5 consequetive registers */
+               for (n1 = 0; n1 < 8; n1++) { /* 8 bits each */
+                       s3c2410_gpio_setpin(pdata->pin_clk, 0);
+-                      s3c2410_gpio_setpin(pdata->pin_clk, 1);
++                      s3c2410_gpio_setpin(pdata->pin_clk, 0);
+                       shifter <<= 1;
+                       if (s3c2410_gpio_getpin(pdata->pin_miso))
+                               shifter |= 1;
++                      s3c2410_gpio_setpin(pdata->pin_clk, 1);
++                      s3c2410_gpio_setpin(pdata->pin_clk, 1);
+               }
+               switch (n) {
+               case 0:
+@@ -953,7 +980,9 @@ void gat02_lis302dl_bitbang_read(struct lis302dl_info *lis)
+               }
+       }
+       s3c2410_gpio_setpin(pdata->pin_chip_select, 1);
+-      spin_unlock_irqrestore(&motion_irq_lock, flags);
++      s3c2410_gpio_setpin(other_cs, 1);
++      local_irq_restore(flags);
++
+       input_sync(lis->input_dev);
+ #ifdef DEBUG_SPEW_MS
+       printk("%s: %d %d %d\n", pdata->name, x, y, z);
+-- 
+1.5.6.3
+