diff options
author | Archit Taneja <archit@ti.com> | 2012-07-06 20:52:37 +0530 |
---|---|---|
committer | Archit Taneja <archit@ti.com> | 2012-08-15 15:49:23 +0530 |
commit | 156fd99e92c30b0a894f7f4874c6901bfdc65c44 (patch) | |
tree | 7b40d42af877119d5c23ab5a1f147298fc8d4d7d /drivers/video/omap2/dss/venc_panel.c | |
parent | 9b4a5716ef54bbf2f57c75f790b12fc63a4be640 (diff) |
OMAPDSS: VENC: Split VENC into interface and panel driver
The current venc.c driver contains both the interface and panel driver code.
This makes the driver hard to read, and difficult to understand the work split
between the interface and panel driver and the how the locking works.
This also makes it easier to clearly define the VENC interface ops called by the
panel driver.
Split venc.c into venc.c and venc_panel.c representing the interface and panel
driver respectively. This split is done along the lines of the HDMI interface
and panel drivers.
Signed-off-by: Archit Taneja <archit@ti.com>
Diffstat (limited to 'drivers/video/omap2/dss/venc_panel.c')
-rw-r--r-- | drivers/video/omap2/dss/venc_panel.c | 244 |
1 files changed, 244 insertions, 0 deletions
diff --git a/drivers/video/omap2/dss/venc_panel.c b/drivers/video/omap2/dss/venc_panel.c new file mode 100644 index 00000000000..cfed9077d2f --- /dev/null +++ b/drivers/video/omap2/dss/venc_panel.c @@ -0,0 +1,244 @@ +/* + * Copyright (C) 2009 Nokia Corporation + * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com> + * + * VENC panel driver + * + * 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/err.h> +#include <linux/io.h> +#include <linux/mutex.h> +#include <linux/module.h> + +#include <video/omapdss.h> + +#include "dss.h" + +static struct { + struct mutex lock; +} venc_panel; + +static ssize_t display_output_type_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct omap_dss_device *dssdev = to_dss_device(dev); + const char *ret; + + switch (dssdev->phy.venc.type) { + case OMAP_DSS_VENC_TYPE_COMPOSITE: + ret = "composite"; + break; + case OMAP_DSS_VENC_TYPE_SVIDEO: + ret = "svideo"; + break; + default: + return -EINVAL; + } + + return snprintf(buf, PAGE_SIZE, "%s\n", ret); +} + +static ssize_t display_output_type_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t size) +{ + struct omap_dss_device *dssdev = to_dss_device(dev); + enum omap_dss_venc_type new_type; + + if (sysfs_streq("composite", buf)) + new_type = OMAP_DSS_VENC_TYPE_COMPOSITE; + else if (sysfs_streq("svideo", buf)) + new_type = OMAP_DSS_VENC_TYPE_SVIDEO; + else + return -EINVAL; + + mutex_lock(&venc_panel.lock); + + if (dssdev->phy.venc.type != new_type) { + dssdev->phy.venc.type = new_type; + if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) { + omapdss_venc_display_disable(dssdev); + omapdss_venc_display_enable(dssdev); + } + } + + mutex_unlock(&venc_panel.lock); + + return size; +} + +static DEVICE_ATTR(output_type, S_IRUGO | S_IWUSR, + display_output_type_show, display_output_type_store); + +static int venc_panel_probe(struct omap_dss_device *dssdev) +{ + /* set default timings to PAL */ + const struct omap_video_timings default_timings = { + .x_res = 720, + .y_res = 574, + .pixel_clock = 13500, + .hsw = 64, + .hfp = 12, + .hbp = 68, + .vsw = 5, + .vfp = 5, + .vbp = 41, + + .vsync_level = OMAPDSS_SIG_ACTIVE_HIGH, + .hsync_level = OMAPDSS_SIG_ACTIVE_HIGH, + + .interlace = true, + }; + + mutex_init(&venc_panel.lock); + + dssdev->panel.timings = default_timings; + + return device_create_file(&dssdev->dev, &dev_attr_output_type); +} + +static void venc_panel_remove(struct omap_dss_device *dssdev) +{ + device_remove_file(&dssdev->dev, &dev_attr_output_type); +} + +static int venc_panel_enable(struct omap_dss_device *dssdev) +{ + int r; + + dev_dbg(&dssdev->dev, "venc_panel_enable\n"); + + mutex_lock(&venc_panel.lock); + + if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) { + r = -EINVAL; + goto err; + } + + r = omapdss_venc_display_enable(dssdev); + if (r) + goto err; + + dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; + + mutex_unlock(&venc_panel.lock); + + return 0; +err: + mutex_unlock(&venc_panel.lock); + + return r; +} + +static void venc_panel_disable(struct omap_dss_device *dssdev) +{ + dev_dbg(&dssdev->dev, "venc_panel_disable\n"); + + mutex_lock(&venc_panel.lock); + + if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED) + goto end; + + if (dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED) { + /* suspended is the same as disabled with venc */ + dssdev->state = OMAP_DSS_DISPLAY_DISABLED; + goto end; + } + + omapdss_venc_display_disable(dssdev); + + dssdev->state = OMAP_DSS_DISPLAY_DISABLED; +end: + mutex_unlock(&venc_panel.lock); +} + +static int venc_panel_suspend(struct omap_dss_device *dssdev) +{ + venc_panel_disable(dssdev); + return 0; +} + +static int venc_panel_resume(struct omap_dss_device *dssdev) +{ + return venc_panel_enable(dssdev); +} + +static void venc_panel_set_timings(struct omap_dss_device *dssdev, + struct omap_video_timings *timings) +{ + dev_dbg(&dssdev->dev, "venc_panel_set_timings\n"); + + mutex_lock(&venc_panel.lock); + + omapdss_venc_set_timings(dssdev, timings); + + mutex_unlock(&venc_panel.lock); +} + +static int venc_panel_check_timings(struct omap_dss_device *dssdev, + struct omap_video_timings *timings) +{ + dev_dbg(&dssdev->dev, "venc_panel_check_timings\n"); + + return omapdss_venc_check_timings(dssdev, timings); +} + +static u32 venc_panel_get_wss(struct omap_dss_device *dssdev) +{ + dev_dbg(&dssdev->dev, "venc_panel_get_wss\n"); + + return omapdss_venc_get_wss(dssdev); +} + +static int venc_panel_set_wss(struct omap_dss_device *dssdev, u32 wss) +{ + dev_dbg(&dssdev->dev, "venc_panel_set_wss\n"); + + return omapdss_venc_set_wss(dssdev, wss); +} + +static struct omap_dss_driver venc_driver = { + .probe = venc_panel_probe, + .remove = venc_panel_remove, + + .enable = venc_panel_enable, + .disable = venc_panel_disable, + .suspend = venc_panel_suspend, + .resume = venc_panel_resume, + + .get_resolution = omapdss_default_get_resolution, + .get_recommended_bpp = omapdss_default_get_recommended_bpp, + + .set_timings = venc_panel_set_timings, + .check_timings = venc_panel_check_timings, + + .get_wss = venc_panel_get_wss, + .set_wss = venc_panel_set_wss, + + .driver = { + .name = "venc", + .owner = THIS_MODULE, + }, +}; + +int venc_panel_init(void) +{ + return omap_dss_register_driver(&venc_driver); +} + +void venc_panel_exit(void) +{ + omap_dss_unregister_driver(&venc_driver); +} |