changed Makefile and profiles, added patches for kernel 2.6.24
[openwrt.git] / target / linux / s3c24xx / patches-2.6.24 / 1303-fix-lid302dl-bitbang-all-the-way-baby.patch.patch
1 From 1c6f5a92c816db43128444606c26507ebe6e5a43 Mon Sep 17 00:00:00 2001
2 From: Andy Green <andy@openmoko.com>
3 Date: Mon, 13 Oct 2008 12:01:05 +0100
4 Subject: [PATCH] fix-lid302dl-bitbang-all-the-way-baby.patch
5
6 This large patch removes motion sensor from Linux SPI bitbang driver.
7 Previously, some access was done through Linux SPI protected
8 by a mutex, and the ISR access was done by platform bitbang code due
9 to inability of Linux SPI driver to work in the interrupt context.
10
11 Now all access is done by bitbang callbacks in mach_gta02.c and are
12 protected by single scheme of interrupt lockout for the duration --
13 I line-by-line'd the driver to confirm that best I could, adding
14 protection and taking more care on several /sys related paths.
15
16 Because this is no longer a Linux SPI bus driver, the path for various
17 /sys things have changed.  They can now be found down, eg,
18
19 /sys/devices/platform/lis302dl.1/sample_rate
20
21 lis302dl.1 is the top sensor and .2 the bottom.  The names of the input
22 susbsytem paths remain the same as before.
23
24 Signed-off-by: Andy Green <andy@openmoko.com>
25 ---
26  arch/arm/mach-s3c2440/mach-gta02.c |  233 +++++++++----------
27  drivers/input/misc/lis302dl.c      |  437 ++++++++++++++++--------------------
28  include/linux/lis302dl.h           |    9 +-
29  3 files changed, 315 insertions(+), 364 deletions(-)
30
31 diff --git a/arch/arm/mach-s3c2440/mach-gta02.c b/arch/arm/mach-s3c2440/mach-gta02.c
32 index 467c417..b19632c 100644
33 --- a/arch/arm/mach-s3c2440/mach-gta02.c
34 +++ b/arch/arm/mach-s3c2440/mach-gta02.c
35 @@ -1052,20 +1052,21 @@ static struct platform_device gta02_vibrator_dev = {
36  /* #define DEBUG_SPEW_MS */
37  #define MG_PER_SAMPLE 18
38  
39 -struct lis302dl_platform_data lis302_pdata[];
40 +struct lis302dl_platform_data lis302_pdata_top;
41 +struct lis302dl_platform_data lis302_pdata_bottom;
42  
43 -void gta02_lis302dl_bitbang_read(struct lis302dl_info *lis)
44 +/*
45 + * generic SPI RX and TX bitbang
46 + * only call with interrupts off!
47 + */
48 +
49 +static void __gta02_lis302dl_bitbang(struct lis302dl_info *lis, u8 *tx,
50 +                                            int tx_bytes, u8 *rx, int rx_bytes)
51  {
52         struct lis302dl_platform_data *pdata = lis->pdata;
53 -       u8 shifter = 0xc0 | LIS302DL_REG_OUT_X; /* read, autoincrement */
54 -       int n, n1;
55 +       int n;
56 +       u8 shifter = 0;
57         unsigned long other_cs;
58 -       unsigned long flags;
59 -#ifdef DEBUG_SPEW_MS
60 -       s8 x, y, z;
61 -#endif
62 -
63 -       local_irq_save(flags);
64  
65         /*
66          * Huh.. "quirk"... CS on this device is not really "CS" like you can
67 @@ -1073,20 +1074,25 @@ void gta02_lis302dl_bitbang_read(struct lis302dl_info *lis)
68          * have 2 devices on one interface, the "disabled" device when we talk
69          * to an "enabled" device sees the clocks as I2C clocks, creating
70          * havoc.
71 +        *
72          * I2C sees MOSI going LOW while CLK HIGH as a START action, we must
73          * ensure this is never issued.
74          */
75  
76 -       if (&lis302_pdata[0] == pdata)
77 -               other_cs = lis302_pdata[1].pin_chip_select;
78 +       if (&lis302_pdata_top == pdata)
79 +               other_cs = lis302_pdata_bottom.pin_chip_select;
80         else
81 -               other_cs = lis302_pdata[0].pin_chip_select;
82 +               other_cs = lis302_pdata_top.pin_chip_select;
83  
84         s3c2410_gpio_setpin(other_cs, 1);
85         s3c2410_gpio_setpin(pdata->pin_chip_select, 1);
86         s3c2410_gpio_setpin(pdata->pin_clk, 1);
87         s3c2410_gpio_setpin(pdata->pin_chip_select, 0);
88 -       for (n = 0; n < 8; n++) { /* write the r/w, inc and address */
89 +
90 +       /* send the register index, r/w and autoinc bits */
91 +       for (n = 0; n < (tx_bytes << 3); n++) {
92 +               if (!(n & 7))
93 +                       shifter = tx[n >> 3];
94                 s3c2410_gpio_setpin(pdata->pin_clk, 0);
95                 s3c2410_gpio_setpin(pdata->pin_mosi, (shifter >> 7) & 1);
96                 s3c2410_gpio_setpin(pdata->pin_clk, 0);
97 @@ -1095,44 +1101,71 @@ void gta02_lis302dl_bitbang_read(struct lis302dl_info *lis)
98                 shifter <<= 1;
99         }
100  
101 -       for (n = 0; n < 5; n++) { /* 5 consequetive registers */
102 -               for (n1 = 0; n1 < 8; n1++) { /* 8 bits each */
103 -                       s3c2410_gpio_setpin(pdata->pin_clk, 0);
104 -                       s3c2410_gpio_setpin(pdata->pin_clk, 0);
105 -                       shifter <<= 1;
106 -                       if (s3c2410_gpio_getpin(pdata->pin_miso))
107 -                               shifter |= 1;
108 -                       s3c2410_gpio_setpin(pdata->pin_clk, 1);
109 -                       s3c2410_gpio_setpin(pdata->pin_clk, 1);
110 -               }
111 -               switch (n) {
112 -               case 0:
113 -#ifdef DEBUG_SPEW_MS
114 -                       x = shifter;
115 -#endif
116 -                       input_report_rel(lis->input_dev, REL_X, MG_PER_SAMPLE * (s8)shifter);
117 -                       break;
118 -               case 2:
119 -#ifdef DEBUG_SPEW_MS
120 -                       y = shifter;
121 -#endif
122 -                       input_report_rel(lis->input_dev, REL_Y, MG_PER_SAMPLE * (s8)shifter);
123 -                       break;
124 -               case 4:
125 -#ifdef DEBUG_SPEW_MS
126 -                       z = shifter;
127 -#endif
128 -                       input_report_rel(lis->input_dev, REL_Z, MG_PER_SAMPLE * (s8)shifter);
129 -                       break;
130 -               }
131 +       for (n = 0; n < (rx_bytes << 3); n++) { /* 8 bits each */
132 +               s3c2410_gpio_setpin(pdata->pin_clk, 0);
133 +               s3c2410_gpio_setpin(pdata->pin_clk, 0);
134 +               shifter <<= 1;
135 +               if (s3c2410_gpio_getpin(pdata->pin_miso))
136 +                       shifter |= 1;
137 +               if ((n & 7) == 7)
138 +                       rx[n >> 3] = shifter;
139 +               s3c2410_gpio_setpin(pdata->pin_clk, 1);
140 +               s3c2410_gpio_setpin(pdata->pin_clk, 1);
141         }
142         s3c2410_gpio_setpin(pdata->pin_chip_select, 1);
143         s3c2410_gpio_setpin(other_cs, 1);
144 +}
145 +
146 +
147 +static int gta02_lis302dl_bitbang_read_reg(struct lis302dl_info *lis, u8 reg)
148 +{
149 +       u8 data = 0xc0 | reg; /* read, autoincrement */
150 +       unsigned long flags;
151 +
152 +       local_irq_save(flags);
153 +
154 +       __gta02_lis302dl_bitbang(lis, &data, 1, &data, 1);
155 +
156 +       local_irq_restore(flags);
157 +
158 +       return data;
159 +}
160 +
161 +static void gta02_lis302dl_bitbang_write_reg(struct lis302dl_info *lis, u8 reg,
162 +                                                                        u8 val)
163 +{
164 +       u8 data[2] = { 0x00 | reg, val }; /* write, no autoincrement */
165 +       unsigned long flags;
166 +
167 +       local_irq_save(flags);
168 +
169 +       __gta02_lis302dl_bitbang(lis, &data[0], 2, NULL, 0);
170 +
171         local_irq_restore(flags);
172  
173 +}
174 +
175 +
176 +static void gta02_lis302dl_bitbang_sample(struct lis302dl_info *lis)
177 +{
178 +       u8 data = 0xc0 | LIS302DL_REG_OUT_X; /* read, autoincrement */
179 +       u8 read[5];
180 +       unsigned long flags;
181 +
182 +       local_irq_save(flags);
183 +
184 +       __gta02_lis302dl_bitbang(lis, &data, 1, &read[0], 5);
185 +
186 +       local_irq_restore(flags);
187 +
188 +       input_report_rel(lis->input_dev, REL_X, MG_PER_SAMPLE * (s8)read[0]);
189 +       input_report_rel(lis->input_dev, REL_Y, MG_PER_SAMPLE * (s8)read[2]);
190 +       input_report_rel(lis->input_dev, REL_Z, MG_PER_SAMPLE * (s8)read[4]);
191 +
192         input_sync(lis->input_dev);
193  #ifdef DEBUG_SPEW_MS
194 -       printk("%s: %d %d %d\n", pdata->name, x, y, z);
195 +       printk(KERN_INFO "%s: %d %d %d\n", pdata->name, read[0], read[2],
196 +                                                                      read[4]);
197  #endif
198  }
199  
200 @@ -1159,103 +1192,58 @@ void gta02_lis302dl_suspend_io(struct lis302dl_info *lis, int resume)
201         s3c2410_gpio_setpin(pdata->pin_clk, 1);
202         /* misnomer: it is a pullDOWN in 2442 */
203         s3c2410_gpio_pullup(pdata->pin_miso, 0);
204 +
205 +       s3c2410_gpio_cfgpin(pdata->pin_chip_select, S3C2410_GPIO_OUTPUT);
206 +       s3c2410_gpio_cfgpin(pdata->pin_clk, S3C2410_GPIO_OUTPUT);
207 +       s3c2410_gpio_cfgpin(pdata->pin_mosi, S3C2410_GPIO_OUTPUT);
208 +       s3c2410_gpio_cfgpin(pdata->pin_miso, S3C2410_GPIO_INPUT);
209 +
210  }
211  
212 -struct lis302dl_platform_data lis302_pdata[] = {
213 -       {
214 +
215 +
216 +struct lis302dl_platform_data lis302_pdata_top = {
217                 .name           = "lis302-1 (top)",
218                 .pin_chip_select= S3C2410_GPD12,
219                 .pin_clk        = S3C2410_GPG7,
220                 .pin_mosi       = S3C2410_GPG6,
221                 .pin_miso       = S3C2410_GPG5,
222 +               .interrupt      = GTA02_IRQ_GSENSOR_1,
223                 .open_drain     = 1, /* altered at runtime by PCB rev */
224 -               .lis302dl_bitbang_read = gta02_lis302dl_bitbang_read,
225 +               .lis302dl_bitbang_read_sample = gta02_lis302dl_bitbang_sample,
226 +               .lis302dl_bitbang_reg_read = gta02_lis302dl_bitbang_read_reg,
227 +               .lis302dl_bitbang_reg_write = gta02_lis302dl_bitbang_write_reg,
228                 .lis302dl_suspend_io = gta02_lis302dl_suspend_io,
229 -       }, {
230 +};
231 +
232 +struct lis302dl_platform_data lis302_pdata_bottom = {
233                 .name           = "lis302-2 (bottom)",
234                 .pin_chip_select= S3C2410_GPD13,
235                 .pin_clk        = S3C2410_GPG7,
236                 .pin_mosi       = S3C2410_GPG6,
237                 .pin_miso       = S3C2410_GPG5,
238 +               .interrupt      = GTA02_IRQ_GSENSOR_2,
239                 .open_drain     = 1, /* altered at runtime by PCB rev */
240 -               .lis302dl_bitbang_read = gta02_lis302dl_bitbang_read,
241 +               .lis302dl_bitbang_read_sample = gta02_lis302dl_bitbang_sample,
242 +               .lis302dl_bitbang_reg_read = gta02_lis302dl_bitbang_read_reg,
243 +               .lis302dl_bitbang_reg_write = gta02_lis302dl_bitbang_write_reg,
244                 .lis302dl_suspend_io = gta02_lis302dl_suspend_io,
245 -       },
246  };
247  
248 -static struct spi_board_info gta02_spi_acc_bdinfo[] = {
249 -       {
250 -               .modalias       = "lis302dl",
251 -               .platform_data  = &lis302_pdata[0],
252 -               .irq            = GTA02_IRQ_GSENSOR_1,
253 -               .max_speed_hz   = 10 * 1000 * 1000,
254 -               .bus_num        = 1,
255 -               .chip_select    = 0,
256 -               .mode           = SPI_MODE_3,
257 -       },
258 -       {
259 -               .modalias       = "lis302dl",
260 -               .platform_data  = &lis302_pdata[1],
261 -               .irq            = GTA02_IRQ_GSENSOR_2,
262 -               .max_speed_hz   = 10 * 1000 * 1000,
263 -               .bus_num        = 1,
264 -               .chip_select    = 1,
265 -               .mode           = SPI_MODE_3,
266 -       },
267 -};
268 -
269 -static void spi_acc_cs(struct s3c2410_spigpio_info *spigpio_info,
270 -                      int csid, int cs)
271 -{
272 -       struct lis302dl_platform_data * plat_data =
273 -                               (struct lis302dl_platform_data *)spigpio_info->
274 -                                                    board_info->platform_data;
275 -       switch (cs) {
276 -       case BITBANG_CS_ACTIVE:
277 -               s3c2410_gpio_setpin(plat_data[csid].pin_chip_select, 0);
278 -               break;
279 -       case BITBANG_CS_INACTIVE:
280 -               s3c2410_gpio_setpin(plat_data[csid].pin_chip_select, 1);
281 -               break;
282 -       }
283 -}
284  
285 -static struct s3c2410_spigpio_info spi_gpio_cfg = {
286 -       .pin_clk        = S3C2410_GPG7,
287 -       .pin_mosi       = S3C2410_GPG6,
288 -       .pin_miso       = S3C2410_GPG5,
289 -       .board_size     = ARRAY_SIZE(gta02_spi_acc_bdinfo),
290 -       .board_info     = gta02_spi_acc_bdinfo,
291 -       .chip_select    = &spi_acc_cs,
292 -       .num_chipselect = 2,
293 -};
294 -
295 -static struct resource s3c_spi_acc_resource[] = {
296 -       [0] = {
297 -               .start = S3C2410_GPG3,
298 -               .end   = S3C2410_GPG3,
299 -       },
300 -       [1] = {
301 -               .start = S3C2410_GPG5,
302 -               .end   = S3C2410_GPG5,
303 -       },
304 -       [2] = {
305 -               .start = S3C2410_GPG6,
306 -               .end   = S3C2410_GPG6,
307 -       },
308 -       [3] = {
309 -               .start = S3C2410_GPG7,
310 -               .end   = S3C2410_GPG7,
311 +static struct platform_device s3c_device_spi_acc1 = {
312 +       .name             = "lis302dl",
313 +       .id               = 1,
314 +       .dev = {
315 +               .platform_data = &lis302_pdata_top,
316         },
317  };
318  
319 -static struct platform_device s3c_device_spi_acc = {
320 -       .name             = "spi_s3c24xx_gpio",
321 -       .id               = 1,
322 -       .num_resources    = ARRAY_SIZE(s3c_spi_acc_resource),
323 -       .resource         = s3c_spi_acc_resource,
324 +static struct platform_device s3c_device_spi_acc2 = {
325 +       .name             = "lis302dl",
326 +       .id               = 2,
327         .dev = {
328 -               .platform_data = &spi_gpio_cfg,
329 +               .platform_data = &lis302_pdata_bottom,
330         },
331  };
332  
333 @@ -1573,8 +1561,8 @@ static void __init gta02_machine_init(void)
334         switch (system_rev) {
335         case GTA02v6_SYSTEM_REV:
336                 /* we need push-pull interrupt from motion sensors */
337 -               lis302_pdata[0].open_drain = 0;
338 -               lis302_pdata[1].open_drain = 0;
339 +               lis302_pdata_top.open_drain = 0;
340 +               lis302_pdata_bottom.open_drain = 0;
341                 break;
342         default:
343                 break;
344 @@ -1635,7 +1623,8 @@ static void __init gta02_machine_init(void)
345         mangle_glamo_res_by_system_rev();
346         platform_device_register(&gta02_glamo_dev);
347  
348 -       platform_device_register(&s3c_device_spi_acc);
349 +       platform_device_register(&s3c_device_spi_acc1);
350 +       platform_device_register(&s3c_device_spi_acc2);
351         platform_device_register(&gta02_button_dev);
352         platform_device_register(&gta02_pm_gsm_dev);
353         platform_device_register(&gta02_pm_usbhost_dev);
354 diff --git a/drivers/input/misc/lis302dl.c b/drivers/input/misc/lis302dl.c
355 index b01ca04..1d5781d 100644
356 --- a/drivers/input/misc/lis302dl.c
357 +++ b/drivers/input/misc/lis302dl.c
358 @@ -1,7 +1,9 @@
359  /* Linux kernel driver for the ST LIS302D 3-axis accelerometer
360   *
361 - * Copyright (C) 2007 by Openmoko, Inc.
362 + * Copyright (C) 2007-2008 by Openmoko, Inc.
363   * Author: Harald Welte <laforge@openmoko.org>
364 + *         converted to private bitbang by:
365 + *         Andy Green <andy@openmoko.com>
366   * All rights reserved.
367   *
368   * This program is free software; you can redistribute it and/or
369 @@ -39,78 +41,19 @@
370  
371  #include <linux/lis302dl.h>
372  
373 -/* lowlevel register access functions */
374  
375 -#define READ_BIT               0x80
376 -#define READ_BIT_INC_ADS       0xc0
377 -#define        ADDR_MASK               0x3f
378  
379 -static u_int8_t __reg_read(struct lis302dl_info *lis, u_int8_t reg)
380 +static void __reg_set_bit_mask(struct lis302dl_info *lis, u8 reg, u8 mask,
381 +                                                                        u8 val)
382  {
383 -       int rc;
384 -       u_int8_t cmd;
385 -
386 -       BUG_ON(reg & ~ADDR_MASK);
387 -
388 -       cmd = reg | READ_BIT;
389 -
390 -       rc = spi_w8r8(lis->spi_dev, cmd);
391 -
392 -       return rc;
393 -}
394 -
395 -static u_int8_t reg_read(struct lis302dl_info *lis, u_int8_t reg)
396 -{
397 -       u_int8_t ret;
398 -
399 -       mutex_lock(&lis->lock);
400 -       ret = __reg_read(lis, reg);
401 -       mutex_unlock(&lis->lock);
402 -
403 -       return ret;
404 -}
405 -
406 -static int __reg_write(struct lis302dl_info *lis, u_int8_t reg, u_int8_t val)
407 -{
408 -       u_int8_t buf[2];
409 -
410 -       BUG_ON(reg & ~ADDR_MASK);
411 -
412 -       buf[0] = reg;
413 -       buf[1] = val;
414 -
415 -       return spi_write(lis->spi_dev, buf, sizeof(buf));
416 -}
417 -
418 -static int reg_write(struct lis302dl_info *lis, u_int8_t reg, u_int8_t val)
419 -{
420 -       int ret;
421 -
422 -       mutex_lock(&lis->lock);
423 -       ret = __reg_write(lis, reg, val);
424 -       mutex_unlock(&lis->lock);
425 -
426 -       return ret;
427 -}
428 -
429 -static int reg_set_bit_mask(struct lis302dl_info *lis,
430 -                           u_int8_t reg, u_int8_t mask, u_int8_t val)
431 -{
432 -       int ret;
433         u_int8_t tmp;
434  
435         val &= mask;
436  
437 -       mutex_lock(&lis->lock);
438 -
439 -       tmp = __reg_read(lis, reg);
440 +       tmp = (lis->pdata->lis302dl_bitbang_reg_read)(lis, reg);
441         tmp &= ~mask;
442         tmp |= val;
443 -       ret = __reg_write(lis, reg, tmp);
444 -
445 -       mutex_unlock(&lis->lock);
446 -
447 -       return ret;
448 +       (lis->pdata->lis302dl_bitbang_reg_write)(lis, reg, tmp);
449  }
450  
451  /* interrupt handling related */
452 @@ -124,17 +67,17 @@ enum lis302dl_intmode {
453         LIS302DL_INTMODE_CLICK          = 0x07,
454  };
455  
456 -static void lis302dl_int_mode(struct spi_device *spi, int int_pin,
457 +static void __lis302dl_int_mode(struct device *dev, int int_pin,
458                               enum lis302dl_intmode mode)
459  {
460 -       struct lis302dl_info *lis = dev_get_drvdata(&spi->dev);
461 +       struct lis302dl_info *lis = dev_get_drvdata(dev);
462  
463         switch (int_pin) {
464         case 1:
465 -               reg_set_bit_mask(lis, LIS302DL_REG_CTRL3, 0x07, mode);
466 +               __reg_set_bit_mask(lis, LIS302DL_REG_CTRL3, 0x07, mode);
467                 break;
468         case 2:
469 -               reg_set_bit_mask(lis, LIS302DL_REG_CTRL3, 0x38, mode << 3);
470 +               __reg_set_bit_mask(lis, LIS302DL_REG_CTRL3, 0x38, mode << 3);
471                 break;
472         default:
473                 BUG();
474 @@ -165,7 +108,7 @@ static irqreturn_t lis302dl_interrupt(int irq, void *_lis)
475  {
476         struct lis302dl_info *lis = _lis;
477  
478 -       (lis->pdata->lis302dl_bitbang_read)(lis);
479 +       (lis->pdata->lis302dl_bitbang_read_sample)(lis);
480         return IRQ_HANDLED;
481  }
482  
483 @@ -175,7 +118,13 @@ static ssize_t show_rate(struct device *dev, struct device_attribute *attr,
484                          char *buf)
485  {
486         struct lis302dl_info *lis = dev_get_drvdata(dev);
487 -       u_int8_t ctrl1 = reg_read(lis, LIS302DL_REG_CTRL1);
488 +       u8 ctrl1;
489 +       unsigned long flags;
490 +
491 +       local_irq_save(flags);
492 +       ctrl1 = (lis->pdata->lis302dl_bitbang_reg_read)
493 +                                                     (lis, LIS302DL_REG_CTRL1);
494 +       local_irq_restore(flags);
495  
496         return sprintf(buf, "%d\n", ctrl1 & LIS302DL_CTRL1_DR ? 400 : 100);
497  }
498 @@ -184,12 +133,17 @@ static ssize_t set_rate(struct device *dev, struct device_attribute *attr,
499                         const char *buf, size_t count)
500  {
501         struct lis302dl_info *lis = dev_get_drvdata(dev);
502 +       unsigned long flags;
503 +
504 +       local_irq_save(flags);
505  
506         if (!strcmp(buf, "400\n"))
507 -               reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, LIS302DL_CTRL1_DR,
508 +               __reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, LIS302DL_CTRL1_DR,
509                                  LIS302DL_CTRL1_DR);
510         else
511 -               reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, LIS302DL_CTRL1_DR, 0);
512 +               __reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, LIS302DL_CTRL1_DR,
513 +                                                                            0);
514 +       local_irq_restore(flags);
515  
516         return count;
517  }
518 @@ -200,7 +154,13 @@ static ssize_t show_scale(struct device *dev, struct device_attribute *attr,
519                           char *buf)
520  {
521         struct lis302dl_info *lis = dev_get_drvdata(dev);
522 -       u_int8_t ctrl1 = reg_read(lis, LIS302DL_REG_CTRL1);
523 +       u_int8_t ctrl1;
524 +       unsigned long flags;
525 +
526 +       local_irq_save(flags);
527 +       ctrl1 = (lis->pdata->lis302dl_bitbang_reg_read)(lis,
528 +                                                           LIS302DL_REG_CTRL1);
529 +       local_irq_restore(flags);
530  
531         return sprintf(buf, "%s\n", ctrl1 & LIS302DL_CTRL1_FS ? "9.2" : "2.3");
532  }
533 @@ -209,12 +169,18 @@ static ssize_t set_scale(struct device *dev, struct device_attribute *attr,
534                          const char *buf, size_t count)
535  {
536         struct lis302dl_info *lis = dev_get_drvdata(dev);
537 +       unsigned long flags;
538 +
539 +       local_irq_save(flags);
540  
541         if (!strcmp(buf, "9.2\n"))
542 -               reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, LIS302DL_CTRL1_FS,
543 +               __reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, LIS302DL_CTRL1_FS,
544                                  LIS302DL_CTRL1_FS);
545         else
546 -               reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, LIS302DL_CTRL1_FS, 0);
547 +               __reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, LIS302DL_CTRL1_FS,
548 +                                                                            0);
549 +
550 +       local_irq_restore(flags);
551  
552         return count;
553  }
554 @@ -222,7 +188,7 @@ static ssize_t set_scale(struct device *dev, struct device_attribute *attr,
555  static DEVICE_ATTR(full_scale, S_IRUGO | S_IWUSR, show_scale, set_scale);
556  
557  static ssize_t lis302dl_dump(struct device *dev, struct device_attribute *attr,
558 -                         char *buf)
559 +                                                                     char *buf)
560  {
561         struct lis302dl_info *lis = dev_get_drvdata(dev);
562         int n = 0;
563 @@ -233,7 +199,7 @@ static ssize_t lis302dl_dump(struct device *dev, struct device_attribute *attr,
564         local_irq_save(flags);
565  
566         for (n = 0; n < sizeof(reg); n++)
567 -               reg[n] = reg_read(lis, n);
568 +               reg[n] = (lis->pdata->lis302dl_bitbang_reg_read)(lis, n);
569  
570         local_irq_restore(flags);
571  
572 @@ -248,9 +214,9 @@ static ssize_t lis302dl_dump(struct device *dev, struct device_attribute *attr,
573  }
574  static DEVICE_ATTR(dump, S_IRUGO, lis302dl_dump, NULL);
575  
576 -static int freefall_ms_to_duration(struct lis302dl_info *lis, int ms)
577 +static int __freefall_ms_to_duration(struct lis302dl_info *lis, int ms)
578  {
579 -       u_int8_t r = reg_read(lis, LIS302DL_REG_CTRL1);
580 +       u8 r = (lis->pdata->lis302dl_bitbang_reg_read)(lis, LIS302DL_REG_CTRL1);
581  
582         /* If we have 400 ms sampling rate, the stepping is 2.5 ms,
583          * on 100 ms the stepping is 10ms */
584 @@ -268,9 +234,9 @@ static int freefall_ms_to_duration(struct lis302dl_info *lis, int ms)
585         return ms / 10;
586  }
587  
588 -static int freefall_duration_to_ms(struct lis302dl_info *lis, int duration)
589 +static int __freefall_duration_to_ms(struct lis302dl_info *lis, int duration)
590  {
591 -       u_int8_t r = reg_read(lis, LIS302DL_REG_CTRL1);
592 +       u8 r = (lis->pdata->lis302dl_bitbang_reg_read)(lis, LIS302DL_REG_CTRL1);
593  
594         if (r & LIS302DL_CTRL1_DR)
595                 return (duration * 25) / 10;
596 @@ -314,18 +280,18 @@ static ssize_t set_freefall_common(int which, struct device *dev,
597                 /* Turn off the interrupt */
598                 local_irq_save(flags);
599                 if (lis->flags & LIS302DL_F_IRQ_WAKE)
600 -                       disable_irq_wake(lis->spi_dev->irq);
601 -               lis302dl_int_mode(lis->spi_dev, which,
602 +                       disable_irq_wake(lis->pdata->interrupt);
603 +               __lis302dl_int_mode(lis->dev, which,
604                                                    LIS302DL_INTMODE_DATA_READY);
605                 lis->flags &= ~(flag_mask | LIS302DL_F_IRQ_WAKE);
606  
607 -               reg_write(lis, r_cfg, 0);
608 -               reg_write(lis, r_ths, 0);
609 -               reg_write(lis, r_duration, 0);
610 +               (lis->pdata->lis302dl_bitbang_reg_write)(lis, r_cfg, 0);
611 +               (lis->pdata->lis302dl_bitbang_reg_write)(lis, r_ths, 0);
612 +               (lis->pdata->lis302dl_bitbang_reg_write)(lis, r_duration, 0);
613  
614                 /* Power off unless the input subsystem is using the device */
615                 if (!(lis->flags & LIS302DL_F_INPUT_OPEN))
616 -                       reg_set_bit_mask(lis, LIS302DL_REG_CTRL1,
617 +                       __reg_set_bit_mask(lis, LIS302DL_REG_CTRL1,
618                                                           LIS302DL_CTRL1_PD, 0);
619  
620                 local_irq_restore(flags);
621 @@ -337,7 +303,10 @@ static ssize_t set_freefall_common(int which, struct device *dev,
622                                                               &and_events) != 6)
623                 return -EINVAL;
624  
625 -       duration = freefall_ms_to_duration(lis, ms);
626 +       local_irq_save(flags);
627 +       duration = __freefall_ms_to_duration(lis, ms);
628 +       local_irq_save(flags);
629 +
630         if (duration < 0)
631                 return -ERANGE;
632  
633 @@ -355,23 +324,25 @@ static ssize_t set_freefall_common(int which, struct device *dev,
634  
635         /* Setup the configuration registers */
636         local_irq_save(flags);
637 -       reg_write(lis, r_cfg, 0); /* First zero to get to a known state */
638 -       reg_write(lis, r_cfg,
639 +       /* First zero to get to a known state */
640 +       (lis->pdata->lis302dl_bitbang_reg_write)(lis, r_cfg, 0);
641 +       (lis->pdata->lis302dl_bitbang_reg_write)(lis, r_cfg,
642                 (and_events ? LIS302DL_FFWUCFG_AOI : 0) |
643                 x_lo | x_hi | y_lo | y_hi | z_lo | z_hi);
644 -       reg_write(lis, r_ths, threshold & ~LIS302DL_FFWUTHS_DCRM);
645 -       reg_write(lis, r_duration, duration);
646 +       (lis->pdata->lis302dl_bitbang_reg_write)(lis, r_ths,
647 +                                           threshold & ~LIS302DL_FFWUTHS_DCRM);
648 +       (lis->pdata->lis302dl_bitbang_reg_write)(lis, r_duration, duration);
649  
650         /* Route the interrupt for wakeup */
651 -       lis302dl_int_mode(lis->spi_dev, which, intmode);
652 +       __lis302dl_int_mode(lis->dev, which, intmode);
653  
654         /* Power up the device and note that we want to wake up from
655          * this interrupt */
656         if (!(lis->flags & LIS302DL_F_IRQ_WAKE))
657 -               enable_irq_wake(lis->spi_dev->irq);
658 +               enable_irq_wake(lis->pdata->interrupt);
659  
660         lis->flags |= flag_mask | LIS302DL_F_IRQ_WAKE;
661 -       reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, LIS302DL_CTRL1_PD,
662 +       __reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, LIS302DL_CTRL1_PD,
663                         LIS302DL_CTRL1_PD);
664         local_irq_restore(flags);
665  
666 @@ -403,6 +374,8 @@ static ssize_t show_freefall_common(int which, struct device *dev,
667         int r_duration = LIS302DL_REG_FF_WU_DURATION_1;
668         int r_cfg = LIS302DL_REG_FF_WU_CFG_1;
669         int r_src = LIS302DL_REG_FF_WU_SRC_1;
670 +       unsigned long flags;
671 +       int ms;
672  
673         /* Configure second freefall/wakeup pin */
674         if (which == 2) {
675 @@ -411,11 +384,15 @@ static ssize_t show_freefall_common(int which, struct device *dev,
676                 r_cfg = LIS302DL_REG_FF_WU_CFG_2;
677                 r_src = LIS302DL_REG_FF_WU_SRC_2;
678         }
679 -       config = reg_read(lis, r_cfg);
680 -       threshold = reg_read(lis, r_ths);
681 -       duration = reg_read(lis, r_duration);
682 -       r4 = reg_read(lis, r_src);
683 -       r5 = reg_read(lis, LIS302DL_REG_CTRL3);
684 +
685 +       local_irq_save(flags);
686 +       config = (lis->pdata->lis302dl_bitbang_reg_read)(lis, r_cfg);
687 +       threshold = (lis->pdata->lis302dl_bitbang_reg_read)(lis, r_ths);
688 +       duration = (lis->pdata->lis302dl_bitbang_reg_read)(lis, r_duration);
689 +       r4 = (lis->pdata->lis302dl_bitbang_reg_read)(lis, r_src);
690 +       r5 = (lis->pdata->lis302dl_bitbang_reg_read)(lis, LIS302DL_REG_CTRL3);
691 +       ms = __freefall_duration_to_ms(lis, duration);
692 +       local_irq_restore(flags);
693  
694         /* All events off? */
695         if ((config & (LIS302DL_FFWUCFG_XLIE | LIS302DL_FFWUCFG_XHIE |
696 @@ -423,13 +400,14 @@ static ssize_t show_freefall_common(int which, struct device *dev,
697                         LIS302DL_FFWUCFG_ZLIE | LIS302DL_FFWUCFG_ZHIE)) == 0)
698                 return sprintf(buf, "off\n");
699  
700 +
701         return sprintf(buf,
702                         "%s events, %s interrupt, duration %d, threshold %d, "
703                         "enabled: %s %s %s %s %s %s\n",
704                         (config & LIS302DL_FFWUCFG_AOI) == 0 ? "or" : "and",
705                         (config & LIS302DL_FFWUCFG_LIR) == 0 ?
706                                                         "don't latch" : "latch",
707 -                       freefall_duration_to_ms(lis, duration), threshold,
708 +                       ms, threshold,
709                         (config & LIS302DL_FFWUCFG_XLIE) == 0 ? "---" : "xlo",
710                         (config & LIS302DL_FFWUCFG_XHIE) == 0 ? "---" : "xhi",
711                         (config & LIS302DL_FFWUCFG_YLIE) == 0 ? "---" : "ylo",
712 @@ -480,14 +458,15 @@ static int lis302dl_input_open(struct input_dev *inp)
713  
714         local_irq_save(flags);
715         /* make sure we're powered up and generate data ready */
716 -       reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, ctrl1, ctrl1);
717 -       local_irq_restore(flags);
718 +       __reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, ctrl1, ctrl1);
719  
720         lis->flags |= LIS302DL_F_INPUT_OPEN;
721  
722         /* kick it off -- since we are edge triggered, if we missed the edge
723          * permanent low interrupt is death for us */
724 -       (lis->pdata->lis302dl_bitbang_read)(lis);
725 +       (lis->pdata->lis302dl_bitbang_read_sample)(lis);
726 +
727 +       local_irq_restore(flags);
728  
729         return 0;
730  }
731 @@ -504,13 +483,13 @@ static void lis302dl_input_close(struct input_dev *inp)
732         /* since the input core already serializes access and makes sure we
733          * only see close() for the close of the last user, we can safely
734          * disable the data ready events */
735 -       reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, ctrl1, 0x00);
736 +       __reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, ctrl1, 0x00);
737         lis->flags &= ~LIS302DL_F_INPUT_OPEN;
738  
739         /* however, don't power down the whole device if still needed */
740         if (!(lis->flags & LIS302DL_F_WUP_FF ||
741               lis->flags & LIS302DL_F_WUP_CLICK)) {
742 -               reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, LIS302DL_CTRL1_PD,
743 +               __reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, LIS302DL_CTRL1_PD,
744                                  0x00);
745         }
746         local_irq_restore(flags);
747 @@ -524,23 +503,23 @@ static int __lis302dl_reset_device(struct lis302dl_info *lis)
748  {
749         int timeout = 10;
750  
751 -       reg_write(lis, LIS302DL_REG_CTRL2, LIS302DL_CTRL2_BOOT |
752 -                                                           LIS302DL_CTRL2_FDS);
753 +       (lis->pdata->lis302dl_bitbang_reg_write)(lis, LIS302DL_REG_CTRL2,
754 +                                     LIS302DL_CTRL2_BOOT | LIS302DL_CTRL2_FDS);
755  
756 -       while ((reg_read(lis, LIS302DL_REG_CTRL2) & LIS302DL_CTRL2_BOOT) &&
757 -                                                                   (timeout--))
758 +       while (((lis->pdata->lis302dl_bitbang_reg_read)(lis, LIS302DL_REG_CTRL2)
759 +                                         & LIS302DL_CTRL2_BOOT) && (timeout--))
760                 mdelay(1);
761  
762         return !!(timeout < 0);
763  }
764  
765 -static int __devinit lis302dl_probe(struct spi_device *spi)
766 +static int __devinit lis302dl_probe(struct platform_device *pdev)
767  {
768         int rc;
769         struct lis302dl_info *lis;
770         u_int8_t wai;
771         unsigned long flags;
772 -       struct lis302dl_platform_data *pdata;
773 +       struct lis302dl_platform_data *pdata = pdev->dev.platform_data;
774  
775         lis = kzalloc(sizeof(*lis), GFP_KERNEL);
776         if (!lis)
777 @@ -548,38 +527,34 @@ static int __devinit lis302dl_probe(struct spi_device *spi)
778  
779         local_irq_save(flags);
780  
781 -       mutex_init(&lis->lock);
782 -       lis->spi_dev = spi;
783 +       lis->dev = &pdev->dev;
784  
785 -       spi_set_drvdata(spi, lis);
786 +       dev_set_drvdata(lis->dev, lis);
787  
788 -       pdata = spi->dev.platform_data;
789 +       lis->pdata = pdata;
790  
791 -       rc = spi_setup(spi);
792 -       if (rc < 0) {
793 -               dev_err(&spi->dev, "error during spi_setup\n");
794 -               dev_set_drvdata(&spi->dev, NULL);
795 -               goto bail_free_lis;
796 -       }
797 +       /* Configure our IO */
798 +       (lis->pdata->lis302dl_suspend_io)(lis, 1);
799  
800 -       wai = reg_read(lis, LIS302DL_REG_WHO_AM_I);
801 +       wai = (lis->pdata->lis302dl_bitbang_reg_read)(lis,
802 +                                                        LIS302DL_REG_WHO_AM_I);
803         if (wai != LIS302DL_WHO_AM_I_MAGIC) {
804 -               dev_err(&spi->dev, "unknown who_am_i signature 0x%02x\n", wai);
805 -               dev_set_drvdata(&spi->dev, NULL);
806 +               dev_err(lis->dev, "unknown who_am_i signature 0x%02x\n", wai);
807 +               dev_set_drvdata(lis->dev, NULL);
808                 rc = -ENODEV;
809                 goto bail_free_lis;
810         }
811  
812 -       rc = sysfs_create_group(&spi->dev.kobj, &lis302dl_attr_group);
813 +       rc = sysfs_create_group(&lis->dev->kobj, &lis302dl_attr_group);
814         if (rc) {
815 -               dev_err(&spi->dev, "error creating sysfs group\n");
816 +               dev_err(lis->dev, "error creating sysfs group\n");
817                 goto bail_free_lis;
818         }
819  
820         /* initialize input layer details */
821         lis->input_dev = input_allocate_device();
822         if (!lis->input_dev) {
823 -               dev_err(&spi->dev, "Unable to allocate input device\n");
824 +               dev_err(lis->dev, "Unable to allocate input device\n");
825                 goto bail_sysfs;
826         }
827  
828 @@ -601,57 +576,64 @@ static int __devinit lis302dl_probe(struct spi_device *spi)
829  
830         rc = input_register_device(lis->input_dev);
831         if (rc) {
832 -               dev_err(&spi->dev, "error %d registering input device\n", rc);
833 +               dev_err(lis->dev, "error %d registering input device\n", rc);
834                 goto bail_inp_dev;
835         }
836  
837         if (__lis302dl_reset_device(lis))
838 -               dev_err(&spi->dev, "device BOOT reload failed\n");
839 +               dev_err(lis->dev, "device BOOT reload failed\n");
840  
841         /* force us powered */
842 -       reg_write(lis, LIS302DL_REG_CTRL1, LIS302DL_CTRL1_PD |
843 -                                          LIS302DL_CTRL1_Xen |
844 -                                          LIS302DL_CTRL1_Yen |
845 -                                          LIS302DL_CTRL1_Zen);
846 +       (lis->pdata->lis302dl_bitbang_reg_write)(lis, LIS302DL_REG_CTRL1,
847 +                                                     LIS302DL_CTRL1_PD |
848 +                                                     LIS302DL_CTRL1_Xen |
849 +                                                     LIS302DL_CTRL1_Yen |
850 +                                                     LIS302DL_CTRL1_Zen);
851         mdelay(1);
852  
853 -       reg_write(lis, LIS302DL_REG_CTRL2, 0);
854 -       reg_write(lis, LIS302DL_REG_CTRL3, LIS302DL_CTRL3_PP_OD |
855 -                                                           LIS302DL_CTRL3_IHL);
856 -       reg_write(lis, LIS302DL_REG_FF_WU_THS_1, 0x0);
857 -       reg_write(lis, LIS302DL_REG_FF_WU_DURATION_1, 0x00);
858 -       reg_write(lis, LIS302DL_REG_FF_WU_CFG_1, 0x0);
859 +       (lis->pdata->lis302dl_bitbang_reg_write)(lis, LIS302DL_REG_CTRL2, 0);
860 +       (lis->pdata->lis302dl_bitbang_reg_write)(lis, LIS302DL_REG_CTRL3,
861 +                                    LIS302DL_CTRL3_PP_OD | LIS302DL_CTRL3_IHL);
862 +       (lis->pdata->lis302dl_bitbang_reg_write)(lis,
863 +                                                LIS302DL_REG_FF_WU_THS_1, 0x0);
864 +       (lis->pdata->lis302dl_bitbang_reg_write)(lis,
865 +                                          LIS302DL_REG_FF_WU_DURATION_1, 0x00);
866 +       (lis->pdata->lis302dl_bitbang_reg_write)(lis,
867 +                                                LIS302DL_REG_FF_WU_CFG_1, 0x0);
868  
869         /* start off in powered down mode; we power up when someone opens us */
870 -       reg_write(lis, LIS302DL_REG_CTRL1, LIS302DL_CTRL1_Xen |
871 -                                          LIS302DL_CTRL1_Yen |
872 -                                          LIS302DL_CTRL1_Zen);
873 +       (lis->pdata->lis302dl_bitbang_reg_write)(lis, LIS302DL_REG_CTRL1,
874 +                                                       LIS302DL_CTRL1_Xen |
875 +                                                       LIS302DL_CTRL1_Yen |
876 +                                                       LIS302DL_CTRL1_Zen);
877  
878         if (pdata->open_drain)
879                 /* switch interrupt to open collector, active-low */
880 -               reg_write(lis, LIS302DL_REG_CTRL3, LIS302DL_CTRL3_PP_OD |
881 -                                                  LIS302DL_CTRL3_IHL);
882 +               (lis->pdata->lis302dl_bitbang_reg_write)(lis,
883 +                       LIS302DL_REG_CTRL3, LIS302DL_CTRL3_PP_OD |
884 +                                           LIS302DL_CTRL3_IHL);
885         else
886                 /* push-pull, active-low */
887 -               reg_write(lis, LIS302DL_REG_CTRL3, LIS302DL_CTRL3_IHL);
888 +               (lis->pdata->lis302dl_bitbang_reg_write)(lis,
889 +                                       LIS302DL_REG_CTRL3, LIS302DL_CTRL3_IHL);
890  
891 -       lis302dl_int_mode(spi, 1, LIS302DL_INTMODE_DATA_READY);
892 -       lis302dl_int_mode(spi, 2, LIS302DL_INTMODE_DATA_READY);
893 +       __lis302dl_int_mode(lis->dev, 1, LIS302DL_INTMODE_DATA_READY);
894 +       __lis302dl_int_mode(lis->dev, 2, LIS302DL_INTMODE_DATA_READY);
895  
896 -       reg_read(lis, LIS302DL_REG_STATUS);
897 -       reg_read(lis, LIS302DL_REG_FF_WU_SRC_1);
898 -       reg_read(lis, LIS302DL_REG_FF_WU_SRC_2);
899 -       reg_read(lis, LIS302DL_REG_CLICK_SRC);
900 +       (lis->pdata->lis302dl_bitbang_reg_read)(lis, LIS302DL_REG_STATUS);
901 +       (lis->pdata->lis302dl_bitbang_reg_read)(lis, LIS302DL_REG_FF_WU_SRC_1);
902 +       (lis->pdata->lis302dl_bitbang_reg_read)(lis, LIS302DL_REG_FF_WU_SRC_2);
903 +       (lis->pdata->lis302dl_bitbang_reg_read)(lis, LIS302DL_REG_CLICK_SRC);
904  
905 -       dev_info(&spi->dev, "Found %s\n", pdata->name);
906 +       dev_info(lis->dev, "Found %s\n", pdata->name);
907  
908         lis->pdata = pdata;
909  
910 -       rc = request_irq(lis->spi_dev->irq, lis302dl_interrupt,
911 +       rc = request_irq(pdata->interrupt, lis302dl_interrupt,
912                          IRQF_TRIGGER_FALLING, "lis302dl", lis);
913         if (rc < 0) {
914 -               dev_err(&spi->dev, "error requesting IRQ %d\n",
915 -                       lis->spi_dev->irq);
916 +               dev_err(lis->dev, "error requesting IRQ %d\n",
917 +                       lis->pdata->interrupt);
918                 goto bail_inp_reg;
919         }
920         local_irq_restore(flags);
921 @@ -662,50 +644,71 @@ bail_inp_reg:
922  bail_inp_dev:
923         input_free_device(lis->input_dev);
924  bail_sysfs:
925 -       sysfs_remove_group(&spi->dev.kobj, &lis302dl_attr_group);
926 +       sysfs_remove_group(&lis->dev->kobj, &lis302dl_attr_group);
927  bail_free_lis:
928         kfree(lis);
929         local_irq_restore(flags);
930         return rc;
931  }
932  
933 -static int __devexit lis302dl_remove(struct spi_device *spi)
934 +static int __devexit lis302dl_remove(struct platform_device *pdev)
935  {
936 -       struct lis302dl_info *lis = dev_get_drvdata(&spi->dev);
937 +       struct lis302dl_info *lis = dev_get_drvdata(&pdev->dev);
938         unsigned long flags;
939  
940         /* Reset and power down the device */
941         local_irq_save(flags);
942 -       reg_write(lis, LIS302DL_REG_CTRL3, 0x00);
943 -       reg_write(lis, LIS302DL_REG_CTRL2, 0x00);
944 -       reg_write(lis, LIS302DL_REG_CTRL1, 0x00);
945 +       (lis->pdata->lis302dl_bitbang_reg_write)(lis, LIS302DL_REG_CTRL3, 0x00);
946 +       (lis->pdata->lis302dl_bitbang_reg_write)(lis, LIS302DL_REG_CTRL2, 0x00);
947 +       (lis->pdata->lis302dl_bitbang_reg_write)(lis, LIS302DL_REG_CTRL1, 0x00);
948         local_irq_restore(flags);
949  
950         /* Cleanup resources */
951 -       free_irq(lis->spi_dev->irq, lis);
952 -       sysfs_remove_group(&spi->dev.kobj, &lis302dl_attr_group);
953 +       free_irq(lis->pdata->interrupt, lis);
954 +       sysfs_remove_group(&pdev->dev.kobj, &lis302dl_attr_group);
955         input_unregister_device(lis->input_dev);
956         if (lis->input_dev)
957                 input_free_device(lis->input_dev);
958 -       dev_set_drvdata(&spi->dev, NULL);
959 +       dev_set_drvdata(lis->dev, NULL);
960         kfree(lis);
961  
962         return 0;
963  }
964  
965  #ifdef CONFIG_PM
966 -static int lis302dl_suspend(struct spi_device *spi, pm_message_t state)
967 +
968 +static u8 regs_to_save[] = {
969 +       LIS302DL_REG_CTRL1,
970 +       LIS302DL_REG_CTRL2,
971 +       LIS302DL_REG_CTRL3,
972 +       LIS302DL_REG_FF_WU_CFG_1,
973 +       LIS302DL_REG_FF_WU_THS_1,
974 +       LIS302DL_REG_FF_WU_DURATION_1,
975 +       LIS302DL_REG_FF_WU_CFG_2,
976 +       LIS302DL_REG_FF_WU_THS_2,
977 +       LIS302DL_REG_FF_WU_DURATION_2,
978 +       LIS302DL_REG_CLICK_CFG,
979 +       LIS302DL_REG_CLICK_THSY_X,
980 +       LIS302DL_REG_CLICK_THSZ,
981 +       LIS302DL_REG_CLICK_TIME_LIMIT,
982 +       LIS302DL_REG_CLICK_LATENCY,
983 +       LIS302DL_REG_CLICK_WINDOW,
984 +
985 +};
986 +
987 +static int lis302dl_suspend(struct platform_device *pdev, pm_message_t state)
988  {
989 -       struct lis302dl_info *lis = dev_get_drvdata(&spi->dev);
990 +       struct lis302dl_info *lis = dev_get_drvdata(&pdev->dev);
991         unsigned long flags;
992         u_int8_t tmp;
993 +       int n;
994  
995         /* determine if we want to wake up from the accel. */
996         if (lis->flags & LIS302DL_F_WUP_FF ||
997                 lis->flags & LIS302DL_F_WUP_CLICK)
998                 return 0;
999  
1000 -       disable_irq(lis->spi_dev->irq);
1001 +       disable_irq(lis->pdata->interrupt);
1002         local_irq_save(flags);
1003  
1004         /*
1005 @@ -718,38 +721,15 @@ static int lis302dl_suspend(struct spi_device *spi, pm_message_t state)
1006         (lis->pdata->lis302dl_suspend_io)(lis, 1);
1007  
1008         /* save registers */
1009 -       lis->regs[LIS302DL_REG_CTRL1] = reg_read(lis, LIS302DL_REG_CTRL1);
1010 -       lis->regs[LIS302DL_REG_CTRL2] = reg_read(lis, LIS302DL_REG_CTRL2);
1011 -       lis->regs[LIS302DL_REG_CTRL3] = reg_read(lis, LIS302DL_REG_CTRL3);
1012 -       lis->regs[LIS302DL_REG_FF_WU_CFG_1] =
1013 -                               reg_read(lis, LIS302DL_REG_FF_WU_CFG_1);
1014 -       lis->regs[LIS302DL_REG_FF_WU_THS_1] =
1015 -                               reg_read(lis, LIS302DL_REG_FF_WU_THS_1);
1016 -       lis->regs[LIS302DL_REG_FF_WU_DURATION_1] =
1017 -                               reg_read(lis, LIS302DL_REG_FF_WU_DURATION_1);
1018 -       lis->regs[LIS302DL_REG_FF_WU_CFG_2] =
1019 -                               reg_read(lis, LIS302DL_REG_FF_WU_CFG_2);
1020 -       lis->regs[LIS302DL_REG_FF_WU_THS_2] =
1021 -                               reg_read(lis, LIS302DL_REG_FF_WU_THS_2);
1022 -       lis->regs[LIS302DL_REG_FF_WU_DURATION_2] =
1023 -                               reg_read(lis, LIS302DL_REG_FF_WU_DURATION_2);
1024 -       lis->regs[LIS302DL_REG_CLICK_CFG] =
1025 -                               reg_read(lis, LIS302DL_REG_CLICK_CFG);
1026 -       lis->regs[LIS302DL_REG_CLICK_THSY_X] =
1027 -                               reg_read(lis, LIS302DL_REG_CLICK_THSY_X);
1028 -       lis->regs[LIS302DL_REG_CLICK_THSZ] =
1029 -                               reg_read(lis, LIS302DL_REG_CLICK_THSZ);
1030 -       lis->regs[LIS302DL_REG_CLICK_TIME_LIMIT] =
1031 -                               reg_read(lis, LIS302DL_REG_CLICK_TIME_LIMIT);
1032 -       lis->regs[LIS302DL_REG_CLICK_LATENCY] =
1033 -                               reg_read(lis, LIS302DL_REG_CLICK_LATENCY);
1034 -       lis->regs[LIS302DL_REG_CLICK_WINDOW] =
1035 -                               reg_read(lis, LIS302DL_REG_CLICK_WINDOW);
1036 +       for (n = 0; n < ARRAY_SIZE(regs_to_save); n++)
1037 +               lis->regs[regs_to_save[n]] =
1038 +                       (lis->pdata->lis302dl_bitbang_reg_read)(lis,
1039 +                                                              regs_to_save[n]);
1040  
1041         /* power down */
1042 -       tmp = reg_read(lis, LIS302DL_REG_CTRL1);
1043 +       tmp = (lis->pdata->lis302dl_bitbang_reg_read)(lis, LIS302DL_REG_CTRL1);
1044         tmp &= ~LIS302DL_CTRL1_PD;
1045 -       reg_write(lis, LIS302DL_REG_CTRL1, tmp);
1046 +       (lis->pdata->lis302dl_bitbang_reg_write)(lis, LIS302DL_REG_CTRL1, tmp);
1047  
1048         /* place our IO to the device in sleep-compatible states */
1049         (lis->pdata->lis302dl_suspend_io)(lis, 0);
1050 @@ -759,10 +739,11 @@ static int lis302dl_suspend(struct spi_device *spi, pm_message_t state)
1051         return 0;
1052  }
1053  
1054 -static int lis302dl_resume(struct spi_device *spi)
1055 +static int lis302dl_resume(struct platform_device *pdev)
1056  {
1057 -       struct lis302dl_info *lis = dev_get_drvdata(&spi->dev);
1058 +       struct lis302dl_info *lis = dev_get_drvdata(&pdev->dev);
1059         unsigned long flags;
1060 +       int n;
1061  
1062         if (lis->flags & LIS302DL_F_WUP_FF ||
1063                 lis->flags & LIS302DL_F_WUP_CLICK)
1064 @@ -774,50 +755,28 @@ static int lis302dl_resume(struct spi_device *spi)
1065         (lis->pdata->lis302dl_suspend_io)(lis, 1);
1066  
1067         /* resume from powerdown first! */
1068 -       reg_write(lis, LIS302DL_REG_CTRL1, LIS302DL_CTRL1_PD |
1069 -                                          LIS302DL_CTRL1_Xen |
1070 -                                          LIS302DL_CTRL1_Yen |
1071 -                                          LIS302DL_CTRL1_Zen);
1072 +       (lis->pdata->lis302dl_bitbang_reg_write)(lis, LIS302DL_REG_CTRL1,
1073 +                                                     LIS302DL_CTRL1_PD |
1074 +                                                     LIS302DL_CTRL1_Xen |
1075 +                                                     LIS302DL_CTRL1_Yen |
1076 +                                                     LIS302DL_CTRL1_Zen);
1077         mdelay(1);
1078  
1079         if (__lis302dl_reset_device(lis))
1080 -               dev_err(&spi->dev, "device BOOT reload failed\n");
1081 +               dev_err(&pdev->dev, "device BOOT reload failed\n");
1082  
1083 -       /* restore registers after resume */
1084 -       reg_write(lis, LIS302DL_REG_CTRL1, lis->regs[LIS302DL_REG_CTRL1] |
1085 -                                               LIS302DL_CTRL1_PD |
1086 +       lis->regs[LIS302DL_REG_CTRL1] |=        LIS302DL_CTRL1_PD |
1087                                                 LIS302DL_CTRL1_Xen |
1088                                                 LIS302DL_CTRL1_Yen |
1089 -                                               LIS302DL_CTRL1_Zen);
1090 -       reg_write(lis, LIS302DL_REG_CTRL2, lis->regs[LIS302DL_REG_CTRL2]);
1091 -       reg_write(lis, LIS302DL_REG_CTRL3, lis->regs[LIS302DL_REG_CTRL3]);
1092 -       reg_write(lis, LIS302DL_REG_FF_WU_CFG_1,
1093 -                 lis->regs[LIS302DL_REG_FF_WU_CFG_1]);
1094 -       reg_write(lis, LIS302DL_REG_FF_WU_THS_1,
1095 -                 lis->regs[LIS302DL_REG_FF_WU_THS_1]);
1096 -       reg_write(lis, LIS302DL_REG_FF_WU_DURATION_1,
1097 -                 lis->regs[LIS302DL_REG_FF_WU_DURATION_1]);
1098 -       reg_write(lis, LIS302DL_REG_FF_WU_CFG_2,
1099 -                 lis->regs[LIS302DL_REG_FF_WU_CFG_2]);
1100 -       reg_write(lis, LIS302DL_REG_FF_WU_THS_2,
1101 -                 lis->regs[LIS302DL_REG_FF_WU_THS_2]);
1102 -       reg_write(lis, LIS302DL_REG_FF_WU_DURATION_2,
1103 -                 lis->regs[LIS302DL_REG_FF_WU_DURATION_2]);
1104 -       reg_write(lis, LIS302DL_REG_CLICK_CFG,
1105 -                 lis->regs[LIS302DL_REG_CLICK_CFG]);
1106 -       reg_write(lis, LIS302DL_REG_CLICK_THSY_X,
1107 -                 lis->regs[LIS302DL_REG_CLICK_THSY_X]);
1108 -       reg_write(lis, LIS302DL_REG_CLICK_THSZ,
1109 -                 lis->regs[LIS302DL_REG_CLICK_THSZ]);
1110 -       reg_write(lis, LIS302DL_REG_CLICK_TIME_LIMIT,
1111 -                 lis->regs[LIS302DL_REG_CLICK_TIME_LIMIT]);
1112 -       reg_write(lis, LIS302DL_REG_CLICK_LATENCY,
1113 -                 lis->regs[LIS302DL_REG_CLICK_LATENCY]);
1114 -       reg_write(lis, LIS302DL_REG_CLICK_WINDOW,
1115 -                 lis->regs[LIS302DL_REG_CLICK_WINDOW]);
1116 +                                               LIS302DL_CTRL1_Zen;
1117 +
1118 +       /* restore registers after resume */
1119 +       for (n = 0; n < ARRAY_SIZE(regs_to_save); n++)
1120 +               (lis->pdata->lis302dl_bitbang_reg_write)(lis,
1121 +                                  regs_to_save[n], lis->regs[regs_to_save[n]]);
1122  
1123         local_irq_restore(flags);
1124 -       enable_irq(lis->spi_dev->irq);
1125 +       enable_irq(lis->pdata->interrupt);
1126  
1127         return 0;
1128  }
1129 @@ -826,7 +785,7 @@ static int lis302dl_resume(struct spi_device *spi)
1130  #define lis302dl_resume                NULL
1131  #endif
1132  
1133 -static struct spi_driver lis302dl_driver = {
1134 +static struct platform_driver lis302dl_driver = {
1135         .driver = {
1136                 .name   = "lis302dl",
1137                 .owner  = THIS_MODULE,
1138 @@ -838,14 +797,14 @@ static struct spi_driver lis302dl_driver = {
1139         .resume  = lis302dl_resume,
1140  };
1141  
1142 -static int __init lis302dl_init(void)
1143 +static int __devinit lis302dl_init(void)
1144  {
1145 -       return spi_register_driver(&lis302dl_driver);
1146 +       return platform_driver_register(&lis302dl_driver);
1147  }
1148  
1149  static void __exit lis302dl_exit(void)
1150  {
1151 -       spi_unregister_driver(&lis302dl_driver);
1152 +       platform_driver_unregister(&lis302dl_driver);
1153  }
1154  
1155  MODULE_AUTHOR("Harald Welte <laforge@openmoko.org>");
1156 diff --git a/include/linux/lis302dl.h b/include/linux/lis302dl.h
1157 index 7daa8b3..4578db4 100644
1158 --- a/include/linux/lis302dl.h
1159 +++ b/include/linux/lis302dl.h
1160 @@ -15,15 +15,18 @@ struct lis302dl_platform_data {
1161         unsigned long pin_mosi;
1162         unsigned long pin_miso;
1163         int open_drain;
1164 -       void (*lis302dl_bitbang_read)(struct lis302dl_info *);
1165 +       int interrupt;
1166 +       void (*lis302dl_bitbang_read_sample)(struct lis302dl_info *);
1167         void (*lis302dl_suspend_io)(struct lis302dl_info *, int resuming);
1168 +       int (*lis302dl_bitbang_reg_read)(struct lis302dl_info *, u8 reg);
1169 +       void (*lis302dl_bitbang_reg_write)(struct lis302dl_info *, u8 reg,
1170 +                                                                       u8 val);
1171  };
1172  
1173  struct lis302dl_info {
1174         struct lis302dl_platform_data *pdata;
1175 -       struct spi_device *spi_dev;
1176 +       struct device *dev;
1177         struct input_dev *input_dev;
1178 -       struct mutex lock;
1179         unsigned int flags;
1180         u_int8_t regs[0x40];
1181  };
1182 -- 
1183 1.5.6.5
1184