From patchwork Mon Apr 18 06:15:46 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: MAYURESH JANORKAR X-Patchwork-Id: 714281 X-Patchwork-Delegate: tomi.valkeinen@nokia.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p3I5xE6V024334 for ; Mon, 18 Apr 2011 05:59:14 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752288Ab1DRF7M (ORCPT ); Mon, 18 Apr 2011 01:59:12 -0400 Received: from comal.ext.ti.com ([198.47.26.152]:53857 "EHLO comal.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751911Ab1DRF7L (ORCPT ); Mon, 18 Apr 2011 01:59:11 -0400 Received: from dlep34.itg.ti.com ([157.170.170.115]) by comal.ext.ti.com (8.13.7/8.13.7) with ESMTP id p3I5xBPh013464 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Mon, 18 Apr 2011 00:59:11 -0500 Received: from legion.dal.design.ti.com (localhost [127.0.0.1]) by dlep34.itg.ti.com (8.13.7/8.13.7) with ESMTP id p3I5x8Eq006120; Mon, 18 Apr 2011 00:59:08 -0500 (CDT) Received: from localhost (ldc-172024137131.apr.dhcp.ti.com [172.24.137.131]) by legion.dal.design.ti.com (8.11.7p1+Sun/8.11.7) with ESMTP id p3I5x6f25723; Mon, 18 Apr 2011 00:59:06 -0500 (CDT) From: Mayuresh Janorkar To: linux-omap@vger.kernel.org Cc: tomi.valkeinen@ti.com, Mythri P K , Mayuresh Janorkar Subject: [PATCH 3/7] OMAP: DSS: Adding a picodlp panel driver Date: Mon, 18 Apr 2011 11:45:46 +0530 Message-Id: <1303107350-22747-4-git-send-email-mayur@ti.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1303107350-22747-1-git-send-email-mayur@ti.com> References: <1303107350-22747-1-git-send-email-mayur@ti.com> Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Mon, 18 Apr 2011 05:59:14 +0000 (UTC) From: Mythri P K A projector panel named picodlp is supported by OMAP. panel driver is required to be added with the name picodlp_panel. It is a WVGA panel with resolution 864 X 480 and panel timing data is defined in the panel driver. picodlp makes use of parallel (DPI) interface multiplexed with secondary lcd in case of OMAP4. Signed-off-by: Mythri P K Signed-off-by: Mayuresh Janorkar --- drivers/video/omap2/displays/panel-picodlp.c | 228 ++++++++++++++++++++++++++ 1 files changed, 228 insertions(+), 0 deletions(-) create mode 100644 drivers/video/omap2/displays/panel-picodlp.c diff --git a/drivers/video/omap2/displays/panel-picodlp.c b/drivers/video/omap2/displays/panel-picodlp.c new file mode 100644 index 0000000..4f12903 --- /dev/null +++ b/drivers/video/omap2/displays/panel-picodlp.c @@ -0,0 +1,228 @@ +/* + * picodlp panel driver + * + * Copyright (C) 2009-2011 Texas Instruments + * Author: Mythri P K + * + * 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 . + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +struct picodlp_data { + struct mutex lock; +}; + +static struct omap_video_timings pico_ls_timings = { + .x_res = 864, + .y_res = 480, + .hsw = 7, + .hfp = 11, + .hbp = 7, + + .pixel_clock = 19200, + + .vsw = 2, + .vfp = 3, + .vbp = 14, +}; + +static int picodlp_panel_power_on(struct omap_dss_device *dssdev) +{ + int r; + + if (dssdev->platform_enable) { + r = dssdev->platform_enable(dssdev); + if (r) + return r; + } + + r = omapdss_dpi_display_enable(dssdev); + if (r) { + dev_err(&dssdev->dev, "failed to enable DPI\n"); + goto err; + } + /* after enabling, wait for some initialize sync interrupts */ + msleep(675); + dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; + + return 0; + +err: + if (dssdev->platform_disable) + dssdev->platform_disable(dssdev); + + return r; +} + +static void picodlp_panel_power_off(struct omap_dss_device *dssdev) +{ + omapdss_dpi_display_disable(dssdev); + + if (dssdev->platform_disable) + dssdev->platform_disable(dssdev); +} + +static int picodlp_panel_probe(struct omap_dss_device *dssdev) +{ + struct picodlp_data *picod; + + dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_ONOFF | + OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IVS; + dssdev->panel.acb = 0x0; + dssdev->panel.timings = pico_ls_timings; + + picod = kzalloc(sizeof(struct picodlp_data), GFP_KERNEL); + if (!picod) + return -ENOMEM; + + mutex_init(&picod->lock); + dev_set_drvdata(&dssdev->dev, picod); + return 0; +} + +static void picodlp_panel_remove(struct omap_dss_device *dssdev) +{ + struct picodlp_data *picod = dev_get_drvdata(&dssdev->dev); + + dev_set_drvdata(&dssdev->dev, NULL); + dev_dbg(&dssdev->dev, " removing picodlp panel\n"); + kfree(picod); +} + +static int picodlp_panel_enable(struct omap_dss_device *dssdev) +{ + struct picodlp_data *picod = dev_get_drvdata(&dssdev->dev); + int r; + + dev_dbg(&dssdev->dev, "enabling picodlp panel\n"); + + mutex_lock(&picod->lock); + if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) { + mutex_unlock(&picod->lock); + return -EINVAL; + } + + r = picodlp_panel_power_on(dssdev); + mutex_unlock(&picod->lock); + + return r; +} + +static void picodlp_panel_disable(struct omap_dss_device *dssdev) +{ + struct picodlp_data *picod = dev_get_drvdata(&dssdev->dev); + + mutex_lock(&picod->lock); + /* Turn off DLP Power */ + if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) + picodlp_panel_power_off(dssdev); + + dev_dbg(&dssdev->dev, " disabling picodlp panel\n"); + dssdev->state = OMAP_DSS_DISPLAY_DISABLED; + + mutex_unlock(&picod->lock); +} + +static int picodlp_panel_suspend(struct omap_dss_device *dssdev) +{ + struct picodlp_data *picod = dev_get_drvdata(&dssdev->dev); + + mutex_lock(&picod->lock); + /* Turn off DLP Power */ + if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) { + dev_dbg(&dssdev->dev, " unable to suspend picodlp panel,"\ + " panel is not ACTIVE\n"); + mutex_unlock(&picod->lock); + return -EINVAL; + } + + picodlp_panel_power_off(dssdev); + + dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; + dev_dbg(&dssdev->dev, " suspending picodlp panel\n"); + + mutex_unlock(&picod->lock); + return 0; +} + +static int picodlp_panel_resume(struct omap_dss_device *dssdev) +{ + struct picodlp_data *picod = dev_get_drvdata(&dssdev->dev); + int r; + + mutex_lock(&picod->lock); + if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) { + dev_dbg(&dssdev->dev, " unable to resume picodlp panel," + " panel is not ACTIVE\n"); + mutex_unlock(&picod->lock); + return -EINVAL; + } + + dev_dbg(&dssdev->dev, " resuming picodlp panel\n"); + r = picodlp_panel_power_on(dssdev); + mutex_unlock(&picod->lock); + + return r; +} + +static void picodlp_get_resolution(struct omap_dss_device *dssdev, + u16 *xres, u16 *yres) +{ + *xres = dssdev->panel.timings.x_res; + *yres = dssdev->panel.timings.y_res; +} + +static struct omap_dss_driver picodlp_driver = { + .probe = picodlp_panel_probe, + .remove = picodlp_panel_remove, + + .enable = picodlp_panel_enable, + .disable = picodlp_panel_disable, + + .get_resolution = picodlp_get_resolution, + + .suspend = picodlp_panel_suspend, + .resume = picodlp_panel_resume, + + .driver = { + .name = "picodlp_panel", + .owner = THIS_MODULE, + }, +}; + +static int __init picodlp_init(void) +{ + return omap_dss_register_driver(&picodlp_driver); +} + +static void __exit picodlp_exit(void) +{ + omap_dss_unregister_driver(&picodlp_driver); +} + +module_init(picodlp_init); +module_exit(picodlp_exit); + +MODULE_AUTHOR("Mythri P K "); +MODULE_DESCRIPTION("picodlp driver"); +MODULE_LICENSE("GPL");