diff options
Diffstat (limited to 'meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.35-OMAP-DSS2-Add-ACX565AKM-Panel-Driver.patch')
-rw-r--r-- | meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.35-OMAP-DSS2-Add-ACX565AKM-Panel-Driver.patch | 813 |
1 files changed, 0 insertions, 813 deletions
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.35-OMAP-DSS2-Add-ACX565AKM-Panel-Driver.patch b/meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.35-OMAP-DSS2-Add-ACX565AKM-Panel-Driver.patch deleted file mode 100644 index 0b3b50129..000000000 --- a/meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.35-OMAP-DSS2-Add-ACX565AKM-Panel-Driver.patch +++ /dev/null @@ -1,813 +0,0 @@ -From 635f44cfde6c057a2ecbb8c9d9a67225e53b6545 Mon Sep 17 00:00:00 2001 -From: Roger Quadros <roger.quadros@nokia.com> -Date: Wed, 10 Mar 2010 17:32:44 +0200 -Subject: [PATCH 3/10] OMAP: DSS2: Add ACX565AKM Panel Driver - -From: Roger Quadros <roger.quadros@nokia.com> - -Patch-mainline: 2.6.35? -Git-repo: http://www.gitorious.org/linux-omap-dss2/linux/commit/4f2308f3be2fe631412ea85a80c91414c3bfe730 - -This is the panel used on Nokia N900 - -Signed-off-by: Roger Quadros <roger.quadros@nokia.com> ---- - drivers/video/omap2/displays/Kconfig | 6 + - drivers/video/omap2/displays/Makefile | 1 + - drivers/video/omap2/displays/panel-acx565akm.c | 760 ++++++++++++++++++++++++ - 3 files changed, 767 insertions(+), 0 deletions(-) - create mode 100644 drivers/video/omap2/displays/panel-acx565akm.c - -diff --git a/drivers/video/omap2/displays/Kconfig b/drivers/video/omap2/displays/Kconfig -index b12a59c..1f5b7d1 100644 ---- a/drivers/video/omap2/displays/Kconfig -+++ b/drivers/video/omap2/displays/Kconfig -@@ -19,4 +19,10 @@ config PANEL_TAAL - help - Taal DSI command mode panel from TPO. - -+config PANEL_ACX565AKM -+ tristate "ACX565AKM Panel" -+ depends on OMAP2_DSS_SDI -+ select BACKLIGHT_CLASS_DEVICE -+ help -+ This is the LCD panel used on Nokia N900 - endmenu -diff --git a/drivers/video/omap2/displays/Makefile b/drivers/video/omap2/displays/Makefile -index 9556464..0af16b7 100644 ---- a/drivers/video/omap2/displays/Makefile -+++ b/drivers/video/omap2/displays/Makefile -@@ -2,3 +2,4 @@ obj-$(CONFIG_PANEL_GENERIC) += panel-generic.o - obj-$(CONFIG_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o - - obj-$(CONFIG_PANEL_TAAL) += panel-taal.o -+obj-$(CONFIG_PANEL_ACX565AKM) += panel-acx565akm.o -diff --git a/drivers/video/omap2/displays/panel-acx565akm.c b/drivers/video/omap2/displays/panel-acx565akm.c -new file mode 100644 -index 0000000..27e9847 ---- /dev/null -+++ b/drivers/video/omap2/displays/panel-acx565akm.c -@@ -0,0 +1,760 @@ -+/* -+ * Support for ACX565AKM LCD Panel used on Nokia N900 -+ * -+ * Copyright (C) 2010 Nokia Corporation -+ * -+ * Original Driver Author: Imre Deak <imre.deak@nokia.com> -+ * Based on panel-generic.c by Tomi Valkeinen <tomi.valkeinen@nokia.com> -+ * Adapted to new DSS2 framework: Roger Quadros <roger.quadros@nokia.com> -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published by -+ * the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see <http://www.gnu.org/licenses/>. -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/platform_device.h> -+#include <linux/delay.h> -+#include <linux/spi/spi.h> -+#include <linux/jiffies.h> -+#include <linux/sched.h> -+#include <linux/backlight.h> -+#include <linux/fb.h> -+ -+#include <plat/display.h> -+ -+#define MIPID_CMD_READ_DISP_ID 0x04 -+#define MIPID_CMD_READ_RED 0x06 -+#define MIPID_CMD_READ_GREEN 0x07 -+#define MIPID_CMD_READ_BLUE 0x08 -+#define MIPID_CMD_READ_DISP_STATUS 0x09 -+#define MIPID_CMD_RDDSDR 0x0F -+#define MIPID_CMD_SLEEP_IN 0x10 -+#define MIPID_CMD_SLEEP_OUT 0x11 -+#define MIPID_CMD_DISP_OFF 0x28 -+#define MIPID_CMD_DISP_ON 0x29 -+#define MIPID_CMD_WRITE_DISP_BRIGHTNESS 0x51 -+#define MIPID_CMD_READ_DISP_BRIGHTNESS 0x52 -+#define MIPID_CMD_WRITE_CTRL_DISP 0x53 -+ -+#define CTRL_DISP_BRIGHTNESS_CTRL_ON (1 << 5) -+#define CTRL_DISP_AMBIENT_LIGHT_CTRL_ON (1 << 4) -+#define CTRL_DISP_BACKLIGHT_ON (1 << 2) -+#define CTRL_DISP_AUTO_BRIGHTNESS_ON (1 << 1) -+ -+#define MIPID_CMD_READ_CTRL_DISP 0x54 -+#define MIPID_CMD_WRITE_CABC 0x55 -+#define MIPID_CMD_READ_CABC 0x56 -+ -+#define MIPID_VER_LPH8923 3 -+#define MIPID_VER_LS041Y3 4 -+#define MIPID_VER_L4F00311 8 -+#define MIPID_VER_ACX565AKM 9 -+ -+struct acx565akm_device { -+ char *name; -+ int enabled; -+ int model; -+ int revision; -+ u8 display_id[3]; -+ unsigned has_bc:1; -+ unsigned has_cabc:1; -+ unsigned cabc_mode; -+ unsigned long hw_guard_end; /* next value of jiffies -+ when we can issue the -+ next sleep in/out command */ -+ unsigned long hw_guard_wait; /* max guard time in jiffies */ -+ -+ struct spi_device *spi; -+ struct mutex mutex; -+ -+ struct omap_dss_device *dssdev; -+ struct backlight_device *bl_dev; -+}; -+ -+static struct acx565akm_device acx_dev; -+static int acx565akm_bl_update_status(struct backlight_device *dev); -+ -+/*--------------------MIPID interface-----------------------------*/ -+ -+static void acx565akm_transfer(struct acx565akm_device *md, int cmd, -+ const u8 *wbuf, int wlen, u8 *rbuf, int rlen) -+{ -+ struct spi_message m; -+ struct spi_transfer *x, xfer[5]; -+ int r; -+ -+ BUG_ON(md->spi == NULL); -+ -+ spi_message_init(&m); -+ -+ memset(xfer, 0, sizeof(xfer)); -+ x = &xfer[0]; -+ -+ cmd &= 0xff; -+ x->tx_buf = &cmd; -+ x->bits_per_word = 9; -+ x->len = 2; -+ -+ if (rlen > 1 && wlen == 0) { -+ /* -+ * Between the command and the response data there is a -+ * dummy clock cycle. Add an extra bit after the command -+ * word to account for this. -+ */ -+ x->bits_per_word = 10; -+ cmd <<= 1; -+ } -+ spi_message_add_tail(x, &m); -+ -+ if (wlen) { -+ x++; -+ x->tx_buf = wbuf; -+ x->len = wlen; -+ x->bits_per_word = 9; -+ spi_message_add_tail(x, &m); -+ } -+ -+ if (rlen) { -+ x++; -+ x->rx_buf = rbuf; -+ x->len = rlen; -+ spi_message_add_tail(x, &m); -+ } -+ -+ r = spi_sync(md->spi, &m); -+ if (r < 0) -+ dev_dbg(&md->spi->dev, "spi_sync %d\n", r); -+} -+ -+static inline void acx565akm_cmd(struct acx565akm_device *md, int cmd) -+{ -+ acx565akm_transfer(md, cmd, NULL, 0, NULL, 0); -+} -+ -+static inline void acx565akm_write(struct acx565akm_device *md, -+ int reg, const u8 *buf, int len) -+{ -+ acx565akm_transfer(md, reg, buf, len, NULL, 0); -+} -+ -+static inline void acx565akm_read(struct acx565akm_device *md, -+ int reg, u8 *buf, int len) -+{ -+ acx565akm_transfer(md, reg, NULL, 0, buf, len); -+} -+ -+static void hw_guard_start(struct acx565akm_device *md, int guard_msec) -+{ -+ md->hw_guard_wait = msecs_to_jiffies(guard_msec); -+ md->hw_guard_end = jiffies + md->hw_guard_wait; -+} -+ -+static void hw_guard_wait(struct acx565akm_device *md) -+{ -+ unsigned long wait = md->hw_guard_end - jiffies; -+ -+ if ((long)wait > 0 && wait <= md->hw_guard_wait) { -+ set_current_state(TASK_UNINTERRUPTIBLE); -+ schedule_timeout(wait); -+ } -+} -+ -+/*----------------------MIPID wrappers----------------------------*/ -+ -+static void set_sleep_mode(struct acx565akm_device *md, int on) -+{ -+ int cmd; -+ -+ if (on) -+ cmd = MIPID_CMD_SLEEP_IN; -+ else -+ cmd = MIPID_CMD_SLEEP_OUT; -+ /* -+ * We have to keep 120msec between sleep in/out commands. -+ * (8.2.15, 8.2.16). -+ */ -+ hw_guard_wait(md); -+ acx565akm_cmd(md, cmd); -+ hw_guard_start(md, 120); -+} -+ -+static void set_display_state(struct acx565akm_device *md, int enabled) -+{ -+ int cmd = enabled ? MIPID_CMD_DISP_ON : MIPID_CMD_DISP_OFF; -+ -+ acx565akm_cmd(md, cmd); -+} -+ -+static int panel_enabled(struct acx565akm_device *md) -+{ -+ u32 disp_status; -+ int enabled; -+ -+ acx565akm_read(md, MIPID_CMD_READ_DISP_STATUS, (u8 *)&disp_status, 4); -+ disp_status = __be32_to_cpu(disp_status); -+ enabled = (disp_status & (1 << 17)) && (disp_status & (1 << 10)); -+ dev_dbg(&md->spi->dev, -+ "LCD panel %senabled by bootloader (status 0x%04x)\n", -+ enabled ? "" : "not ", disp_status); -+ return enabled; -+} -+ -+static int panel_detect(struct acx565akm_device *md) -+{ -+ acx565akm_read(md, MIPID_CMD_READ_DISP_ID, md->display_id, 3); -+ dev_dbg(&md->spi->dev, "MIPI display ID: %02x%02x%02x\n", -+ md->display_id[0], md->display_id[1], md->display_id[2]); -+ -+ switch (md->display_id[0]) { -+ case 0x10: -+ md->model = MIPID_VER_ACX565AKM; -+ md->name = "acx565akm"; -+ md->has_bc = 1; -+ md->has_cabc = 1; -+ break; -+ case 0x29: -+ md->model = MIPID_VER_L4F00311; -+ md->name = "l4f00311"; -+ break; -+ case 0x45: -+ md->model = MIPID_VER_LPH8923; -+ md->name = "lph8923"; -+ break; -+ case 0x83: -+ md->model = MIPID_VER_LS041Y3; -+ md->name = "ls041y3"; -+ break; -+ default: -+ md->name = "unknown"; -+ dev_err(&md->spi->dev, "invalid display ID\n"); -+ return -ENODEV; -+ } -+ -+ md->revision = md->display_id[1]; -+ -+ dev_info(&md->spi->dev, "omapfb: %s rev %02x LCD detected\n", -+ md->name, md->revision); -+ -+ return 0; -+} -+ -+/*----------------------Backlight Control-------------------------*/ -+ -+static void enable_backlight_ctrl(struct acx565akm_device *md, int enable) -+{ -+ u16 ctrl; -+ -+ acx565akm_read(md, MIPID_CMD_READ_CTRL_DISP, (u8 *)&ctrl, 1); -+ if (enable) { -+ ctrl |= CTRL_DISP_BRIGHTNESS_CTRL_ON | -+ CTRL_DISP_BACKLIGHT_ON; -+ } else { -+ ctrl &= ~(CTRL_DISP_BRIGHTNESS_CTRL_ON | -+ CTRL_DISP_BACKLIGHT_ON); -+ } -+ -+ ctrl |= 1 << 8; -+ acx565akm_write(md, MIPID_CMD_WRITE_CTRL_DISP, (u8 *)&ctrl, 2); -+} -+ -+static void set_cabc_mode(struct acx565akm_device *md, unsigned mode) -+{ -+ u16 cabc_ctrl; -+ -+ md->cabc_mode = mode; -+ if (!md->enabled) -+ return; -+ cabc_ctrl = 0; -+ acx565akm_read(md, MIPID_CMD_READ_CABC, (u8 *)&cabc_ctrl, 1); -+ cabc_ctrl &= ~3; -+ cabc_ctrl |= (1 << 8) | (mode & 3); -+ acx565akm_write(md, MIPID_CMD_WRITE_CABC, (u8 *)&cabc_ctrl, 2); -+} -+ -+static unsigned get_cabc_mode(struct acx565akm_device *md) -+{ -+ return md->cabc_mode; -+} -+ -+static unsigned get_hw_cabc_mode(struct acx565akm_device *md) -+{ -+ u8 cabc_ctrl; -+ -+ acx565akm_read(md, MIPID_CMD_READ_CABC, &cabc_ctrl, 1); -+ return cabc_ctrl & 3; -+} -+ -+static void acx565akm_set_brightness(struct acx565akm_device *md, int level) -+{ -+ int bv; -+ -+ bv = level | (1 << 8); -+ acx565akm_write(md, MIPID_CMD_WRITE_DISP_BRIGHTNESS, (u8 *)&bv, 2); -+ -+ if (level) -+ enable_backlight_ctrl(md, 1); -+ else -+ enable_backlight_ctrl(md, 0); -+} -+ -+static int acx565akm_get_actual_brightness(struct acx565akm_device *md) -+{ -+ u8 bv; -+ -+ acx565akm_read(md, MIPID_CMD_READ_DISP_BRIGHTNESS, &bv, 1); -+ -+ return bv; -+} -+ -+ -+static int acx565akm_bl_update_status(struct backlight_device *dev) -+{ -+ struct acx565akm_device *md = dev_get_drvdata(&dev->dev); -+ int r; -+ int level; -+ -+ dev_dbg(&md->spi->dev, "%s\n", __func__); -+ -+ mutex_lock(&md->mutex); -+ -+ if (dev->props.fb_blank == FB_BLANK_UNBLANK && -+ dev->props.power == FB_BLANK_UNBLANK) -+ level = dev->props.brightness; -+ else -+ level = 0; -+ -+ r = 0; -+ if (md->has_bc) -+ acx565akm_set_brightness(md, level); -+ else if (md->dssdev->set_backlight) -+ r = md->dssdev->set_backlight(md->dssdev, level); -+ else -+ r = -ENODEV; -+ -+ mutex_unlock(&md->mutex); -+ -+ return r; -+} -+ -+static int acx565akm_bl_get_intensity(struct backlight_device *dev) -+{ -+ struct acx565akm_device *md = dev_get_drvdata(&dev->dev); -+ -+ dev_dbg(&dev->dev, "%s\n", __func__); -+ -+ if (!md->has_bc && md->dssdev->set_backlight == NULL) -+ return -ENODEV; -+ -+ if (dev->props.fb_blank == FB_BLANK_UNBLANK && -+ dev->props.power == FB_BLANK_UNBLANK) { -+ if (md->has_bc) -+ return acx565akm_get_actual_brightness(md); -+ else -+ return dev->props.brightness; -+ } -+ -+ return 0; -+} -+ -+static struct backlight_ops acx565akm_bl_ops = { -+ .get_brightness = acx565akm_bl_get_intensity, -+ .update_status = acx565akm_bl_update_status, -+}; -+ -+/*--------------------Auto Brightness control via Sysfs---------------------*/ -+ -+static const char *cabc_modes[] = { -+ "off", /* always used when CABC is not supported */ -+ "ui", -+ "still-image", -+ "moving-image", -+}; -+ -+static ssize_t show_cabc_mode(struct device *dev, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ struct acx565akm_device *md = dev_get_drvdata(dev); -+ const char *mode_str; -+ int mode; -+ int len; -+ -+ if (!md->has_cabc) -+ mode = 0; -+ else -+ mode = get_cabc_mode(md); -+ mode_str = "unknown"; -+ if (mode >= 0 && mode < ARRAY_SIZE(cabc_modes)) -+ mode_str = cabc_modes[mode]; -+ len = snprintf(buf, PAGE_SIZE, "%s\n", mode_str); -+ -+ return len < PAGE_SIZE - 1 ? len : PAGE_SIZE - 1; -+} -+ -+static ssize_t store_cabc_mode(struct device *dev, -+ struct device_attribute *attr, -+ const char *buf, size_t count) -+{ -+ struct acx565akm_device *md = dev_get_drvdata(dev); -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(cabc_modes); i++) { -+ const char *mode_str = cabc_modes[i]; -+ int cmp_len = strlen(mode_str); -+ -+ if (count > 0 && buf[count - 1] == '\n') -+ count--; -+ if (count != cmp_len) -+ continue; -+ -+ if (strncmp(buf, mode_str, cmp_len) == 0) -+ break; -+ } -+ -+ if (i == ARRAY_SIZE(cabc_modes)) -+ return -EINVAL; -+ -+ if (!md->has_cabc && i != 0) -+ return -EINVAL; -+ -+ mutex_lock(&md->mutex); -+ set_cabc_mode(md, i); -+ mutex_unlock(&md->mutex); -+ -+ return count; -+} -+ -+static ssize_t show_cabc_available_modes(struct device *dev, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ struct acx565akm_device *md = dev_get_drvdata(dev); -+ int len; -+ int i; -+ -+ if (!md->has_cabc) -+ return snprintf(buf, PAGE_SIZE, "%s\n", cabc_modes[0]); -+ -+ for (i = 0, len = 0; -+ len < PAGE_SIZE && i < ARRAY_SIZE(cabc_modes); i++) -+ len += snprintf(&buf[len], PAGE_SIZE - len, "%s%s%s", -+ i ? " " : "", cabc_modes[i], -+ i == ARRAY_SIZE(cabc_modes) - 1 ? "\n" : ""); -+ -+ return len < PAGE_SIZE ? len : PAGE_SIZE - 1; -+} -+ -+static DEVICE_ATTR(cabc_mode, S_IRUGO | S_IWUSR, -+ show_cabc_mode, store_cabc_mode); -+static DEVICE_ATTR(cabc_available_modes, S_IRUGO, -+ show_cabc_available_modes, NULL); -+ -+static struct attribute *bldev_attrs[] = { -+ &dev_attr_cabc_mode.attr, -+ &dev_attr_cabc_available_modes.attr, -+ NULL, -+}; -+ -+static struct attribute_group bldev_attr_group = { -+ .attrs = bldev_attrs, -+}; -+ -+/*---------------------------ACX Panel----------------------------*/ -+ -+static struct omap_video_timings acx_panel_timings = { -+ .x_res = 800, -+ .y_res = 480, -+ .pixel_clock = 24000, -+ .hfp = 28, -+ .hsw = 4, -+ .hbp = 24, -+ .vfp = 3, -+ .vsw = 3, -+ .vbp = 4, -+}; -+ -+static int acx_panel_probe(struct omap_dss_device *dssdev) -+{ -+ int r; -+ struct acx565akm_device *md = &acx_dev; -+ struct backlight_device *bldev; -+ int max_brightness, brightness; -+ -+ dev_dbg(&dssdev->dev, "%s\n", __func__); -+ dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS | -+ OMAP_DSS_LCD_IHS; -+ /* FIXME AC bias ? */ -+ dssdev->panel.timings = acx_panel_timings; -+ dssdev->panel.recommended_bpp = 16; -+ -+ if (dssdev->platform_enable) -+ dssdev->platform_enable(dssdev); -+ /* -+ * After reset we have to wait 5 msec before the first -+ * command can be sent. -+ */ -+ msleep(5); -+ -+ md->enabled = panel_enabled(md); -+ -+ r = panel_detect(md); -+ if (r) { -+ dev_err(&dssdev->dev, "%s panel detect error\n", __func__); -+ if (!md->enabled && dssdev->platform_disable) -+ dssdev->platform_disable(dssdev); -+ return r; -+ } -+ -+ mutex_lock(&acx_dev.mutex); -+ acx_dev.dssdev = dssdev; -+ mutex_unlock(&acx_dev.mutex); -+ -+ if (!md->enabled) { -+ if (dssdev->platform_disable) -+ dssdev->platform_disable(dssdev); -+ } -+ -+ /*------- Backlight control --------*/ -+ -+ bldev = backlight_device_register("acx565akm", &md->spi->dev, -+ md, &acx565akm_bl_ops); -+ md->bl_dev = bldev; -+ if (md->has_cabc) { -+ r = sysfs_create_group(&bldev->dev.kobj, &bldev_attr_group); -+ if (r) { -+ dev_err(&bldev->dev, -+ "%s failed to create sysfs files\n", __func__); -+ backlight_device_unregister(bldev); -+ return r; -+ } -+ md->cabc_mode = get_hw_cabc_mode(md); -+ } -+ -+ bldev->props.fb_blank = FB_BLANK_UNBLANK; -+ bldev->props.power = FB_BLANK_UNBLANK; -+ -+ if (md->has_bc) -+ max_brightness = 255; -+ else -+ max_brightness = dssdev->max_backlight_level; -+ -+ if (md->has_bc) -+ brightness = acx565akm_get_actual_brightness(md); -+ else if (dssdev->get_backlight) -+ brightness = dssdev->get_backlight(dssdev); -+ else -+ brightness = 0; -+ -+ bldev->props.max_brightness = max_brightness; -+ bldev->props.brightness = brightness; -+ -+ acx565akm_bl_update_status(bldev); -+ return 0; -+} -+ -+static void acx_panel_remove(struct omap_dss_device *dssdev) -+{ -+ struct acx565akm_device *md = &acx_dev; -+ -+ dev_dbg(&dssdev->dev, "%s\n", __func__); -+ sysfs_remove_group(&md->bl_dev->dev.kobj, &bldev_attr_group); -+ backlight_device_unregister(md->bl_dev); -+ mutex_lock(&acx_dev.mutex); -+ acx_dev.dssdev = NULL; -+ mutex_unlock(&acx_dev.mutex); -+} -+ -+static int acx_panel_power_on(struct omap_dss_device *dssdev) -+{ -+ struct acx565akm_device *md = &acx_dev; -+ int r; -+ -+ dev_dbg(&dssdev->dev, "%s\n", __func__); -+ -+ mutex_lock(&md->mutex); -+ -+ if (dssdev->platform_enable) { -+ r = dssdev->platform_enable(dssdev); -+ if (r) -+ return r; -+ } -+ -+ if (md->enabled) { -+ dev_dbg(&md->spi->dev, "panel already enabled\n"); -+ mutex_unlock(&md->mutex); -+ return 0; -+ } -+ -+ /* -+ * We have to meet all the following delay requirements: -+ * 1. tRW: reset pulse width 10usec (7.12.1) -+ * 2. tRT: reset cancel time 5msec (7.12.1) -+ * 3. Providing PCLK,HS,VS signals for 2 frames = ~50msec worst -+ * case (7.6.2) -+ * 4. 120msec before the sleep out command (7.12.1) -+ */ -+ msleep(120); -+ -+ set_sleep_mode(md, 0); -+ md->enabled = 1; -+ -+ /* 5msec between sleep out and the next command. (8.2.16) */ -+ msleep(5); -+ set_display_state(md, 1); -+ set_cabc_mode(md, md->cabc_mode); -+ -+ mutex_unlock(&md->mutex); -+ -+ return acx565akm_bl_update_status(md->bl_dev); -+} -+ -+static void acx_panel_power_off(struct omap_dss_device *dssdev) -+{ -+ struct acx565akm_device *md = &acx_dev; -+ -+ dev_dbg(&dssdev->dev, "%s\n", __func__); -+ -+ mutex_lock(&md->mutex); -+ -+ if (!md->enabled) { -+ mutex_unlock(&md->mutex); -+ return; -+ } -+ set_display_state(md, 0); -+ set_sleep_mode(md, 1); -+ md->enabled = 0; -+ /* -+ * We have to provide PCLK,HS,VS signals for 2 frames (worst case -+ * ~50msec) after sending the sleep in command and asserting the -+ * reset signal. We probably could assert the reset w/o the delay -+ * but we still delay to avoid possible artifacts. (7.6.1) -+ */ -+ msleep(50); -+ -+ if (dssdev->platform_disable) -+ dssdev->platform_disable(dssdev); -+ -+ mutex_unlock(&md->mutex); -+} -+ -+static int acx_panel_enable(struct omap_dss_device *dssdev) -+{ -+ int r; -+ -+ dev_dbg(&dssdev->dev, "%s\n", __func__); -+ r = acx_panel_power_on(dssdev); -+ -+ if (r) -+ return r; -+ -+ dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; -+ return 0; -+} -+ -+static void acx_panel_disable(struct omap_dss_device *dssdev) -+{ -+ dev_dbg(&dssdev->dev, "%s\n", __func__); -+ acx_panel_power_off(dssdev); -+ dssdev->state = OMAP_DSS_DISPLAY_DISABLED; -+} -+ -+static int acx_panel_suspend(struct omap_dss_device *dssdev) -+{ -+ dev_dbg(&dssdev->dev, "%s\n", __func__); -+ acx_panel_power_off(dssdev); -+ dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; -+ return 0; -+} -+ -+static int acx_panel_resume(struct omap_dss_device *dssdev) -+{ -+ int r; -+ -+ dev_dbg(&dssdev->dev, "%s\n", __func__); -+ r = acx_panel_power_on(dssdev); -+ if (r) -+ return r; -+ -+ dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; -+ return 0; -+} -+ -+static struct omap_dss_driver acx_panel_driver = { -+ .probe = acx_panel_probe, -+ .remove = acx_panel_remove, -+ -+ .enable = acx_panel_enable, -+ .disable = acx_panel_disable, -+ .suspend = acx_panel_suspend, -+ .resume = acx_panel_resume, -+ -+ .driver = { -+ .name = "panel-acx565akm", -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+/*--------------------SPI probe-------------------------*/ -+ -+static int acx565akm_spi_probe(struct spi_device *spi) -+{ -+ struct acx565akm_device *md = &acx_dev; -+ -+ dev_dbg(&spi->dev, "%s\n", __func__); -+ -+ spi->mode = SPI_MODE_3; -+ md->spi = spi; -+ mutex_init(&md->mutex); -+ dev_set_drvdata(&spi->dev, md); -+ -+ omap_dss_register_driver(&acx_panel_driver); -+ -+ return 0; -+} -+ -+static int acx565akm_spi_remove(struct spi_device *spi) -+{ -+ struct acx565akm_device *md = dev_get_drvdata(&spi->dev); -+ -+ dev_dbg(&md->spi->dev, "%s\n", __func__); -+ omap_dss_unregister_driver(&acx_panel_driver); -+ -+ return 0; -+} -+ -+static struct spi_driver acx565akm_spi_driver = { -+ .driver = { -+ .name = "acx565akm", -+ .bus = &spi_bus_type, -+ .owner = THIS_MODULE, -+ }, -+ .probe = acx565akm_spi_probe, -+ .remove = __devexit_p(acx565akm_spi_remove), -+}; -+ -+static int __init acx565akm_init(void) -+{ -+ return spi_register_driver(&acx565akm_spi_driver); -+} -+ -+static void __exit acx565akm_exit(void) -+{ -+ spi_unregister_driver(&acx565akm_spi_driver); -+} -+ -+module_init(acx565akm_init); -+module_exit(acx565akm_exit); -+ -+MODULE_AUTHOR("Nokia Corporation"); -+MODULE_DESCRIPTION("acx565akm LCD Driver"); -+MODULE_LICENSE("GPL"); --- -1.6.0.4 - |