diff options
author | Martin Jansa <Martin.Jansa@gmail.com> | 2010-05-17 13:31:01 +0200 |
---|---|---|
committer | Martin Jansa <Martin.Jansa@gmail.com> | 2010-05-17 21:23:57 +0200 |
commit | 14e1ed70361f7f5a5e54d93a606a7c8d53460b95 (patch) | |
tree | b0ea6e76cacf9bf282af487021ca29de6ef77ca9 /recipes/linux/linux-openmoko-2.6.32/0010-JBT6k74-work-for-KMS.patch | |
parent | 7c393dcee85c4ac5556f11a61300d01bbd9c037d (diff) |
linux-openmoko-2.6.32: add patches from gdrm-for-merging instead of gdrm-2.6.32 branch and rebase
Signed-off-by: Martin Jansa <Martin.Jansa@gmail.com>
Diffstat (limited to 'recipes/linux/linux-openmoko-2.6.32/0010-JBT6k74-work-for-KMS.patch')
-rw-r--r-- | recipes/linux/linux-openmoko-2.6.32/0010-JBT6k74-work-for-KMS.patch | 540 |
1 files changed, 540 insertions, 0 deletions
diff --git a/recipes/linux/linux-openmoko-2.6.32/0010-JBT6k74-work-for-KMS.patch b/recipes/linux/linux-openmoko-2.6.32/0010-JBT6k74-work-for-KMS.patch new file mode 100644 index 0000000000..2105ab60aa --- /dev/null +++ b/recipes/linux/linux-openmoko-2.6.32/0010-JBT6k74-work-for-KMS.patch @@ -0,0 +1,540 @@ +From 5788c7777a6fa63dc56093277ae14c4dac4ee6cb Mon Sep 17 00:00:00 2001 +From: Thomas White <taw@bitwiz.org.uk> +Date: Sat, 21 Nov 2009 21:42:16 +0100 +Subject: [PATCH 10/14] JBT6k74 work for KMS + +This simplifies the JBT6k74 driver, and adds hooks for the Glamo driver to cooperate +more closely with it. + +Signed-off-by: Thomas White <taw@bitwiz.org.uk> +--- + drivers/video/backlight/jbt6k74.c | 252 ++++++++++++++++++------------------ + include/linux/jbt6k74.h | 17 +++- + 2 files changed, 142 insertions(+), 127 deletions(-) + +diff --git a/drivers/video/backlight/jbt6k74.c b/drivers/video/backlight/jbt6k74.c +index 8450904..91651e7 100644 +--- a/drivers/video/backlight/jbt6k74.c ++++ b/drivers/video/backlight/jbt6k74.c +@@ -101,20 +101,10 @@ enum jbt_register { + JBT_REG_HCLOCK_QVGA = 0xed, + }; + +-enum jbt_resolution { +- JBT_RESOLUTION_VGA, +- JBT_RESOLUTION_QVGA, +-}; +- +-enum jbt_power_mode { +- JBT_POWER_MODE_DEEP_STANDBY, +- JBT_POWER_MODE_SLEEP, +- JBT_POWER_MODE_NORMAL, +-}; + + static const char *jbt_power_mode_names[] = { +- [JBT_POWER_MODE_DEEP_STANDBY] = "deep-standby", +- [JBT_POWER_MODE_SLEEP] = "sleep", ++ [JBT_POWER_MODE_OFF] = "off", ++ [JBT_POWER_MODE_STANDBY] = "standby", + [JBT_POWER_MODE_NORMAL] = "normal", + }; + +@@ -123,6 +113,7 @@ static const char *jbt_resolution_names[] = { + [JBT_RESOLUTION_QVGA] = "qvga", + }; + ++ + struct jbt_info { + struct mutex lock; /* protects this structure */ + enum jbt_resolution resolution; +@@ -141,6 +132,8 @@ struct jbt_info { + uint16_t reg_cache[0xEE]; + }; + ++struct jbt_info *jbt_global; ++ + #define JBT_COMMAND 0x000 + #define JBT_DATA 0x100 + +@@ -156,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; + } + +@@ -173,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; + } + +@@ -191,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; + } + +@@ -218,7 +217,7 @@ static int jbt_init_regs(struct jbt_info *jbt) + * to avoid red / blue flicker + */ + ret |= jbt_reg_write(jbt, JBT_REG_ASW_SLEW, 0x00 | (1 << 5)); +- ret |= jbt_reg_write(jbt, JBT_REG_DUMMY_DISPLAY, 0x00); ++ ret |= jbt_reg_write(jbt, JBT_REG_DUMMY_DISPLAY, 0xff); + + ret |= jbt_reg_write(jbt, JBT_REG_SLEEP_OUT_FR_A, 0x11); + ret |= jbt_reg_write(jbt, JBT_REG_SLEEP_OUT_FR_B, 0x11); +@@ -260,14 +259,18 @@ static int jbt_init_regs(struct jbt_info *jbt) + return ret ? -EIO : 0; + } + +-static int jbt_standby_to_sleep(struct jbt_info *jbt) ++ ++static int jbt_off_to_normal(struct jbt_info *jbt) + { + int ret; ++ + struct jbt6k74_platform_data *pdata = jbt->spi->dev.platform_data; + + gpio_set_value_cansleep(pdata->gpio_reset, 1); + ret = regulator_bulk_enable(ARRAY_SIZE(jbt->supplies), jbt->supplies); + ++ mdelay(120); ++ + /* three times command zero */ + ret |= jbt_reg_write_nodata(jbt, 0x00); + mdelay(1); +@@ -279,18 +282,11 @@ static int jbt_standby_to_sleep(struct jbt_info *jbt) + /* deep standby out */ + ret |= jbt_reg_write(jbt, JBT_REG_POWER_ON_OFF, 0x11); + mdelay(1); +- ret = jbt_reg_write(jbt, JBT_REG_DISPLAY_MODE, 0x28); ++ ret |= jbt_reg_write(jbt, JBT_REG_DISPLAY_MODE, 0x28); + + /* (re)initialize register set */ + ret |= jbt_init_regs(jbt); + +- return ret ? -EIO : 0; +-} +- +-static int jbt_sleep_to_normal(struct jbt_info *jbt) +-{ +- int ret; +- + /* Make sure we are 120 ms after SLEEP_OUT */ + if (time_before(jiffies, jbt->next_sleep)) + mdelay(jiffies_to_msecs(jbt->next_sleep - jiffies)); +@@ -320,6 +316,7 @@ static int jbt_sleep_to_normal(struct jbt_info *jbt) + + /* Sleep mode off */ + ret |= jbt_reg_write_nodata(jbt, JBT_REG_SLEEP_OUT); ++ + jbt->next_sleep = jiffies + msecs_to_jiffies(120); + + /* Allow the booster and display controller to restart stably */ +@@ -328,45 +325,68 @@ static int jbt_sleep_to_normal(struct jbt_info *jbt) + return ret ? -EIO : 0; + } + +-static int jbt_normal_to_sleep(struct jbt_info *jbt) ++static int jbt_normal_to_off(struct jbt_info *jbt) + { + int ret; ++ struct jbt6k74_platform_data *pdata = jbt->spi->dev.platform_data; + +- /* Make sure we are 120 ms after SLEEP_OUT */ +- while (time_before(jiffies, jbt->next_sleep)) +- cpu_relax(); ++ /* Pull the plug! */ ++ ret = regulator_bulk_disable(ARRAY_SIZE(jbt->supplies), ++ jbt->supplies); + ++ if (!ret) ++ gpio_set_value_cansleep(pdata->gpio_reset, 0); ++ ++ return ret ? -EIO : 0; ++} ++ ++ ++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(120); ++ jbt->next_sleep = jiffies + msecs_to_jiffies(150); + +- /* Allow the internal circuits to stop automatically */ +- mdelay(5); ++ jbt->power_mode = JBT_POWER_MODE_STANDBY; + + return ret ? -EIO : 0; + } + +-static int jbt_sleep_to_standby(struct jbt_info *jbt) ++ ++static int jbt_standby_to_normal(struct jbt_info *jbt) + { + int ret; +- struct jbt6k74_platform_data *pdata = jbt->spi->dev.platform_data; + +- ret = jbt_reg_write(jbt, JBT_REG_POWER_ON_OFF, 0x00); ++ if ( jbt->power_mode != JBT_POWER_MODE_STANDBY ) return 0; + +- if (!ret) +- ret = regulator_bulk_disable(ARRAY_SIZE(jbt->supplies), jbt->supplies); ++ /* Make sure we are 120 ms after SLEEP_{IN,OUT} */ ++ while (time_before(jiffies, jbt->next_sleep)) cpu_relax(); + +- if (!ret) +- gpio_set_value_cansleep(pdata->gpio_reset, 0); ++ ret = jbt_reg_write_nodata(jbt, JBT_REG_SLEEP_OUT); ++ jbt->next_sleep = jiffies + msecs_to_jiffies(150); + +- return ret; ++ 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) + { +- struct jbt6k74_platform_data *pdata = jbt->spi->dev.platform_data; + int ret = -EINVAL; + + dev_dbg(&jbt->spi->dev, "entering (old_state=%s, new_state=%s)\n", +@@ -375,49 +395,17 @@ static int jbt6k74_enter_power_mode(struct jbt_info *jbt, + + mutex_lock(&jbt->lock); + +- if (jbt->suspended) { +- switch (new_mode) { +- case JBT_POWER_MODE_DEEP_STANDBY: +- case JBT_POWER_MODE_SLEEP: +- case JBT_POWER_MODE_NORMAL: +- ret = 0; +- jbt->suspend_mode = new_mode; +- break; +- default: +- break; +- } +- } else if (new_mode == JBT_POWER_MODE_NORMAL && +- pdata->enable_pixel_clock) { +- pdata->enable_pixel_clock(&jbt->spi->dev, 1); +- } +- + switch (jbt->power_mode) { +- case JBT_POWER_MODE_DEEP_STANDBY: ++ case JBT_POWER_MODE_OFF: + switch (new_mode) { +- case JBT_POWER_MODE_DEEP_STANDBY: ++ case JBT_POWER_MODE_OFF: + ret = 0; + break; +- case JBT_POWER_MODE_SLEEP: +- ret = jbt_standby_to_sleep(jbt); +- break; + case JBT_POWER_MODE_NORMAL: +- /* first transition into sleep */ +- ret = jbt_standby_to_sleep(jbt); +- /* then transition into normal */ +- ret |= jbt_sleep_to_normal(jbt); ++ ret = jbt_off_to_normal(jbt); + break; +- } +- break; +- case JBT_POWER_MODE_SLEEP: +- switch (new_mode) { +- case JBT_POWER_MODE_SLEEP: +- ret = 0; +- break; +- case JBT_POWER_MODE_DEEP_STANDBY: +- ret = jbt_sleep_to_standby(jbt); +- break; +- case JBT_POWER_MODE_NORMAL: +- ret = jbt_sleep_to_normal(jbt); ++ case JBT_POWER_MODE_STANDBY: ++ ret = -EINVAL; + break; + } + break; +@@ -426,25 +414,23 @@ static int jbt6k74_enter_power_mode(struct jbt_info *jbt, + case JBT_POWER_MODE_NORMAL: + ret = 0; + break; +- case JBT_POWER_MODE_DEEP_STANDBY: +- /* first transition into sleep */ +- ret = jbt_normal_to_sleep(jbt); +- /* then transition into deep standby */ +- ret |= jbt_sleep_to_standby(jbt); ++ case JBT_POWER_MODE_OFF: ++ ret = jbt_normal_to_off(jbt); + break; +- case JBT_POWER_MODE_SLEEP: +- ret = jbt_normal_to_sleep(jbt); ++ case JBT_POWER_MODE_STANDBY: ++ ret = -EINVAL; + break; + } ++ break; ++ case JBT_POWER_MODE_STANDBY: ++ ret = -EINVAL; ++ break; + } + + if (ret == 0) { + jbt->power_mode = new_mode; +- if (new_mode != JBT_POWER_MODE_NORMAL && +- pdata->enable_pixel_clock) +- pdata->enable_pixel_clock(&jbt->spi->dev, 0); + } else { +- dev_err(&jbt->spi->dev, "Failed enter state '%s': %d\n", ++ dev_err(&jbt->spi->dev, "Failed to enter state '%s': %d\n", + jbt_power_mode_names[new_mode], ret); + } + +@@ -456,28 +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); + +- /* first transition into sleep */ +- ret = jbt_normal_to_sleep(jbt); +- ret |= jbt_sleep_to_normal(jbt); ++ 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); ++ } ++ ++ 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: +@@ -589,7 +593,7 @@ static ssize_t reset_write(struct device *dev, struct device_attribute *attr, + + mutex_unlock(&jbt->lock); + +- jbt->power_mode = JBT_POWER_MODE_DEEP_STANDBY; ++ jbt->power_mode = JBT_POWER_MODE_OFF; + jbt6k74_enter_power_mode(jbt, old_power_mode); + + return count; +@@ -616,27 +620,6 @@ static struct attribute_group jbt_attr_group = { + .attrs = jbt_sysfs_entries, + }; + +-/* FIXME: This in an ugly hack to delay display blanking. +- When the jbt is in sleep mode it displays an all white screen and thus one +- will a see a short flash. +- By delaying the blanking we will give the backlight a chance to turn off and +- thus avoid getting the flash */ +-static void jbt_blank_worker(struct work_struct *work) +-{ +- struct jbt_info *jbt = container_of(work, struct jbt_info, +- blank_work.work); +- +- switch (jbt->blank_mode) { +- case FB_BLANK_NORMAL: +- jbt6k74_enter_power_mode(jbt, JBT_POWER_MODE_SLEEP); +- break; +- case FB_BLANK_POWERDOWN: +- jbt6k74_enter_power_mode(jbt, JBT_POWER_MODE_DEEP_STANDBY); +- break; +- default: +- break; +- } +-} + + static int jbt6k74_set_mode(struct lcd_device *ld, struct fb_videomode *m) + { +@@ -649,7 +632,7 @@ static int jbt6k74_set_mode(struct lcd_device *ld, struct fb_videomode *m) + ret = jbt6k74_set_resolution(jbt, JBT_RESOLUTION_VGA); + } else { + dev_err(&jbt->spi->dev, "Unknown resolution.\n"); +- jbt6k74_enter_power_mode(jbt, JBT_POWER_MODE_SLEEP); ++ jbt6k74_enter_power_mode(jbt, JBT_POWER_MODE_OFF); + } + + return ret; +@@ -671,11 +654,11 @@ static int jbt6k74_set_power(struct lcd_device *ld, int power) + break; + case FB_BLANK_NORMAL: + dev_dbg(&jbt->spi->dev, "blank\n"); +- ret = schedule_delayed_work(&jbt->blank_work, HZ); ++ ret = jbt6k74_enter_power_mode(jbt, JBT_POWER_MODE_OFF); + break; + case FB_BLANK_POWERDOWN: + dev_dbg(&jbt->spi->dev, "powerdown\n"); +- ret = schedule_delayed_work(&jbt->blank_work, HZ); ++ ret = jbt6k74_enter_power_mode(jbt, JBT_POWER_MODE_OFF); + break; + default: + break; +@@ -691,10 +674,10 @@ static int jbt6k74_get_power(struct lcd_device *ld) + switch (jbt->power_mode) { + case JBT_POWER_MODE_NORMAL: + return FB_BLANK_UNBLANK; +- case JBT_POWER_MODE_SLEEP: ++ case JBT_POWER_MODE_OFF: + return FB_BLANK_NORMAL; + default: +- return JBT_POWER_MODE_DEEP_STANDBY; ++ return JBT_POWER_MODE_OFF; + } + } + +@@ -728,6 +711,8 @@ static int __devinit jbt_probe(struct spi_device *spi) + if (!jbt) + return -ENOMEM; + ++ jbt_global = jbt; ++ + jbt->spi = spi; + + jbt->lcd_dev = lcd_device_register("jbt6k74-lcd", &spi->dev, jbt, +@@ -738,11 +723,9 @@ static int __devinit jbt_probe(struct spi_device *spi) + goto err_free_drvdata; + } + +- INIT_DELAYED_WORK(&jbt->blank_work, jbt_blank_worker); +- + jbt->resolution = JBT_RESOLUTION_VGA; +- jbt->power_mode = JBT_POWER_MODE_DEEP_STANDBY; + jbt->next_sleep = jiffies + msecs_to_jiffies(120); ++ jbt->power_mode = JBT_POWER_MODE_OFF; + mutex_init(&jbt->lock); + + dev_set_drvdata(&spi->dev, jbt); +@@ -831,6 +814,24 @@ static int __devexit jbt_remove(struct spi_device *spi) + return 0; + } + ++/* Begin horrible layering violations in the interest of making stuff work */ ++ ++int jbt6k74_finish_resolutionchange(enum jbt_resolution new_resolution) ++{ ++ if ( !jbt_global ) return 0; ++ return jbt6k74_set_resolution(jbt_global, new_resolution); ++} ++EXPORT_SYMBOL_GPL(jbt6k74_finish_resolutionchange); ++ ++void jbt6k74_setpower(enum jbt_power_mode new_power) ++{ ++ if ( !jbt_global ) return; ++ jbt6k74_enter_power_mode(jbt_global, new_power); ++} ++EXPORT_SYMBOL_GPL(jbt6k74_setpower); ++ ++/* End horrible layering violations */ ++ + #ifdef CONFIG_PM + static int jbt_suspend(struct spi_device *spi, pm_message_t state) + { +@@ -838,8 +839,7 @@ static int jbt_suspend(struct spi_device *spi, pm_message_t state) + + jbt->suspend_mode = jbt->power_mode; + +- jbt6k74_enter_power_mode(jbt, JBT_POWER_MODE_DEEP_STANDBY); +- jbt->suspended = 1; ++ jbt6k74_enter_power_mode(jbt, JBT_POWER_MODE_OFF); + + dev_info(&spi->dev, "suspended\n"); + +diff --git a/include/linux/jbt6k74.h b/include/linux/jbt6k74.h +index 75488c4..2010bdc 100644 +--- a/include/linux/jbt6k74.h ++++ b/include/linux/jbt6k74.h +@@ -3,6 +3,22 @@ + + #include <linux/spi/spi.h> + ++enum jbt_resolution { ++ JBT_RESOLUTION_VGA, ++ JBT_RESOLUTION_QVGA, ++}; ++ ++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_prepare_resolutionchange(enum jbt_resolution new_resolution); ++extern int jbt6k74_finish_resolutionchange(enum jbt_resolution new_resolution); ++ ++ + /* + * struct jbt6k74_platform_data - Platform data for jbt6k74 driver + * @probe_completed: Callback to be called when the driver has been +@@ -13,7 +29,6 @@ + */ + struct jbt6k74_platform_data { + void (*probe_completed)(struct device *dev); +- void (*enable_pixel_clock)(struct device *dev, int enable); + + int gpio_reset; + }; +-- +1.7.1 + |