aboutsummaryrefslogtreecommitdiffstats
path: root/recipes/linux/linux-openmoko-2.6.32/0022-JBT6k74-tweaks-Make-resolution-switch-work.patch
diff options
context:
space:
mode:
Diffstat (limited to 'recipes/linux/linux-openmoko-2.6.32/0022-JBT6k74-tweaks-Make-resolution-switch-work.patch')
-rw-r--r--recipes/linux/linux-openmoko-2.6.32/0022-JBT6k74-tweaks-Make-resolution-switch-work.patch316
1 files changed, 316 insertions, 0 deletions
diff --git a/recipes/linux/linux-openmoko-2.6.32/0022-JBT6k74-tweaks-Make-resolution-switch-work.patch b/recipes/linux/linux-openmoko-2.6.32/0022-JBT6k74-tweaks-Make-resolution-switch-work.patch
new file mode 100644
index 0000000000..6acefa3382
--- /dev/null
+++ b/recipes/linux/linux-openmoko-2.6.32/0022-JBT6k74-tweaks-Make-resolution-switch-work.patch
@@ -0,0 +1,316 @@
+From 6296b2623da88372bc6762160ba2a990cc99902c Mon Sep 17 00:00:00 2001
+From: Thomas White <taw@bitwiz.org.uk>
+Date: Sat, 24 Apr 2010 21:04:46 +0200
+Subject: [PATCH 28/31] JBT6k74 tweaks: Make resolution switch work
+
+Signed-off-by: Thomas White <taw@bitwiz.org.uk>
+---
+ arch/arm/mach-s3c2442/mach-gta02.c | 2 +-
+ drivers/mfd/glamo/glamo-display.c | 9 ++-
+ drivers/video/backlight/jbt6k74.c | 121 +++++++++++++++++++++++++++--------
+ include/linux/jbt6k74.h | 4 +-
+ 4 files changed, 102 insertions(+), 34 deletions(-)
+
+diff --git a/arch/arm/mach-s3c2442/mach-gta02.c b/arch/arm/mach-s3c2442/mach-gta02.c
+index 8b59fa7..9a30687 100644
+--- a/arch/arm/mach-s3c2442/mach-gta02.c
++++ b/arch/arm/mach-s3c2442/mach-gta02.c
+@@ -246,7 +246,7 @@ static struct fb_videomode gta02_glamo_modes[] = {
+ .name = "240x320",
+ .xres = 240,
+ .yres = 320,
+- .pixclock = 100000,
++ .pixclock = 40816,
+ .left_margin = 8,
+ .right_margin = 16,
+ .upper_margin = 2,
+diff --git a/drivers/mfd/glamo/glamo-display.c b/drivers/mfd/glamo/glamo-display.c
+index f57d273..a551968 100644
+--- a/drivers/mfd/glamo/glamo-display.c
++++ b/drivers/mfd/glamo/glamo-display.c
+@@ -307,6 +307,7 @@ static int glamo_crtc_mode_set(struct drm_crtc *crtc,
+ printk(KERN_WARNING "[glamo-drm] Display is off - "
+ "enabling it before setting mode.\n");
+ glamo_lcd_power(gdrm, 1);
++ msleep(500);
+ }
+
+ glamo_lcd_cmd_mode(gdrm, 1);
+@@ -355,14 +356,14 @@ static int glamo_crtc_mode_set(struct drm_crtc *crtc,
+
+ glamo_lcd_cmd_mode(gdrm, 0);
+
++ glamo_crtc_mode_set_base(crtc, 0, 0, old_fb);
++
+ if ( mode->hdisplay == 240 ) {
+- jbt6k74_setresolution(JBT_RESOLUTION_QVGA);
++ jbt6k74_finish_resolutionchange(JBT_RESOLUTION_QVGA);
+ } else {
+- jbt6k74_setresolution(JBT_RESOLUTION_VGA);
++ jbt6k74_finish_resolutionchange(JBT_RESOLUTION_VGA);
+ }
+
+- glamo_crtc_mode_set_base(crtc, 0, 0, old_fb);
+-
+ gcrtc->current_mode = *mode;
+ gcrtc->current_mode_set = 1;
+ gcrtc->current_fb = old_fb;
+diff --git a/drivers/video/backlight/jbt6k74.c b/drivers/video/backlight/jbt6k74.c
+index 40c31f6..43249ad 100644
+--- a/drivers/video/backlight/jbt6k74.c
++++ b/drivers/video/backlight/jbt6k74.c
+@@ -104,6 +104,7 @@ enum jbt_register {
+
+ static const char *jbt_power_mode_names[] = {
+ [JBT_POWER_MODE_OFF] = "off",
++ [JBT_POWER_MODE_STANDBY] = "standby",
+ [JBT_POWER_MODE_NORMAL] = "normal",
+ };
+
+@@ -148,6 +149,8 @@ static int jbt_reg_write_nodata(struct jbt_info *jbt, uint8_t reg)
+ else
+ dev_err(&jbt->spi->dev, "Write failed: %d\n", ret);
+
++ mdelay(1);
++
+ return ret;
+ }
+
+@@ -165,6 +168,8 @@ static int jbt_reg_write(struct jbt_info *jbt, uint8_t reg, uint8_t data)
+ else
+ dev_err(&jbt->spi->dev, "Write failed: %d\n", ret);
+
++ mdelay(1);
++
+ return ret;
+ }
+
+@@ -183,6 +188,8 @@ static int jbt_reg_write16(struct jbt_info *jbt, uint8_t reg, uint16_t data)
+ else
+ dev_err(&jbt->spi->dev, "Write failed: %d\n", ret);
+
++ mdelay(1);
++
+ return ret;
+ }
+
+@@ -262,7 +269,7 @@ static int jbt_off_to_normal(struct jbt_info *jbt)
+ gpio_set_value_cansleep(pdata->gpio_reset, 1);
+ ret = regulator_bulk_enable(ARRAY_SIZE(jbt->supplies), jbt->supplies);
+
+- mdelay(30);
++ mdelay(120);
+
+ /* three times command zero */
+ ret |= jbt_reg_write_nodata(jbt, 0x00);
+@@ -334,6 +341,49 @@ static int jbt_normal_to_off(struct jbt_info *jbt)
+ }
+
+
++static int jbt_normal_to_standby(struct jbt_info *jbt)
++{
++ int ret;
++
++ if ( jbt->power_mode != JBT_POWER_MODE_NORMAL ) return 0;
++
++ /* Make sure we are 120 ms after SLEEP_{IN,OUT} */
++ while (time_before(jiffies, jbt->next_sleep)) cpu_relax();
++
++ /* Sleep mode on */
++ ret = jbt_reg_write_nodata(jbt, JBT_REG_DISPLAY_OFF);
++ ret |= jbt_reg_write16(jbt, JBT_REG_OUTPUT_CONTROL, 0x8000 | 1 << 3);
++
++ ret |= jbt_reg_write_nodata(jbt, JBT_REG_SLEEP_IN);
++ jbt->next_sleep = jiffies + msecs_to_jiffies(150);
++
++ jbt->power_mode = JBT_POWER_MODE_STANDBY;
++
++ return ret ? -EIO : 0;
++}
++
++
++static int jbt_standby_to_normal(struct jbt_info *jbt)
++{
++ int ret;
++
++ if ( jbt->power_mode != JBT_POWER_MODE_STANDBY ) return 0;
++
++ /* Make sure we are 120 ms after SLEEP_{IN,OUT} */
++ while (time_before(jiffies, jbt->next_sleep)) cpu_relax();
++
++ ret = jbt_reg_write_nodata(jbt, JBT_REG_SLEEP_OUT);
++ jbt->next_sleep = jiffies + msecs_to_jiffies(150);
++
++ ret |= jbt_reg_write_nodata(jbt, JBT_REG_DISPLAY_ON);
++ ret |= jbt_reg_write16(jbt, JBT_REG_OUTPUT_CONTROL, 0xdff9);
++
++ jbt->power_mode = JBT_POWER_MODE_NORMAL;
++
++ return ret ? -EIO : 0;
++}
++
++
+ static int jbt6k74_enter_power_mode(struct jbt_info *jbt,
+ enum jbt_power_mode new_mode)
+ {
+@@ -354,6 +404,9 @@ static int jbt6k74_enter_power_mode(struct jbt_info *jbt,
+ case JBT_POWER_MODE_NORMAL:
+ ret = jbt_off_to_normal(jbt);
+ break;
++ case JBT_POWER_MODE_STANDBY:
++ ret = -EINVAL;
++ break;
+ }
+ break;
+ case JBT_POWER_MODE_NORMAL:
+@@ -364,7 +417,14 @@ static int jbt6k74_enter_power_mode(struct jbt_info *jbt,
+ case JBT_POWER_MODE_OFF:
+ ret = jbt_normal_to_off(jbt);
+ break;
++ case JBT_POWER_MODE_STANDBY:
++ ret = -EINVAL;
++ break;
+ }
++ break;
++ case JBT_POWER_MODE_STANDBY:
++ ret = -EINVAL;
++ break;
+ }
+
+ if (ret == 0) {
+@@ -382,29 +442,46 @@ static int jbt6k74_enter_power_mode(struct jbt_info *jbt,
+ static int jbt6k74_set_resolution(struct jbt_info *jbt,
+ enum jbt_resolution new_resolution)
+ {
++ int old_resolution;
+ int ret = 0;
+- enum jbt_resolution old_resolution;
++
++ if ( !jbt ) return -1;
+
+ mutex_lock(&jbt->lock);
+
+- if (jbt->resolution == new_resolution)
+- goto out_unlock;
++ if ( jbt->resolution == new_resolution ) goto out_unlock;
++ if ( jbt->power_mode == JBT_POWER_MODE_OFF ) goto out_unlock;
+
+ old_resolution = jbt->resolution;
+ jbt->resolution = new_resolution;
+
+- if (jbt->power_mode == JBT_POWER_MODE_NORMAL) {
++ if ( jbt->power_mode == JBT_POWER_MODE_NORMAL ) {
++
++ ret = jbt_normal_to_standby(jbt);
++
++ mdelay(25);
++
++ if (jbt->resolution == JBT_RESOLUTION_VGA) {
++ /* Quad mode off */
++ ret |= jbt_reg_write(jbt, JBT_REG_QUAD_RATE, 0x00);
++ ret = jbt_reg_write(jbt, JBT_REG_DISPLAY_MODE, 0x80);
++ } else {
++ /* Quad mode on */
++ ret |= jbt_reg_write(jbt, JBT_REG_QUAD_RATE, 0x22);
++ ret = jbt_reg_write(jbt, JBT_REG_DISPLAY_MODE, 0x81);
++ }
+
+- /* "Reboot" the LCM */
+- ret = jbt_normal_to_off(jbt);
+- mdelay(1000);
+- ret |= jbt_off_to_normal(jbt);
++ mdelay(25);
++
++ ret |= jbt_standby_to_normal(jbt);
+
+ if (ret) {
+ jbt->resolution = old_resolution;
+- dev_err(&jbt->spi->dev, "Failed to set resolution '%s')\n",
++ dev_err(&jbt->spi->dev,
++ "Failed to set resolution '%s')\n",
+ jbt_resolution_names[new_resolution]);
+ }
++
+ }
+
+ out_unlock:
+@@ -737,26 +814,18 @@ static int __devexit jbt_remove(struct spi_device *spi)
+ return 0;
+ }
+
+-/* Begin horrible layering violations (in the interest of making stuff work) */
++/* Begin horrible layering violations in the interest of making stuff work */
+
+-int jbt6k74_setresolution(enum jbt_resolution new_resolution)
++int jbt6k74_finish_resolutionchange(enum jbt_resolution new_resolution)
+ {
+- if ( !jbt_global ) {
+- printk(KERN_CRIT "JBT not initialised!!!\n");
+- return -1;
+- }
+- jbt6k74_set_resolution(jbt_global, new_resolution);
+- return 0;
++ if ( !jbt_global ) return 0;
++ return jbt6k74_set_resolution(jbt_global, new_resolution);
+ }
+-EXPORT_SYMBOL_GPL(jbt6k74_setresolution);
++EXPORT_SYMBOL_GPL(jbt6k74_finish_resolutionchange);
+
+-/* This is utterly, totally horrible. I'm REALLY sorry... */
+ void jbt6k74_setpower(enum jbt_power_mode new_power)
+ {
+- if ( !jbt_global ) {
+- printk(KERN_CRIT "JBT not initialised!!!\n");
+- return;
+- }
++ if ( !jbt_global ) return;
+ jbt6k74_enter_power_mode(jbt_global, new_power);
+ }
+ EXPORT_SYMBOL_GPL(jbt6k74_setpower);
+@@ -770,10 +839,8 @@ static int jbt_suspend(struct spi_device *spi, pm_message_t state)
+
+ jbt->suspend_mode = jbt->power_mode;
+
+- printk(KERN_CRIT "[jbt] powering off for suspend\n");
+ jbt6k74_enter_power_mode(jbt, JBT_POWER_MODE_OFF);
+
+- printk(KERN_CRIT "[jbt] done\n");
+ dev_info(&spi->dev, "suspended\n");
+
+ return 0;
+@@ -784,13 +851,11 @@ int jbt6k74_resume(struct spi_device *spi)
+ struct jbt_info *jbt = dev_get_drvdata(&spi->dev);
+ dev_info(&spi->dev, "starting resume: %d\n", jbt->suspend_mode);
+
+- printk(KERN_CRIT "[jbt] powering on for resume\n");
+ mdelay(20);
+
+ jbt->suspended = 0;
+ jbt6k74_enter_power_mode(jbt, jbt->suspend_mode);
+
+- printk(KERN_CRIT "[jbt] done\n");
+ dev_info(&spi->dev, "resumed: %d\n", jbt->suspend_mode);
+
+ return 0;
+diff --git a/include/linux/jbt6k74.h b/include/linux/jbt6k74.h
+index f430e5a..2010bdc 100644
+--- a/include/linux/jbt6k74.h
++++ b/include/linux/jbt6k74.h
+@@ -10,11 +10,13 @@ enum jbt_resolution {
+
+ enum jbt_power_mode {
+ JBT_POWER_MODE_OFF,
++ JBT_POWER_MODE_STANDBY,
+ JBT_POWER_MODE_NORMAL,
+ };
+
+ extern void jbt6k74_setpower(enum jbt_power_mode new_power);
+-extern int jbt6k74_setresolution(enum jbt_resolution new_resolution);
++extern int jbt6k74_prepare_resolutionchange(enum jbt_resolution new_resolution);
++extern int jbt6k74_finish_resolutionchange(enum jbt_resolution new_resolution);
+
+
+ /*
+--
+1.7.0.4
+