/*
 * 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;
		omapdss_venc_set_type(dssdev, 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;
	}

	omapdss_venc_set_timings(dssdev, &dssdev->panel.timings);
	omapdss_venc_set_type(dssdev, dssdev->phy.venc.type);
	omapdss_venc_invert_vid_out_polarity(dssdev,
		dssdev->phy.venc.invert_polarity);

	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;

	omapdss_venc_display_disable(dssdev);

	dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
end:
	mutex_unlock(&venc_panel.lock);
}

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);
	dssdev->panel.timings = *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,

	.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);
}
