diff options
Diffstat (limited to 'target/linux/s3c24xx/patches-2.6.24/1303-fix-lid302dl-bitbang-all-the-way-baby.patch.patch')
-rw-r--r-- | target/linux/s3c24xx/patches-2.6.24/1303-fix-lid302dl-bitbang-all-the-way-baby.patch.patch | 1184 |
1 files changed, 0 insertions, 1184 deletions
diff --git a/target/linux/s3c24xx/patches-2.6.24/1303-fix-lid302dl-bitbang-all-the-way-baby.patch.patch b/target/linux/s3c24xx/patches-2.6.24/1303-fix-lid302dl-bitbang-all-the-way-baby.patch.patch deleted file mode 100644 index 852faaeb42..0000000000 --- a/target/linux/s3c24xx/patches-2.6.24/1303-fix-lid302dl-bitbang-all-the-way-baby.patch.patch +++ /dev/null @@ -1,1184 +0,0 @@ -From 1c6f5a92c816db43128444606c26507ebe6e5a43 Mon Sep 17 00:00:00 2001 -From: Andy Green <andy@openmoko.com> -Date: Mon, 13 Oct 2008 12:01:05 +0100 -Subject: [PATCH] fix-lid302dl-bitbang-all-the-way-baby.patch - -This large patch removes motion sensor from Linux SPI bitbang driver. -Previously, some access was done through Linux SPI protected -by a mutex, and the ISR access was done by platform bitbang code due -to inability of Linux SPI driver to work in the interrupt context. - -Now all access is done by bitbang callbacks in mach_gta02.c and are -protected by single scheme of interrupt lockout for the duration -- -I line-by-line'd the driver to confirm that best I could, adding -protection and taking more care on several /sys related paths. - -Because this is no longer a Linux SPI bus driver, the path for various -/sys things have changed. They can now be found down, eg, - -/sys/devices/platform/lis302dl.1/sample_rate - -lis302dl.1 is the top sensor and .2 the bottom. The names of the input -susbsytem paths remain the same as before. - -Signed-off-by: Andy Green <andy@openmoko.com> ---- - arch/arm/mach-s3c2440/mach-gta02.c | 233 +++++++++---------- - drivers/input/misc/lis302dl.c | 437 ++++++++++++++++-------------------- - include/linux/lis302dl.h | 9 +- - 3 files changed, 315 insertions(+), 364 deletions(-) - -diff --git a/arch/arm/mach-s3c2440/mach-gta02.c b/arch/arm/mach-s3c2440/mach-gta02.c -index 467c417..b19632c 100644 ---- a/arch/arm/mach-s3c2440/mach-gta02.c -+++ b/arch/arm/mach-s3c2440/mach-gta02.c -@@ -1052,20 +1052,21 @@ static struct platform_device gta02_vibrator_dev = { - /* #define DEBUG_SPEW_MS */ - #define MG_PER_SAMPLE 18 - --struct lis302dl_platform_data lis302_pdata[]; -+struct lis302dl_platform_data lis302_pdata_top; -+struct lis302dl_platform_data lis302_pdata_bottom; - --void gta02_lis302dl_bitbang_read(struct lis302dl_info *lis) -+/* -+ * generic SPI RX and TX bitbang -+ * only call with interrupts off! -+ */ -+ -+static void __gta02_lis302dl_bitbang(struct lis302dl_info *lis, u8 *tx, -+ int tx_bytes, u8 *rx, int rx_bytes) - { - struct lis302dl_platform_data *pdata = lis->pdata; -- u8 shifter = 0xc0 | LIS302DL_REG_OUT_X; /* read, autoincrement */ -- int n, n1; -+ int n; -+ u8 shifter = 0; - unsigned long other_cs; -- unsigned long flags; --#ifdef DEBUG_SPEW_MS -- s8 x, y, z; --#endif -- -- local_irq_save(flags); - - /* - * Huh.. "quirk"... CS on this device is not really "CS" like you can -@@ -1073,20 +1074,25 @@ void gta02_lis302dl_bitbang_read(struct lis302dl_info *lis) - * 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; -+ if (&lis302_pdata_top == pdata) -+ other_cs = lis302_pdata_bottom.pin_chip_select; - else -- other_cs = lis302_pdata[0].pin_chip_select; -+ other_cs = lis302_pdata_top.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 */ -+ -+ /* send the register index, r/w and autoinc bits */ -+ for (n = 0; n < (tx_bytes << 3); n++) { -+ if (!(n & 7)) -+ shifter = tx[n >> 3]; - s3c2410_gpio_setpin(pdata->pin_clk, 0); - s3c2410_gpio_setpin(pdata->pin_mosi, (shifter >> 7) & 1); - s3c2410_gpio_setpin(pdata->pin_clk, 0); -@@ -1095,44 +1101,71 @@ void gta02_lis302dl_bitbang_read(struct lis302dl_info *lis) - 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, 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: --#ifdef DEBUG_SPEW_MS -- x = shifter; --#endif -- input_report_rel(lis->input_dev, REL_X, MG_PER_SAMPLE * (s8)shifter); -- break; -- case 2: --#ifdef DEBUG_SPEW_MS -- y = shifter; --#endif -- input_report_rel(lis->input_dev, REL_Y, MG_PER_SAMPLE * (s8)shifter); -- break; -- case 4: --#ifdef DEBUG_SPEW_MS -- z = shifter; --#endif -- input_report_rel(lis->input_dev, REL_Z, MG_PER_SAMPLE * (s8)shifter); -- break; -- } -+ for (n = 0; n < (rx_bytes << 3); n++) { /* 8 bits each */ -+ s3c2410_gpio_setpin(pdata->pin_clk, 0); -+ s3c2410_gpio_setpin(pdata->pin_clk, 0); -+ shifter <<= 1; -+ if (s3c2410_gpio_getpin(pdata->pin_miso)) -+ shifter |= 1; -+ if ((n & 7) == 7) -+ rx[n >> 3] = shifter; -+ s3c2410_gpio_setpin(pdata->pin_clk, 1); -+ s3c2410_gpio_setpin(pdata->pin_clk, 1); - } - s3c2410_gpio_setpin(pdata->pin_chip_select, 1); - s3c2410_gpio_setpin(other_cs, 1); -+} -+ -+ -+static int gta02_lis302dl_bitbang_read_reg(struct lis302dl_info *lis, u8 reg) -+{ -+ u8 data = 0xc0 | reg; /* read, autoincrement */ -+ unsigned long flags; -+ -+ local_irq_save(flags); -+ -+ __gta02_lis302dl_bitbang(lis, &data, 1, &data, 1); -+ -+ local_irq_restore(flags); -+ -+ return data; -+} -+ -+static void gta02_lis302dl_bitbang_write_reg(struct lis302dl_info *lis, u8 reg, -+ u8 val) -+{ -+ u8 data[2] = { 0x00 | reg, val }; /* write, no autoincrement */ -+ unsigned long flags; -+ -+ local_irq_save(flags); -+ -+ __gta02_lis302dl_bitbang(lis, &data[0], 2, NULL, 0); -+ - local_irq_restore(flags); - -+} -+ -+ -+static void gta02_lis302dl_bitbang_sample(struct lis302dl_info *lis) -+{ -+ u8 data = 0xc0 | LIS302DL_REG_OUT_X; /* read, autoincrement */ -+ u8 read[5]; -+ unsigned long flags; -+ -+ local_irq_save(flags); -+ -+ __gta02_lis302dl_bitbang(lis, &data, 1, &read[0], 5); -+ -+ local_irq_restore(flags); -+ -+ input_report_rel(lis->input_dev, REL_X, MG_PER_SAMPLE * (s8)read[0]); -+ input_report_rel(lis->input_dev, REL_Y, MG_PER_SAMPLE * (s8)read[2]); -+ input_report_rel(lis->input_dev, REL_Z, MG_PER_SAMPLE * (s8)read[4]); -+ - input_sync(lis->input_dev); - #ifdef DEBUG_SPEW_MS -- printk("%s: %d %d %d\n", pdata->name, x, y, z); -+ printk(KERN_INFO "%s: %d %d %d\n", pdata->name, read[0], read[2], -+ read[4]); - #endif - } - -@@ -1159,103 +1192,58 @@ void gta02_lis302dl_suspend_io(struct lis302dl_info *lis, int resume) - s3c2410_gpio_setpin(pdata->pin_clk, 1); - /* misnomer: it is a pullDOWN in 2442 */ - s3c2410_gpio_pullup(pdata->pin_miso, 0); -+ -+ s3c2410_gpio_cfgpin(pdata->pin_chip_select, S3C2410_GPIO_OUTPUT); -+ s3c2410_gpio_cfgpin(pdata->pin_clk, S3C2410_GPIO_OUTPUT); -+ s3c2410_gpio_cfgpin(pdata->pin_mosi, S3C2410_GPIO_OUTPUT); -+ s3c2410_gpio_cfgpin(pdata->pin_miso, S3C2410_GPIO_INPUT); -+ - } - --struct lis302dl_platform_data lis302_pdata[] = { -- { -+ -+ -+struct lis302dl_platform_data lis302_pdata_top = { - .name = "lis302-1 (top)", - .pin_chip_select= S3C2410_GPD12, - .pin_clk = S3C2410_GPG7, - .pin_mosi = S3C2410_GPG6, - .pin_miso = S3C2410_GPG5, -+ .interrupt = GTA02_IRQ_GSENSOR_1, - .open_drain = 1, /* altered at runtime by PCB rev */ -- .lis302dl_bitbang_read = gta02_lis302dl_bitbang_read, -+ .lis302dl_bitbang_read_sample = gta02_lis302dl_bitbang_sample, -+ .lis302dl_bitbang_reg_read = gta02_lis302dl_bitbang_read_reg, -+ .lis302dl_bitbang_reg_write = gta02_lis302dl_bitbang_write_reg, - .lis302dl_suspend_io = gta02_lis302dl_suspend_io, -- }, { -+}; -+ -+struct lis302dl_platform_data lis302_pdata_bottom = { - .name = "lis302-2 (bottom)", - .pin_chip_select= S3C2410_GPD13, - .pin_clk = S3C2410_GPG7, - .pin_mosi = S3C2410_GPG6, - .pin_miso = S3C2410_GPG5, -+ .interrupt = GTA02_IRQ_GSENSOR_2, - .open_drain = 1, /* altered at runtime by PCB rev */ -- .lis302dl_bitbang_read = gta02_lis302dl_bitbang_read, -+ .lis302dl_bitbang_read_sample = gta02_lis302dl_bitbang_sample, -+ .lis302dl_bitbang_reg_read = gta02_lis302dl_bitbang_read_reg, -+ .lis302dl_bitbang_reg_write = gta02_lis302dl_bitbang_write_reg, - .lis302dl_suspend_io = gta02_lis302dl_suspend_io, -- }, - }; - --static struct spi_board_info gta02_spi_acc_bdinfo[] = { -- { -- .modalias = "lis302dl", -- .platform_data = &lis302_pdata[0], -- .irq = GTA02_IRQ_GSENSOR_1, -- .max_speed_hz = 10 * 1000 * 1000, -- .bus_num = 1, -- .chip_select = 0, -- .mode = SPI_MODE_3, -- }, -- { -- .modalias = "lis302dl", -- .platform_data = &lis302_pdata[1], -- .irq = GTA02_IRQ_GSENSOR_2, -- .max_speed_hz = 10 * 1000 * 1000, -- .bus_num = 1, -- .chip_select = 1, -- .mode = SPI_MODE_3, -- }, --}; -- --static void spi_acc_cs(struct s3c2410_spigpio_info *spigpio_info, -- int csid, int cs) --{ -- struct lis302dl_platform_data * plat_data = -- (struct lis302dl_platform_data *)spigpio_info-> -- board_info->platform_data; -- switch (cs) { -- case BITBANG_CS_ACTIVE: -- s3c2410_gpio_setpin(plat_data[csid].pin_chip_select, 0); -- break; -- case BITBANG_CS_INACTIVE: -- s3c2410_gpio_setpin(plat_data[csid].pin_chip_select, 1); -- break; -- } --} - --static struct s3c2410_spigpio_info spi_gpio_cfg = { -- .pin_clk = S3C2410_GPG7, -- .pin_mosi = S3C2410_GPG6, -- .pin_miso = S3C2410_GPG5, -- .board_size = ARRAY_SIZE(gta02_spi_acc_bdinfo), -- .board_info = gta02_spi_acc_bdinfo, -- .chip_select = &spi_acc_cs, -- .num_chipselect = 2, --}; -- --static struct resource s3c_spi_acc_resource[] = { -- [0] = { -- .start = S3C2410_GPG3, -- .end = S3C2410_GPG3, -- }, -- [1] = { -- .start = S3C2410_GPG5, -- .end = S3C2410_GPG5, -- }, -- [2] = { -- .start = S3C2410_GPG6, -- .end = S3C2410_GPG6, -- }, -- [3] = { -- .start = S3C2410_GPG7, -- .end = S3C2410_GPG7, -+static struct platform_device s3c_device_spi_acc1 = { -+ .name = "lis302dl", -+ .id = 1, -+ .dev = { -+ .platform_data = &lis302_pdata_top, - }, - }; - --static struct platform_device s3c_device_spi_acc = { -- .name = "spi_s3c24xx_gpio", -- .id = 1, -- .num_resources = ARRAY_SIZE(s3c_spi_acc_resource), -- .resource = s3c_spi_acc_resource, -+static struct platform_device s3c_device_spi_acc2 = { -+ .name = "lis302dl", -+ .id = 2, - .dev = { -- .platform_data = &spi_gpio_cfg, -+ .platform_data = &lis302_pdata_bottom, - }, - }; - -@@ -1573,8 +1561,8 @@ static void __init gta02_machine_init(void) - switch (system_rev) { - case GTA02v6_SYSTEM_REV: - /* we need push-pull interrupt from motion sensors */ -- lis302_pdata[0].open_drain = 0; -- lis302_pdata[1].open_drain = 0; -+ lis302_pdata_top.open_drain = 0; -+ lis302_pdata_bottom.open_drain = 0; - break; - default: - break; -@@ -1635,7 +1623,8 @@ static void __init gta02_machine_init(void) - mangle_glamo_res_by_system_rev(); - platform_device_register(>a02_glamo_dev); - -- platform_device_register(&s3c_device_spi_acc); -+ platform_device_register(&s3c_device_spi_acc1); -+ platform_device_register(&s3c_device_spi_acc2); - platform_device_register(>a02_button_dev); - platform_device_register(>a02_pm_gsm_dev); - platform_device_register(>a02_pm_usbhost_dev); -diff --git a/drivers/input/misc/lis302dl.c b/drivers/input/misc/lis302dl.c -index b01ca04..1d5781d 100644 ---- a/drivers/input/misc/lis302dl.c -+++ b/drivers/input/misc/lis302dl.c -@@ -1,7 +1,9 @@ - /* Linux kernel driver for the ST LIS302D 3-axis accelerometer - * -- * Copyright (C) 2007 by Openmoko, Inc. -+ * Copyright (C) 2007-2008 by Openmoko, Inc. - * Author: Harald Welte <laforge@openmoko.org> -+ * converted to private bitbang by: -+ * Andy Green <andy@openmoko.com> - * All rights reserved. - * - * This program is free software; you can redistribute it and/or -@@ -39,78 +41,19 @@ - - #include <linux/lis302dl.h> - --/* lowlevel register access functions */ - --#define READ_BIT 0x80 --#define READ_BIT_INC_ADS 0xc0 --#define ADDR_MASK 0x3f - --static u_int8_t __reg_read(struct lis302dl_info *lis, u_int8_t reg) -+static void __reg_set_bit_mask(struct lis302dl_info *lis, u8 reg, u8 mask, -+ u8 val) - { -- int rc; -- u_int8_t cmd; -- -- BUG_ON(reg & ~ADDR_MASK); -- -- cmd = reg | READ_BIT; -- -- rc = spi_w8r8(lis->spi_dev, cmd); -- -- return rc; --} -- --static u_int8_t reg_read(struct lis302dl_info *lis, u_int8_t reg) --{ -- u_int8_t ret; -- -- mutex_lock(&lis->lock); -- ret = __reg_read(lis, reg); -- mutex_unlock(&lis->lock); -- -- return ret; --} -- --static int __reg_write(struct lis302dl_info *lis, u_int8_t reg, u_int8_t val) --{ -- u_int8_t buf[2]; -- -- BUG_ON(reg & ~ADDR_MASK); -- -- buf[0] = reg; -- buf[1] = val; -- -- return spi_write(lis->spi_dev, buf, sizeof(buf)); --} -- --static int reg_write(struct lis302dl_info *lis, u_int8_t reg, u_int8_t val) --{ -- int ret; -- -- mutex_lock(&lis->lock); -- ret = __reg_write(lis, reg, val); -- mutex_unlock(&lis->lock); -- -- return ret; --} -- --static int reg_set_bit_mask(struct lis302dl_info *lis, -- u_int8_t reg, u_int8_t mask, u_int8_t val) --{ -- int ret; - u_int8_t tmp; - - val &= mask; - -- mutex_lock(&lis->lock); -- -- tmp = __reg_read(lis, reg); -+ tmp = (lis->pdata->lis302dl_bitbang_reg_read)(lis, reg); - tmp &= ~mask; - tmp |= val; -- ret = __reg_write(lis, reg, tmp); -- -- mutex_unlock(&lis->lock); -- -- return ret; -+ (lis->pdata->lis302dl_bitbang_reg_write)(lis, reg, tmp); - } - - /* interrupt handling related */ -@@ -124,17 +67,17 @@ enum lis302dl_intmode { - LIS302DL_INTMODE_CLICK = 0x07, - }; - --static void lis302dl_int_mode(struct spi_device *spi, int int_pin, -+static void __lis302dl_int_mode(struct device *dev, int int_pin, - enum lis302dl_intmode mode) - { -- struct lis302dl_info *lis = dev_get_drvdata(&spi->dev); -+ struct lis302dl_info *lis = dev_get_drvdata(dev); - - switch (int_pin) { - case 1: -- reg_set_bit_mask(lis, LIS302DL_REG_CTRL3, 0x07, mode); -+ __reg_set_bit_mask(lis, LIS302DL_REG_CTRL3, 0x07, mode); - break; - case 2: -- reg_set_bit_mask(lis, LIS302DL_REG_CTRL3, 0x38, mode << 3); -+ __reg_set_bit_mask(lis, LIS302DL_REG_CTRL3, 0x38, mode << 3); - break; - default: - BUG(); -@@ -165,7 +108,7 @@ static irqreturn_t lis302dl_interrupt(int irq, void *_lis) - { - struct lis302dl_info *lis = _lis; - -- (lis->pdata->lis302dl_bitbang_read)(lis); -+ (lis->pdata->lis302dl_bitbang_read_sample)(lis); - return IRQ_HANDLED; - } - -@@ -175,7 +118,13 @@ static ssize_t show_rate(struct device *dev, struct device_attribute *attr, - char *buf) - { - struct lis302dl_info *lis = dev_get_drvdata(dev); -- u_int8_t ctrl1 = reg_read(lis, LIS302DL_REG_CTRL1); -+ u8 ctrl1; -+ unsigned long flags; -+ -+ local_irq_save(flags); -+ ctrl1 = (lis->pdata->lis302dl_bitbang_reg_read) -+ (lis, LIS302DL_REG_CTRL1); -+ local_irq_restore(flags); - - return sprintf(buf, "%d\n", ctrl1 & LIS302DL_CTRL1_DR ? 400 : 100); - } -@@ -184,12 +133,17 @@ static ssize_t set_rate(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) - { - struct lis302dl_info *lis = dev_get_drvdata(dev); -+ unsigned long flags; -+ -+ local_irq_save(flags); - - if (!strcmp(buf, "400\n")) -- reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, LIS302DL_CTRL1_DR, -+ __reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, LIS302DL_CTRL1_DR, - LIS302DL_CTRL1_DR); - else -- reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, LIS302DL_CTRL1_DR, 0); -+ __reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, LIS302DL_CTRL1_DR, -+ 0); -+ local_irq_restore(flags); - - return count; - } -@@ -200,7 +154,13 @@ static ssize_t show_scale(struct device *dev, struct device_attribute *attr, - char *buf) - { - struct lis302dl_info *lis = dev_get_drvdata(dev); -- u_int8_t ctrl1 = reg_read(lis, LIS302DL_REG_CTRL1); -+ u_int8_t ctrl1; -+ unsigned long flags; -+ -+ local_irq_save(flags); -+ ctrl1 = (lis->pdata->lis302dl_bitbang_reg_read)(lis, -+ LIS302DL_REG_CTRL1); -+ local_irq_restore(flags); - - return sprintf(buf, "%s\n", ctrl1 & LIS302DL_CTRL1_FS ? "9.2" : "2.3"); - } -@@ -209,12 +169,18 @@ static ssize_t set_scale(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) - { - struct lis302dl_info *lis = dev_get_drvdata(dev); -+ unsigned long flags; -+ -+ local_irq_save(flags); - - if (!strcmp(buf, "9.2\n")) -- reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, LIS302DL_CTRL1_FS, -+ __reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, LIS302DL_CTRL1_FS, - LIS302DL_CTRL1_FS); - else -- reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, LIS302DL_CTRL1_FS, 0); -+ __reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, LIS302DL_CTRL1_FS, -+ 0); -+ -+ local_irq_restore(flags); - - return count; - } -@@ -222,7 +188,7 @@ static ssize_t set_scale(struct device *dev, struct device_attribute *attr, - static DEVICE_ATTR(full_scale, S_IRUGO | S_IWUSR, show_scale, set_scale); - - static ssize_t lis302dl_dump(struct device *dev, struct device_attribute *attr, -- char *buf) -+ char *buf) - { - struct lis302dl_info *lis = dev_get_drvdata(dev); - int n = 0; -@@ -233,7 +199,7 @@ static ssize_t lis302dl_dump(struct device *dev, struct device_attribute *attr, - local_irq_save(flags); - - for (n = 0; n < sizeof(reg); n++) -- reg[n] = reg_read(lis, n); -+ reg[n] = (lis->pdata->lis302dl_bitbang_reg_read)(lis, n); - - local_irq_restore(flags); - -@@ -248,9 +214,9 @@ static ssize_t lis302dl_dump(struct device *dev, struct device_attribute *attr, - } - static DEVICE_ATTR(dump, S_IRUGO, lis302dl_dump, NULL); - --static int freefall_ms_to_duration(struct lis302dl_info *lis, int ms) -+static int __freefall_ms_to_duration(struct lis302dl_info *lis, int ms) - { -- u_int8_t r = reg_read(lis, LIS302DL_REG_CTRL1); -+ u8 r = (lis->pdata->lis302dl_bitbang_reg_read)(lis, LIS302DL_REG_CTRL1); - - /* If we have 400 ms sampling rate, the stepping is 2.5 ms, - * on 100 ms the stepping is 10ms */ -@@ -268,9 +234,9 @@ static int freefall_ms_to_duration(struct lis302dl_info *lis, int ms) - return ms / 10; - } - --static int freefall_duration_to_ms(struct lis302dl_info *lis, int duration) -+static int __freefall_duration_to_ms(struct lis302dl_info *lis, int duration) - { -- u_int8_t r = reg_read(lis, LIS302DL_REG_CTRL1); -+ u8 r = (lis->pdata->lis302dl_bitbang_reg_read)(lis, LIS302DL_REG_CTRL1); - - if (r & LIS302DL_CTRL1_DR) - return (duration * 25) / 10; -@@ -314,18 +280,18 @@ static ssize_t set_freefall_common(int which, struct device *dev, - /* Turn off the interrupt */ - local_irq_save(flags); - if (lis->flags & LIS302DL_F_IRQ_WAKE) -- disable_irq_wake(lis->spi_dev->irq); -- lis302dl_int_mode(lis->spi_dev, which, -+ disable_irq_wake(lis->pdata->interrupt); -+ __lis302dl_int_mode(lis->dev, which, - LIS302DL_INTMODE_DATA_READY); - lis->flags &= ~(flag_mask | LIS302DL_F_IRQ_WAKE); - -- reg_write(lis, r_cfg, 0); -- reg_write(lis, r_ths, 0); -- reg_write(lis, r_duration, 0); -+ (lis->pdata->lis302dl_bitbang_reg_write)(lis, r_cfg, 0); -+ (lis->pdata->lis302dl_bitbang_reg_write)(lis, r_ths, 0); -+ (lis->pdata->lis302dl_bitbang_reg_write)(lis, r_duration, 0); - - /* Power off unless the input subsystem is using the device */ - if (!(lis->flags & LIS302DL_F_INPUT_OPEN)) -- reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, -+ __reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, - LIS302DL_CTRL1_PD, 0); - - local_irq_restore(flags); -@@ -337,7 +303,10 @@ static ssize_t set_freefall_common(int which, struct device *dev, - &and_events) != 6) - return -EINVAL; - -- duration = freefall_ms_to_duration(lis, ms); -+ local_irq_save(flags); -+ duration = __freefall_ms_to_duration(lis, ms); -+ local_irq_save(flags); -+ - if (duration < 0) - return -ERANGE; - -@@ -355,23 +324,25 @@ static ssize_t set_freefall_common(int which, struct device *dev, - - /* Setup the configuration registers */ - local_irq_save(flags); -- reg_write(lis, r_cfg, 0); /* First zero to get to a known state */ -- reg_write(lis, r_cfg, -+ /* First zero to get to a known state */ -+ (lis->pdata->lis302dl_bitbang_reg_write)(lis, r_cfg, 0); -+ (lis->pdata->lis302dl_bitbang_reg_write)(lis, r_cfg, - (and_events ? LIS302DL_FFWUCFG_AOI : 0) | - x_lo | x_hi | y_lo | y_hi | z_lo | z_hi); -- reg_write(lis, r_ths, threshold & ~LIS302DL_FFWUTHS_DCRM); -- reg_write(lis, r_duration, duration); -+ (lis->pdata->lis302dl_bitbang_reg_write)(lis, r_ths, -+ threshold & ~LIS302DL_FFWUTHS_DCRM); -+ (lis->pdata->lis302dl_bitbang_reg_write)(lis, r_duration, duration); - - /* Route the interrupt for wakeup */ -- lis302dl_int_mode(lis->spi_dev, which, intmode); -+ __lis302dl_int_mode(lis->dev, which, intmode); - - /* Power up the device and note that we want to wake up from - * this interrupt */ - if (!(lis->flags & LIS302DL_F_IRQ_WAKE)) -- enable_irq_wake(lis->spi_dev->irq); -+ enable_irq_wake(lis->pdata->interrupt); - - lis->flags |= flag_mask | LIS302DL_F_IRQ_WAKE; -- reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, LIS302DL_CTRL1_PD, -+ __reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, LIS302DL_CTRL1_PD, - LIS302DL_CTRL1_PD); - local_irq_restore(flags); - -@@ -403,6 +374,8 @@ static ssize_t show_freefall_common(int which, struct device *dev, - int r_duration = LIS302DL_REG_FF_WU_DURATION_1; - int r_cfg = LIS302DL_REG_FF_WU_CFG_1; - int r_src = LIS302DL_REG_FF_WU_SRC_1; -+ unsigned long flags; -+ int ms; - - /* Configure second freefall/wakeup pin */ - if (which == 2) { -@@ -411,11 +384,15 @@ static ssize_t show_freefall_common(int which, struct device *dev, - r_cfg = LIS302DL_REG_FF_WU_CFG_2; - r_src = LIS302DL_REG_FF_WU_SRC_2; - } -- config = reg_read(lis, r_cfg); -- threshold = reg_read(lis, r_ths); -- duration = reg_read(lis, r_duration); -- r4 = reg_read(lis, r_src); -- r5 = reg_read(lis, LIS302DL_REG_CTRL3); -+ -+ local_irq_save(flags); -+ config = (lis->pdata->lis302dl_bitbang_reg_read)(lis, r_cfg); -+ threshold = (lis->pdata->lis302dl_bitbang_reg_read)(lis, r_ths); -+ duration = (lis->pdata->lis302dl_bitbang_reg_read)(lis, r_duration); -+ r4 = (lis->pdata->lis302dl_bitbang_reg_read)(lis, r_src); -+ r5 = (lis->pdata->lis302dl_bitbang_reg_read)(lis, LIS302DL_REG_CTRL3); -+ ms = __freefall_duration_to_ms(lis, duration); -+ local_irq_restore(flags); - - /* All events off? */ - if ((config & (LIS302DL_FFWUCFG_XLIE | LIS302DL_FFWUCFG_XHIE | -@@ -423,13 +400,14 @@ static ssize_t show_freefall_common(int which, struct device *dev, - LIS302DL_FFWUCFG_ZLIE | LIS302DL_FFWUCFG_ZHIE)) == 0) - return sprintf(buf, "off\n"); - -+ - return sprintf(buf, - "%s events, %s interrupt, duration %d, threshold %d, " - "enabled: %s %s %s %s %s %s\n", - (config & LIS302DL_FFWUCFG_AOI) == 0 ? "or" : "and", - (config & LIS302DL_FFWUCFG_LIR) == 0 ? - "don't latch" : "latch", -- freefall_duration_to_ms(lis, duration), threshold, -+ ms, threshold, - (config & LIS302DL_FFWUCFG_XLIE) == 0 ? "---" : "xlo", - (config & LIS302DL_FFWUCFG_XHIE) == 0 ? "---" : "xhi", - (config & LIS302DL_FFWUCFG_YLIE) == 0 ? "---" : "ylo", -@@ -480,14 +458,15 @@ static int lis302dl_input_open(struct input_dev *inp) - - local_irq_save(flags); - /* make sure we're powered up and generate data ready */ -- reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, ctrl1, ctrl1); -- local_irq_restore(flags); -+ __reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, ctrl1, ctrl1); - - lis->flags |= LIS302DL_F_INPUT_OPEN; - - /* kick it off -- since we are edge triggered, if we missed the edge - * permanent low interrupt is death for us */ -- (lis->pdata->lis302dl_bitbang_read)(lis); -+ (lis->pdata->lis302dl_bitbang_read_sample)(lis); -+ -+ local_irq_restore(flags); - - return 0; - } -@@ -504,13 +483,13 @@ static void lis302dl_input_close(struct input_dev *inp) - /* since the input core already serializes access and makes sure we - * only see close() for the close of the last user, we can safely - * disable the data ready events */ -- reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, ctrl1, 0x00); -+ __reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, ctrl1, 0x00); - lis->flags &= ~LIS302DL_F_INPUT_OPEN; - - /* however, don't power down the whole device if still needed */ - if (!(lis->flags & LIS302DL_F_WUP_FF || - lis->flags & LIS302DL_F_WUP_CLICK)) { -- reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, LIS302DL_CTRL1_PD, -+ __reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, LIS302DL_CTRL1_PD, - 0x00); - } - local_irq_restore(flags); -@@ -524,23 +503,23 @@ static int __lis302dl_reset_device(struct lis302dl_info *lis) - { - int timeout = 10; - -- reg_write(lis, LIS302DL_REG_CTRL2, LIS302DL_CTRL2_BOOT | -- LIS302DL_CTRL2_FDS); -+ (lis->pdata->lis302dl_bitbang_reg_write)(lis, LIS302DL_REG_CTRL2, -+ LIS302DL_CTRL2_BOOT | LIS302DL_CTRL2_FDS); - -- while ((reg_read(lis, LIS302DL_REG_CTRL2) & LIS302DL_CTRL2_BOOT) && -- (timeout--)) -+ while (((lis->pdata->lis302dl_bitbang_reg_read)(lis, LIS302DL_REG_CTRL2) -+ & LIS302DL_CTRL2_BOOT) && (timeout--)) - mdelay(1); - - return !!(timeout < 0); - } - --static int __devinit lis302dl_probe(struct spi_device *spi) -+static int __devinit lis302dl_probe(struct platform_device *pdev) - { - int rc; - struct lis302dl_info *lis; - u_int8_t wai; - unsigned long flags; -- struct lis302dl_platform_data *pdata; -+ struct lis302dl_platform_data *pdata = pdev->dev.platform_data; - - lis = kzalloc(sizeof(*lis), GFP_KERNEL); - if (!lis) -@@ -548,38 +527,34 @@ static int __devinit lis302dl_probe(struct spi_device *spi) - - local_irq_save(flags); - -- mutex_init(&lis->lock); -- lis->spi_dev = spi; -+ lis->dev = &pdev->dev; - -- spi_set_drvdata(spi, lis); -+ dev_set_drvdata(lis->dev, lis); - -- pdata = spi->dev.platform_data; -+ lis->pdata = pdata; - -- rc = spi_setup(spi); -- if (rc < 0) { -- dev_err(&spi->dev, "error during spi_setup\n"); -- dev_set_drvdata(&spi->dev, NULL); -- goto bail_free_lis; -- } -+ /* Configure our IO */ -+ (lis->pdata->lis302dl_suspend_io)(lis, 1); - -- wai = reg_read(lis, LIS302DL_REG_WHO_AM_I); -+ wai = (lis->pdata->lis302dl_bitbang_reg_read)(lis, -+ LIS302DL_REG_WHO_AM_I); - if (wai != LIS302DL_WHO_AM_I_MAGIC) { -- dev_err(&spi->dev, "unknown who_am_i signature 0x%02x\n", wai); -- dev_set_drvdata(&spi->dev, NULL); -+ dev_err(lis->dev, "unknown who_am_i signature 0x%02x\n", wai); -+ dev_set_drvdata(lis->dev, NULL); - rc = -ENODEV; - goto bail_free_lis; - } - -- rc = sysfs_create_group(&spi->dev.kobj, &lis302dl_attr_group); -+ rc = sysfs_create_group(&lis->dev->kobj, &lis302dl_attr_group); - if (rc) { -- dev_err(&spi->dev, "error creating sysfs group\n"); -+ dev_err(lis->dev, "error creating sysfs group\n"); - goto bail_free_lis; - } - - /* initialize input layer details */ - lis->input_dev = input_allocate_device(); - if (!lis->input_dev) { -- dev_err(&spi->dev, "Unable to allocate input device\n"); -+ dev_err(lis->dev, "Unable to allocate input device\n"); - goto bail_sysfs; - } - -@@ -601,57 +576,64 @@ static int __devinit lis302dl_probe(struct spi_device *spi) - - rc = input_register_device(lis->input_dev); - if (rc) { -- dev_err(&spi->dev, "error %d registering input device\n", rc); -+ dev_err(lis->dev, "error %d registering input device\n", rc); - goto bail_inp_dev; - } - - if (__lis302dl_reset_device(lis)) -- dev_err(&spi->dev, "device BOOT reload failed\n"); -+ dev_err(lis->dev, "device BOOT reload failed\n"); - - /* force us powered */ -- reg_write(lis, LIS302DL_REG_CTRL1, LIS302DL_CTRL1_PD | -- LIS302DL_CTRL1_Xen | -- LIS302DL_CTRL1_Yen | -- LIS302DL_CTRL1_Zen); -+ (lis->pdata->lis302dl_bitbang_reg_write)(lis, LIS302DL_REG_CTRL1, -+ LIS302DL_CTRL1_PD | -+ LIS302DL_CTRL1_Xen | -+ LIS302DL_CTRL1_Yen | -+ LIS302DL_CTRL1_Zen); - mdelay(1); - -- reg_write(lis, LIS302DL_REG_CTRL2, 0); -- reg_write(lis, LIS302DL_REG_CTRL3, LIS302DL_CTRL3_PP_OD | -- LIS302DL_CTRL3_IHL); -- reg_write(lis, LIS302DL_REG_FF_WU_THS_1, 0x0); -- reg_write(lis, LIS302DL_REG_FF_WU_DURATION_1, 0x00); -- reg_write(lis, LIS302DL_REG_FF_WU_CFG_1, 0x0); -+ (lis->pdata->lis302dl_bitbang_reg_write)(lis, LIS302DL_REG_CTRL2, 0); -+ (lis->pdata->lis302dl_bitbang_reg_write)(lis, LIS302DL_REG_CTRL3, -+ LIS302DL_CTRL3_PP_OD | LIS302DL_CTRL3_IHL); -+ (lis->pdata->lis302dl_bitbang_reg_write)(lis, -+ LIS302DL_REG_FF_WU_THS_1, 0x0); -+ (lis->pdata->lis302dl_bitbang_reg_write)(lis, -+ LIS302DL_REG_FF_WU_DURATION_1, 0x00); -+ (lis->pdata->lis302dl_bitbang_reg_write)(lis, -+ LIS302DL_REG_FF_WU_CFG_1, 0x0); - - /* start off in powered down mode; we power up when someone opens us */ -- reg_write(lis, LIS302DL_REG_CTRL1, LIS302DL_CTRL1_Xen | -- LIS302DL_CTRL1_Yen | -- LIS302DL_CTRL1_Zen); -+ (lis->pdata->lis302dl_bitbang_reg_write)(lis, LIS302DL_REG_CTRL1, -+ LIS302DL_CTRL1_Xen | -+ LIS302DL_CTRL1_Yen | -+ LIS302DL_CTRL1_Zen); - - if (pdata->open_drain) - /* switch interrupt to open collector, active-low */ -- reg_write(lis, LIS302DL_REG_CTRL3, LIS302DL_CTRL3_PP_OD | -- LIS302DL_CTRL3_IHL); -+ (lis->pdata->lis302dl_bitbang_reg_write)(lis, -+ LIS302DL_REG_CTRL3, LIS302DL_CTRL3_PP_OD | -+ LIS302DL_CTRL3_IHL); - else - /* push-pull, active-low */ -- reg_write(lis, LIS302DL_REG_CTRL3, LIS302DL_CTRL3_IHL); -+ (lis->pdata->lis302dl_bitbang_reg_write)(lis, -+ LIS302DL_REG_CTRL3, LIS302DL_CTRL3_IHL); - -- lis302dl_int_mode(spi, 1, LIS302DL_INTMODE_DATA_READY); -- lis302dl_int_mode(spi, 2, LIS302DL_INTMODE_DATA_READY); -+ __lis302dl_int_mode(lis->dev, 1, LIS302DL_INTMODE_DATA_READY); -+ __lis302dl_int_mode(lis->dev, 2, LIS302DL_INTMODE_DATA_READY); - -- reg_read(lis, LIS302DL_REG_STATUS); -- reg_read(lis, LIS302DL_REG_FF_WU_SRC_1); -- reg_read(lis, LIS302DL_REG_FF_WU_SRC_2); -- reg_read(lis, LIS302DL_REG_CLICK_SRC); -+ (lis->pdata->lis302dl_bitbang_reg_read)(lis, LIS302DL_REG_STATUS); -+ (lis->pdata->lis302dl_bitbang_reg_read)(lis, LIS302DL_REG_FF_WU_SRC_1); -+ (lis->pdata->lis302dl_bitbang_reg_read)(lis, LIS302DL_REG_FF_WU_SRC_2); -+ (lis->pdata->lis302dl_bitbang_reg_read)(lis, LIS302DL_REG_CLICK_SRC); - -- dev_info(&spi->dev, "Found %s\n", pdata->name); -+ dev_info(lis->dev, "Found %s\n", pdata->name); - - lis->pdata = pdata; - -- rc = request_irq(lis->spi_dev->irq, lis302dl_interrupt, -+ rc = request_irq(pdata->interrupt, lis302dl_interrupt, - IRQF_TRIGGER_FALLING, "lis302dl", lis); - if (rc < 0) { -- dev_err(&spi->dev, "error requesting IRQ %d\n", -- lis->spi_dev->irq); -+ dev_err(lis->dev, "error requesting IRQ %d\n", -+ lis->pdata->interrupt); - goto bail_inp_reg; - } - local_irq_restore(flags); -@@ -662,50 +644,71 @@ bail_inp_reg: - bail_inp_dev: - input_free_device(lis->input_dev); - bail_sysfs: -- sysfs_remove_group(&spi->dev.kobj, &lis302dl_attr_group); -+ sysfs_remove_group(&lis->dev->kobj, &lis302dl_attr_group); - bail_free_lis: - kfree(lis); - local_irq_restore(flags); - return rc; - } - --static int __devexit lis302dl_remove(struct spi_device *spi) -+static int __devexit lis302dl_remove(struct platform_device *pdev) - { -- struct lis302dl_info *lis = dev_get_drvdata(&spi->dev); -+ struct lis302dl_info *lis = dev_get_drvdata(&pdev->dev); - unsigned long flags; - - /* Reset and power down the device */ - local_irq_save(flags); -- reg_write(lis, LIS302DL_REG_CTRL3, 0x00); -- reg_write(lis, LIS302DL_REG_CTRL2, 0x00); -- reg_write(lis, LIS302DL_REG_CTRL1, 0x00); -+ (lis->pdata->lis302dl_bitbang_reg_write)(lis, LIS302DL_REG_CTRL3, 0x00); -+ (lis->pdata->lis302dl_bitbang_reg_write)(lis, LIS302DL_REG_CTRL2, 0x00); -+ (lis->pdata->lis302dl_bitbang_reg_write)(lis, LIS302DL_REG_CTRL1, 0x00); - local_irq_restore(flags); - - /* Cleanup resources */ -- free_irq(lis->spi_dev->irq, lis); -- sysfs_remove_group(&spi->dev.kobj, &lis302dl_attr_group); -+ free_irq(lis->pdata->interrupt, lis); -+ sysfs_remove_group(&pdev->dev.kobj, &lis302dl_attr_group); - input_unregister_device(lis->input_dev); - if (lis->input_dev) - input_free_device(lis->input_dev); -- dev_set_drvdata(&spi->dev, NULL); -+ dev_set_drvdata(lis->dev, NULL); - kfree(lis); - - return 0; - } - - #ifdef CONFIG_PM --static int lis302dl_suspend(struct spi_device *spi, pm_message_t state) -+ -+static u8 regs_to_save[] = { -+ LIS302DL_REG_CTRL1, -+ LIS302DL_REG_CTRL2, -+ LIS302DL_REG_CTRL3, -+ LIS302DL_REG_FF_WU_CFG_1, -+ LIS302DL_REG_FF_WU_THS_1, -+ LIS302DL_REG_FF_WU_DURATION_1, -+ LIS302DL_REG_FF_WU_CFG_2, -+ LIS302DL_REG_FF_WU_THS_2, -+ LIS302DL_REG_FF_WU_DURATION_2, -+ LIS302DL_REG_CLICK_CFG, -+ LIS302DL_REG_CLICK_THSY_X, -+ LIS302DL_REG_CLICK_THSZ, -+ LIS302DL_REG_CLICK_TIME_LIMIT, -+ LIS302DL_REG_CLICK_LATENCY, -+ LIS302DL_REG_CLICK_WINDOW, -+ -+}; -+ -+static int lis302dl_suspend(struct platform_device *pdev, pm_message_t state) - { -- struct lis302dl_info *lis = dev_get_drvdata(&spi->dev); -+ struct lis302dl_info *lis = dev_get_drvdata(&pdev->dev); - unsigned long flags; - u_int8_t tmp; -+ int n; - - /* determine if we want to wake up from the accel. */ - if (lis->flags & LIS302DL_F_WUP_FF || - lis->flags & LIS302DL_F_WUP_CLICK) - return 0; - -- disable_irq(lis->spi_dev->irq); -+ disable_irq(lis->pdata->interrupt); - local_irq_save(flags); - - /* -@@ -718,38 +721,15 @@ static int lis302dl_suspend(struct spi_device *spi, pm_message_t state) - (lis->pdata->lis302dl_suspend_io)(lis, 1); - - /* save registers */ -- lis->regs[LIS302DL_REG_CTRL1] = reg_read(lis, LIS302DL_REG_CTRL1); -- lis->regs[LIS302DL_REG_CTRL2] = reg_read(lis, LIS302DL_REG_CTRL2); -- lis->regs[LIS302DL_REG_CTRL3] = reg_read(lis, LIS302DL_REG_CTRL3); -- lis->regs[LIS302DL_REG_FF_WU_CFG_1] = -- reg_read(lis, LIS302DL_REG_FF_WU_CFG_1); -- lis->regs[LIS302DL_REG_FF_WU_THS_1] = -- reg_read(lis, LIS302DL_REG_FF_WU_THS_1); -- lis->regs[LIS302DL_REG_FF_WU_DURATION_1] = -- reg_read(lis, LIS302DL_REG_FF_WU_DURATION_1); -- lis->regs[LIS302DL_REG_FF_WU_CFG_2] = -- reg_read(lis, LIS302DL_REG_FF_WU_CFG_2); -- lis->regs[LIS302DL_REG_FF_WU_THS_2] = -- reg_read(lis, LIS302DL_REG_FF_WU_THS_2); -- lis->regs[LIS302DL_REG_FF_WU_DURATION_2] = -- reg_read(lis, LIS302DL_REG_FF_WU_DURATION_2); -- lis->regs[LIS302DL_REG_CLICK_CFG] = -- reg_read(lis, LIS302DL_REG_CLICK_CFG); -- lis->regs[LIS302DL_REG_CLICK_THSY_X] = -- reg_read(lis, LIS302DL_REG_CLICK_THSY_X); -- lis->regs[LIS302DL_REG_CLICK_THSZ] = -- reg_read(lis, LIS302DL_REG_CLICK_THSZ); -- lis->regs[LIS302DL_REG_CLICK_TIME_LIMIT] = -- reg_read(lis, LIS302DL_REG_CLICK_TIME_LIMIT); -- lis->regs[LIS302DL_REG_CLICK_LATENCY] = -- reg_read(lis, LIS302DL_REG_CLICK_LATENCY); -- lis->regs[LIS302DL_REG_CLICK_WINDOW] = -- reg_read(lis, LIS302DL_REG_CLICK_WINDOW); -+ for (n = 0; n < ARRAY_SIZE(regs_to_save); n++) -+ lis->regs[regs_to_save[n]] = -+ (lis->pdata->lis302dl_bitbang_reg_read)(lis, -+ regs_to_save[n]); - - /* power down */ -- tmp = reg_read(lis, LIS302DL_REG_CTRL1); -+ tmp = (lis->pdata->lis302dl_bitbang_reg_read)(lis, LIS302DL_REG_CTRL1); - tmp &= ~LIS302DL_CTRL1_PD; -- reg_write(lis, LIS302DL_REG_CTRL1, tmp); -+ (lis->pdata->lis302dl_bitbang_reg_write)(lis, LIS302DL_REG_CTRL1, tmp); - - /* place our IO to the device in sleep-compatible states */ - (lis->pdata->lis302dl_suspend_io)(lis, 0); -@@ -759,10 +739,11 @@ static int lis302dl_suspend(struct spi_device *spi, pm_message_t state) - return 0; - } - --static int lis302dl_resume(struct spi_device *spi) -+static int lis302dl_resume(struct platform_device *pdev) - { -- struct lis302dl_info *lis = dev_get_drvdata(&spi->dev); -+ struct lis302dl_info *lis = dev_get_drvdata(&pdev->dev); - unsigned long flags; -+ int n; - - if (lis->flags & LIS302DL_F_WUP_FF || - lis->flags & LIS302DL_F_WUP_CLICK) -@@ -774,50 +755,28 @@ static int lis302dl_resume(struct spi_device *spi) - (lis->pdata->lis302dl_suspend_io)(lis, 1); - - /* resume from powerdown first! */ -- reg_write(lis, LIS302DL_REG_CTRL1, LIS302DL_CTRL1_PD | -- LIS302DL_CTRL1_Xen | -- LIS302DL_CTRL1_Yen | -- LIS302DL_CTRL1_Zen); -+ (lis->pdata->lis302dl_bitbang_reg_write)(lis, LIS302DL_REG_CTRL1, -+ LIS302DL_CTRL1_PD | -+ LIS302DL_CTRL1_Xen | -+ LIS302DL_CTRL1_Yen | -+ LIS302DL_CTRL1_Zen); - mdelay(1); - - if (__lis302dl_reset_device(lis)) -- dev_err(&spi->dev, "device BOOT reload failed\n"); -+ dev_err(&pdev->dev, "device BOOT reload failed\n"); - -- /* restore registers after resume */ -- reg_write(lis, LIS302DL_REG_CTRL1, lis->regs[LIS302DL_REG_CTRL1] | -- LIS302DL_CTRL1_PD | -+ lis->regs[LIS302DL_REG_CTRL1] |= LIS302DL_CTRL1_PD | - LIS302DL_CTRL1_Xen | - LIS302DL_CTRL1_Yen | -- LIS302DL_CTRL1_Zen); -- reg_write(lis, LIS302DL_REG_CTRL2, lis->regs[LIS302DL_REG_CTRL2]); -- reg_write(lis, LIS302DL_REG_CTRL3, lis->regs[LIS302DL_REG_CTRL3]); -- reg_write(lis, LIS302DL_REG_FF_WU_CFG_1, -- lis->regs[LIS302DL_REG_FF_WU_CFG_1]); -- reg_write(lis, LIS302DL_REG_FF_WU_THS_1, -- lis->regs[LIS302DL_REG_FF_WU_THS_1]); -- reg_write(lis, LIS302DL_REG_FF_WU_DURATION_1, -- lis->regs[LIS302DL_REG_FF_WU_DURATION_1]); -- reg_write(lis, LIS302DL_REG_FF_WU_CFG_2, -- lis->regs[LIS302DL_REG_FF_WU_CFG_2]); -- reg_write(lis, LIS302DL_REG_FF_WU_THS_2, -- lis->regs[LIS302DL_REG_FF_WU_THS_2]); -- reg_write(lis, LIS302DL_REG_FF_WU_DURATION_2, -- lis->regs[LIS302DL_REG_FF_WU_DURATION_2]); -- reg_write(lis, LIS302DL_REG_CLICK_CFG, -- lis->regs[LIS302DL_REG_CLICK_CFG]); -- reg_write(lis, LIS302DL_REG_CLICK_THSY_X, -- lis->regs[LIS302DL_REG_CLICK_THSY_X]); -- reg_write(lis, LIS302DL_REG_CLICK_THSZ, -- lis->regs[LIS302DL_REG_CLICK_THSZ]); -- reg_write(lis, LIS302DL_REG_CLICK_TIME_LIMIT, -- lis->regs[LIS302DL_REG_CLICK_TIME_LIMIT]); -- reg_write(lis, LIS302DL_REG_CLICK_LATENCY, -- lis->regs[LIS302DL_REG_CLICK_LATENCY]); -- reg_write(lis, LIS302DL_REG_CLICK_WINDOW, -- lis->regs[LIS302DL_REG_CLICK_WINDOW]); -+ LIS302DL_CTRL1_Zen; -+ -+ /* restore registers after resume */ -+ for (n = 0; n < ARRAY_SIZE(regs_to_save); n++) -+ (lis->pdata->lis302dl_bitbang_reg_write)(lis, -+ regs_to_save[n], lis->regs[regs_to_save[n]]); - - local_irq_restore(flags); -- enable_irq(lis->spi_dev->irq); -+ enable_irq(lis->pdata->interrupt); - - return 0; - } -@@ -826,7 +785,7 @@ static int lis302dl_resume(struct spi_device *spi) - #define lis302dl_resume NULL - #endif - --static struct spi_driver lis302dl_driver = { -+static struct platform_driver lis302dl_driver = { - .driver = { - .name = "lis302dl", - .owner = THIS_MODULE, -@@ -838,14 +797,14 @@ static struct spi_driver lis302dl_driver = { - .resume = lis302dl_resume, - }; - --static int __init lis302dl_init(void) -+static int __devinit lis302dl_init(void) - { -- return spi_register_driver(&lis302dl_driver); -+ return platform_driver_register(&lis302dl_driver); - } - - static void __exit lis302dl_exit(void) - { -- spi_unregister_driver(&lis302dl_driver); -+ platform_driver_unregister(&lis302dl_driver); - } - - MODULE_AUTHOR("Harald Welte <laforge@openmoko.org>"); -diff --git a/include/linux/lis302dl.h b/include/linux/lis302dl.h -index 7daa8b3..4578db4 100644 ---- a/include/linux/lis302dl.h -+++ b/include/linux/lis302dl.h -@@ -15,15 +15,18 @@ struct lis302dl_platform_data { - unsigned long pin_mosi; - unsigned long pin_miso; - int open_drain; -- void (*lis302dl_bitbang_read)(struct lis302dl_info *); -+ int interrupt; -+ void (*lis302dl_bitbang_read_sample)(struct lis302dl_info *); - void (*lis302dl_suspend_io)(struct lis302dl_info *, int resuming); -+ int (*lis302dl_bitbang_reg_read)(struct lis302dl_info *, u8 reg); -+ void (*lis302dl_bitbang_reg_write)(struct lis302dl_info *, u8 reg, -+ u8 val); - }; - - struct lis302dl_info { - struct lis302dl_platform_data *pdata; -- struct spi_device *spi_dev; -+ struct device *dev; - struct input_dev *input_dev; -- struct mutex lock; - unsigned int flags; - u_int8_t regs[0x40]; - }; --- -1.5.6.5 - |