/*
 * Copyright (C) 2010 Texas Instruments Inc
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation version 2.
 *
 * 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, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/ctype.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/videodev2.h>
#include <linux/slab.h>

#include <mach/hardware.h>
#include <mach/mux.h>
#include <mach/io.h>
#include <mach/i2c.h>

#include <linux/io.h>

#include <media/davinci/vpbe_types.h>
#include <media/davinci/vpbe_venc.h>
#include <media/davinci/vpss.h>
#include <media/v4l2-device.h>

#include "vpbe_venc_regs.h"

#define MODULE_NAME	VPBE_VENC_SUBDEV_NAME

static int debug = 2;
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "Debug level 0-2");

struct venc_state {
	struct v4l2_subdev sd;
	struct venc_callback *callback;
	struct venc_platform_data *pdata;
	struct device *pdev;
	u32 output;
	v4l2_std_id std;
	spinlock_t lock;
	void __iomem *venc_base;
	void __iomem *vdaccfg_reg;
};

static inline struct venc_state *to_state(struct v4l2_subdev *sd)
{
	return container_of(sd, struct venc_state, sd);
}

static inline u32 venc_read(struct v4l2_subdev *sd, u32 offset)
{
	struct venc_state *venc = to_state(sd);

	return readl(venc->venc_base + offset);
}

static inline u32 venc_write(struct v4l2_subdev *sd, u32 offset, u32 val)
{
	struct venc_state *venc = to_state(sd);

	writel(val, (venc->venc_base + offset));

	return val;
}

static inline u32 venc_modify(struct v4l2_subdev *sd, u32 offset,
				 u32 val, u32 mask)
{
	u32 new_val = (venc_read(sd, offset) & ~mask) | (val & mask);

	venc_write(sd, offset, new_val);

	return new_val;
}

static inline u32 vdaccfg_write(struct v4l2_subdev *sd, u32 val)
{
	struct venc_state *venc = to_state(sd);

	writel(val, venc->vdaccfg_reg);

	val = readl(venc->vdaccfg_reg);

	return val;
}

/* This function sets the dac of the VPBE for various outputs
 */
static int venc_set_dac(struct v4l2_subdev *sd, u32 out_index)
{
	switch (out_index) {
	case 0:
		v4l2_dbg(debug, 1, sd, "Setting output to Composite\n");
		venc_write(sd, VENC_DACSEL, 0);
		break;
	case 1:
		v4l2_dbg(debug, 1, sd, "Setting output to S-Video\n");
		venc_write(sd, VENC_DACSEL, 0x210);
		break;
	case  2:
		venc_write(sd, VENC_DACSEL, 0x543);
		break;
	default:
		return -EINVAL;
	}

	return 0;
}

static void venc_enabledigitaloutput(struct v4l2_subdev *sd, int benable)
{
	v4l2_dbg(debug, 2, sd, "venc_enabledigitaloutput\n");

	if (benable) {
		venc_write(sd, VENC_VMOD, 0);
		venc_write(sd, VENC_CVBS, 0);
		venc_write(sd, VENC_LCDOUT, 0);
		venc_write(sd, VENC_HSPLS, 0);
		venc_write(sd, VENC_HSTART, 0);
		venc_write(sd, VENC_HVALID, 0);
		venc_write(sd, VENC_HINT, 0);
		venc_write(sd, VENC_VSPLS, 0);
		venc_write(sd, VENC_VSTART, 0);
		venc_write(sd, VENC_VVALID, 0);
		venc_write(sd, VENC_VINT, 0);
		venc_write(sd, VENC_YCCCTL, 0);
		venc_write(sd, VENC_DACSEL, 0);

	} else {
		venc_write(sd, VENC_VMOD, 0);
		/* disable VCLK output pin enable */
		venc_write(sd, VENC_VIDCTL, 0x141);

		/* Disable output sync pins */
		venc_write(sd, VENC_SYNCCTL, 0);

		/* Disable DCLOCK */
		venc_write(sd, VENC_DCLKCTL, 0);
		venc_write(sd, VENC_DRGBX1, 0x0000057C);

		/* Disable LCD output control (accepting default polarity) */
		venc_write(sd, VENC_LCDOUT, 0);
		venc_write(sd, VENC_CMPNT, 0x100);
		venc_write(sd, VENC_HSPLS, 0);
		venc_write(sd, VENC_HINT, 0);
		venc_write(sd, VENC_HSTART, 0);
		venc_write(sd, VENC_HVALID, 0);

		venc_write(sd, VENC_VSPLS, 0);
		venc_write(sd, VENC_VINT, 0);
		venc_write(sd, VENC_VSTART, 0);
		venc_write(sd, VENC_VVALID, 0);

		venc_write(sd, VENC_HSDLY, 0);
		venc_write(sd, VENC_VSDLY, 0);

		venc_write(sd, VENC_YCCCTL, 0);
		venc_write(sd, VENC_VSTARTA, 0);

		/* Set OSD clock and OSD Sync Adavance registers */
		venc_write(sd, VENC_OSDCLK0, 1);
		venc_write(sd, VENC_OSDCLK1, 2);
	}
}

/*
 * setting NTSC mode
 */
static int venc_set_ntsc(struct v4l2_subdev *sd)
{
	struct venc_state *venc = to_state(sd);
	struct venc_platform_data *pdata = venc->pdata;

	v4l2_dbg(debug, 2, sd, "venc_set_ntsc\n");

	/* Setup clock at VPSS & VENC for SD */
	vpss_enable_clock(VPSS_VENC_CLOCK_SEL, 1);
	if (pdata->setup_clock(VPBE_ENC_STD, V4L2_STD_525_60) < 0)
		return -EINVAL;

	venc_enabledigitaloutput(sd, 0);

	/* to set VENC CLK DIV to 1 - final clock is 54 MHz */
	venc_modify(sd, VENC_VIDCTL, 0, 1 << 1);
	/* Set REC656 Mode */
	venc_write(sd, VENC_YCCCTL, 0x1);
	venc_modify(sd, VENC_VDPRO, 0, VENC_VDPRO_DAFRQ);
	venc_modify(sd, VENC_VDPRO, 0, VENC_VDPRO_DAUPS);

	venc_write(sd, VENC_VMOD, 0);
	venc_modify(sd, VENC_VMOD, (1 << VENC_VMOD_VIE_SHIFT),
			VENC_VMOD_VIE);
	venc_modify(sd, VENC_VMOD, (0 << VENC_VMOD_VMD), VENC_VMOD_VMD);
	venc_modify(sd, VENC_VMOD, (0 << VENC_VMOD_TVTYP_SHIFT),
			VENC_VMOD_TVTYP);
	venc_write(sd, VENC_DACTST, 0x0);
	venc_modify(sd, VENC_VMOD, VENC_VMOD_VENC, VENC_VMOD_VENC);

	return 0;
}

/*
 * setting PAL mode
 */
static int venc_set_pal(struct v4l2_subdev *sd)
{
	struct venc_state *venc = to_state(sd);

	v4l2_dbg(debug, 2, sd, "venc_set_pal\n");

	/* Setup clock at VPSS & VENC for SD */
	vpss_enable_clock(VPSS_VENC_CLOCK_SEL, 1);
	if (venc->pdata->setup_clock(VPBE_ENC_STD, V4L2_STD_625_50) < 0)
		return -EINVAL;

	venc_enabledigitaloutput(sd, 0);

	/* to set VENC CLK DIV to 1 - final clock is 54 MHz */
	venc_modify(sd, VENC_VIDCTL, 0, 1 << 1);
	/* Set REC656 Mode */
	venc_write(sd, VENC_YCCCTL, 0x1);

	venc_modify(sd, VENC_SYNCCTL, 1 << VENC_SYNCCTL_OVD_SHIFT,
			VENC_SYNCCTL_OVD);
	venc_write(sd, VENC_VMOD, 0);
	venc_modify(sd, VENC_VMOD,
			(1 << VENC_VMOD_VIE_SHIFT),
			VENC_VMOD_VIE);
	venc_modify(sd, VENC_VMOD,
			(0 << VENC_VMOD_VMD), VENC_VMOD_VMD);
	venc_modify(sd, VENC_VMOD,
			(1 << VENC_VMOD_TVTYP_SHIFT),
			VENC_VMOD_TVTYP);
	venc_write(sd, VENC_DACTST, 0x0);
	venc_modify(sd, VENC_VMOD, VENC_VMOD_VENC, VENC_VMOD_VENC);

	return 0;
}

/*
 * venc_set_480p59_94
 *
 * This function configures the video encoder to EDTV(525p) component setting.
 */
static int venc_set_480p59_94(struct v4l2_subdev *sd)
{
	struct venc_state *venc = to_state(sd);
	struct venc_platform_data *pdata = venc->pdata;

	v4l2_dbg(debug, 2, sd, "venc_set_480p59_94\n");

	/* Setup clock at VPSS & VENC for SD */
	if (pdata->setup_clock(VPBE_ENC_DV_PRESET, V4L2_DV_480P59_94) < 0)
		return -EINVAL;

	venc_enabledigitaloutput(sd, 0);

	venc_write(sd, VENC_OSDCLK0, 0);
	venc_write(sd, VENC_OSDCLK1, 1);
	venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAFRQ,
		    VENC_VDPRO_DAFRQ);
	venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAUPS,
		    VENC_VDPRO_DAUPS);
	venc_write(sd, VENC_VMOD, 0);
	venc_modify(sd, VENC_VMOD, (1 << VENC_VMOD_VIE_SHIFT),
		    VENC_VMOD_VIE);
	venc_modify(sd, VENC_VMOD, VENC_VMOD_HDMD, VENC_VMOD_HDMD);
	venc_modify(sd, VENC_VMOD, (HDTV_525P << VENC_VMOD_TVTYP_SHIFT),
		    VENC_VMOD_TVTYP);
	venc_modify(sd, VENC_VMOD, VENC_VMOD_VDMD_YCBCR8 <<
		    VENC_VMOD_VDMD_SHIFT, VENC_VMOD_VDMD);

	venc_modify(sd, VENC_VMOD, VENC_VMOD_VENC, VENC_VMOD_VENC);

	return 0;
}

/*
 * venc_set_625p
 *
 * This function configures the video encoder to HDTV(625p) component setting
 */
static int venc_set_576p50(struct v4l2_subdev *sd)
{
	struct venc_state *venc = to_state(sd);
	struct venc_platform_data *pdata = venc->pdata;

	v4l2_dbg(debug, 2, sd, "venc_set_576p50\n");

	/* Setup clock at VPSS & VENC for SD */
	if (pdata->setup_clock(VPBE_ENC_DV_PRESET, V4L2_DV_576P50) < 0)
		return -EINVAL;

	venc_enabledigitaloutput(sd, 0);

	venc_write(sd, VENC_OSDCLK0, 0);
	venc_write(sd, VENC_OSDCLK1, 1);

	venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAFRQ,
		    VENC_VDPRO_DAFRQ);
	venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAUPS,
		    VENC_VDPRO_DAUPS);

	venc_write(sd, VENC_VMOD, 0);
	venc_modify(sd, VENC_VMOD, (1 << VENC_VMOD_VIE_SHIFT),
		    VENC_VMOD_VIE);
	venc_modify(sd, VENC_VMOD, VENC_VMOD_HDMD, VENC_VMOD_HDMD);
	venc_modify(sd, VENC_VMOD, (HDTV_625P << VENC_VMOD_TVTYP_SHIFT),
		    VENC_VMOD_TVTYP);

	venc_modify(sd, VENC_VMOD, VENC_VMOD_VDMD_YCBCR8 <<
		    VENC_VMOD_VDMD_SHIFT, VENC_VMOD_VDMD);
	venc_modify(sd, VENC_VMOD, VENC_VMOD_VENC, VENC_VMOD_VENC);

	return 0;
}

static int venc_s_std_output(struct v4l2_subdev *sd, v4l2_std_id norm)
{
	v4l2_dbg(debug, 1, sd, "venc_s_std_output\n");

	if (norm & V4L2_STD_525_60)
		return venc_set_ntsc(sd);
	else if (norm & V4L2_STD_625_50)
		return venc_set_pal(sd);

	return -EINVAL;
}

static int venc_s_dv_preset(struct v4l2_subdev *sd,
			    struct v4l2_dv_preset *dv_preset)
{
	v4l2_dbg(debug, 1, sd, "venc_s_dv_preset\n");

	if (dv_preset->preset == V4L2_DV_576P50)
		return venc_set_576p50(sd);
	else if (dv_preset->preset == V4L2_DV_480P59_94)
		return venc_set_480p59_94(sd);

	return -EINVAL;
}

static int venc_s_routing(struct v4l2_subdev *sd, u32 input, u32 output,
			  u32 config)
{
	struct venc_state *venc = to_state(sd);
	int ret;

	v4l2_dbg(debug, 1, sd, "venc_s_routing\n");

	ret = venc_set_dac(sd, output);
	if (!ret)
		venc->output = output;

	return ret;
}

static long venc_ioctl(struct v4l2_subdev *sd,
			unsigned int cmd,
			void *arg)
{
	u32 val;

	switch (cmd) {
	case VENC_GET_FLD:
		val = venc_read(sd, VENC_VSTAT);
		*((int *)arg) = ((val & VENC_VSTAT_FIDST) ==
		VENC_VSTAT_FIDST);
		break;
	default:
		v4l2_err(sd, "Wrong IOCTL cmd\n");
		break;
	}

	return 0;
}

static const struct v4l2_subdev_core_ops venc_core_ops = {
	.ioctl      = venc_ioctl,
};

static const struct v4l2_subdev_video_ops venc_video_ops = {
	.s_routing = venc_s_routing,
	.s_std_output = venc_s_std_output,
	.s_dv_preset = venc_s_dv_preset,
};

static const struct v4l2_subdev_ops venc_ops = {
	.core = &venc_core_ops,
	.video = &venc_video_ops,
};

static int venc_initialize(struct v4l2_subdev *sd)
{
	struct venc_state *venc = to_state(sd);
	int ret;

	/* Set default to output to composite and std to NTSC */
	venc->output = 0;
	venc->std = V4L2_STD_525_60;

	ret = venc_s_routing(sd, 0, venc->output, 0);
	if (ret < 0) {
		v4l2_err(sd, "Error setting output during init\n");
		return -EINVAL;
	}

	ret = venc_s_std_output(sd, venc->std);
	if (ret < 0) {
		v4l2_err(sd, "Error setting std during init\n");
		return -EINVAL;
	}

	return ret;
}

static int venc_device_get(struct device *dev, void *data)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct venc_state **venc = data;

	if (strcmp(MODULE_NAME, pdev->name) == 0)
		*venc = platform_get_drvdata(pdev);

	return 0;
}

struct v4l2_subdev *venc_sub_dev_init(struct v4l2_device *v4l2_dev,
		const char *venc_name)
{
	struct venc_state *venc;
	int err;

	err = bus_for_each_dev(&platform_bus_type, NULL, &venc,
			venc_device_get);
	if (venc == NULL)
		return NULL;

	v4l2_subdev_init(&venc->sd, &venc_ops);

	strcpy(venc->sd.name, venc_name);
	if (v4l2_device_register_subdev(v4l2_dev, &venc->sd) < 0) {
		v4l2_err(v4l2_dev,
			"vpbe unable to register venc sub device\n");
		return NULL;
	}
	if (venc_initialize(&venc->sd)) {
		v4l2_err(v4l2_dev,
			"vpbe venc initialization failed\n");
		return NULL;
	}

	return &venc->sd;
}
EXPORT_SYMBOL(venc_sub_dev_init);

static int venc_probe(struct platform_device *pdev)
{
	struct venc_state *venc;
	struct resource *res;
	int ret;

	venc = kzalloc(sizeof(struct venc_state), GFP_KERNEL);
	if (venc == NULL)
		return -ENOMEM;

	venc->pdev = &pdev->dev;
	venc->pdata = pdev->dev.platform_data;
	if (NULL == venc->pdata) {
		dev_err(venc->pdev, "Unable to get platform data for"
			" VENC sub device");
		ret = -ENOENT;
		goto free_mem;
	}
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(venc->pdev,
			"Unable to get VENC register address map\n");
		ret = -ENODEV;
		goto free_mem;
	}

	if (!request_mem_region(res->start, resource_size(res), "venc")) {
		dev_err(venc->pdev, "Unable to reserve VENC MMIO region\n");
		ret = -ENODEV;
		goto free_mem;
	}

	venc->venc_base = ioremap_nocache(res->start, resource_size(res));
	if (!venc->venc_base) {
		dev_err(venc->pdev, "Unable to map VENC IO space\n");
		ret = -ENODEV;
		goto release_venc_mem_region;
	}

	spin_lock_init(&venc->lock);
	platform_set_drvdata(pdev, venc);
	dev_notice(venc->pdev, "VENC sub device probe success\n");
	return 0;

release_venc_mem_region:
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	release_mem_region(res->start, resource_size(res));
free_mem:
	kfree(venc);
	return ret;
}

static int venc_remove(struct platform_device *pdev)
{
	struct venc_state *venc = platform_get_drvdata(pdev);
	struct resource *res;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	iounmap((void *)venc->venc_base);
	release_mem_region(res->start, resource_size(res));
	kfree(venc);

	return 0;
}

static struct platform_driver venc_driver = {
	.probe		= venc_probe,
	.remove		= venc_remove,
	.driver		= {
		.name	= MODULE_NAME,
		.owner	= THIS_MODULE,
	},
};

static int venc_init(void)
{
	if (platform_driver_register(&venc_driver)) {
		printk(KERN_ERR "Unable to register venc driver\n");
		return -ENODEV;
	}
	return 0;
}

static void venc_exit(void)
{
	platform_driver_unregister(&venc_driver);
	return;
}

module_init(venc_init);
module_exit(venc_exit);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("VPBE VENC Driver");
MODULE_AUTHOR("Texas Instruments");
