diff options
Diffstat (limited to 'drivers/video/display/jbt6k74.c')
-rw-r--r-- | drivers/video/display/jbt6k74.c | 136 |
1 files changed, 61 insertions, 75 deletions
diff --git a/drivers/video/display/jbt6k74.c b/drivers/video/display/jbt6k74.c index 5d7a6519de9..0307ed5318f 100644 --- a/drivers/video/display/jbt6k74.c +++ b/drivers/video/display/jbt6k74.c @@ -31,7 +31,6 @@ #include <linux/delay.h> #include <linux/jbt6k74.h> #include <linux/fb.h> -#include <linux/time.h> enum jbt_register { JBT_REG_SLEEP_IN = 0x10, @@ -118,18 +117,12 @@ struct jbt_info { struct notifier_block fb_notif; u16 tx_buf[8]; u16 reg_cache[0xEE]; - struct timespec last_sleep; + int have_resumed; }; #define JBT_COMMAND 0x000 #define JBT_DATA 0x100 -static inline unsigned int timespec_sub_ms(struct timespec lhs, - struct timespec rhs) -{ - struct timespec ts = timespec_sub(lhs, rhs); - return (ts.tv_sec * MSEC_PER_SEC) + (ts.tv_nsec / NSEC_PER_MSEC); -} static int jbt_reg_write_nodata(struct jbt_info *jbt, u8 reg) { @@ -186,7 +179,7 @@ static int jbt_init_regs(struct jbt_info *jbt) { int rc; - dev_dbg(&jbt->spi_dev->dev, "entering %cVGA mode\n", + dev_dbg(&jbt->spi_dev->dev, "entering %cVGA mode\n", jbt->normal_state == JBT_STATE_QVGA_NORMAL ? 'Q' : ' '); rc = jbt_reg_write(jbt, JBT_REG_DISPLAY_MODE1, 0x01); @@ -275,25 +268,36 @@ static int sleep_to_normal(struct jbt_info *jbt) { int rc; - /* Make sure we are 120 ms after SLEEP_OUT */ - unsigned int sleep_time = timespec_sub_ms(current_kernel_time(), - jbt->last_sleep); - if (sleep_time < 120) - mdelay(120 - sleep_time); + /* RGB I/F on, RAM wirte off, QVGA through, SIGCON enable */ + rc = jbt_reg_write(jbt, JBT_REG_DISPLAY_MODE, 0x80); - if (jbt->normal_state == JBT_STATE_NORMAL) { - /* RGB I/F on, RAM wirte off, QVGA through, SIGCON enable */ - rc = jbt_reg_write(jbt, JBT_REG_DISPLAY_MODE, 0x80); + /* Quad mode off */ + rc |= jbt_reg_write(jbt, JBT_REG_QUAD_RATE, 0x00); - /* Quad mode off */ - rc |= jbt_reg_write(jbt, JBT_REG_QUAD_RATE, 0x00); - } else { - /* RGB I/F on, RAM wirte off, QVGA through, SIGCON enable */ - rc = jbt_reg_write(jbt, JBT_REG_DISPLAY_MODE, 0x81); + /* AVDD on, XVDD on */ + rc |= jbt_reg_write(jbt, JBT_REG_POWER_ON_OFF, 0x16); - /* Quad mode on */ - rc |= jbt_reg_write(jbt, JBT_REG_QUAD_RATE, 0x22); - } + /* Output control */ + rc |= jbt_reg_write16(jbt, JBT_REG_OUTPUT_CONTROL, 0xfff9); + + /* Turn on display */ + rc |= jbt_reg_write_nodata(jbt, JBT_REG_DISPLAY_ON); + + /* Sleep mode off */ + rc |= jbt_reg_write_nodata(jbt, JBT_REG_SLEEP_OUT); + + return rc ? -EIO : 0; +} + +static int sleep_to_qvga_normal(struct jbt_info *jbt) +{ + int rc; + + /* RGB I/F on, RAM wirte off, QVGA through, SIGCON enable */ + rc = jbt_reg_write(jbt, JBT_REG_DISPLAY_MODE, 0x81); + + /* Quad mode on */ + rc |= jbt_reg_write(jbt, JBT_REG_QUAD_RATE, 0x22); /* AVDD on, XVDD on */ rc |= jbt_reg_write(jbt, JBT_REG_POWER_ON_OFF, 0x16); @@ -306,10 +310,6 @@ static int sleep_to_normal(struct jbt_info *jbt) /* Sleep mode off */ rc |= jbt_reg_write_nodata(jbt, JBT_REG_SLEEP_OUT); - jbt->last_sleep = current_kernel_time(); - - /* Allow the booster and display controller to restart stably */ - mdelay(5); return rc ? -EIO : 0; } @@ -318,19 +318,9 @@ static int normal_to_sleep(struct jbt_info *jbt) { int rc; - /* Make sure we are 120 ms after SLEEP_OUT */ - unsigned int sleep_time = timespec_sub_ms(current_kernel_time(), - jbt->last_sleep); - if (sleep_time < 120) - mdelay(120 - sleep_time); - 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); - jbt->last_sleep = current_kernel_time(); - - /* Allow the internal circuits to stop automatically */ - mdelay(5); return rc ? -EIO : 0; } @@ -345,9 +335,8 @@ int jbt6k74_enter_state(struct jbt_info *jbt, enum jbt_state new_state) { int rc = -EINVAL; - dev_dbg(&jbt->spi_dev->dev, "entering (old_state=%s, new_state=%s)\n", - jbt_state_names[jbt->state], - jbt_state_names[new_state]); + dev_dbg(&jbt->spi_dev->dev, "entering (old_state=%s, " + "new_state=%s)\n", jbt_state_names[jbt->state], jbt_state_names[new_state]); mutex_lock(&jbt->lock); @@ -374,7 +363,7 @@ int jbt6k74_enter_state(struct jbt_info *jbt, enum jbt_state new_state) /* first transition into sleep */ rc = standby_to_sleep(jbt); /* then transition into normal */ - rc |= sleep_to_normal(jbt); + rc |= sleep_to_qvga_normal(jbt); break; } break; @@ -387,9 +376,11 @@ int jbt6k74_enter_state(struct jbt_info *jbt, enum jbt_state new_state) rc = sleep_to_standby(jbt); break; case JBT_STATE_NORMAL: - case JBT_STATE_QVGA_NORMAL: rc = sleep_to_normal(jbt); break; + case JBT_STATE_QVGA_NORMAL: + rc = sleep_to_qvga_normal(jbt); + break; } break; case JBT_STATE_NORMAL: @@ -414,7 +405,7 @@ int jbt6k74_enter_state(struct jbt_info *jbt, enum jbt_state new_state) /* third transition into sleep */ rc |= standby_to_sleep(jbt); /* fourth transition into normal */ - rc |= sleep_to_normal(jbt); + rc |= sleep_to_qvga_normal(jbt); break; } break; @@ -445,13 +436,12 @@ int jbt6k74_enter_state(struct jbt_info *jbt, enum jbt_state new_state) } break; } - + if (rc == 0) jbt->state = new_state; else - dev_err(&jbt->spi_dev->dev, "Failed enter state '%s')\n", - jbt_state_names[new_state]); - + dev_err(&jbt->spi_dev->dev, "Failed enter state '%s')\n", jbt_state_names[new_state]); + mutex_unlock(&jbt->lock); return rc; @@ -535,27 +525,18 @@ static ssize_t gamma_write(struct device *dev, struct device_attribute *attr, static ssize_t reset_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - int rc; struct jbt_info *jbt = dev_get_drvdata(dev); - struct jbt6k74_platform_data *pdata = jbt->spi_dev->dev.platform_data; + struct jbt6k74_platform_data *jbt6k74_pdata = jbt->spi_dev->dev.platform_data; dev_info(dev, "reset\n"); - mutex_lock(&jbt->lock); - - jbt->state = JBT_STATE_DEEP_STANDBY; + jbt6k74_enter_state(jbt, JBT_STATE_DEEP_STANDBY); /* hard reset the jbt6k74 */ - (pdata->reset)(0, 0); + mutex_lock(&jbt->lock); + (jbt6k74_pdata->reset)(0, 0); mdelay(1); - (pdata->reset)(0, 1); - mdelay(120); - - rc = jbt_reg_write_nodata(jbt, 0x01); - if (rc < 0) - dev_err(&jbt->spi_dev->dev, "cannot soft reset\n"); - mdelay(120); - + (jbt6k74_pdata->reset)(0, 1); mutex_unlock(&jbt->lock); jbt6k74_enter_state(jbt, jbt->normal_state); @@ -599,22 +580,26 @@ static int fb_notifier_callback(struct notifier_block *self, return 0; fb_blank = *(int *)evdata->data; + switch (fb_blank) { case FB_BLANK_UNBLANK: - dev_dbg(&jbt->spi_dev->dev, "unblank\n"); + dev_info(&jbt->spi_dev->dev, "**** jbt6k74 unblank\n"); jbt6k74_enter_state(jbt, jbt->normal_state); break; case FB_BLANK_NORMAL: - dev_dbg(&jbt->spi_dev->dev, "blank\n"); + dev_info(&jbt->spi_dev->dev, "**** jbt6k74 normal\n"); break; case FB_BLANK_VSYNC_SUSPEND: - dev_dbg(&jbt->spi_dev->dev, "vsync suspend\n"); + dev_info(&jbt->spi_dev->dev, "**** jbt6k74 vsync suspend\n"); break; case FB_BLANK_HSYNC_SUSPEND: - dev_dbg(&jbt->spi_dev->dev, "hsync suspend\n"); + dev_info(&jbt->spi_dev->dev, "**** jbt6k74 hsync suspend\n"); break; case FB_BLANK_POWERDOWN: - dev_dbg(&jbt->spi_dev->dev, "powerdown\n"); + dev_info(&jbt->spi_dev->dev, "**** jbt6k74 powerdown\n"); + /* FIXME DEEP STANDBY wihtout suspend causes WSOD at cold + * temperature on certain devices. */ + /*jbt6k74_enter_state(jbt, JBT_STATE_DEEP_STANDBY);*/ jbt6k74_enter_state(jbt, JBT_STATE_SLEEP); break; } @@ -628,7 +613,7 @@ static int __devinit jbt_probe(struct spi_device *spi) { int rc; struct jbt_info *jbt; - struct jbt6k74_platform_data *pdata = spi->dev.platform_data; + struct jbt6k74_platform_data *jbt6k74_pdata = spi->dev.platform_data; /* the controller doesn't have a MISO pin; we can't do detection */ @@ -649,7 +634,6 @@ static int __devinit jbt_probe(struct spi_device *spi) jbt->spi_dev = spi; jbt->normal_state = JBT_STATE_NORMAL; jbt->state = JBT_STATE_DEEP_STANDBY; - jbt->last_sleep = current_kernel_time(); mutex_init(&jbt->lock); dev_set_drvdata(&spi->dev, jbt); @@ -673,8 +657,8 @@ static int __devinit jbt_probe(struct spi_device *spi) goto err_sysfs; } - if (pdata->probe_completed) - (pdata->probe_completed)(&spi->dev); + if (jbt6k74_pdata->probe_completed) + (jbt6k74_pdata->probe_completed)(&spi->dev); return 0; @@ -712,6 +696,8 @@ static int jbt_suspend(struct spi_device *spi, pm_message_t state) jbt6k74_enter_state(jbt, JBT_STATE_DEEP_STANDBY); + jbt->have_resumed = 0; + dev_info(&spi->dev, "suspended\n"); return 0; @@ -720,12 +706,12 @@ static int jbt_suspend(struct spi_device *spi, pm_message_t state) int jbt6k74_resume(struct spi_device *spi) { struct jbt_info *jbt = dev_get_drvdata(&spi->dev); - struct jbt6k74_platform_data *pdata = spi->dev.platform_data; + struct jbt6k74_platform_data *jbt6k74_pdata = spi->dev.platform_data; jbt6k74_enter_state(jbt, jbt->normal_state); - if (pdata->resuming) - (pdata->resuming)(0); + if (jbt6k74_pdata->resuming) + (jbt6k74_pdata->resuming)(0); dev_info(&spi->dev, "resumed\n"); |