aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorAndy Green <andy@openmoko.com>2008-11-19 17:09:43 +0000
committerAndy Green <agreen@pads.home.warmcat.com>2008-11-19 17:09:43 +0000
commit2bf6c9a4db92f98b97205d79cb6076a379675f98 (patch)
treebdcb5d88efe0660aada3b312575341efb5c37a44 /drivers
parent55a09978f230a2ec899ce5adda219c7f7819c3a1 (diff)
fix-suspend-backlight-timing-pm-debug.patch
This patch improves the smoothness of suspend and resume action. Taking out CONFIG_PM_DEBUG allows much more rapid resume (the low level serial traffic appears to be synchronous) Added a platform callback in jbt driver and support in pcf50633 so we can defer bringing up the backlight until the LCM is able to process video again (which must happen after the glamo is up and producing video beacuse the LCM is hooked to glamo SPI) GTA01 should not be affected by all this as the callback will default to null and it is on pcf50606 Signed-off-by: Andy Green <andy@openmoko.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/i2c/chips/pcf50633.c50
-rw-r--r--drivers/video/display/jbt6k74.c12
2 files changed, 48 insertions, 14 deletions
diff --git a/drivers/i2c/chips/pcf50633.c b/drivers/i2c/chips/pcf50633.c
index cb4cad8e66f..da58aa326ad 100644
--- a/drivers/i2c/chips/pcf50633.c
+++ b/drivers/i2c/chips/pcf50633.c
@@ -1466,7 +1466,7 @@ static int pcf50633bl_set_intensity(struct backlight_device *bd)
struct pcf50633_data *pcf = bl_get_data(bd);
int intensity = bd->props.brightness;
int old_intensity = reg_read(pcf, PCF50633_REG_LEDOUT);
- u_int8_t ledena;
+ u_int8_t ledena = 2;
int ret;
if (bd->props.power != FB_BLANK_UNBLANK)
@@ -1474,16 +1474,19 @@ static int pcf50633bl_set_intensity(struct backlight_device *bd)
if (bd->props.fb_blank != FB_BLANK_UNBLANK)
intensity = 0;
- /* The PCF50633 seems to have some kind of oddity (bug?) when
- * the intensity was 0, you need to completely switch it off
- * and re-enable it, before it produces any output voltage again */
+ /* The PCF50633 cannot handle LEDOUT = 0 (datasheet p60)
+ * if seen, you have to re-enable the LED unit
+ */
if (intensity != 0 && old_intensity == 0) {
ledena = reg_read(pcf, PCF50633_REG_LEDENA);
reg_write(pcf, PCF50633_REG_LEDENA, 0x00);
}
- ret = reg_set_bit_mask(pcf, PCF50633_REG_LEDOUT, 0x3f,
+ if (!intensity) /* illegal to set LEDOUT to 0 */
+ ret = reg_set_bit_mask(pcf, PCF50633_REG_LEDOUT, 0x3f, 2);
+ else
+ ret = reg_set_bit_mask(pcf, PCF50633_REG_LEDOUT, 0x3f,
intensity);
if (intensity != 0 && old_intensity == 0)
@@ -1920,6 +1923,8 @@ static int pcf50633_suspend(struct device *dev, pm_message_t state)
}
/* turn off the backlight */
+ __reg_write(pcf, PCF50633_REG_LEDDIM, 0);
+ __reg_write(pcf, PCF50633_REG_LEDOUT, 2);
__reg_write(pcf, PCF50633_REG_LEDENA, 0x00);
pcf->standby_regs.int1m = __reg_read(pcf, PCF50633_REG_INT1M);
@@ -1938,17 +1943,30 @@ static int pcf50633_suspend(struct device *dev, pm_message_t state)
return 0;
}
+/*
+ * if backlight resume is selected to be deferred by platform, then it
+ * can call this to finally reset backlight status (after LCM is resumed
+ * for example
+ */
+
+void pcf50633_backlight_resume(struct pcf50633_data *pcf)
+{
+ __reg_write(pcf, PCF50633_REG_LEDOUT, pcf->standby_regs.ledout);
+ __reg_write(pcf, PCF50633_REG_LEDENA, pcf->standby_regs.ledena);
+ __reg_write(pcf, PCF50633_REG_LEDDIM, pcf->standby_regs.leddim);
+}
+EXPORT_SYMBOL_GPL(pcf50633_backlight_resume);
+
+
static int pcf50633_resume(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
struct pcf50633_data *pcf = i2c_get_clientdata(client);
int i;
- printk(KERN_INFO"a\n");
/* mutex_lock(&pcf->lock); */ /* resume in atomic context */
__reg_write(pcf, PCF50633_REG_LEDENA, 0x01);
- printk(KERN_INFO"b\n");
/* Resume all saved registers that don't "survive" standby state */
__reg_write(pcf, PCF50633_REG_INT1M, pcf->standby_regs.int1m);
@@ -1956,7 +1974,6 @@ static int pcf50633_resume(struct device *dev)
__reg_write(pcf, PCF50633_REG_INT3M, pcf->standby_regs.int3m);
__reg_write(pcf, PCF50633_REG_INT4M, pcf->standby_regs.int4m);
__reg_write(pcf, PCF50633_REG_INT5M, pcf->standby_regs.int5m);
- printk(KERN_INFO"c\n");
__reg_write(pcf, PCF50633_REG_OOCTIM2, pcf->standby_regs.ooctim2);
__reg_write(pcf, PCF50633_REG_AUTOOUT, pcf->standby_regs.autoout);
@@ -1967,17 +1984,24 @@ static int pcf50633_resume(struct device *dev)
__reg_write(pcf, PCF50633_REG_DOWN2ENA, pcf->standby_regs.down2ena);
__reg_write(pcf, PCF50633_REG_MEMLDOOUT, pcf->standby_regs.memldoout);
__reg_write(pcf, PCF50633_REG_MEMLDOENA, pcf->standby_regs.memldoena);
- __reg_write(pcf, PCF50633_REG_LEDOUT, pcf->standby_regs.ledout);
- __reg_write(pcf, PCF50633_REG_LEDENA, pcf->standby_regs.ledena);
- __reg_write(pcf, PCF50633_REG_LEDDIM, pcf->standby_regs.leddim);
- printk(KERN_INFO"d\n");
+
+ /* platform can choose to defer backlight bringup */
+ if (!pcf->pdata->defer_resume_backlight) {
+ __reg_write(pcf, PCF50633_REG_LEDOUT, pcf->standby_regs.ledout);
+ __reg_write(pcf, PCF50633_REG_LEDENA, pcf->standby_regs.ledena);
+ __reg_write(pcf, PCF50633_REG_LEDDIM, pcf->standby_regs.leddim);
+ } else { /* force backlight down, platform will restore later */
+ __reg_write(pcf, PCF50633_REG_LEDOUT, 2);
+ __reg_write(pcf, PCF50633_REG_LEDENA, 0x20);
+ __reg_write(pcf, PCF50633_REG_LEDDIM, 1);
+ }
+
/* FIXME: one big read? */
for (i = 0; i < 7; i++) {
u_int8_t reg_out = PCF50633_REG_LDO1OUT + 2*i;
__reg_write(pcf, reg_out, pcf->standby_regs.ldo[i].out);
__reg_write(pcf, reg_out+1, pcf->standby_regs.ldo[i].ena);
}
- printk(KERN_INFO"e\n");
/* mutex_unlock(&pcf->lock); */ /* resume in atomic context */
diff --git a/drivers/video/display/jbt6k74.c b/drivers/video/display/jbt6k74.c
index 7e11da7b47d..178e2daba63 100644
--- a/drivers/video/display/jbt6k74.c
+++ b/drivers/video/display/jbt6k74.c
@@ -647,9 +647,14 @@ static int jbt_suspend(struct spi_device *spi, pm_message_t state)
static void jbt_resume_work(struct work_struct *work)
{
struct jbt_info *jbt = container_of(work, struct jbt_info, work);
+ struct jbt6k74_platform_data *jbt6k74_pdata =
+ jbt->spi_dev->dev.platform_data;
printk(KERN_INFO"jbt_resume_work waiting...\n");
- msleep(2000);
+ /* 100ms is not enough here 2008-05-08 andy@openmoko.com
+ * if CONFIG_PM_DEBUG is enabled 2000ms is required
+ */
+ msleep(400);
printk(KERN_INFO"jbt_resume_work GO...\n");
jbt6k74_enter_state(jbt, JBT_STATE_DEEP_STANDBY);
@@ -665,6 +670,11 @@ static void jbt_resume_work(struct work_struct *work)
}
jbt6k74_display_onoff(jbt, 1);
+ /* this gives the platform a chance to bring up backlight now */
+
+ if (jbt6k74_pdata->resuming)
+ (jbt6k74_pdata->resuming)(0);
+
printk(KERN_INFO"jbt_resume_work done...\n");
}