diff options
author | Andy Green <andy@openmoko.com> | 2008-11-19 17:09:34 +0000 |
---|---|---|
committer | Andy Green <agreen@pads.home.warmcat.com> | 2008-11-19 17:09:34 +0000 |
commit | 6b5297122074ac393720b826fb534a2a4ad25772 (patch) | |
tree | 8a069dbf63d6001201db542d882eb3078cc713d9 | |
parent | cd399d1273d3e3a3a3827ec70eaf23eacae61d74 (diff) |
fix-lis302dl-suspend-gpio.patch
Add platform stuff to deal with going in and out of suspend
so the motion sensor IO is not driving high into unpowered sensors
Signed-off-by: Andy Green <andy@openmoko.com>
-rw-r--r-- | arch/arm/mach-s3c2440/mach-gta02.c | 28 | ||||
-rw-r--r-- | drivers/input/misc/lis302dl.c | 15 | ||||
-rw-r--r-- | include/linux/lis302dl.h | 1 |
3 files changed, 43 insertions, 1 deletions
diff --git a/arch/arm/mach-s3c2440/mach-gta02.c b/arch/arm/mach-s3c2440/mach-gta02.c index 5bd68a69f49..99206eee663 100644 --- a/arch/arm/mach-s3c2440/mach-gta02.c +++ b/arch/arm/mach-s3c2440/mach-gta02.c @@ -887,7 +887,31 @@ void gat02_lis302dl_bitbang_read(struct lis302dl_info *lis) } -struct lis302dl_platform_data lis302_pdata[] = { +void gat02_lis302dl_suspend_io(struct lis302dl_info *lis, int resume) +{ + struct lis302dl_platform_data *pdata = lis->pdata; + + if (!resume) { + /* + * we don't want to power them with a high level + * because GSENSOR_3V3 is not up during suspend + */ + s3c2410_gpio_setpin(pdata->pin_chip_select, 0); + s3c2410_gpio_setpin(pdata->pin_clk, 0); + s3c2410_gpio_setpin(pdata->pin_mosi, 0); + /* misnomer: it is a pullDOWN in 2442 */ + s3c2410_gpio_pullup(pdata->pin_miso, 1); + return; + } + + /* back to normal */ + s3c2410_gpio_setpin(pdata->pin_chip_select, 1); + s3c2410_gpio_setpin(pdata->pin_clk, 1); + /* misnomer: it is a pullDOWN in 2442 */ + s3c2410_gpio_pullup(pdata->pin_miso, 0); +} + +const struct lis302dl_platform_data lis302_pdata[] = { { .name = "lis302-1 (top)", .pin_chip_select= S3C2410_GPD12, @@ -896,6 +920,7 @@ struct lis302dl_platform_data lis302_pdata[] = { .pin_miso = S3C2410_GPG5, .open_drain = 1, /* altered at runtime by PCB rev */ .lis302dl_bitbang_read = gat02_lis302dl_bitbang_read, + .lis302dl_suspend_io = gat02_lis302dl_suspend_io, }, { .name = "lis302-2 (bottom)", .pin_chip_select= S3C2410_GPD13, @@ -904,6 +929,7 @@ struct lis302dl_platform_data lis302_pdata[] = { .pin_miso = S3C2410_GPG5, .open_drain = 1, /* altered at runtime by PCB rev */ .lis302dl_bitbang_read = gat02_lis302dl_bitbang_read, + .lis302dl_suspend_io = gat02_lis302dl_suspend_io, }, }; diff --git a/drivers/input/misc/lis302dl.c b/drivers/input/misc/lis302dl.c index 36bdcf79b02..2be816a2ebb 100644 --- a/drivers/input/misc/lis302dl.c +++ b/drivers/input/misc/lis302dl.c @@ -428,6 +428,15 @@ static int lis302dl_suspend(struct spi_device *spi, pm_message_t state) disable_irq(lis->spi_dev->irq); local_save_flags(flags); + /* + * When we share SPI over multiple sensors, there is a race here + * that one or more sensors will lose. In that case, the shared + * SPI bus GPIO will be in sleep mode and partially pulled down. So + * we explicitly put our IO into "wake" mode here before the final + * traffic to the sensor. + */ + (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); @@ -467,6 +476,9 @@ static int lis302dl_suspend(struct spi_device *spi, pm_message_t state) reg_write(lis, LIS302DL_REG_CTRL1, tmp); } + /* place our IO to the device in sleep-compatible states */ + (lis->pdata->lis302dl_suspend_io)(lis, 0); + local_irq_restore(flags); return 0; @@ -479,6 +491,9 @@ static int lis302dl_resume(struct spi_device *spi) local_save_flags(flags); + /* get our IO to the device back in operational states */ + (lis->pdata->lis302dl_suspend_io)(lis, 1); + /* restore registers after resume */ reg_write(lis, LIS302DL_REG_CTRL1, lis->regs[LIS302DL_REG_CTRL1]); reg_write(lis, LIS302DL_REG_CTRL2, lis->regs[LIS302DL_REG_CTRL2]); diff --git a/include/linux/lis302dl.h b/include/linux/lis302dl.h index 2dea8130a24..0d6b4c48bcb 100644 --- a/include/linux/lis302dl.h +++ b/include/linux/lis302dl.h @@ -16,6 +16,7 @@ struct lis302dl_platform_data { unsigned long pin_miso; int open_drain; void (*lis302dl_bitbang_read)(struct lis302dl_info *); + void (*lis302dl_suspend_io)(struct lis302dl_info *, int resuming); }; struct lis302dl_info { |