diff options
Diffstat (limited to 'drivers/video/omap2')
25 files changed, 2017 insertions, 1778 deletions
diff --git a/drivers/video/omap2/displays/Kconfig b/drivers/video/omap2/displays/Kconfig index b12a59c9c50..dfb57ee5086 100644 --- a/drivers/video/omap2/displays/Kconfig +++ b/drivers/video/omap2/displays/Kconfig @@ -13,10 +13,28 @@ config PANEL_SHARP_LS037V7DW01 help LCD Panel used in TI's SDP3430 and EVM boards +config PANEL_SHARP_LQ043T1DG01 + tristate "Sharp LQ043T1DG01 LCD Panel" + depends on OMAP2_DSS + help + LCD Panel used in TI's OMAP3517 EVM boards + config PANEL_TAAL tristate "Taal DSI Panel" depends on OMAP2_DSS_DSI help Taal DSI command mode panel from TPO. +config PANEL_TOPPOLY_TDO35S + tristate "Toppoly TDO35S LCD Panel support" + depends on OMAP2_DSS + help + LCD Panel used in CM-T35 + +config PANEL_TPO_TD043MTEA1 + tristate "TPO TD043MTEA1 LCD Panel" + depends on OMAP2_DSS && I2C + help + LCD Panel used in OMAP3 Pandora + endmenu diff --git a/drivers/video/omap2/displays/Makefile b/drivers/video/omap2/displays/Makefile index 955646440b3..e2bb32168de 100644 --- a/drivers/video/omap2/displays/Makefile +++ b/drivers/video/omap2/displays/Makefile @@ -1,4 +1,7 @@ obj-$(CONFIG_PANEL_GENERIC) += panel-generic.o obj-$(CONFIG_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o +obj-$(CONFIG_PANEL_SHARP_LQ043T1DG01) += panel-sharp-lq043t1dg01.o obj-$(CONFIG_PANEL_TAAL) += panel-taal.o +obj-$(CONFIG_PANEL_TOPPOLY_TDO35S) += panel-toppoly-tdo35s.o +obj-$(CONFIG_PANEL_TPO_TD043MTEA1) += panel-tpo-td043mtea1.o diff --git a/drivers/video/omap2/displays/panel-generic.c b/drivers/video/omap2/displays/panel-generic.c index eb48d1afd80..c59e4baed8b 100644 --- a/drivers/video/omap2/displays/panel-generic.c +++ b/drivers/video/omap2/displays/panel-generic.c @@ -35,6 +35,35 @@ static struct omap_video_timings generic_panel_timings = { .vbp = 7, }; +static int generic_panel_power_on(struct omap_dss_device *dssdev) +{ + int r; + + r = omapdss_dpi_display_enable(dssdev); + if (r) + goto err0; + + if (dssdev->platform_enable) { + r = dssdev->platform_enable(dssdev); + if (r) + goto err1; + } + + return 0; +err1: + omapdss_dpi_display_disable(dssdev); +err0: + return r; +} + +static void generic_panel_power_off(struct omap_dss_device *dssdev) +{ + if (dssdev->platform_disable) + dssdev->platform_disable(dssdev); + + omapdss_dpi_display_disable(dssdev); +} + static int generic_panel_probe(struct omap_dss_device *dssdev) { dssdev->panel.config = OMAP_DSS_LCD_TFT; @@ -51,27 +80,40 @@ static int generic_panel_enable(struct omap_dss_device *dssdev) { int r = 0; - if (dssdev->platform_enable) - r = dssdev->platform_enable(dssdev); + r = generic_panel_power_on(dssdev); + if (r) + return r; - return r; + dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; + + return 0; } static void generic_panel_disable(struct omap_dss_device *dssdev) { - if (dssdev->platform_disable) - dssdev->platform_disable(dssdev); + generic_panel_power_off(dssdev); + + dssdev->state = OMAP_DSS_DISPLAY_DISABLED; } static int generic_panel_suspend(struct omap_dss_device *dssdev) { - generic_panel_disable(dssdev); + generic_panel_power_off(dssdev); + dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; return 0; } static int generic_panel_resume(struct omap_dss_device *dssdev) { - return generic_panel_enable(dssdev); + int r = 0; + + r = generic_panel_power_on(dssdev); + if (r) + return r; + + dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; + + return 0; } static struct omap_dss_driver generic_driver = { diff --git a/drivers/video/omap2/displays/panel-sharp-lq043t1dg01.c b/drivers/video/omap2/displays/panel-sharp-lq043t1dg01.c new file mode 100644 index 00000000000..10267461991 --- /dev/null +++ b/drivers/video/omap2/displays/panel-sharp-lq043t1dg01.c @@ -0,0 +1,159 @@ +/* + * LCD panel driver for Sharp LQ043T1DG01 + * + * Copyright (C) 2009 Texas Instruments Inc + * Author: Vaibhav Hiremath <hvaibhav@ti.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 <linux/device.h> +#include <linux/err.h> + +#include <plat/display.h> + +static struct omap_video_timings sharp_lq_timings = { + .x_res = 480, + .y_res = 272, + + .pixel_clock = 9000, + + .hsw = 42, + .hfp = 3, + .hbp = 2, + + .vsw = 11, + .vfp = 3, + .vbp = 2, +}; + +static int sharp_lq_panel_power_on(struct omap_dss_device *dssdev) +{ + int r; + + r = omapdss_dpi_display_enable(dssdev); + if (r) + goto err0; + + /* wait couple of vsyncs until enabling the LCD */ + msleep(50); + + if (dssdev->platform_enable) { + r = dssdev->platform_enable(dssdev); + if (r) + goto err1; + } + + return 0; +err1: + omapdss_dpi_display_disable(dssdev); +err0: + return r; +} + +static void sharp_lq_panel_power_off(struct omap_dss_device *dssdev) +{ + if (dssdev->platform_disable) + dssdev->platform_disable(dssdev); + + /* wait at least 5 vsyncs after disabling the LCD */ + msleep(100); + + omapdss_dpi_display_disable(dssdev); +} + +static int sharp_lq_panel_probe(struct omap_dss_device *dssdev) +{ + + dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS | + OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IEO; + dssdev->panel.acb = 0x0; + dssdev->panel.timings = sharp_lq_timings; + + return 0; +} + +static void sharp_lq_panel_remove(struct omap_dss_device *dssdev) +{ +} + +static int sharp_lq_panel_enable(struct omap_dss_device *dssdev) +{ + int r = 0; + + r = sharp_lq_panel_power_on(dssdev); + if (r) + return r; + + dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; + + return 0; +} + +static void sharp_lq_panel_disable(struct omap_dss_device *dssdev) +{ + sharp_lq_panel_power_off(dssdev); + + dssdev->state = OMAP_DSS_DISPLAY_DISABLED; +} + +static int sharp_lq_panel_suspend(struct omap_dss_device *dssdev) +{ + sharp_lq_panel_power_off(dssdev); + dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; + return 0; +} + +static int sharp_lq_panel_resume(struct omap_dss_device *dssdev) +{ + int r = 0; + + r = sharp_lq_panel_power_on(dssdev); + if (r) + return r; + + dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; + + return 0; +} + +static struct omap_dss_driver sharp_lq_driver = { + .probe = sharp_lq_panel_probe, + .remove = sharp_lq_panel_remove, + + .enable = sharp_lq_panel_enable, + .disable = sharp_lq_panel_disable, + .suspend = sharp_lq_panel_suspend, + .resume = sharp_lq_panel_resume, + + .driver = { + .name = "sharp_lq_panel", + .owner = THIS_MODULE, + }, +}; + +static int __init sharp_lq_panel_drv_init(void) +{ + return omap_dss_register_driver(&sharp_lq_driver); +} + +static void __exit sharp_lq_panel_drv_exit(void) +{ + omap_dss_unregister_driver(&sharp_lq_driver); +} + +module_init(sharp_lq_panel_drv_init); +module_exit(sharp_lq_panel_drv_exit); +MODULE_LICENSE("GPL"); diff --git a/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c index bbe880bbe79..8d51a5e6341 100644 --- a/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c +++ b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c @@ -20,19 +20,10 @@ #include <linux/module.h> #include <linux/delay.h> #include <linux/device.h> -#include <linux/regulator/consumer.h> #include <linux/err.h> #include <plat/display.h> -struct sharp_data { - /* XXX This regulator should actually be in SDP board file, not here, - * as it doesn't actually power the LCD, but something else that - * affects the output to LCD (I think. Somebody clarify). It doesn't do - * harm here, as SDP is the only board using this currently */ - struct regulator *vdvi_reg; -}; - static struct omap_video_timings sharp_ls_timings = { .x_res = 480, .y_res = 640, @@ -50,77 +41,81 @@ static struct omap_video_timings sharp_ls_timings = { static int sharp_ls_panel_probe(struct omap_dss_device *dssdev) { - struct sharp_data *sd; - dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS | OMAP_DSS_LCD_IHS; dssdev->panel.acb = 0x28; dssdev->panel.timings = sharp_ls_timings; - sd = kzalloc(sizeof(*sd), GFP_KERNEL); - if (!sd) - return -ENOMEM; - - dev_set_drvdata(&dssdev->dev, sd); - - sd->vdvi_reg = regulator_get(&dssdev->dev, "vdvi"); - if (IS_ERR(sd->vdvi_reg)) { - kfree(sd); - pr_err("failed to get VDVI regulator\n"); - return PTR_ERR(sd->vdvi_reg); - } - return 0; } static void sharp_ls_panel_remove(struct omap_dss_device *dssdev) { - struct sharp_data *sd = dev_get_drvdata(&dssdev->dev); - - regulator_put(sd->vdvi_reg); - - kfree(sd); } -static int sharp_ls_panel_enable(struct omap_dss_device *dssdev) +static int sharp_ls_power_on(struct omap_dss_device *dssdev) { - struct sharp_data *sd = dev_get_drvdata(&dssdev->dev); int r = 0; + r = omapdss_dpi_display_enable(dssdev); + if (r) + goto err0; + /* wait couple of vsyncs until enabling the LCD */ msleep(50); - regulator_enable(sd->vdvi_reg); - - if (dssdev->platform_enable) + if (dssdev->platform_enable) { r = dssdev->platform_enable(dssdev); + if (r) + goto err1; + } + return 0; +err1: + omapdss_dpi_display_disable(dssdev); +err0: return r; } -static void sharp_ls_panel_disable(struct omap_dss_device *dssdev) +static void sharp_ls_power_off(struct omap_dss_device *dssdev) { - struct sharp_data *sd = dev_get_drvdata(&dssdev->dev); - if (dssdev->platform_disable) dssdev->platform_disable(dssdev); - regulator_disable(sd->vdvi_reg); - /* wait at least 5 vsyncs after disabling the LCD */ msleep(100); + + omapdss_dpi_display_disable(dssdev); +} + +static int sharp_ls_panel_enable(struct omap_dss_device *dssdev) +{ + int r; + r = sharp_ls_power_on(dssdev); + dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; + return r; +} + +static void sharp_ls_panel_disable(struct omap_dss_device *dssdev) +{ + sharp_ls_power_off(dssdev); + dssdev->state = OMAP_DSS_DISPLAY_DISABLED; } static int sharp_ls_panel_suspend(struct omap_dss_device *dssdev) { - sharp_ls_panel_disable(dssdev); + sharp_ls_power_off(dssdev); + dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; return 0; } static int sharp_ls_panel_resume(struct omap_dss_device *dssdev) { - return sharp_ls_panel_enable(dssdev); + int r; + r = sharp_ls_power_on(dssdev); + dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; + return r; } static struct omap_dss_driver sharp_ls_driver = { diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c index 1f01dfc5e52..fcd6a61a91e 100644 --- a/drivers/video/omap2/displays/panel-taal.c +++ b/drivers/video/omap2/displays/panel-taal.c @@ -63,6 +63,8 @@ /* #define TAAL_USE_ESD_CHECK */ #define TAAL_ESD_CHECK_PERIOD msecs_to_jiffies(5000) +static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable); + struct taal_data { struct backlight_device *bldev; @@ -510,15 +512,12 @@ static int taal_probe(struct omap_dss_device *dssdev) if (td->esd_wq == NULL) { dev_err(&dssdev->dev, "can't create ESD workqueue\n"); r = -ENOMEM; - goto err2; + goto err1; } INIT_DELAYED_WORK_DEFERRABLE(&td->esd_work, taal_esd_work); dev_set_drvdata(&dssdev->dev, td); - dssdev->get_timings = taal_get_timings; - dssdev->get_resolution = taal_get_resolution; - /* if no platform set_backlight() defined, presume DSI backlight * control */ if (!dssdev->set_backlight) @@ -528,7 +527,7 @@ static int taal_probe(struct omap_dss_device *dssdev) &taal_bl_ops); if (IS_ERR(bldev)) { r = PTR_ERR(bldev); - goto err1; + goto err2; } td->bldev = bldev; @@ -621,14 +620,12 @@ static void taal_remove(struct omap_dss_device *dssdev) kfree(td); } -static int taal_enable(struct omap_dss_device *dssdev) +static int taal_power_on(struct omap_dss_device *dssdev) { struct taal_data *td = dev_get_drvdata(&dssdev->dev); u8 id1, id2, id3; int r; - dev_dbg(&dssdev->dev, "enable\n"); - if (dssdev->platform_enable) { r = dssdev->platform_enable(dssdev); if (r) @@ -638,6 +635,16 @@ static int taal_enable(struct omap_dss_device *dssdev) /* it seems we have to wait a bit until taal is ready */ msleep(5); + dsi_bus_lock(); + + r = omapdss_dsi_display_enable(dssdev); + if (r) { + dev_err(&dssdev->dev, "failed to enable DSI\n"); + goto err0; + } + + omapdss_dsi_vc_enable_hs(TCH, false); + r = taal_sleep_out(td); if (r) goto err; @@ -661,6 +668,10 @@ static int taal_enable(struct omap_dss_device *dssdev) taal_dcs_write_0(DCS_DISPLAY_ON); + r = _taal_enable_te(dssdev, td->te_enabled); + if (r) + goto err; + #ifdef TAAL_USE_ESD_CHECK queue_delayed_work(td->esd_wq, &td->esd_work, TAAL_ESD_CHECK_PERIOD); #endif @@ -676,19 +687,27 @@ static int taal_enable(struct omap_dss_device *dssdev) td->intro_printed = true; } + omapdss_dsi_vc_enable_hs(TCH, true); + + dsi_bus_unlock(); + return 0; err: + dsi_bus_unlock(); + + omapdss_dsi_display_disable(dssdev); +err0: if (dssdev->platform_disable) dssdev->platform_disable(dssdev); return r; } -static void taal_disable(struct omap_dss_device *dssdev) +static void taal_power_off(struct omap_dss_device *dssdev) { struct taal_data *td = dev_get_drvdata(&dssdev->dev); - dev_dbg(&dssdev->dev, "disable\n"); + dsi_bus_lock(); cancel_delayed_work(&td->esd_work); @@ -698,41 +717,124 @@ static void taal_disable(struct omap_dss_device *dssdev) /* wait a bit so that the message goes through */ msleep(10); + omapdss_dsi_display_disable(dssdev); + if (dssdev->platform_disable) dssdev->platform_disable(dssdev); td->enabled = 0; + + dsi_bus_unlock(); +} + +static int taal_enable(struct omap_dss_device *dssdev) +{ + int r; + dev_dbg(&dssdev->dev, "enable\n"); + + if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) + return -EINVAL; + + r = taal_power_on(dssdev); + if (r) + return r; + + dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; + + return r; +} + +static void taal_disable(struct omap_dss_device *dssdev) +{ + dev_dbg(&dssdev->dev, "disable\n"); + + if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) + taal_power_off(dssdev); + + dssdev->state = OMAP_DSS_DISPLAY_DISABLED; } static int taal_suspend(struct omap_dss_device *dssdev) { - struct taal_data *td = dev_get_drvdata(&dssdev->dev); - struct backlight_device *bldev = td->bldev; + dev_dbg(&dssdev->dev, "suspend\n"); - bldev->props.power = FB_BLANK_POWERDOWN; - taal_bl_update_status(bldev); + if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) + return -EINVAL; + + taal_power_off(dssdev); + dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; return 0; } static int taal_resume(struct omap_dss_device *dssdev) { + int r; + dev_dbg(&dssdev->dev, "resume\n"); + + if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) + return -EINVAL; + + r = taal_power_on(dssdev); + dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; + return r; +} + +static void taal_framedone_cb(int err, void *data) +{ + struct omap_dss_device *dssdev = data; + dev_dbg(&dssdev->dev, "framedone, err %d\n", err); + dsi_bus_unlock(); +} + +static int taal_update(struct omap_dss_device *dssdev, + u16 x, u16 y, u16 w, u16 h) +{ struct taal_data *td = dev_get_drvdata(&dssdev->dev); - struct backlight_device *bldev = td->bldev; + int r; - bldev->props.power = FB_BLANK_UNBLANK; - taal_bl_update_status(bldev); + dev_dbg(&dssdev->dev, "update %d, %d, %d x %d\n", x, y, w, h); + + dsi_bus_lock(); + + if (!td->enabled) { + r = 0; + goto err; + } + + r = omap_dsi_prepare_update(dssdev, &x, &y, &w, &h); + if (r) + goto err; + + r = taal_set_update_window(x, y, w, h); + if (r) + goto err; + + r = omap_dsi_update(dssdev, TCH, x, y, w, h, + taal_framedone_cb, dssdev); + if (r) + goto err; + /* note: no bus_unlock here. unlock is in framedone_cb */ return 0; +err: + dsi_bus_unlock(); + return r; } -static void taal_setup_update(struct omap_dss_device *dssdev, - u16 x, u16 y, u16 w, u16 h) +static int taal_sync(struct omap_dss_device *dssdev) { - taal_set_update_window(x, y, w, h); + dev_dbg(&dssdev->dev, "sync\n"); + + dsi_bus_lock(); + dsi_bus_unlock(); + + dev_dbg(&dssdev->dev, "sync done\n"); + + return 0; } -static int taal_enable_te(struct omap_dss_device *dssdev, bool enable) +static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable) { struct taal_data *td = dev_get_drvdata(&dssdev->dev); int r; @@ -744,25 +846,32 @@ static int taal_enable_te(struct omap_dss_device *dssdev, bool enable) else r = taal_dcs_write_0(DCS_TEAR_OFF); + omapdss_dsi_enable_te(dssdev, enable); + + /* XXX for some reason, DSI TE breaks if we don't wait here. + * Panel bug? Needs more studying */ + msleep(100); + return r; } -static int taal_wait_te(struct omap_dss_device *dssdev) +static int taal_enable_te(struct omap_dss_device *dssdev, bool enable) { - struct taal_data *td = dev_get_drvdata(&dssdev->dev); - long wait = msecs_to_jiffies(500); + int r; - if (!td->use_ext_te || !td->te_enabled) - return 0; + dsi_bus_lock(); - INIT_COMPLETION(td->te_completion); - wait = wait_for_completion_timeout(&td->te_completion, wait); - if (wait == 0) { - dev_err(&dssdev->dev, "timeout waiting TE\n"); - return -ETIME; - } + r = _taal_enable_te(dssdev, enable); - return 0; + dsi_bus_unlock(); + + return r; +} + +static int taal_get_te(struct omap_dss_device *dssdev) +{ + struct taal_data *td = dev_get_drvdata(&dssdev->dev); + return td->te_enabled; } static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate) @@ -772,16 +881,21 @@ static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate) dev_dbg(&dssdev->dev, "rotate %d\n", rotate); + dsi_bus_lock(); + if (td->enabled) { r = taal_set_addr_mode(rotate, td->mirror); - if (r) - return r; + goto err; } td->rotate = rotate; + dsi_bus_unlock(); return 0; +err: + dsi_bus_unlock(); + return r; } static u8 taal_get_rotate(struct omap_dss_device *dssdev) @@ -797,16 +911,20 @@ static int taal_mirror(struct omap_dss_device *dssdev, bool enable) dev_dbg(&dssdev->dev, "mirror %d\n", enable); + dsi_bus_lock(); if (td->enabled) { r = taal_set_addr_mode(td->rotate, enable); - if (r) - return r; + goto err; } td->mirror = enable; + dsi_bus_unlock(); return 0; +err: + dsi_bus_unlock(); + return r; } static bool taal_get_mirror(struct omap_dss_device *dssdev) @@ -820,17 +938,23 @@ static int taal_run_test(struct omap_dss_device *dssdev, int test_num) u8 id1, id2, id3; int r; + dsi_bus_lock(); + r = taal_dcs_read_1(DCS_GET_ID1, &id1); if (r) - return r; + goto err; r = taal_dcs_read_1(DCS_GET_ID2, &id2); if (r) - return r; + goto err; r = taal_dcs_read_1(DCS_GET_ID3, &id3); if (r) - return r; + goto err; + dsi_bus_unlock(); return 0; +err: + dsi_bus_unlock(); + return r; } static int taal_memory_read(struct omap_dss_device *dssdev, @@ -841,6 +965,10 @@ static int taal_memory_read(struct omap_dss_device *dssdev, int first = 1; int plen; unsigned buf_used = 0; + struct taal_data *td = dev_get_drvdata(&dssdev->dev); + + if (!td->enabled) + return -ENODEV; if (size < w * h * 3) return -ENOMEM; @@ -849,6 +977,8 @@ static int taal_memory_read(struct omap_dss_device *dssdev, dssdev->panel.timings.x_res * dssdev->panel.timings.y_res * 3); + dsi_bus_lock(); + /* plen 1 or 2 goes into short packet. until checksum error is fixed, * use short packets. plen 32 works, but bigger packets seem to cause * an error. */ @@ -857,11 +987,11 @@ static int taal_memory_read(struct omap_dss_device *dssdev, else plen = 2; - taal_setup_update(dssdev, x, y, w, h); + taal_set_update_window(x, y, w, h); r = dsi_vc_set_max_rx_packet_size(TCH, plen); if (r) - return r; + goto err0; while (buf_used < size) { u8 dcs_cmd = first ? 0x2e : 0x3e; @@ -894,7 +1024,8 @@ static int taal_memory_read(struct omap_dss_device *dssdev, err: dsi_vc_set_max_rx_packet_size(TCH, 1); - +err0: + dsi_bus_unlock(); return r; } @@ -939,8 +1070,11 @@ static void taal_esd_work(struct work_struct *work) } /* Self-diagnostics result is also shown on TE GPIO line. We need * to re-enable TE after self diagnostics */ - if (td->use_ext_te && td->te_enabled) - taal_enable_te(dssdev, true); + if (td->use_ext_te && td->te_enabled) { + r = taal_dcs_write_1(DCS_TEAR_ON, 0); + if (r) + goto err; + } dsi_bus_unlock(); @@ -958,6 +1092,20 @@ err: queue_delayed_work(td->esd_wq, &td->esd_work, TAAL_ESD_CHECK_PERIOD); } +static int taal_set_update_mode(struct omap_dss_device *dssdev, + enum omap_dss_update_mode mode) +{ + if (mode != OMAP_DSS_UPDATE_MANUAL) + return -EINVAL; + return 0; +} + +static enum omap_dss_update_mode taal_get_update_mode( + struct omap_dss_device *dssdev) +{ + return OMAP_DSS_UPDATE_MANUAL; +} + static struct omap_dss_driver taal_driver = { .probe = taal_probe, .remove = taal_remove, @@ -967,9 +1115,18 @@ static struct omap_dss_driver taal_driver = { .suspend = taal_suspend, .resume = taal_resume, - .setup_update = taal_setup_update, + .set_update_mode = taal_set_update_mode, + .get_update_mode = taal_get_update_mode, + + .update = taal_update, + .sync = taal_sync, + + .get_resolution = taal_get_resolution, + .get_recommended_bpp = omapdss_default_get_recommended_bpp, + .enable_te = taal_enable_te, - .wait_for_te = taal_wait_te, + .get_te = taal_get_te, + .set_rotate = taal_rotate, .get_rotate = taal_get_rotate, .set_mirror = taal_mirror, @@ -977,6 +1134,8 @@ static struct omap_dss_driver taal_driver = { .run_test = taal_run_test, .memory_read = taal_memory_read, + .get_timings = taal_get_timings, + .driver = { .name = "taal", .owner = THIS_MODULE, diff --git a/drivers/video/omap2/displays/panel-toppoly-tdo35s.c b/drivers/video/omap2/displays/panel-toppoly-tdo35s.c new file mode 100644 index 00000000000..fa434ca6e4b --- /dev/null +++ b/drivers/video/omap2/displays/panel-toppoly-tdo35s.c @@ -0,0 +1,154 @@ +/* + * LCD panel driver for Toppoly TDO35S + * + * Copyright (C) 2009 CompuLab, Ltd. + * Author: Mike Rapoport <mike@compulab.co.il> + * + * Based on generic panel support + * Copyright (C) 2008 Nokia Corporation + * Author: Tomi Valkeinen <tomi.valkeinen@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/module.h> +#include <linux/delay.h> + +#include <plat/display.h> + +static struct omap_video_timings toppoly_tdo_panel_timings = { + /* 640 x 480 @ 60 Hz Reduced blanking VESA CVT 0.31M3-R */ + .x_res = 480, + .y_res = 640, + + .pixel_clock = 26000, + + .hfp = 104, + .hsw = 8, + .hbp = 8, + + .vfp = 4, + .vsw = 2, + .vbp = 2, +}; + +static int toppoly_tdo_panel_power_on(struct omap_dss_device *dssdev) +{ + int r; + + r = omapdss_dpi_display_enable(dssdev); + if (r) + goto err0; + + if (dssdev->platform_enable) { + r = dssdev->platform_enable(dssdev); + if (r) + goto err1; + } + + return 0; +err1: + omapdss_dpi_display_disable(dssdev); +err0: + return r; +} + +static void toppoly_tdo_panel_power_off(struct omap_dss_device *dssdev) +{ + if (dssdev->platform_disable) + dssdev->platform_disable(dssdev); + + omapdss_dpi_display_disable(dssdev); +} + +static int toppoly_tdo_panel_probe(struct omap_dss_device *dssdev) +{ + dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS | + OMAP_DSS_LCD_IHS; + dssdev->panel.timings = toppoly_tdo_panel_timings; + + return 0; +} + +static void toppoly_tdo_panel_remove(struct omap_dss_device *dssdev) +{ +} + +static int toppoly_tdo_panel_enable(struct omap_dss_device *dssdev) +{ + int r = 0; + + r = toppoly_tdo_panel_power_on(dssdev); + if (r) + return r; + + dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; + + return 0; +} + +static void toppoly_tdo_panel_disable(struct omap_dss_device *dssdev) +{ + toppoly_tdo_panel_power_off(dssdev); + + dssdev->state = OMAP_DSS_DISPLAY_DISABLED; +} + +static int toppoly_tdo_panel_suspend(struct omap_dss_device *dssdev) +{ + toppoly_tdo_panel_power_off(dssdev); |