summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/configs/minnow_defconfig3
-rw-r--r--drivers/leds/leds-lm3535.c21
-rw-r--r--drivers/video/omap2/displays/panel-minnow.c187
-rw-r--r--drivers/video/omap2/dss/core.c3
-rw-r--r--drivers/video/omap2/dss/dsi.c21
-rw-r--r--kernel/power/Kconfig7
6 files changed, 125 insertions, 117 deletions
diff --git a/arch/arm/configs/minnow_defconfig b/arch/arm/configs/minnow_defconfig
index 285b69e34af..4eb092c483d 100644
--- a/arch/arm/configs/minnow_defconfig
+++ b/arch/arm/configs/minnow_defconfig
@@ -555,6 +555,7 @@ CONFIG_PM_OPP=y
CONFIG_PM_CLK=y
CONFIG_CPU_PM=y
# CONFIG_SUSPEND_TIME is not set
+CONFIG_HAS_AMBIENTMODE=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_ARM_CPU_SUSPEND=y
CONFIG_NET=y
@@ -1763,7 +1764,7 @@ CONFIG_FB_MODE_HELPERS=y
# CONFIG_FB_SIMPLE is not set
CONFIG_OMAP2_VRFB=y
CONFIG_OMAP2_DSS=y
-CONFIG_OMAP2_DSS_DEBUG=y
+# CONFIG_OMAP2_DSS_DEBUG is not set
CONFIG_OMAP2_DSS_DEBUGFS=y
# CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS is not set
# CONFIG_OMAP2_DSS_DPI is not set
diff --git a/drivers/leds/leds-lm3535.c b/drivers/leds/leds-lm3535.c
index 03915b63b5e..20dbf96c408 100644
--- a/drivers/leds/leds-lm3535.c
+++ b/drivers/leds/leds-lm3535.c
@@ -187,11 +187,12 @@ static struct early_suspend early_suspend_data = {
.suspend = lm3535_early_suspend,
.resume = lm3535_late_resume,
};
-
#endif
+#if defined(CONFIG_HAS_EARLYSUSPEND) || !defined(CONFIG_HAS_AMBIENTMODE)
static int lm3535_suspend (struct i2c_client *client, pm_message_t mesg);
static int lm3535_resume (struct i2c_client *client);
#endif
+#endif
static void (*lm3535_set_options_f)(uint8_t *buf, unsigned ramp) =
lm3535_set_options_r1;
@@ -235,7 +236,7 @@ static struct i2c_driver lm3535_driver =
.id_table = lm3535_id,
.probe = lm3535_probe,
.remove = lm3535_remove,
-#ifndef CONFIG_HAS_EARLYSUSPEND
+#if !defined(CONFIG_HAS_EARLYSUSPEND) && !defined(CONFIG_HAS_AMBIENTMODE)
.suspend = lm3535_suspend,
.resume = lm3535_resume,
#endif
@@ -499,14 +500,12 @@ static void lm3535_brightness_set (struct led_classdev *led_cdev,
bright_zone = atomic_read (&lm3535_data.bright_zone);
mutex_lock (&lm3535_mutex);
- if (value == -1) { // Special case for ALS adjustment
- value = led_cdev->brightness;
- }
-
- if ((value > 0) && (value <= 5))
- value = 0; /* Special case for G2 */
- if ((value > 5) && (value <= 10))
- value = 1; /* Special dim case for G2 */
+ if (value == -1)
+ value = led_cdev->brightness; /* Special case for ALS adjustment */
+ else if ((value > 0) && (value < 5))
+ value = 0; /* Special case for turn off */
+ else if ((value >= 5) && (value < 10))
+ value = 1; /* Special case for dim */
if ((value == 0) && (!lm3535_data.enabled)) {
/* If LED already disabled, we don't need to do anything */
@@ -1321,6 +1320,7 @@ static int lm3535_remove (struct i2c_client *client)
return 0;
}
+#if defined(CONFIG_HAS_EARLYSUSPEND) || !defined(CONFIG_HAS_AMBIENTMODE)
static int lm3535_suspend (struct i2c_client *client, pm_message_t mesg)
{
printk_suspend ("%s: called with pm message %d\n",
@@ -1363,6 +1363,7 @@ static int lm3535_resume (struct i2c_client *client)
return 0;
}
+#endif
#ifdef CONFIG_HAS_EARLYSUSPEND
static void lm3535_early_suspend (struct early_suspend *h)
diff --git a/drivers/video/omap2/displays/panel-minnow.c b/drivers/video/omap2/displays/panel-minnow.c
index ed9b9c7eea8..31c90f7faeb 100644
--- a/drivers/video/omap2/displays/panel-minnow.c
+++ b/drivers/video/omap2/displays/panel-minnow.c
@@ -408,6 +408,7 @@ struct minnow_panel_data {
/* runtime variables */
bool enabled;
+ bool interactive;
enum minnow_panel_dummy_type dummy_panel;
bool te_enabled;
@@ -494,22 +495,6 @@ exit1:
static void minnow_panel_esd_work(struct work_struct *work);
static void minnow_panel_ulps_work(struct work_struct *work);
-static void hw_guard_start(struct minnow_panel_data *mpd, int guard_msec)
-{
- mpd->hw_guard_wait = msecs_to_jiffies(guard_msec);
- mpd->hw_guard_end = jiffies + mpd->hw_guard_wait;
-}
-
-static void hw_guard_wait(struct minnow_panel_data *mpd)
-{
- unsigned long wait = mpd->hw_guard_end - jiffies;
-
- if ((long)wait > 0 && wait <= mpd->hw_guard_wait) {
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(wait);
- }
-}
-
static int set_bridge_retrans(struct minnow_panel_data *mpd, int enable)
{
u8 data[2] = {0xFF, enable ? 0x01 : 0x00};
@@ -545,33 +530,6 @@ static int minnow_panel_dcs_write_1(struct minnow_panel_data *mpd, u8 dcs_cmd, u
return dsi_vc_dcs_write(mpd->dssdev, mpd->channel, buf, 2);
}
-static int minnow_panel_sleep_out(struct minnow_panel_data *mpd)
-{
- int r;
-
- hw_guard_wait(mpd);
-
- r = minnow_panel_dcs_write_0(mpd, MIPI_DCS_EXIT_SLEEP_MODE);
- if (r)
- return r;
- if (mpd->id_panel == MINNOW_PANEL_CM_BRIDGE_320X320) {
- r = set_bridge_retrans(mpd, true);
- if (!r) {
- r = minnow_panel_dcs_write_0(mpd,
- MIPI_DCS_EXIT_SLEEP_MODE);
- set_bridge_retrans(mpd, false);
- }
- if (r)
- return r;
- }
-
- hw_guard_start(mpd, 120);
-
- msleep(10);
-
- return 0;
-}
-
static int minnow_panel_get_bridge_rev(struct minnow_panel_data *mpd,
u8 *id1, u8 *id2, u8 *id3)
{
@@ -976,11 +934,12 @@ static int minnow_panel_enter_ulps(struct omap_dss_device *dssdev)
omapdss_dsi_display_disable(dssdev, false, true);
mpd->ulps_enabled = true;
+ dev_info(&dssdev->dev, "entered ULPS mode\n");
return 0;
err:
- dev_err(&dssdev->dev, "enter ULPS failed");
+ dev_err(&dssdev->dev, "enter ULPS failed\n");
minnow_panel_reset(dssdev);
mpd->ulps_enabled = false;
@@ -1019,10 +978,12 @@ static int minnow_panel_exit_ulps(struct omap_dss_device *dssdev)
mpd->ulps_enabled = false;
+ dev_info(&dssdev->dev, "exited ULPS mode\n");
+
return 0;
err2:
- dev_err(&dssdev->dev, "failed to exit ULPS");
+ dev_err(&dssdev->dev, "failed to exit ULPS\n");
r = minnow_panel_reset(dssdev);
if (!r) {
@@ -1384,6 +1345,7 @@ static ssize_t minnow_panel_show_ulps_timeout(struct device *dev,
return snprintf(buf, PAGE_SIZE, "%u\n", t);
}
+#ifdef DEBUG
static ssize_t minnow_panel_store_init_data(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
@@ -1440,6 +1402,56 @@ static ssize_t minnow_panel_show_init_data(struct device *dev,
return i < PAGE_SIZE ? i : PAGE_SIZE;
}
+#endif
+
+static ssize_t minnow_panel_show_interactivemode(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct omap_dss_device *dssdev = to_dss_device(dev);
+ struct minnow_panel_data *mpd = dev_get_drvdata(&dssdev->dev);
+ unsigned t;
+
+ mutex_lock(&mpd->lock);
+ t = mpd->interactive;
+ mutex_unlock(&mpd->lock);
+
+ return snprintf(buf, PAGE_SIZE, "%u\n", t);
+}
+
+static ssize_t minnow_panel_store_interactivemode(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct omap_dss_device *dssdev = to_dss_device(dev);
+ struct minnow_panel_data *mpd = dev_get_drvdata(&dssdev->dev);
+ unsigned long t;
+ int r;
+
+ r = strict_strtoul(buf, 10, &t);
+ if (!r) {
+ bool enable = !!t;
+ /* Temporary force DSI goto ULPS mode when interactive mode
+ * turns OFF, it will add support to switch bridge/panel to
+ * low refresh mode later
+ */
+ mutex_lock(&mpd->lock);
+ if (mpd->enabled && (mpd->interactive != enable)) {
+ mpd->interactive = enable;
+ dsi_bus_lock(dssdev);
+ if (enable)
+ r = minnow_panel_wake_up(dssdev);
+ else
+ r = minnow_panel_enter_ulps(dssdev);
+ dsi_bus_unlock(dssdev);
+ }
+ mutex_unlock(&mpd->lock);
+ dev_info(&dssdev->dev, "%s interactive mode%s\n",
+ enable ? "enable" : "disable", r ? " failed" : "");
+ }
+
+ return r ? r : count;
+}
static DEVICE_ATTR(num_dsi_errors, S_IRUGO, minnow_panel_num_errors_show, NULL);
static DEVICE_ATTR(hw_revision, S_IRUGO, minnow_panel_hw_revision_show, NULL);
@@ -1453,8 +1465,12 @@ static DEVICE_ATTR(ulps, S_IRUGO | S_IWUSR,
minnow_panel_show_ulps, minnow_panel_store_ulps);
static DEVICE_ATTR(ulps_timeout, S_IRUGO | S_IWUSR,
minnow_panel_show_ulps_timeout, minnow_panel_store_ulps_timeout);
+#ifdef DEBUG
static DEVICE_ATTR(init_data, S_IRUGO | S_IWUSR,
minnow_panel_show_init_data, minnow_panel_store_init_data);
+#endif
+static DEVICE_ATTR(interactivemode, S_IRUGO | S_IWUSR,
+ minnow_panel_show_interactivemode, minnow_panel_store_interactivemode);
static struct attribute *minnow_panel_attrs[] = {
&dev_attr_num_dsi_errors.attr,
@@ -1464,7 +1480,10 @@ static struct attribute *minnow_panel_attrs[] = {
&dev_attr_esd_interval.attr,
&dev_attr_ulps.attr,
&dev_attr_ulps_timeout.attr,
+#ifdef DEBUG
&dev_attr_init_data.attr,
+#endif
+ &dev_attr_interactivemode.attr,
NULL,
};
@@ -1645,7 +1664,8 @@ static int minnow_panel_dt_init(struct minnow_panel_data *mpd)
mpd->esd_interval = value;
DTINFO("esd_interval = %d\n", mpd->esd_interval);
}
- mpd->ulps_timeout = 0;
+ /* automatically go to ULPS mode for none-update within 250ms */
+ mpd->ulps_timeout = 250;
mpd->use_dsi_backlight = false;
mpd->pin_config.num_pins = 4;
@@ -1989,23 +2009,17 @@ init_start:
/* for the first time power on, do not reset h/w to keep logo on */
if (mpd->first_enable && def_skip_first_init) {
dsi_vc_send_bta_sync(dssdev, mpd->channel);
- retry = 0;
- } else
+ } else {
_minnow_panel_hw_reset(dssdev);
- while (retry--) {
r = minnow_panel_process_cmdbuf(mpd, &mpd->power_on);
if (!r) {
if (mpd->dummy_panel == DUMMY_DISABLED)
r = minnow_panel_check_panel_status(mpd);
- if (!r)
- break;
}
- if (!retry)
- goto err;
- dev_err(&dssdev->dev, "Reset hardware to retry ...\n");
- _minnow_panel_hw_reset(dssdev);
- /* for dummy panel, it needs reset DSI */
- if (mpd->dummy_panel == DUMMY_ENABLED) {
+ if (r) {
+ if (!retry--)
+ goto err;
+ dev_err(&dssdev->dev, "Reset hardware to retry ...\n");
omapdss_dsi_display_disable(dssdev, true, false);
goto init_start;
}
@@ -2033,7 +2047,8 @@ init_start:
if (r)
goto err;
- mpd->enabled = 1;
+ mpd->enabled = true;
+ mpd->interactive = true;
if (mpd->first_enable)
dev_info(&dssdev->dev, "panel revision %02x.%02x.%02x\n",
@@ -2064,7 +2079,8 @@ static void minnow_panel_power_off(struct omap_dss_device *dssdev)
omapdss_dsi_display_disable(dssdev, true, false);
- mpd->enabled = 0;
+ mpd->enabled = false;
+ mpd->interactive = false;
}
static int minnow_panel_reset(struct omap_dss_device *dssdev)
@@ -2211,25 +2227,23 @@ static int minnow_panel_update(struct omap_dss_device *dssdev,
u16 x, u16 y, u16 w, u16 h)
{
struct minnow_panel_data *mpd = dev_get_drvdata(&dssdev->dev);
- int r;
+ int r = 0;
/* for video mode, do not need manual update */
if (mpd->dsi_config.mode == OMAP_DSS_DSI_VIDEO_MODE)
- return 0;
+ return r;
dev_dbg(&dssdev->dev, "update %d, %d, %d x %d\n", x, y, w, h);
mutex_lock(&mpd->lock);
dsi_bus_lock(dssdev);
- r = minnow_panel_wake_up(dssdev);
- if (r)
+ if (!mpd->enabled)
goto err;
- if (!mpd->enabled) {
- r = 0;
+ r = minnow_panel_wake_up(dssdev);
+ if (r)
goto err;
- }
/* XXX no need to send this every frame, but dsi break if not done */
r = minnow_panel_set_update_window(mpd, 0, 0,
@@ -2471,7 +2485,6 @@ static void minnow_panel_esd_work(struct work_struct *work)
struct minnow_panel_data *mpd = container_of(work, struct minnow_panel_data,
esd_work.work);
struct omap_dss_device *dssdev = mpd->dssdev;
- u8 state1, state2;
int r;
mutex_lock(&mpd->lock);
@@ -2489,57 +2502,29 @@ static void minnow_panel_esd_work(struct work_struct *work)
goto err;
}
- r = minnow_panel_dcs_read_1(mpd, MIPI_DCS_GET_DIAGNOSTIC_RESULT, &state1);
- if (r) {
- dev_err(&dssdev->dev, "failed to read minnow-panel status\n");
- goto err;
- }
-
- /* Run self diagnostics */
- r = minnow_panel_sleep_out(mpd);
- if (r) {
- dev_err(&dssdev->dev, "failed to run minnow-panel self-diagnostics\n");
- goto err;
- }
-
- r = minnow_panel_dcs_read_1(mpd, MIPI_DCS_GET_DIAGNOSTIC_RESULT, &state2);
+ r = minnow_panel_check_panel_status(mpd);
if (r) {
dev_err(&dssdev->dev, "failed to read minnow-panel status\n");
goto err;
}
- /* Each sleep out command will trigger a self diagnostic and flip
- * Bit6 if the test passes.
- */
- if (!((state1 ^ state2) & (1 << 6))) {
- dev_err(&dssdev->dev, "LCD self diagnostics failed\n");
- goto err;
- }
- /* Self-diagnostics result is also shown on TE GPIO line. We need
- * to re-enable TE after self diagnostics */
- if (mpd->te_enabled && gpio_is_valid(mpd->ext_te_gpio)) {
- r = minnow_panel_dcs_write_1(mpd, MIPI_DCS_SET_TEAR_ON, 0);
- if (r)
- goto err;
- }
+ if (!mpd->interactive)
+ minnow_panel_enter_ulps(dssdev);
dsi_bus_unlock(dssdev);
minnow_panel_queue_esd_work(dssdev);
-
mutex_unlock(&mpd->lock);
return;
err:
dev_err(&dssdev->dev, "performing LCD reset\n");
- minnow_panel_reset(dssdev);
-
dsi_bus_unlock(dssdev);
-
- minnow_panel_queue_esd_work(dssdev);
-
mutex_unlock(&mpd->lock);
+
+ minnow_panel_disable(dssdev);
+ minnow_panel_enable(dssdev);
}
static struct omap_dss_driver minnow_panel_driver = {
diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c
index e08d71fef88..fc053fe1991 100644
--- a/drivers/video/omap2/dss/core.c
+++ b/drivers/video/omap2/dss/core.c
@@ -216,6 +216,7 @@ static int omap_dss_pm_notif(struct notifier_block *b, unsigned long v, void *d)
DSSDBG("pm notif %lu\n", v);
switch (v) {
+#if !defined(CONFIG_HAS_AMBIENTMODE)
case PM_SUSPEND_PREPARE:
DSSDBG("suspending displays\n");
return dss_suspend_all_devices();
@@ -223,7 +224,7 @@ static int omap_dss_pm_notif(struct notifier_block *b, unsigned long v, void *d)
case PM_POST_SUSPEND:
DSSDBG("resuming displays\n");
return dss_resume_all_devices();
-
+#endif
default:
return 0;
}
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 69b44185ed1..e2a0260a298 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -4570,6 +4570,22 @@ static void dsi_display_uninit_dsi(struct platform_device *dsidev,
dsi_pll_uninit(dsidev, disconnect_lanes);
}
+static int dsi_soft_reset(struct platform_device *dsidev)
+{
+ int i = 5;
+ /* enable DSI soft reset */
+ REG_FLD_MOD(dsidev, DSI_SYSCONFIG, 1, 1, 1);
+ /* waiting for DSI soft reset done*/
+ while (REG_GET(dsidev, DSI_SYSSTATUS, 0, 0) == 0) {
+ if (!i--) {
+ DSSERR("DSI soft reset failed!\n");
+ return -ENODEV;
+ }
+ udelay(1);
+ }
+ return 0;
+}
+
int omapdss_dsi_display_enable(struct omap_dss_device *dssdev)
{
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
@@ -4594,10 +4610,7 @@ int omapdss_dsi_display_enable(struct omap_dss_device *dssdev)
dsi_enable_pll_clock(dsidev, 1);
-#ifndef CONFIG_OMAP2_DSS_RESET
- dsi_vc_enable(dsidev, 0, 0);
- dsi_vc_enable(dsidev, 1, 0);
-#endif
+ dsi_soft_reset(dsidev);
_dsi_initialize_irq(dsidev);
diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
index f8cc6c43efe..361341b6069 100644
--- a/kernel/power/Kconfig
+++ b/kernel/power/Kconfig
@@ -289,3 +289,10 @@ config SUSPEND_TIME
Prints the time spent in suspend in the kernel log, and
keeps statistics on the time spent in suspend in
/sys/kernel/debug/suspend_time
+
+config HAS_AMBIENTMODE
+ def_bool y
+ depends on PM
+ ---help---
+ Ambient mode should not turn off/on display/back-light/etc.
+ at suspend/resume time