]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
OMAPDSS: Add TPO TD043MTEA1 panel driver
authorTomi Valkeinen <tomi.valkeinen@ti.com>
Fri, 31 May 2013 10:13:44 +0000 (13:13 +0300)
committerTomi Valkeinen <tomi.valkeinen@ti.com>
Mon, 17 Jun 2013 11:33:04 +0000 (14:33 +0300)
Add TPO TD043MTEA1 panel driver which uses the new DSS device model
and DSS ops.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Tested-by: Grazvydas Ignotas <notasas@gmail.com>
drivers/video/omap2/displays-new/Kconfig
drivers/video/omap2/displays-new/Makefile
drivers/video/omap2/displays-new/panel-tpo-td043mtea1.c [new file with mode: 0644]
include/video/omap-panel-data.h

index 917db6e7966c081228a2fcbfda12fd9bebe9fdf2..c66ecb23e3d90b9c4334cd3df3b2bca465df5e47 100644 (file)
@@ -55,4 +55,11 @@ config DISPLAY_PANEL_SHARP_LS037V7DW01
         depends on BACKLIGHT_CLASS_DEVICE
         help
           LCD Panel used in TI's SDP3430 and EVM boards
+
+config DISPLAY_PANEL_TPO_TD043MTEA1
+        tristate "TPO TD043MTEA1 LCD Panel"
+        depends on SPI
+        help
+          LCD Panel used in OMAP3 Pandora
+
 endmenu
index dde7b8ddda0bd6e99fd8286c27db4755e017b704..628ea3e7bb69faa3b85ea000718a6141d3adb664 100644 (file)
@@ -8,3 +8,4 @@ obj-$(CONFIG_DISPLAY_PANEL_DSI_CM) += panel-dsi-cm.o
 obj-$(CONFIG_DISPLAY_PANEL_SONY_ACX565AKM) += panel-sony-acx565akm.o
 obj-$(CONFIG_DISPLAY_PANEL_LGPHILIPS_LB035Q02) += panel-lgphilips-lb035q02.o
 obj-$(CONFIG_DISPLAY_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o
+obj-$(CONFIG_DISPLAY_PANEL_TPO_TD043MTEA1) += panel-tpo-td043mtea1.o
diff --git a/drivers/video/omap2/displays-new/panel-tpo-td043mtea1.c b/drivers/video/omap2/displays-new/panel-tpo-td043mtea1.c
new file mode 100644 (file)
index 0000000..eadc652
--- /dev/null
@@ -0,0 +1,646 @@
+/*
+ * TPO TD043MTEA1 Panel driver
+ *
+ * Author: Gražvydas Ignotas <notasas@gmail.com>
+ * Converted to new DSS device model: Tomi Valkeinen <tomi.valkeinen@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/spi/spi.h>
+#include <linux/regulator/consumer.h>
+#include <linux/gpio.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+
+#include <video/omapdss.h>
+#include <video/omap-panel-data.h>
+
+#define TPO_R02_MODE(x)                ((x) & 7)
+#define TPO_R02_MODE_800x480   7
+#define TPO_R02_NCLK_RISING    BIT(3)
+#define TPO_R02_HSYNC_HIGH     BIT(4)
+#define TPO_R02_VSYNC_HIGH     BIT(5)
+
+#define TPO_R03_NSTANDBY       BIT(0)
+#define TPO_R03_EN_CP_CLK      BIT(1)
+#define TPO_R03_EN_VGL_PUMP    BIT(2)
+#define TPO_R03_EN_PWM         BIT(3)
+#define TPO_R03_DRIVING_CAP_100        BIT(4)
+#define TPO_R03_EN_PRE_CHARGE  BIT(6)
+#define TPO_R03_SOFTWARE_CTL   BIT(7)
+
+#define TPO_R04_NFLIP_H                BIT(0)
+#define TPO_R04_NFLIP_V                BIT(1)
+#define TPO_R04_CP_CLK_FREQ_1H BIT(2)
+#define TPO_R04_VGL_FREQ_1H    BIT(4)
+
+#define TPO_R03_VAL_NORMAL (TPO_R03_NSTANDBY | TPO_R03_EN_CP_CLK | \
+                       TPO_R03_EN_VGL_PUMP |  TPO_R03_EN_PWM | \
+                       TPO_R03_DRIVING_CAP_100 | TPO_R03_EN_PRE_CHARGE | \
+                       TPO_R03_SOFTWARE_CTL)
+
+#define TPO_R03_VAL_STANDBY (TPO_R03_DRIVING_CAP_100 | \
+                       TPO_R03_EN_PRE_CHARGE | TPO_R03_SOFTWARE_CTL)
+
+static const u16 tpo_td043_def_gamma[12] = {
+       105, 315, 381, 431, 490, 537, 579, 686, 780, 837, 880, 1023
+};
+
+struct panel_drv_data {
+       struct omap_dss_device  dssdev;
+       struct omap_dss_device *in;
+
+       struct omap_video_timings videomode;
+
+       int data_lines;
+
+       struct spi_device *spi;
+       struct regulator *vcc_reg;
+       int nreset_gpio;
+       u16 gamma[12];
+       u32 mode;
+       u32 hmirror:1;
+       u32 vmirror:1;
+       u32 powered_on:1;
+       u32 spi_suspended:1;
+       u32 power_on_resume:1;
+};
+
+static const struct omap_video_timings tpo_td043_timings = {
+       .x_res          = 800,
+       .y_res          = 480,
+
+       .pixel_clock    = 36000,
+
+       .hsw            = 1,
+       .hfp            = 68,
+       .hbp            = 214,
+
+       .vsw            = 1,
+       .vfp            = 39,
+       .vbp            = 34,
+
+       .vsync_level    = OMAPDSS_SIG_ACTIVE_LOW,
+       .hsync_level    = OMAPDSS_SIG_ACTIVE_LOW,
+       .data_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE,
+       .de_level       = OMAPDSS_SIG_ACTIVE_HIGH,
+       .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
+};
+
+#define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev)
+
+static int tpo_td043_write(struct spi_device *spi, u8 addr, u8 data)
+{
+       struct spi_message      m;
+       struct spi_transfer     xfer;
+       u16                     w;
+       int                     r;
+
+       spi_message_init(&m);
+
+       memset(&xfer, 0, sizeof(xfer));
+
+       w = ((u16)addr << 10) | (1 << 8) | data;
+       xfer.tx_buf = &w;
+       xfer.bits_per_word = 16;
+       xfer.len = 2;
+       spi_message_add_tail(&xfer, &m);
+
+       r = spi_sync(spi, &m);
+       if (r < 0)
+               dev_warn(&spi->dev, "failed to write to LCD reg (%d)\n", r);
+       return r;
+}
+
+static void tpo_td043_write_gamma(struct spi_device *spi, u16 gamma[12])
+{
+       u8 i, val;
+
+       /* gamma bits [9:8] */
+       for (val = i = 0; i < 4; i++)
+               val |= (gamma[i] & 0x300) >> ((i + 1) * 2);
+       tpo_td043_write(spi, 0x11, val);
+
+       for (val = i = 0; i < 4; i++)
+               val |= (gamma[i+4] & 0x300) >> ((i + 1) * 2);
+       tpo_td043_write(spi, 0x12, val);
+
+       for (val = i = 0; i < 4; i++)
+               val |= (gamma[i+8] & 0x300) >> ((i + 1) * 2);
+       tpo_td043_write(spi, 0x13, val);
+
+       /* gamma bits [7:0] */
+       for (val = i = 0; i < 12; i++)
+               tpo_td043_write(spi, 0x14 + i, gamma[i] & 0xff);
+}
+
+static int tpo_td043_write_mirror(struct spi_device *spi, bool h, bool v)
+{
+       u8 reg4 = TPO_R04_NFLIP_H | TPO_R04_NFLIP_V |
+               TPO_R04_CP_CLK_FREQ_1H | TPO_R04_VGL_FREQ_1H;
+       if (h)
+               reg4 &= ~TPO_R04_NFLIP_H;
+       if (v)
+               reg4 &= ~TPO_R04_NFLIP_V;
+
+       return tpo_td043_write(spi, 4, reg4);
+}
+
+static int tpo_td043_set_hmirror(struct omap_dss_device *dssdev, bool enable)
+{
+       struct panel_drv_data *ddata = dev_get_drvdata(dssdev->dev);
+
+       ddata->hmirror = enable;
+       return tpo_td043_write_mirror(ddata->spi, ddata->hmirror,
+                       ddata->vmirror);
+}
+
+static bool tpo_td043_get_hmirror(struct omap_dss_device *dssdev)
+{
+       struct panel_drv_data *ddata = dev_get_drvdata(dssdev->dev);
+
+       return ddata->hmirror;
+}
+
+static ssize_t tpo_td043_vmirror_show(struct device *dev,
+       struct device_attribute *attr, char *buf)
+{
+       struct panel_drv_data *ddata = dev_get_drvdata(dev);
+
+       return snprintf(buf, PAGE_SIZE, "%d\n", ddata->vmirror);
+}
+
+static ssize_t tpo_td043_vmirror_store(struct device *dev,
+       struct device_attribute *attr, const char *buf, size_t count)
+{
+       struct panel_drv_data *ddata = dev_get_drvdata(dev);
+       int val;
+       int ret;
+
+       ret = kstrtoint(buf, 0, &val);
+       if (ret < 0)
+               return ret;
+
+       val = !!val;
+
+       ret = tpo_td043_write_mirror(ddata->spi, ddata->hmirror, val);
+       if (ret < 0)
+               return ret;
+
+       ddata->vmirror = val;
+
+       return count;
+}
+
+static ssize_t tpo_td043_mode_show(struct device *dev,
+       struct device_attribute *attr, char *buf)
+{
+       struct panel_drv_data *ddata = dev_get_drvdata(dev);
+
+       return snprintf(buf, PAGE_SIZE, "%d\n", ddata->mode);
+}
+
+static ssize_t tpo_td043_mode_store(struct device *dev,
+       struct device_attribute *attr, const char *buf, size_t count)
+{
+       struct panel_drv_data *ddata = dev_get_drvdata(dev);
+       long val;
+       int ret;
+
+       ret = kstrtol(buf, 0, &val);
+       if (ret != 0 || val & ~7)
+               return -EINVAL;
+
+       ddata->mode = val;
+
+       val |= TPO_R02_NCLK_RISING;
+       tpo_td043_write(ddata->spi, 2, val);
+
+       return count;
+}
+
+static ssize_t tpo_td043_gamma_show(struct device *dev,
+       struct device_attribute *attr, char *buf)
+{
+       struct panel_drv_data *ddata = dev_get_drvdata(dev);
+       ssize_t len = 0;
+       int ret;
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(ddata->gamma); i++) {
+               ret = snprintf(buf + len, PAGE_SIZE - len, "%u ",
+                               ddata->gamma[i]);
+               if (ret < 0)
+                       return ret;
+               len += ret;
+       }
+       buf[len - 1] = '\n';
+
+       return len;
+}
+
+static ssize_t tpo_td043_gamma_store(struct device *dev,
+       struct device_attribute *attr, const char *buf, size_t count)
+{
+       struct panel_drv_data *ddata = dev_get_drvdata(dev);
+       unsigned int g[12];
+       int ret;
+       int i;
+
+       ret = sscanf(buf, "%u %u %u %u %u %u %u %u %u %u %u %u",
+                       &g[0], &g[1], &g[2], &g[3], &g[4], &g[5],
+                       &g[6], &g[7], &g[8], &g[9], &g[10], &g[11]);
+
+       if (ret != 12)
+               return -EINVAL;
+
+       for (i = 0; i < 12; i++)
+               ddata->gamma[i] = g[i];
+
+       tpo_td043_write_gamma(ddata->spi, ddata->gamma);
+
+       return count;
+}
+
+static DEVICE_ATTR(vmirror, S_IRUGO | S_IWUSR,
+               tpo_td043_vmirror_show, tpo_td043_vmirror_store);
+static DEVICE_ATTR(mode, S_IRUGO | S_IWUSR,
+               tpo_td043_mode_show, tpo_td043_mode_store);
+static DEVICE_ATTR(gamma, S_IRUGO | S_IWUSR,
+               tpo_td043_gamma_show, tpo_td043_gamma_store);
+
+static struct attribute *tpo_td043_attrs[] = {
+       &dev_attr_vmirror.attr,
+       &dev_attr_mode.attr,
+       &dev_attr_gamma.attr,
+       NULL,
+};
+
+static struct attribute_group tpo_td043_attr_group = {
+       .attrs = tpo_td043_attrs,
+};
+
+static int tpo_td043_power_on(struct panel_drv_data *ddata)
+{
+       int r;
+
+       if (ddata->powered_on)
+               return 0;
+
+       r = regulator_enable(ddata->vcc_reg);
+       if (r != 0)
+               return r;
+
+       /* wait for panel to stabilize */
+       msleep(160);
+
+       if (gpio_is_valid(ddata->nreset_gpio))
+               gpio_set_value(ddata->nreset_gpio, 1);
+
+       tpo_td043_write(ddata->spi, 2,
+                       TPO_R02_MODE(ddata->mode) | TPO_R02_NCLK_RISING);
+       tpo_td043_write(ddata->spi, 3, TPO_R03_VAL_NORMAL);
+       tpo_td043_write(ddata->spi, 0x20, 0xf0);
+       tpo_td043_write(ddata->spi, 0x21, 0xf0);
+       tpo_td043_write_mirror(ddata->spi, ddata->hmirror,
+                       ddata->vmirror);
+       tpo_td043_write_gamma(ddata->spi, ddata->gamma);
+
+       ddata->powered_on = 1;
+       return 0;
+}
+
+static void tpo_td043_power_off(struct panel_drv_data *ddata)
+{
+       if (!ddata->powered_on)
+               return;
+
+       tpo_td043_write(ddata->spi, 3,
+                       TPO_R03_VAL_STANDBY | TPO_R03_EN_PWM);
+
+       if (gpio_is_valid(ddata->nreset_gpio))
+               gpio_set_value(ddata->nreset_gpio, 0);
+
+       /* wait for at least 2 vsyncs before cutting off power */
+       msleep(50);
+
+       tpo_td043_write(ddata->spi, 3, TPO_R03_VAL_STANDBY);
+
+       regulator_disable(ddata->vcc_reg);
+
+       ddata->powered_on = 0;
+}
+
+static int tpo_td043_connect(struct omap_dss_device *dssdev)
+{
+       struct panel_drv_data *ddata = to_panel_data(dssdev);
+       struct omap_dss_device *in = ddata->in;
+       int r;
+
+       if (omapdss_device_is_connected(dssdev))
+               return 0;
+
+       r = in->ops.dpi->connect(in, dssdev);
+       if (r)
+               return r;
+
+       return 0;
+}
+
+static void tpo_td043_disconnect(struct omap_dss_device *dssdev)
+{
+       struct panel_drv_data *ddata = to_panel_data(dssdev);
+       struct omap_dss_device *in = ddata->in;
+
+       if (!omapdss_device_is_connected(dssdev))
+               return;
+
+       in->ops.dpi->disconnect(in, dssdev);
+}
+
+static int tpo_td043_enable(struct omap_dss_device *dssdev)
+{
+       struct panel_drv_data *ddata = to_panel_data(dssdev);
+       struct omap_dss_device *in = ddata->in;
+       int r;
+
+       if (!omapdss_device_is_connected(dssdev))
+               return -ENODEV;
+
+       if (omapdss_device_is_enabled(dssdev))
+               return 0;
+
+       in->ops.dpi->set_data_lines(in, ddata->data_lines);
+       in->ops.dpi->set_timings(in, &ddata->videomode);
+
+       r = in->ops.dpi->enable(in);
+       if (r)
+               return r;
+
+       /*
+        * If we are resuming from system suspend, SPI clocks might not be
+        * enabled yet, so we'll program the LCD from SPI PM resume callback.
+        */
+       if (!ddata->spi_suspended) {
+               r = tpo_td043_power_on(ddata);
+               if (r) {
+                       in->ops.dpi->disable(in);
+                       return r;
+               }
+       }
+
+       dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+
+       return 0;
+}
+
+static void tpo_td043_disable(struct omap_dss_device *dssdev)
+{
+       struct panel_drv_data *ddata = to_panel_data(dssdev);
+       struct omap_dss_device *in = ddata->in;
+
+       if (!omapdss_device_is_enabled(dssdev))
+               return;
+
+       in->ops.dpi->disable(in);
+
+       if (!ddata->spi_suspended)
+               tpo_td043_power_off(ddata);
+
+       dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
+}
+
+static void tpo_td043_set_timings(struct omap_dss_device *dssdev,
+               struct omap_video_timings *timings)
+{
+       struct panel_drv_data *ddata = to_panel_data(dssdev);
+       struct omap_dss_device *in = ddata->in;
+
+       ddata->videomode = *timings;
+       dssdev->panel.timings = *timings;
+
+       in->ops.dpi->set_timings(in, timings);
+}
+
+static void tpo_td043_get_timings(struct omap_dss_device *dssdev,
+               struct omap_video_timings *timings)
+{
+       struct panel_drv_data *ddata = to_panel_data(dssdev);
+
+       *timings = ddata->videomode;
+}
+
+static int tpo_td043_check_timings(struct omap_dss_device *dssdev,
+               struct omap_video_timings *timings)
+{
+       struct panel_drv_data *ddata = to_panel_data(dssdev);
+       struct omap_dss_device *in = ddata->in;
+
+       return in->ops.dpi->check_timings(in, timings);
+}
+
+static struct omap_dss_driver tpo_td043_ops = {
+       .connect        = tpo_td043_connect,
+       .disconnect     = tpo_td043_disconnect,
+
+       .enable         = tpo_td043_enable,
+       .disable        = tpo_td043_disable,
+
+       .set_timings    = tpo_td043_set_timings,
+       .get_timings    = tpo_td043_get_timings,
+       .check_timings  = tpo_td043_check_timings,
+
+       .set_mirror     = tpo_td043_set_hmirror,
+       .get_mirror     = tpo_td043_get_hmirror,
+
+       .get_resolution = omapdss_default_get_resolution,
+};
+
+
+static int tpo_td043_probe_pdata(struct spi_device *spi)
+{
+       const struct panel_tpo_td043mtea1_platform_data *pdata;
+       struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
+       struct omap_dss_device *dssdev, *in;
+
+       pdata = dev_get_platdata(&spi->dev);
+
+       ddata->nreset_gpio = pdata->nreset_gpio;
+
+       in = omap_dss_find_output(pdata->source);
+       if (in == NULL) {
+               dev_err(&spi->dev, "failed to find video source '%s'\n",
+                               pdata->source);
+               return -EPROBE_DEFER;
+       }
+       ddata->in = in;
+
+       ddata->data_lines = pdata->data_lines;
+
+       dssdev = &ddata->dssdev;
+       dssdev->name = pdata->name;
+
+       return 0;
+}
+
+static int tpo_td043_probe(struct spi_device *spi)
+{
+       struct panel_drv_data *ddata;
+       struct omap_dss_device *dssdev;
+       int r;
+
+       dev_dbg(&spi->dev, "%s\n", __func__);
+
+       spi->bits_per_word = 16;
+       spi->mode = SPI_MODE_0;
+
+       r = spi_setup(spi);
+       if (r < 0) {
+               dev_err(&spi->dev, "spi_setup failed: %d\n", r);
+               return r;
+       }
+
+       ddata = devm_kzalloc(&spi->dev, sizeof(*ddata), GFP_KERNEL);
+       if (ddata == NULL)
+               return -ENOMEM;
+
+       dev_set_drvdata(&spi->dev, ddata);
+
+       ddata->spi = spi;
+
+       if (dev_get_platdata(&spi->dev)) {
+               r = tpo_td043_probe_pdata(spi);
+               if (r)
+                       return r;
+       } else {
+               return -ENODEV;
+       }
+
+       ddata->mode = TPO_R02_MODE_800x480;
+       memcpy(ddata->gamma, tpo_td043_def_gamma, sizeof(ddata->gamma));
+
+       ddata->vcc_reg = devm_regulator_get(&spi->dev, "vcc");
+       if (IS_ERR(ddata->vcc_reg)) {
+               dev_err(&spi->dev, "failed to get LCD VCC regulator\n");
+               r = PTR_ERR(ddata->vcc_reg);
+               goto err_regulator;
+       }
+
+       if (gpio_is_valid(ddata->nreset_gpio)) {
+               r = devm_gpio_request_one(&spi->dev,
+                               ddata->nreset_gpio, GPIOF_OUT_INIT_LOW,
+                               "lcd reset");
+               if (r < 0) {
+                       dev_err(&spi->dev, "couldn't request reset GPIO\n");
+                       goto err_gpio_req;
+               }
+       }
+
+       r = sysfs_create_group(&spi->dev.kobj, &tpo_td043_attr_group);
+       if (r) {
+               dev_err(&spi->dev, "failed to create sysfs files\n");
+               goto err_sysfs;
+       }
+
+       ddata->videomode = tpo_td043_timings;
+
+       dssdev = &ddata->dssdev;
+       dssdev->dev = &spi->dev;
+       dssdev->driver = &tpo_td043_ops;
+       dssdev->type = OMAP_DISPLAY_TYPE_DPI;
+       dssdev->owner = THIS_MODULE;
+       dssdev->panel.timings = ddata->videomode;
+
+       r = omapdss_register_display(dssdev);
+       if (r) {
+               dev_err(&spi->dev, "Failed to register panel\n");
+               goto err_reg;
+       }
+
+       return 0;
+
+err_reg:
+       sysfs_remove_group(&spi->dev.kobj, &tpo_td043_attr_group);
+err_sysfs:
+err_gpio_req:
+err_regulator:
+       omap_dss_put_device(ddata->in);
+       return r;
+}
+
+static int tpo_td043_remove(struct spi_device *spi)
+{
+       struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
+       struct omap_dss_device *dssdev = &ddata->dssdev;
+       struct omap_dss_device *in = ddata->in;
+
+       dev_dbg(&ddata->spi->dev, "%s\n", __func__);
+
+       omapdss_unregister_display(dssdev);
+
+       tpo_td043_disable(dssdev);
+       tpo_td043_disconnect(dssdev);
+
+       omap_dss_put_device(in);
+
+       sysfs_remove_group(&spi->dev.kobj, &tpo_td043_attr_group);
+
+       return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int tpo_td043_spi_suspend(struct device *dev)
+{
+       struct panel_drv_data *ddata = dev_get_drvdata(dev);
+
+       dev_dbg(dev, "tpo_td043_spi_suspend, tpo %p\n", ddata);
+
+       ddata->power_on_resume = ddata->powered_on;
+       tpo_td043_power_off(ddata);
+       ddata->spi_suspended = 1;
+
+       return 0;
+}
+
+static int tpo_td043_spi_resume(struct device *dev)
+{
+       struct panel_drv_data *ddata = dev_get_drvdata(dev);
+       int ret;
+
+       dev_dbg(dev, "tpo_td043_spi_resume\n");
+
+       if (ddata->power_on_resume) {
+               ret = tpo_td043_power_on(ddata);
+               if (ret)
+                       return ret;
+       }
+       ddata->spi_suspended = 0;
+
+       return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(tpo_td043_spi_pm,
+       tpo_td043_spi_suspend, tpo_td043_spi_resume);
+
+static struct spi_driver tpo_td043_spi_driver = {
+       .driver = {
+               .name   = "panel-tpo-td043mtea1",
+               .owner  = THIS_MODULE,
+               .pm     = &tpo_td043_spi_pm,
+       },
+       .probe  = tpo_td043_probe,
+       .remove = tpo_td043_remove,
+};
+
+module_spi_driver(tpo_td043_spi_driver);
+
+MODULE_AUTHOR("Gražvydas Ignotas <notasas@gmail.com>");
+MODULE_DESCRIPTION("TPO TD043MTEA1 LCD Driver");
+MODULE_LICENSE("GPL");
index 5a6e1e8645d7693bfa363a43080cef814664700d..efa1c80f724ebed2553ff36780579b8634d1af69 100644 (file)
@@ -322,4 +322,20 @@ struct panel_sharp_ls037v7dw01_platform_data {
        int ud_gpio;
 };
 
+/**
+ * panel-tpo-td043mtea1 platform data
+ * @name: name for this display entity
+ * @source: name of the display entity used as a video source
+ * @data_lines: number of DPI datalines
+ * @nreset_gpio: reset signal
+ */
+struct panel_tpo_td043mtea1_platform_data {
+       const char *name;
+       const char *source;
+
+       int data_lines;
+
+       int nreset_gpio;
+};
+
 #endif /* __OMAP_PANEL_DATA_H */