diff options
Diffstat (limited to 'target/linux/s3c24xx/patches-2.6.26/1141-fix-motion-sensor-corruption.patch.patch')
-rwxr-xr-x | target/linux/s3c24xx/patches-2.6.26/1141-fix-motion-sensor-corruption.patch.patch | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/target/linux/s3c24xx/patches-2.6.26/1141-fix-motion-sensor-corruption.patch.patch b/target/linux/s3c24xx/patches-2.6.26/1141-fix-motion-sensor-corruption.patch.patch new file mode 100755 index 0000000..a9b7243 --- /dev/null +++ b/target/linux/s3c24xx/patches-2.6.26/1141-fix-motion-sensor-corruption.patch.patch @@ -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 + |