disable IMQ on 2.6.28 as well -- people should use IFB..
[openwrt.git] / target / linux / s3c24xx / patches / 0141-fix-motion-sensor-corruption.patch.patch
1 From 18a3bda7bf72a36c3e3164402cd0e4dfa2ff4687 Mon Sep 17 00:00:00 2001
2 From: Andy Green <agreen@localhost.localdomain>
3 Date: Fri, 25 Jul 2008 23:06:09 +0100
4 Subject: [PATCH] fix-motion-sensor-corruption.patch
5
6 ---
7  arch/arm/mach-s3c2440/mach-gta02.c |   35 ++++++++++++++++++++++++++++++++---
8  1 files changed, 32 insertions(+), 3 deletions(-)
9
10 diff --git a/arch/arm/mach-s3c2440/mach-gta02.c b/arch/arm/mach-s3c2440/mach-gta02.c
11 index e1984a9..9e8fae7 100644
12 --- a/arch/arm/mach-s3c2440/mach-gta02.c
13 +++ b/arch/arm/mach-s3c2440/mach-gta02.c
14 @@ -905,31 +905,58 @@ static struct platform_device gta02_vibrator_dev = {
15  /* #define DEBUG_SPEW_MS */
16  #define MG_PER_SAMPLE 18
17  
18 +struct lis302dl_platform_data lis302_pdata[];
19 +
20  void gat02_lis302dl_bitbang_read(struct lis302dl_info *lis)
21  {
22         struct lis302dl_platform_data *pdata = lis->pdata;
23         u8 shifter = 0xc0 | LIS302DL_REG_OUT_X; /* read, autoincrement */
24         int n, n1;
25 +       unsigned long other_cs;
26         unsigned long flags;
27  #ifdef DEBUG_SPEW_MS
28         s8 x, y, z;
29  #endif
30  
31 -       spin_lock_irqsave(&motion_irq_lock, flags);
32 +       local_save_flags(flags);
33 +
34 +       /*
35 +        * Huh.. "quirk"... CS on this device is not really "CS" like you can
36 +        * expect.  Instead when 1 it selects I2C interface mode.  Because we
37 +        * have 2 devices on one interface, the "disabled" device when we talk
38 +        * to an "enabled" device sees the clocks as I2C clocks, creating
39 +        * havoc.
40 +        * I2C sees MOSI going LOW while CLK HIGH as a START action, we must
41 +        * ensure this is never issued.
42 +        */
43 +
44 +       if (&lis302_pdata[0] == pdata)
45 +               other_cs = lis302_pdata[1].pin_chip_select;
46 +       else
47 +               other_cs = lis302_pdata[0].pin_chip_select;
48 +
49 +       s3c2410_gpio_setpin(other_cs, 1);
50 +       s3c2410_gpio_setpin(pdata->pin_chip_select, 1);
51 +       s3c2410_gpio_setpin(pdata->pin_clk, 1);
52         s3c2410_gpio_setpin(pdata->pin_chip_select, 0);
53         for (n = 0; n < 8; n++) { /* write the r/w, inc and address */
54                 s3c2410_gpio_setpin(pdata->pin_clk, 0);
55                 s3c2410_gpio_setpin(pdata->pin_mosi, (shifter >> 7) & 1);
56 +               s3c2410_gpio_setpin(pdata->pin_clk, 0);
57 +               s3c2410_gpio_setpin(pdata->pin_clk, 1);
58                 s3c2410_gpio_setpin(pdata->pin_clk, 1);
59                 shifter <<= 1;
60         }
61 +
62         for (n = 0; n < 5; n++) { /* 5 consequetive registers */
63                 for (n1 = 0; n1 < 8; n1++) { /* 8 bits each */
64                         s3c2410_gpio_setpin(pdata->pin_clk, 0);
65 -                       s3c2410_gpio_setpin(pdata->pin_clk, 1);
66 +                       s3c2410_gpio_setpin(pdata->pin_clk, 0);
67                         shifter <<= 1;
68                         if (s3c2410_gpio_getpin(pdata->pin_miso))
69                                 shifter |= 1;
70 +                       s3c2410_gpio_setpin(pdata->pin_clk, 1);
71 +                       s3c2410_gpio_setpin(pdata->pin_clk, 1);
72                 }
73                 switch (n) {
74                 case 0:
75 @@ -953,7 +980,9 @@ void gat02_lis302dl_bitbang_read(struct lis302dl_info *lis)
76                 }
77         }
78         s3c2410_gpio_setpin(pdata->pin_chip_select, 1);
79 -       spin_unlock_irqrestore(&motion_irq_lock, flags);
80 +       s3c2410_gpio_setpin(other_cs, 1);
81 +       local_irq_restore(flags);
82 +
83         input_sync(lis->input_dev);
84  #ifdef DEBUG_SPEW_MS
85         printk("%s: %d %d %d\n", pdata->name, x, y, z);
86 -- 
87 1.5.6.3
88