mirror of https://github.com/hak5/openwrt.git
277 lines
7.8 KiB
Diff
277 lines
7.8 KiB
Diff
|
From 62b3330f97b940c715a8931abc7161c99362abaa Mon Sep 17 00:00:00 2001
|
||
|
From: Nicolas Dufresne <nicolas.dufresne@gmail.com>
|
||
|
Date: Thu, 4 Dec 2008 17:49:02 +0000
|
||
|
Subject: [PATCH] jbt6k74_no_deep_sleep.patch
|
||
|
|
||
|
This patch from
|
||
|
|
||
|
https://docs.openmoko.org/trac/ticket/1841
|
||
|
|
||
|
defeats deep sleep on the LCM ASIC and is reported to stop the WSOD
|
||
|
behaviour on LCMs that exhibit it.
|
||
|
---
|
||
|
drivers/video/display/jbt6k74.c | 114 ++++++++++++++++++++++-----------------
|
||
|
1 files changed, 65 insertions(+), 49 deletions(-)
|
||
|
|
||
|
diff --git a/drivers/video/display/jbt6k74.c b/drivers/video/display/jbt6k74.c
|
||
|
index 9570543..0635823 100644
|
||
|
--- a/drivers/video/display/jbt6k74.c
|
||
|
+++ b/drivers/video/display/jbt6k74.c
|
||
|
@@ -252,22 +252,36 @@ static int jbt_init_regs(struct jbt_info *jbt, int qvga)
|
||
|
return rc ? -EIO : 0;
|
||
|
}
|
||
|
|
||
|
-static int standby_to_sleep(struct jbt_info *jbt)
|
||
|
+int jbt6k74_display_onoff(struct jbt_info *jbt, int on)
|
||
|
{
|
||
|
- int rc;
|
||
|
-
|
||
|
- /* three times command zero */
|
||
|
- rc = jbt_reg_write_nodata(jbt, 0x00);
|
||
|
- mdelay(1);
|
||
|
- rc |= jbt_reg_write_nodata(jbt, 0x00);
|
||
|
- mdelay(1);
|
||
|
- rc |= jbt_reg_write_nodata(jbt, 0x00);
|
||
|
- mdelay(1);
|
||
|
-
|
||
|
- /* deep standby out */
|
||
|
- rc |= jbt_reg_write(jbt, JBT_REG_POWER_ON_OFF, 0x17);
|
||
|
+ if (on)
|
||
|
+ return jbt_reg_write_nodata(jbt, JBT_REG_DISPLAY_ON);
|
||
|
+ else
|
||
|
+ return jbt_reg_write_nodata(jbt, JBT_REG_DISPLAY_OFF);
|
||
|
+}
|
||
|
+EXPORT_SYMBOL_GPL(jbt6k74_display_onoff);
|
||
|
|
||
|
- return rc ? -EIO : 0;
|
||
|
+static int standby_to_sleep(struct jbt_info *jbt)
|
||
|
+{
|
||
|
+ static int once = 0;
|
||
|
+ if (!once++) {
|
||
|
+ int rc;
|
||
|
+
|
||
|
+ /* three times command zero */
|
||
|
+ rc = jbt_reg_write_nodata(jbt, 0x00);
|
||
|
+ mdelay(1);
|
||
|
+ rc |= jbt_reg_write_nodata(jbt, 0x00);
|
||
|
+ mdelay(1);
|
||
|
+ rc |= jbt_reg_write_nodata(jbt, 0x00);
|
||
|
+ mdelay(1);
|
||
|
+
|
||
|
+ /* deep standby out */
|
||
|
+ rc |= jbt_reg_write(jbt, JBT_REG_POWER_ON_OFF, 0x17);
|
||
|
+
|
||
|
+ return rc ? -EIO : 0;
|
||
|
+ }
|
||
|
+ else
|
||
|
+ return 0;
|
||
|
}
|
||
|
|
||
|
static int sleep_to_normal(struct jbt_info *jbt)
|
||
|
@@ -292,6 +306,9 @@ static int sleep_to_normal(struct jbt_info *jbt)
|
||
|
/* initialize register set */
|
||
|
rc |= jbt_init_regs(jbt, 0);
|
||
|
|
||
|
+ /* Turn on display */
|
||
|
+ rc |= jbt6k74_display_onoff(jbt, 1);
|
||
|
+
|
||
|
return rc ? -EIO : 0;
|
||
|
}
|
||
|
|
||
|
@@ -317,6 +334,9 @@ static int sleep_to_qvga_normal(struct jbt_info *jbt)
|
||
|
/* initialize register set for qvga*/
|
||
|
rc |= jbt_init_regs(jbt, 1);
|
||
|
|
||
|
+ /* Turn on display */
|
||
|
+ rc |= jbt6k74_display_onoff(jbt, 1);
|
||
|
+
|
||
|
return rc ? -EIO : 0;
|
||
|
}
|
||
|
|
||
|
@@ -324,7 +344,8 @@ static int normal_to_sleep(struct jbt_info *jbt)
|
||
|
{
|
||
|
int rc;
|
||
|
|
||
|
- rc = jbt_reg_write_nodata(jbt, JBT_REG_DISPLAY_OFF);
|
||
|
+ rc = jbt6k74_display_onoff(jbt, 0);
|
||
|
+ rc |= jbt_reg_write_nodata(jbt, JBT_REG_DISPLAY_OFF);
|
||
|
rc |= jbt_reg_write16(jbt, JBT_REG_OUTPUT_CONTROL, 0x8002);
|
||
|
rc |= jbt_reg_write_nodata(jbt, JBT_REG_SLEEP_IN);
|
||
|
|
||
|
@@ -333,7 +354,11 @@ static int normal_to_sleep(struct jbt_info *jbt)
|
||
|
|
||
|
static int sleep_to_standby(struct jbt_info *jbt)
|
||
|
{
|
||
|
+#if 0
|
||
|
return jbt_reg_write(jbt, JBT_REG_POWER_ON_OFF, 0x00);
|
||
|
+#else
|
||
|
+ return 0;
|
||
|
+#endif
|
||
|
}
|
||
|
|
||
|
/* frontend function */
|
||
|
@@ -436,6 +461,7 @@ int jbt6k74_enter_state(struct jbt_info *jbt, enum jbt_state new_state)
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
+
|
||
|
if (rc == 0)
|
||
|
jbt->state = new_state;
|
||
|
|
||
|
@@ -443,15 +469,6 @@ int jbt6k74_enter_state(struct jbt_info *jbt, enum jbt_state new_state)
|
||
|
}
|
||
|
EXPORT_SYMBOL_GPL(jbt6k74_enter_state);
|
||
|
|
||
|
-int jbt6k74_display_onoff(struct jbt_info *jbt, int on)
|
||
|
-{
|
||
|
- if (on)
|
||
|
- return jbt_reg_write_nodata(jbt, JBT_REG_DISPLAY_ON);
|
||
|
- else
|
||
|
- return jbt_reg_write_nodata(jbt, JBT_REG_DISPLAY_OFF);
|
||
|
-}
|
||
|
-EXPORT_SYMBOL_GPL(jbt6k74_display_onoff);
|
||
|
-
|
||
|
static ssize_t state_read(struct device *dev, struct device_attribute *attr,
|
||
|
char *buf)
|
||
|
{
|
||
|
@@ -475,17 +492,6 @@ static ssize_t state_write(struct device *dev, struct device_attribute *attr,
|
||
|
rc = jbt6k74_enter_state(jbt, i);
|
||
|
if (rc)
|
||
|
return rc;
|
||
|
- switch (i) {
|
||
|
- case JBT_STATE_NORMAL:
|
||
|
- case JBT_STATE_QVGA_NORMAL:
|
||
|
- /* Enable display again after deep-standby */
|
||
|
- rc = jbt6k74_display_onoff(jbt, 1);
|
||
|
- if (rc)
|
||
|
- return rc;
|
||
|
- break;
|
||
|
- default:
|
||
|
- break;
|
||
|
- }
|
||
|
return count;
|
||
|
}
|
||
|
}
|
||
|
@@ -528,6 +534,8 @@ static ssize_t gamma_write(struct device *dev, struct device_attribute *attr,
|
||
|
int reg = reg_by_string(attr->attr.name);
|
||
|
unsigned long val = simple_strtoul(buf, NULL, 10);
|
||
|
|
||
|
+ dev_info(dev, "**** jbt6k74 writing gama %lu\n", val & 0xff);
|
||
|
+
|
||
|
jbt_reg_write(jbt, reg, val & 0xff);
|
||
|
|
||
|
return count;
|
||
|
@@ -567,19 +575,27 @@ static int fb_notifier_callback(struct notifier_block *self,
|
||
|
|
||
|
switch (fb_blank) {
|
||
|
case FB_BLANK_UNBLANK:
|
||
|
+ dev_info(&jbt->spi_dev->dev, "**** jbt6k74 unblank\n");
|
||
|
+ break;
|
||
|
case FB_BLANK_NORMAL:
|
||
|
- jbt6k74_enter_state(jbt, JBT_STATE_NORMAL);
|
||
|
- jbt6k74_display_onoff(jbt, 1);
|
||
|
+ dev_info(&jbt->spi_dev->dev, "**** jbt6k74 normal\n");
|
||
|
+ /*jbt6k74_enter_state(jbt, JBT_STATE_NORMAL);
|
||
|
+ jbt6k74_display_onoff(jbt, 1); */
|
||
|
break;
|
||
|
case FB_BLANK_VSYNC_SUSPEND:
|
||
|
+ dev_info(&jbt->spi_dev->dev, "**** jbt6k74 vsync suspend\n");
|
||
|
+ break;
|
||
|
case FB_BLANK_HSYNC_SUSPEND:
|
||
|
+ dev_info(&jbt->spi_dev->dev, "**** jbt6k74 hsync suspend\n");
|
||
|
/* FIXME: we disable SLEEP since it would result in
|
||
|
* a visible artefact (white screen) before the backlight
|
||
|
* is dimmed to a dark enough level */
|
||
|
/* jbt6k74_enter_state(jbt, JBT_STATE_SLEEP); */
|
||
|
+ /*jbt6k74_display_onoff(jbt, 0);*/
|
||
|
break;
|
||
|
case FB_BLANK_POWERDOWN:
|
||
|
- jbt6k74_enter_state(jbt, JBT_STATE_DEEP_STANDBY);
|
||
|
+ dev_info(&jbt->spi_dev->dev, "**** jbt6k74 powerdown\n");
|
||
|
+ /*jbt6k74_enter_state(jbt, JBT_STATE_DEEP_STANDBY);*/
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
@@ -621,16 +637,10 @@ static int __devinit jbt_probe(struct spi_device *spi)
|
||
|
goto err_free_drvdata;
|
||
|
}
|
||
|
|
||
|
- rc = jbt6k74_display_onoff(jbt, 1);
|
||
|
- if (rc < 0) {
|
||
|
- dev_err(&spi->dev, "cannot switch display on\n");
|
||
|
- goto err_standby;
|
||
|
- }
|
||
|
-
|
||
|
rc = sysfs_create_group(&spi->dev.kobj, &jbt_attr_group);
|
||
|
if (rc < 0) {
|
||
|
dev_err(&spi->dev, "cannot create sysfs group\n");
|
||
|
- goto err_off;
|
||
|
+ goto err_standby;
|
||
|
}
|
||
|
|
||
|
jbt->fb_notif.notifier_call = fb_notifier_callback;
|
||
|
@@ -644,8 +654,6 @@ static int __devinit jbt_probe(struct spi_device *spi)
|
||
|
|
||
|
err_sysfs:
|
||
|
sysfs_remove_group(&spi->dev.kobj, &jbt_attr_group);
|
||
|
-err_off:
|
||
|
- jbt6k74_display_onoff(jbt, 0);
|
||
|
err_standby:
|
||
|
jbt6k74_enter_state(jbt, JBT_STATE_DEEP_STANDBY);
|
||
|
err_free_drvdata:
|
||
|
@@ -676,6 +684,8 @@ 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;
|
||
|
|
||
|
+ dev_info(&spi->dev, "**** jbt6k74 suspend start\n");
|
||
|
+
|
||
|
/* platform can register resume dependencies here, if any */
|
||
|
if (jbt6k74_pdata->suspending)
|
||
|
(jbt6k74_pdata->suspending)(0, spi);
|
||
|
@@ -689,6 +699,8 @@ static int jbt_suspend(struct spi_device *spi, pm_message_t state)
|
||
|
|
||
|
/* (jbt6k74_pdata->reset)(0, 0); */
|
||
|
|
||
|
+ dev_info(&spi->dev, "**** jbt6k74 suspend end\n");
|
||
|
+
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
@@ -697,6 +709,7 @@ int jbt6k74_resume(struct spi_device *spi)
|
||
|
struct jbt_info *jbt = dev_get_drvdata(&spi->dev);
|
||
|
struct jbt6k74_platform_data *jbt6k74_pdata = spi->dev.platform_data;
|
||
|
|
||
|
+ dev_info(&spi->dev, "**** jbt6k74 resume start\n");
|
||
|
if (jbt6k74_pdata->all_dependencies_resumed)
|
||
|
if (!(jbt6k74_pdata->all_dependencies_resumed)(0))
|
||
|
return 0;
|
||
|
@@ -704,8 +717,10 @@ int jbt6k74_resume(struct spi_device *spi)
|
||
|
/* we can get called twice with all dependencies resumed if our core
|
||
|
* resume callback is last of all. Protect against doing anything twice
|
||
|
*/
|
||
|
- if (jbt->have_resumed)
|
||
|
+ if (jbt->have_resumed) {
|
||
|
+ dev_info(&spi->dev, "**** jbt6k74 already resumed\n");
|
||
|
return 0;
|
||
|
+ }
|
||
|
|
||
|
jbt->have_resumed |= 1;
|
||
|
|
||
|
@@ -717,11 +732,12 @@ int jbt6k74_resume(struct spi_device *spi)
|
||
|
jbt6k74_enter_state(jbt, JBT_STATE_NORMAL);
|
||
|
break;
|
||
|
}
|
||
|
- jbt6k74_display_onoff(jbt, 1);
|
||
|
|
||
|
if (jbt6k74_pdata->resuming)
|
||
|
(jbt6k74_pdata->resuming)(0);
|
||
|
|
||
|
+ dev_info(&spi->dev, "**** jbt6k74 resume end\n");
|
||
|
+
|
||
|
return 0;
|
||
|
}
|
||
|
EXPORT_SYMBOL_GPL(jbt6k74_resume);
|
||
|
--
|
||
|
1.5.6.5
|
||
|
|