diff options
author | NeilBrown <neilb@suse.de> | 2011-11-18 16:35:04 +1100 |
---|---|---|
committer | Paul Kocialkowski <contact@paulk.fr> | 2013-05-04 23:06:55 +0200 |
commit | e1fc3435c653032417b2984cfe8988b4d8f30eb1 (patch) | |
tree | 31dd59e4f4b38ee89512b8f4a79774db00edc73b | |
parent | 59bc19226c746f479edc2acca9a41f60669cbe82 (diff) | |
download | kernel_goldelico_gta04-e1fc3435c653032417b2984cfe8988b4d8f30eb1.zip kernel_goldelico_gta04-e1fc3435c653032417b2984cfe8988b4d8f30eb1.tar.gz kernel_goldelico_gta04-e1fc3435c653032417b2984cfe8988b4d8f30eb1.tar.bz2 |
Add panel drivers for GTA04
-rw-r--r-- | drivers/video/omap2/displays/Kconfig | 13 | ||||
-rw-r--r-- | drivers/video/omap2/displays/Makefile | 3 | ||||
-rw-r--r-- | drivers/video/omap2/displays/panel-ortus-com37h3m05dtc.c | 143 | ||||
-rw-r--r-- | drivers/video/omap2/displays/panel-tpo-td028ttec1.c | 487 |
4 files changed, 646 insertions, 0 deletions
diff --git a/drivers/video/omap2/displays/Kconfig b/drivers/video/omap2/displays/Kconfig index 609a280..e5a2346 100644 --- a/drivers/video/omap2/displays/Kconfig +++ b/drivers/video/omap2/displays/Kconfig @@ -48,4 +48,17 @@ config PANEL_ACX565AKM select BACKLIGHT_CLASS_DEVICE help This is the LCD panel used on Nokia N900 + +config PANEL_TPO_TD028TTEC1 + tristate "Toppoly TD028TTEC1 Panel" + depends on OMAP2_DSS_DSI + help + TPO panel used by Openmoko. + +config PANEL_ORTUS_COM37H3M05DTC + tristate "Ortustech COM37H3M05DTC Panel" + depends on OMAP2_DSS_DSI + help + Ortustech panel used by GTA04 Custom variant. + endmenu diff --git a/drivers/video/omap2/displays/Makefile b/drivers/video/omap2/displays/Makefile index 0f601ab3a..645ce4b 100644 --- a/drivers/video/omap2/displays/Makefile +++ b/drivers/video/omap2/displays/Makefile @@ -6,3 +6,6 @@ obj-$(CONFIG_PANEL_NEC_NL8048HL11_01B) += panel-nec-nl8048hl11-01b.o obj-$(CONFIG_PANEL_TAAL) += panel-taal.o obj-$(CONFIG_PANEL_TPO_TD043MTEA1) += panel-tpo-td043mtea1.o obj-$(CONFIG_PANEL_ACX565AKM) += panel-acx565akm.o + +obj-$(CONFIG_PANEL_TPO_TD028TTEC1) += panel-tpo-td028ttec1.o +obj-$(CONFIG_PANEL_ORTUS_COM37H3M05DTC) += panel-ortus-com37h3m05dtc.o diff --git a/drivers/video/omap2/displays/panel-ortus-com37h3m05dtc.c b/drivers/video/omap2/displays/panel-ortus-com37h3m05dtc.c new file mode 100644 index 0000000..65003e7 --- /dev/null +++ b/drivers/video/omap2/displays/panel-ortus-com37h3m05dtc.c @@ -0,0 +1,143 @@ +/* + * Ortustech COM37H3M05DTC panel support + * + * Copyright (C) 2008 Nokia Corporation + * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com> + * Author: H. Nikolaus Schaller <hns@goldelico.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/module.h> +#include <linux/delay.h> +#include <asm/mach-types.h> + +#include <video/omapdss.h> +#include <linux/gpio.h> + +static struct omap_video_timings com37h3m05dtc_panel_timings = { + .x_res = 480, + .y_res = 640, + .pixel_clock = 22400, + .hfp = 2, + .hsw = 2, + .hbp = 9, + .vfp = 2, + .vsw = 1, + .vbp = 3, +}; + + +// FIXME: this should be passed from the board initialization structure or should be set by driver parameters +#define GPIO_STBY 158 + +static int com37h3m05dtc_panel_probe(struct omap_dss_device *dssdev) +{ + int rc = 0; + printk("com37h3m05dtc_panel_probe()\n"); + /* not set: OMAP_DSS_LCD_IEO, OMAP_DSS_LCD_IPC, ACBI */ + dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_ONOFF | OMAP_DSS_LCD_RF | OMAP_DSS_LCD_IVS | OMAP_DSS_LCD_IHS; + dssdev->panel.acb = 0x28; + dssdev->panel.timings = com37h3m05dtc_panel_timings; + rc = gpio_request(GPIO_STBY, "COM37_STBY"); + if(rc < 0) + printk(KERN_ERR "Unable to get COM37_STBY GPIO %d\n", GPIO_STBY); + gpio_direction_output(GPIO_STBY, true); + + return rc; +} + +static void com37h3m05dtc_panel_remove(struct omap_dss_device *dssdev) +{ + printk("com37h3m05dtc_panel_remove()\n"); + gpio_free(GPIO_STBY); +} + +static int com37h3m05dtc_panel_suspend(struct omap_dss_device *dssdev) +{ // set STBY to 1 + printk("com37h3m05dtc_panel_suspend()\n"); + gpio_set_value(GPIO_STBY, 0); + return 0; +} + +static int com37h3m05dtc_panel_resume(struct omap_dss_device *dssdev) +{ // set STBY to 0 + printk("com37h3m05dtc_panel_resume()\n"); + gpio_set_value(GPIO_STBY, 1); + return 0; +} + +static int com37h3m05dtc_panel_enable(struct omap_dss_device *dssdev) +{ + int rc = 0; + + printk("com37h3m05dtc_panel_enable()\n"); + if (dssdev->platform_enable) + rc = dssdev->platform_enable(dssdev); // enable e.g. power, backlight + + if(rc) + return rc; + + // 1. standby_to_sleep() + + // 2. sleep_to_normal() + + com37h3m05dtc_panel_resume(dssdev); + + return rc ? -EIO : 0; +} + +static void com37h3m05dtc_panel_disable(struct omap_dss_device *dssdev) +{ + + printk("com37h3m05dtc_panel_disable()\n"); + if (dssdev->platform_disable) + dssdev->platform_disable(dssdev); + + // 1. normal_to_sleep() + + com37h3m05dtc_panel_suspend(dssdev); + + // 2. sleep_to_standby() + + // FIXME +} + +static struct omap_dss_driver com37h3m05dtc_driver = { + .probe = com37h3m05dtc_panel_probe, + .remove = com37h3m05dtc_panel_remove, + + .enable = com37h3m05dtc_panel_enable, + .disable = com37h3m05dtc_panel_disable, + .suspend = com37h3m05dtc_panel_suspend, + .resume = com37h3m05dtc_panel_resume, + + .driver = { + .name = "com37h3m05dtc_panel", + .owner = THIS_MODULE, + }, +}; + +static int __init com37h3m05dtc_panel_drv_init(void) +{ + return omap_dss_register_driver(&com37h3m05dtc_driver); +} + +static void __exit com37h3m05dtc_panel_drv_exit(void) +{ + omap_dss_unregister_driver(&com37h3m05dtc_driver); +} + +module_init(com37h3m05dtc_panel_drv_init); +module_exit(com37h3m05dtc_panel_drv_exit); +MODULE_LICENSE("GPL"); diff --git a/drivers/video/omap2/displays/panel-tpo-td028ttec1.c b/drivers/video/omap2/displays/panel-tpo-td028ttec1.c new file mode 100644 index 0000000..bbbf1c3 --- /dev/null +++ b/drivers/video/omap2/displays/panel-tpo-td028ttec1.c @@ -0,0 +1,487 @@ +/* + * Toppoly TD028TTEC1 panel support + * + * Copyright (C) 2008 Nokia Corporation + * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com> + * + * Neo 1973 code (jbt6k74.c): + * Copyright (C) 2006-2007 by OpenMoko, Inc. + * Author: Harald Welte <laforge@openmoko.org> + * + * Ported and adapted from Neo 1973 U-Boot by H. Nikolaus Schaller <hns@goldelico.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/module.h> +#include <linux/delay.h> +#include <asm/mach-types.h> + +//#include <plat/display.h> +#include <video/omapdss.h> +#include <linux/gpio.h> + +static struct omap_video_timings td028ttec1_panel_timings = { +.x_res = 480, +.y_res = 640, +.pixel_clock = 22000, +.hfp = 24, +.hsw = 8, +.hbp = 8, +.vfp = 4, +.vsw = 2, +.vbp = 2, +}; + +struct jbt_info { + u_int16_t tx_buf[4]; + struct spi_device *spi_dev; + int state; +}; + +static struct jbt_info _jbt, *jbt = &_jbt; + +#define JBT_COMMAND 0x000 +#define JBT_DATA 0x100 + +// FIXME: this should be passed from the board initialization structure or should be set by driver parameters +#define GPIO_CS (machine_is_gta04()?19:161) +#define GPIO_SCL (machine_is_gta04()?12:162) +#define GPIO_DIN (machine_is_gta04()?18:159) +#define GPIO_DOUT (machine_is_gta04()?20:158) + +#define SPI_READ() (gpio_get_value(GPIO_DIN)) +#define SPI_CS(bit) (gpio_set_value(GPIO_CS, bit)) +#define SPI_SDA(bit) (gpio_set_value(GPIO_DOUT, bit)) +#define SPI_SCL(bit) (gpio_set_value(GPIO_SCL, bit)) + +/* 150uS minimum clock cycle, we have two of this plus our other + * instructions */ + +#define SPI_DELAY() udelay(200) + +static int jbt_spi_xfer(int wordnum, int bitlen, u_int16_t *dout) +{ + u_int16_t tmpdout = 0; + int i, j; + +// printk("jbt_spi_xfer: dout %08X wordnum %u bitlen %d\n", *(uint *)dout, wordnum, bitlen); + + SPI_CS(0); + + for (i = 0; i < wordnum; i ++) { + tmpdout = dout[i]; + + for (j = 0; j < bitlen; j++) { + SPI_SCL(0); + if (tmpdout & (1 << (bitlen-1))) { + SPI_SDA(1); + if(SPI_READ() == 0) + return 1; + } else { + SPI_SDA(0); + if(SPI_READ() != 0) + return 1; + } + SPI_DELAY(); + SPI_SCL(1); + SPI_DELAY(); + tmpdout <<= 1; + } + } + + SPI_CS(1); + + return 0; +} + +#define JBT_COMMAND 0x000 +#define JBT_DATA 0x100 + +int jbt_reg_write_nodata(struct jbt_info *jbt, u_int8_t reg) +{ + int rc; + + jbt->tx_buf[0] = JBT_COMMAND | reg; + + rc = jbt_spi_xfer(1, 9, jbt->tx_buf); + + return rc; +} + + +int jbt_reg_write(struct jbt_info *jbt, u_int8_t reg, u_int8_t data) +{ + int rc; + + jbt->tx_buf[0] = JBT_COMMAND | reg; + jbt->tx_buf[1] = JBT_DATA | data; + + rc = jbt_spi_xfer(2, 9, jbt->tx_buf); + + return rc; +} + +int jbt_reg_write16(struct jbt_info *jbt, u_int8_t reg, u_int16_t data) +{ + int rc; + + jbt->tx_buf[0] = JBT_COMMAND | reg; + jbt->tx_buf[1] = JBT_DATA | (data >> 8); + jbt->tx_buf[2] = JBT_DATA | (data & 0xff); + + rc = jbt_spi_xfer(3, 9, jbt->tx_buf); + + return rc; +} + +int jbt_reg_init(void) +{ + int i; + int failed=0; + int r; + + printk("jbt_reg_init()\n"); + + SPI_CS(1); // unselect + SPI_SCL(1); // inactive + SPI_SDA(0); // default + + r = gpio_request(GPIO_CS, "TD028_CS"); + if(r < 0) + printk(KERN_ERR "Unable to get TD028_CS GPIO %d\n", GPIO_CS); + r = gpio_request(GPIO_SCL, "TD028_SCL"); + if(r < 0) + printk(KERN_ERR "Unable to get TD028_SCL GPIO %d\n", GPIO_SCL); + r = gpio_request(GPIO_DOUT, "TD028_DOUT"); + if(r < 0) + printk(KERN_ERR "Unable to get TD028_DOUT GPIO %d\n", GPIO_DOUT); + r = gpio_request(GPIO_DIN, "TD028_DIN"); + if(r < 0) + printk(KERN_ERR "Unable to get TD028_DIN GPIO %d\n", GPIO_DIN); + + gpio_direction_output(GPIO_CS, true); + gpio_direction_output(GPIO_SCL, true); + gpio_direction_output(GPIO_DOUT, true); + gpio_direction_input(GPIO_DIN); + + /* according to data sheet: wait 50ms (Tpos of LCM). However, 50ms + * seems unreliable with later LCM batches, increasing to 90ms */ + mdelay(90); + +#if 0 + for(i=0; i<16; i++) + { // check for connection between GPIO158 -> GPIO159; since we have 10 kOhm pse. make sure that the PUP/PDN is disabled in the MUX config! + int bit=i&1; + SPI_SDA(bit); // write bit + SPI_DELAY(); +#if 1 + printk("bit: %d out: %d in: %d (%d)\n", bit, gpio_get_value(GPIO_DOUT), gpio_get_value(GPIO_DIN), SPI_READ()); +#endif + if(SPI_READ() != bit) // did not read back correctly + failed++; + } + if(failed > 0) + { + printk(" machine_arch_type = %d (%d)\n", machine_arch_type, machine_is_gta04()); + printk("jbt_reg_init() - no correct response, assuming no connection between GPIO%d and GPIO%d\n", GPIO_DOUT, GPIO_DIN); + return 1; + } +#endif + + printk("did jbt_reg_init()\n"); + return 0; +} + +enum jbt_register { + JBT_REG_SLEEP_IN = 0x10, + JBT_REG_SLEEP_OUT = 0x11, + + JBT_REG_DISPLAY_OFF = 0x28, + JBT_REG_DISPLAY_ON = 0x29, + + JBT_REG_RGB_FORMAT = 0x3a, + JBT_REG_QUAD_RATE = 0x3b, + + JBT_REG_POWER_ON_OFF = 0xb0, + JBT_REG_BOOSTER_OP = 0xb1, + JBT_REG_BOOSTER_MODE = 0xb2, + JBT_REG_BOOSTER_FREQ = 0xb3, + JBT_REG_OPAMP_SYSCLK = 0xb4, + JBT_REG_VSC_VOLTAGE = 0xb5, + JBT_REG_VCOM_VOLTAGE = 0xb6, + JBT_REG_EXT_DISPL = 0xb7, + JBT_REG_OUTPUT_CONTROL = 0xb8, + JBT_REG_DCCLK_DCEV = 0xb9, + JBT_REG_DISPLAY_MODE1 = 0xba, + JBT_REG_DISPLAY_MODE2 = 0xbb, + JBT_REG_DISPLAY_MODE = 0xbc, + JBT_REG_ASW_SLEW = 0xbd, + JBT_REG_DUMMY_DISPLAY = 0xbe, + JBT_REG_DRIVE_SYSTEM = 0xbf, + + JBT_REG_SLEEP_OUT_FR_A = 0xc0, + JBT_REG_SLEEP_OUT_FR_B = 0xc1, + JBT_REG_SLEEP_OUT_FR_C = 0xc2, + JBT_REG_SLEEP_IN_LCCNT_D = 0xc3, + JBT_REG_SLEEP_IN_LCCNT_E = 0xc4, + JBT_REG_SLEEP_IN_LCCNT_F = 0xc5, + JBT_REG_SLEEP_IN_LCCNT_G = 0xc6, + + JBT_REG_GAMMA1_FINE_1 = 0xc7, + JBT_REG_GAMMA1_FINE_2 = 0xc8, + JBT_REG_GAMMA1_INCLINATION = 0xc9, + JBT_REG_GAMMA1_BLUE_OFFSET = 0xca, + + JBT_REG_BLANK_CONTROL = 0xcf, + JBT_REG_BLANK_TH_TV = 0xd0, + JBT_REG_CKV_ON_OFF = 0xd1, + JBT_REG_CKV_1_2 = 0xd2, + JBT_REG_OEV_TIMING = 0xd3, + JBT_REG_ASW_TIMING_1 = 0xd4, + JBT_REG_ASW_TIMING_2 = 0xd5, + + JBT_REG_HCLOCK_VGA = 0xec, + JBT_REG_HCLOCK_QVGA = 0xed, + +}; + +static int td028ttec1_panel_probe(struct omap_dss_device *dssdev) +{ + int rc; + + printk("td028ttec1_panel_probe()\n"); + dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_ONOFF | OMAP_DSS_LCD_IPC | OMAP_DSS_LCD_IVS | OMAP_DSS_LCD_IHS; + dssdev->panel.acb = 0x28; + dssdev->panel.timings = td028ttec1_panel_timings; + + rc = jbt_reg_init(); + + return 0; + return rc ? -ENODEV : 0; +} + +static void td028ttec1_panel_remove(struct omap_dss_device *dssdev) +{ + printk("td028ttec1_panel_remove()\n"); + // disable GPIOs? +} + +static int td028ttec1_panel_suspend(struct omap_dss_device *dssdev) +{ // normal_to_sleep() + int rc; + + printk("td028ttec1_panel_suspend()\n"); + + omapdss_dpi_display_disable(dssdev); + + 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); + + // turn off backlight + if (dssdev->platform_disable) + dssdev->platform_disable(dssdev); + + dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; + + return rc ? -EIO : 0; +} + +static int td028ttec1_panel_resume(struct omap_dss_device *dssdev) +{ // sleep_to_normal() + int rc; + + printk("td028ttec1_panel_resume()\n"); + /* RGB I/F on, RAM write 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); + + /* AVDD on, XVDD on */ + rc |= jbt_reg_write(jbt, JBT_REG_POWER_ON_OFF, 0x16); + + /* Output control */ + rc |= jbt_reg_write16(jbt, JBT_REG_OUTPUT_CONTROL, 0xfff9); + + /* Sleep mode off */ + rc |= jbt_reg_write_nodata(jbt, JBT_REG_SLEEP_OUT); + + /* at this point we have like 50% grey */ + + /* initialize register set */ + rc = jbt_reg_write(jbt, JBT_REG_DISPLAY_MODE1, 0x01); + rc |= jbt_reg_write(jbt, JBT_REG_DISPLAY_MODE2, 0x00); + rc |= jbt_reg_write(jbt, JBT_REG_RGB_FORMAT, 0x60); + rc |= jbt_reg_write(jbt, JBT_REG_DRIVE_SYSTEM, 0x10); + rc |= jbt_reg_write(jbt, JBT_REG_BOOSTER_OP, 0x56); + rc |= jbt_reg_write(jbt, JBT_REG_BOOSTER_MODE, 0x33); + rc |= jbt_reg_write(jbt, JBT_REG_BOOSTER_FREQ, 0x11); + rc |= jbt_reg_write(jbt, JBT_REG_BOOSTER_FREQ, 0x11); + rc |= jbt_reg_write(jbt, JBT_REG_OPAMP_SYSCLK, 0x02); + rc |= jbt_reg_write(jbt, JBT_REG_VSC_VOLTAGE, 0x2b); + rc |= jbt_reg_write(jbt, JBT_REG_VCOM_VOLTAGE, 0x40); + rc |= jbt_reg_write(jbt, JBT_REG_EXT_DISPL, 0x03); + rc |= jbt_reg_write(jbt, JBT_REG_DCCLK_DCEV, 0x04); + /* + * default of 0x02 in JBT_REG_ASW_SLEW responsible for 72Hz requirement + * to avoid red / blue flicker + */ + rc |= jbt_reg_write(jbt, JBT_REG_ASW_SLEW, 0x04); + rc |= jbt_reg_write(jbt, JBT_REG_DUMMY_DISPLAY, 0x00); + + rc |= jbt_reg_write(jbt, JBT_REG_SLEEP_OUT_FR_A, 0x11); + rc |= jbt_reg_write(jbt, JBT_REG_SLEEP_OUT_FR_B, 0x11); + rc |= jbt_reg_write(jbt, JBT_REG_SLEEP_OUT_FR_C, 0x11); + rc |= jbt_reg_write16(jbt, JBT_REG_SLEEP_IN_LCCNT_D, 0x2040); + rc |= jbt_reg_write16(jbt, JBT_REG_SLEEP_IN_LCCNT_E, 0x60c0); + rc |= jbt_reg_write16(jbt, JBT_REG_SLEEP_IN_LCCNT_F, 0x1020); + rc |= jbt_reg_write16(jbt, JBT_REG_SLEEP_IN_LCCNT_G, 0x60c0); + + rc |= jbt_reg_write16(jbt, JBT_REG_GAMMA1_FINE_1, 0x5533); + rc |= jbt_reg_write(jbt, JBT_REG_GAMMA1_FINE_2, 0x00); + rc |= jbt_reg_write(jbt, JBT_REG_GAMMA1_INCLINATION, 0x00); + rc |= jbt_reg_write(jbt, JBT_REG_GAMMA1_BLUE_OFFSET, 0x00); + rc |= jbt_reg_write(jbt, JBT_REG_GAMMA1_BLUE_OFFSET, 0x00); + + rc |= jbt_reg_write16(jbt, JBT_REG_HCLOCK_VGA, 0x1f0); + rc |= jbt_reg_write(jbt, JBT_REG_BLANK_CONTROL, 0x02); + rc |= jbt_reg_write16(jbt, JBT_REG_BLANK_TH_TV, 0x0804); + rc |= jbt_reg_write16(jbt, JBT_REG_BLANK_TH_TV, 0x0804); + + rc |= jbt_reg_write(jbt, JBT_REG_CKV_ON_OFF, 0x01); + rc |= jbt_reg_write16(jbt, JBT_REG_CKV_1_2, 0x0000); + + rc |= jbt_reg_write16(jbt, JBT_REG_OEV_TIMING, 0x0d0e); + rc |= jbt_reg_write16(jbt, JBT_REG_ASW_TIMING_1, 0x11a4); + rc |= jbt_reg_write(jbt, JBT_REG_ASW_TIMING_2, 0x0e); + +#if 0 + rc |= jbt_reg_write16(jbt, JBT_REG_HCLOCK_QVGA, 0x00ff); + rc |= jbt_reg_write16(jbt, JBT_REG_HCLOCK_QVGA, 0x00ff); +#endif + + jbt_reg_write_nodata(jbt, JBT_REG_DISPLAY_ON); + + rc = omapdss_dpi_display_enable(dssdev); + if(rc) + return -EIO; + + // turn on backlight + dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; + + return rc ? -EIO : 0; +} + +static int td028ttec1_panel_enable(struct omap_dss_device *dssdev) +{ + int rc = 0; + if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) + return rc; + + printk("td028ttec1_panel_enable()\n"); + + if (dssdev->platform_enable) + rc = dssdev->platform_enable(dssdev); // enable e.g. power, backlight + + if(rc) + return rc; + + // 1. standby_to_sleep() + + /* three times command zero */ + rc = jbt_reg_write_nodata(jbt, 0x00); + udelay(1000); + rc = jbt_reg_write_nodata(jbt, 0x00); + udelay(1000); + rc = jbt_reg_write_nodata(jbt, 0x00); + udelay(1000); + + /* deep standby out */ + rc |= jbt_reg_write(jbt, JBT_REG_POWER_ON_OFF, 0x17); + + // 2. sleep_to_normal() + + td028ttec1_panel_resume(dssdev); + + return rc ? -EIO : 0; +} + +static void td028ttec1_panel_disable(struct omap_dss_device *dssdev) +{ + printk("td028ttec1_panel_disable()\n"); + if (dssdev->platform_disable) + dssdev->platform_disable(dssdev); + + // 1. normal_to_sleep() + + td028ttec1_panel_suspend(dssdev); + + // 2. sleep_to_standby() + + jbt_reg_write(jbt, JBT_REG_POWER_ON_OFF, 0x00); + + dssdev->state=OMAP_DSS_DISPLAY_DISABLED; +} + +static void td028ttec1_panel_set_timings(struct omap_dss_device *dssdev, + struct omap_video_timings *timings) +{ + dpi_set_timings(dssdev, timings); +} + +static void td028ttec1_panel_get_timings(struct omap_dss_device *dssdev, + struct omap_video_timings *timings) +{ + *timings = dssdev->panel.timings; +} + +static int td028ttec1_panel_check_timings(struct omap_dss_device *dssdev, + struct omap_video_timings *timings) +{ + return dpi_check_timings(dssdev, timings); +} + +static struct omap_dss_driver td028ttec1_driver = { + .probe = td028ttec1_panel_probe, + .remove = td028ttec1_panel_remove, + + .enable = td028ttec1_panel_enable, + .disable = td028ttec1_panel_disable, + .suspend = td028ttec1_panel_suspend, + .resume = td028ttec1_panel_resume, + + .set_timings = td028ttec1_panel_set_timings, + .get_timings = td028ttec1_panel_get_timings, + .check_timings = td028ttec1_panel_check_timings, + + .driver = { + .name = "td028ttec1_panel", + .owner = THIS_MODULE, + }, +}; + +static int __init td028ttec1_panel_drv_init(void) +{ + return omap_dss_register_driver(&td028ttec1_driver); +} + +static void __exit td028ttec1_panel_drv_exit(void) +{ + omap_dss_unregister_driver(&td028ttec1_driver); +} + +module_init(td028ttec1_panel_drv_init); +module_exit(td028ttec1_panel_drv_exit); +MODULE_LICENSE("GPL"); |