/*
 * 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,
		.pixelclock	= 13500000,
		.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);
}
