From bcf06c774c2c55fbd05b74ea01f1a2a6b3de2dc7 Mon Sep 17 00:00:00 2001 From: warmcat Date: Sun, 13 Apr 2008 07:25:50 +0100 Subject: [PATCH] fix-lcm-reinit-post-resume.patch --- arch/arm/mach-s3c2440/mach-gta02.c | 12 +++++++++ drivers/mfd/glamo/glamo-core.c | 15 ++++++++++- drivers/mfd/glamo/glamo-spi-gpio.c | 38 ++++++++++++++++++++++++++-- drivers/video/display/jbt6k74.c | 47 ++++++++++++++++++++++++++++++++---- include/linux/glamofb.h | 1 + include/linux/jbt6k74.h | 8 ++++++ 6 files changed, 111 insertions(+), 10 deletions(-) create mode 100644 include/linux/jbt6k74.h diff --git a/arch/arm/mach-s3c2440/mach-gta02.c b/arch/arm/mach-s3c2440/mach-gta02.c index f2b1b66..750fd97 100644 --- a/arch/arm/mach-s3c2440/mach-gta02.c +++ b/arch/arm/mach-s3c2440/mach-gta02.c @@ -76,6 +76,7 @@ #include #include #include +#include #include @@ -756,10 +757,21 @@ static struct s3c2410_ts_mach_info gta02_ts_cfg = { /* SPI: LCM control interface attached to Glamo3362 */ +void gta02_jbt6k74_reset(int devidx, int level) +{ + glamo_lcm_reset(level); +} + + +const struct jbt6k74_platform_data jbt6k74_pdata = { + .reset = gta02_jbt6k74_reset, +}; + static struct spi_board_info gta02_spi_board_info[] = { { .modalias = "jbt6k74", /* platform_data */ + .platform_data = &jbt6k74_pdata, /* controller_data */ /* irq */ .max_speed_hz = 10 * 1000 * 1000, diff --git a/drivers/mfd/glamo/glamo-core.c b/drivers/mfd/glamo/glamo-core.c index ffa4945..2076e61 100644 --- a/drivers/mfd/glamo/glamo-core.c +++ b/drivers/mfd/glamo/glamo-core.c @@ -513,6 +513,17 @@ void glamo_engine_reset(struct glamo_core *glamo, enum glamo_engine engine) } EXPORT_SYMBOL_GPL(glamo_engine_reset); +void glamo_lcm_reset(int level) +{ + if (!glamo_handle) + return; + + glamo_gpio_setpin(glamo_handle, GLAMO_GPIO4, level); + glamo_gpio_cfgpin(glamo_handle, GLAMO_GPIO4_OUTPUT); + +} +EXPORT_SYMBOL_GPL(glamo_lcm_reset); + enum glamo_pll { GLAMO_PLL1, GLAMO_PLL2, @@ -1142,8 +1153,8 @@ static int glamo_resume(struct platform_device *pdev) static struct platform_driver glamo_driver = { .probe = glamo_probe, .remove = glamo_remove, - .suspend = glamo_suspend, - .resume = glamo_resume, + .suspend_late = glamo_suspend, + .resume_early = glamo_resume, .driver = { .name = "glamo3362", .owner = THIS_MODULE, diff --git a/drivers/mfd/glamo/glamo-spi-gpio.c b/drivers/mfd/glamo/glamo-spi-gpio.c index 73926bd..eda7322 100644 --- a/drivers/mfd/glamo/glamo-spi-gpio.c +++ b/drivers/mfd/glamo/glamo-spi-gpio.c @@ -224,14 +224,46 @@ static int glamo_spigpio_remove(struct platform_device *pdev) return 0; } -#define glamo_spigpio_suspend NULL +/*#define glamo_spigpio_suspend NULL #define glamo_spigpio_resume NULL +*/ + + +#ifdef CONFIG_PM +static int glamo_spigpio_suspend(struct platform_device *pdev, pm_message_t state) +{ + return 0; +} + +static int glamo_spigpio_resume(struct platform_device *pdev) +{ + struct glamo_spigpio *sp = platform_get_drvdata(pdev); + + if (!sp) + return 0; + + /* set state of spi pins */ + glamo_gpio_setpin(sp->glamo, sp->info->pin_clk, 0); + glamo_gpio_setpin(sp->glamo, sp->info->pin_mosi, 0); + glamo_gpio_setpin(sp->glamo, sp->info->pin_cs, 1); + + glamo_gpio_cfgpin(sp->glamo, sp->info->pin_clk); + glamo_gpio_cfgpin(sp->glamo, sp->info->pin_mosi); + glamo_gpio_cfgpin(sp->glamo, sp->info->pin_cs); + if (sp->info->pin_miso) + glamo_gpio_cfgpin(sp->glamo, sp->info->pin_miso); + + return 0; +} +#endif static struct platform_driver glamo_spi_drv = { .probe = glamo_spigpio_probe, .remove = glamo_spigpio_remove, - .suspend = glamo_spigpio_suspend, - .resume = glamo_spigpio_resume, +#ifdef CONFIG_PM + .suspend_late = glamo_spigpio_suspend, + .resume_early = glamo_spigpio_resume, +#endif .driver = { .name = "glamo-spi-gpio", .owner = THIS_MODULE, diff --git a/drivers/video/display/jbt6k74.c b/drivers/video/display/jbt6k74.c index d021d7e..d7e9442 100644 --- a/drivers/video/display/jbt6k74.c +++ b/drivers/video/display/jbt6k74.c @@ -27,6 +27,8 @@ #include #include #include +#include +#include #include @@ -114,11 +116,15 @@ struct jbt_info { struct mutex lock; /* protects tx_buf and reg_cache */ u16 tx_buf[8]; u16 reg_cache[0xEE]; + struct work_struct work; }; #define JBT_COMMAND 0x000 #define JBT_DATA 0x100 +static void jbt_resume_work(struct work_struct *work); + + static int jbt_reg_write_nodata(struct jbt_info *jbt, u8 reg) { int rc; @@ -130,6 +136,9 @@ static int jbt_reg_write_nodata(struct jbt_info *jbt, u8 reg) 1*sizeof(u16)); if (rc == 0) jbt->reg_cache[reg] = 0; + else + printk(KERN_ERR"jbt_reg_write_nodata spi_write ret %d\n", + rc); mutex_unlock(&jbt->lock); @@ -149,6 +158,8 @@ static int jbt_reg_write(struct jbt_info *jbt, u8 reg, u8 data) 2*sizeof(u16)); if (rc == 0) jbt->reg_cache[reg] = data; + else + printk(KERN_ERR"jbt_reg_write spi_write ret %d\n", rc); mutex_unlock(&jbt->lock); @@ -169,6 +180,8 @@ static int jbt_reg_write16(struct jbt_info *jbt, u8 reg, u16 data) 3*sizeof(u16)); if (rc == 0) jbt->reg_cache[reg] = data; + else + printk(KERN_ERR"jbt_reg_write16 spi_write ret %d\n", rc); mutex_unlock(&jbt->lock); @@ -563,6 +576,8 @@ static int __devinit jbt_probe(struct spi_device *spi) if (!jbt) return -ENOMEM; + INIT_WORK(&jbt->work, jbt_resume_work); + jbt->spi_dev = spi; jbt->state = JBT_STATE_DEEP_STANDBY; mutex_init(&jbt->lock); @@ -618,28 +633,50 @@ static int __devexit jbt_remove(struct spi_device *spi) static int jbt_suspend(struct spi_device *spi, pm_message_t state) { struct jbt_info *jbt = dev_get_drvdata(&spi->dev); + struct jbt6k74_platform_data *jbt6k74_pdata = spi->dev.platform_data; /* Save mode for resume */ jbt->last_state = jbt->state; jbt6k74_enter_state(jbt, JBT_STATE_DEEP_STANDBY); + (jbt6k74_pdata->reset)(0, 0); + return 0; } -static int jbt_resume(struct spi_device *spi) +static void jbt_resume_work(struct work_struct *work) { - struct jbt_info *jbt = dev_get_drvdata(&spi->dev); + struct jbt_info *jbt = container_of(work, struct jbt_info, work); + + printk(KERN_INFO"jbt_resume_work waiting...\n"); + msleep(2000); + printk(KERN_INFO"jbt_resume_work GO...\n"); - jbt6k74_enter_state(jbt, jbt->last_state); + jbt6k74_enter_state(jbt, JBT_STATE_DEEP_STANDBY); + msleep(100); switch (jbt->last_state) { - case JBT_STATE_NORMAL: case JBT_STATE_QVGA_NORMAL: - jbt6k74_display_onoff(jbt, 1); + jbt6k74_enter_state(jbt, JBT_STATE_QVGA_NORMAL); break; default: + jbt6k74_enter_state(jbt, JBT_STATE_NORMAL); break; } + jbt6k74_display_onoff(jbt, 1); + + printk(KERN_INFO"jbt_resume_work done...\n"); +} + +static int jbt_resume(struct spi_device *spi) +{ + struct jbt_info *jbt = dev_get_drvdata(&spi->dev); + struct jbt6k74_platform_data *jbt6k74_pdata = spi->dev.platform_data; + + (jbt6k74_pdata->reset)(0, 1); + + if (!schedule_work(&jbt->work)) + dev_err(&spi->dev, "Unable to schedule LCM wakeup work\n"); return 0; } diff --git a/include/linux/glamofb.h b/include/linux/glamofb.h index 24742a2..75eefef 100644 --- a/include/linux/glamofb.h +++ b/include/linux/glamofb.h @@ -35,5 +35,6 @@ struct glamofb_platform_data { void glamofb_cmd_mode(struct glamofb_handle *gfb, int on); int glamofb_cmd_write(struct glamofb_handle *gfb, u_int16_t val); +void glamo_lcm_reset(int level); #endif diff --git a/include/linux/jbt6k74.h b/include/linux/jbt6k74.h new file mode 100644 index 0000000..3fbe178 --- /dev/null +++ b/include/linux/jbt6k74.h @@ -0,0 +1,8 @@ +#ifndef __JBT6K74_H__ +#define __JBT6K74_H__ + +struct jbt6k74_platform_data { + void (* reset)(int devindex, int level); +}; + +#endif -- 1.5.6.5