diff options
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.patch | 316 |
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 + |