changed Makefile and profiles, added patches for kernel 2.6.24
[openwrt.git] / target / linux / s3c24xx / patches-2.6.26 / 0090-fix-lis302dl-suspend-gpio.patch.patch
1 From f97c81869175362f755488bd50ddf85570236ce8 Mon Sep 17 00:00:00 2001
2 From: Andy Green <andy@openmoko.com>
3 Date: Fri, 25 Jul 2008 23:06:02 +0100
4 Subject: [PATCH] fix-lis302dl-suspend-gpio.patch
5  Add platform stuff to deal with going in and out of suspend
6  so the motion sensor IO is not driving high into unpowered sensors
7
8 Signed-off-by: Andy Green <andy@openmoko.com>
9 ---
10  arch/arm/mach-s3c2440/mach-gta02.c |   28 +++++++++++++++++++++++++++-
11  drivers/input/misc/lis302dl.c      |   15 +++++++++++++++
12  include/linux/lis302dl.h           |    1 +
13  3 files changed, 43 insertions(+), 1 deletions(-)
14
15 diff --git a/arch/arm/mach-s3c2440/mach-gta02.c b/arch/arm/mach-s3c2440/mach-gta02.c
16 index 5bd68a6..99206ee 100644
17 --- a/arch/arm/mach-s3c2440/mach-gta02.c
18 +++ b/arch/arm/mach-s3c2440/mach-gta02.c
19 @@ -887,7 +887,31 @@ void gat02_lis302dl_bitbang_read(struct lis302dl_info *lis)
20  }
21  
22  
23 -struct lis302dl_platform_data lis302_pdata[] = {
24 +void gat02_lis302dl_suspend_io(struct lis302dl_info *lis, int resume)
25 +{
26 +       struct lis302dl_platform_data *pdata = lis->pdata;
27 +
28 +       if (!resume) {
29 +                /*
30 +                * we don't want to power them with a high level
31 +                * because GSENSOR_3V3 is not up during suspend
32 +                */
33 +               s3c2410_gpio_setpin(pdata->pin_chip_select, 0);
34 +               s3c2410_gpio_setpin(pdata->pin_clk, 0);
35 +               s3c2410_gpio_setpin(pdata->pin_mosi, 0);
36 +               /* misnomer: it is a pullDOWN in 2442 */
37 +               s3c2410_gpio_pullup(pdata->pin_miso, 1);
38 +               return;
39 +       }
40 +
41 +       /* back to normal */
42 +       s3c2410_gpio_setpin(pdata->pin_chip_select, 1);
43 +       s3c2410_gpio_setpin(pdata->pin_clk, 1);
44 +       /* misnomer: it is a pullDOWN in 2442 */
45 +       s3c2410_gpio_pullup(pdata->pin_miso, 0);
46 +}
47 +
48 +const struct lis302dl_platform_data lis302_pdata[] = {
49         {
50                 .name           = "lis302-1 (top)",
51                 .pin_chip_select= S3C2410_GPD12,
52 @@ -896,6 +920,7 @@ struct lis302dl_platform_data lis302_pdata[] = {
53                 .pin_miso       = S3C2410_GPG5,
54                 .open_drain     = 1, /* altered at runtime by PCB rev */
55                 .lis302dl_bitbang_read = gat02_lis302dl_bitbang_read,
56 +               .lis302dl_suspend_io = gat02_lis302dl_suspend_io,
57         }, {
58                 .name           = "lis302-2 (bottom)",
59                 .pin_chip_select= S3C2410_GPD13,
60 @@ -904,6 +929,7 @@ struct lis302dl_platform_data lis302_pdata[] = {
61                 .pin_miso       = S3C2410_GPG5,
62                 .open_drain     = 1, /* altered at runtime by PCB rev */
63                 .lis302dl_bitbang_read = gat02_lis302dl_bitbang_read,
64 +               .lis302dl_suspend_io = gat02_lis302dl_suspend_io,
65         },
66  };
67  
68 diff --git a/drivers/input/misc/lis302dl.c b/drivers/input/misc/lis302dl.c
69 index 36bdcf7..2be816a 100644
70 --- a/drivers/input/misc/lis302dl.c
71 +++ b/drivers/input/misc/lis302dl.c
72 @@ -428,6 +428,15 @@ static int lis302dl_suspend(struct spi_device *spi, pm_message_t state)
73         disable_irq(lis->spi_dev->irq);
74         local_save_flags(flags);
75  
76 +       /*
77 +        * When we share SPI over multiple sensors, there is a race here
78 +        * that one or more sensors will lose.  In that case, the shared
79 +        * SPI bus GPIO will be in sleep mode and partially pulled down.  So
80 +        * we explicitly put our IO into "wake" mode here before the final
81 +        * traffic to the sensor.
82 +        */
83 +       (lis->pdata->lis302dl_suspend_io)(lis, 1);
84 +
85         /* save registers */
86         lis->regs[LIS302DL_REG_CTRL1] = reg_read(lis, LIS302DL_REG_CTRL1);
87         lis->regs[LIS302DL_REG_CTRL2] = reg_read(lis, LIS302DL_REG_CTRL2);
88 @@ -467,6 +476,9 @@ static int lis302dl_suspend(struct spi_device *spi, pm_message_t state)
89                 reg_write(lis, LIS302DL_REG_CTRL1, tmp);
90         }
91  
92 +       /* place our IO to the device in sleep-compatible states */
93 +       (lis->pdata->lis302dl_suspend_io)(lis, 0);
94 +
95         local_irq_restore(flags);
96  
97         return 0;
98 @@ -479,6 +491,9 @@ static int lis302dl_resume(struct spi_device *spi)
99  
100         local_save_flags(flags);
101  
102 +       /* get our IO to the device back in operational states */
103 +       (lis->pdata->lis302dl_suspend_io)(lis, 1);
104 +
105         /* restore registers after resume */
106         reg_write(lis, LIS302DL_REG_CTRL1, lis->regs[LIS302DL_REG_CTRL1]);
107         reg_write(lis, LIS302DL_REG_CTRL2, lis->regs[LIS302DL_REG_CTRL2]);
108 diff --git a/include/linux/lis302dl.h b/include/linux/lis302dl.h
109 index 2dea813..0d6b4c4 100644
110 --- a/include/linux/lis302dl.h
111 +++ b/include/linux/lis302dl.h
112 @@ -16,6 +16,7 @@ struct lis302dl_platform_data {
113         unsigned long pin_miso;
114         int open_drain;
115         void (*lis302dl_bitbang_read)(struct lis302dl_info *);
116 +       void (*lis302dl_suspend_io)(struct lis302dl_info *, int resuming);
117  };
118  
119  struct lis302dl_info {
120 -- 
121 1.5.6.3
122