/*
 * Samsung TV Mixer driver
 *
 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
 *
 * Tomasz Stanislawski, <t.stanislaws@samsung.com>
 *
 * 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 Foundiation. either version 2 of the License,
 * or (at your option) any later version
 */

#include "mixer.h"

#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/fb.h>
#include <linux/delay.h>
#include <linux/pm_runtime.h>
#include <linux/clk.h>

MODULE_AUTHOR("Tomasz Stanislawski, <t.stanislaws@samsung.com>");
MODULE_DESCRIPTION("Samsung MIXER");
MODULE_LICENSE("GPL");

/* --------- DRIVER PARAMETERS ---------- */

static struct mxr_output_conf mxr_output_conf[] = {
	{
		.output_name = "S5P HDMI connector",
		.module_name = "s5p-hdmi",
		.cookie = 1,
	},
	{
		.output_name = "S5P SDO connector",
		.module_name = "s5p-sdo",
		.cookie = 0,
	},
};

void mxr_get_mbus_fmt(struct mxr_device *mdev,
	struct v4l2_mbus_framefmt *mbus_fmt)
{
	struct v4l2_subdev *sd;
	int ret;

	mutex_lock(&mdev->mutex);
	sd = to_outsd(mdev);
	ret = v4l2_subdev_call(sd, video, g_mbus_fmt, mbus_fmt);
	WARN(ret, "failed to get mbus_fmt for output %s\n", sd->name);
	mutex_unlock(&mdev->mutex);
}

void mxr_streamer_get(struct mxr_device *mdev)
{
	mutex_lock(&mdev->mutex);
	++mdev->n_streamer;
	mxr_dbg(mdev, "%s(%d)\n", __func__, mdev->n_streamer);
	if (mdev->n_streamer == 1) {
		struct v4l2_subdev *sd = to_outsd(mdev);
		struct v4l2_mbus_framefmt mbus_fmt;
		struct mxr_resources *res = &mdev->res;
		int ret;

		if (to_output(mdev)->cookie == 0)
			clk_set_parent(res->sclk_mixer, res->sclk_dac);
		else
			clk_set_parent(res->sclk_mixer, res->sclk_hdmi);
		mxr_reg_s_output(mdev, to_output(mdev)->cookie);

		ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mbus_fmt);
		WARN(ret, "failed to get mbus_fmt for output %s\n", sd->name);
		ret = v4l2_subdev_call(sd, video, s_stream, 1);
		WARN(ret, "starting stream failed for output %s\n", sd->name);

		mxr_reg_set_mbus_fmt(mdev, &mbus_fmt);
		mxr_reg_streamon(mdev);
		ret = mxr_reg_wait4vsync(mdev);
		WARN(ret, "failed to get vsync (%d) from output\n", ret);
	}
	mutex_unlock(&mdev->mutex);
	mxr_reg_dump(mdev);
	/* FIXME: what to do when streaming fails? */
}

void mxr_streamer_put(struct mxr_device *mdev)
{
	mutex_lock(&mdev->mutex);
	--mdev->n_streamer;
	mxr_dbg(mdev, "%s(%d)\n", __func__, mdev->n_streamer);
	if (mdev->n_streamer == 0) {
		int ret;
		struct v4l2_subdev *sd = to_outsd(mdev);

		mxr_reg_streamoff(mdev);
		/* vsync applies Mixer setup */
		ret = mxr_reg_wait4vsync(mdev);
		WARN(ret, "failed to get vsync (%d) from output\n", ret);
		ret = v4l2_subdev_call(sd, video, s_stream, 0);
		WARN(ret, "stopping stream failed for output %s\n", sd->name);
	}
	WARN(mdev->n_streamer < 0, "negative number of streamers (%d)\n",
		mdev->n_streamer);
	mutex_unlock(&mdev->mutex);
	mxr_reg_dump(mdev);
}

void mxr_output_get(struct mxr_device *mdev)
{
	mutex_lock(&mdev->mutex);
	++mdev->n_output;
	mxr_dbg(mdev, "%s(%d)\n", __func__, mdev->n_output);
	/* turn on auxiliary driver */
	if (mdev->n_output == 1)
		v4l2_subdev_call(to_outsd(mdev), core, s_power, 1);
	mutex_unlock(&mdev->mutex);
}

void mxr_output_put(struct mxr_device *mdev)
{
	mutex_lock(&mdev->mutex);
	--mdev->n_output;
	mxr_dbg(mdev, "%s(%d)\n", __func__, mdev->n_output);
	/* turn on auxiliary driver */
	if (mdev->n_output == 0)
		v4l2_subdev_call(to_outsd(mdev), core, s_power, 0);
	WARN(mdev->n_output < 0, "negative number of output users (%d)\n",
		mdev->n_output);
	mutex_unlock(&mdev->mutex);
}

int mxr_power_get(struct mxr_device *mdev)
{
	int ret = pm_runtime_get_sync(mdev->dev);

	/* returning 1 means that power is already enabled,
	 * so zero success be returned */
	if (IS_ERR_VALUE(ret))
		return ret;
	return 0;
}

void mxr_power_put(struct mxr_device *mdev)
{
	pm_runtime_put_sync(mdev->dev);
}

/* --------- RESOURCE MANAGEMENT -------------*/

static int mxr_acquire_plat_resources(struct mxr_device *mdev,
				      struct platform_device *pdev)
{
	struct resource *res;
	int ret;

	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mxr");
	if (res == NULL) {
		mxr_err(mdev, "get memory resource failed.\n");
		ret = -ENXIO;
		goto fail;
	}

	mdev->res.mxr_regs = ioremap(res->start, resource_size(res));
	if (mdev->res.mxr_regs == NULL) {
		mxr_err(mdev, "register mapping failed.\n");
		ret = -ENXIO;
		goto fail;
	}

	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vp");
	if (res == NULL) {
		mxr_err(mdev, "get memory resource failed.\n");
		ret = -ENXIO;
		goto fail_mxr_regs;
	}

	mdev->res.vp_regs = ioremap(res->start, resource_size(res));
	if (mdev->res.vp_regs == NULL) {
		mxr_err(mdev, "register mapping failed.\n");
		ret = -ENXIO;
		goto fail_mxr_regs;
	}

	res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "irq");
	if (res == NULL) {
		mxr_err(mdev, "get interrupt resource failed.\n");
		ret = -ENXIO;
		goto fail_vp_regs;
	}

	ret = request_irq(res->start, mxr_irq_handler, 0, "s5p-mixer", mdev);
	if (ret) {
		mxr_err(mdev, "request interrupt failed.\n");
		goto fail_vp_regs;
	}
	mdev->res.irq = res->start;

	return 0;

fail_vp_regs:
	iounmap(mdev->res.vp_regs);

fail_mxr_regs:
	iounmap(mdev->res.mxr_regs);

fail:
	return ret;
}

static void mxr_resource_clear_clocks(struct mxr_resources *res)
{
	res->mixer	= ERR_PTR(-EINVAL);
	res->vp		= ERR_PTR(-EINVAL);
	res->sclk_mixer	= ERR_PTR(-EINVAL);
	res->sclk_hdmi	= ERR_PTR(-EINVAL);
	res->sclk_dac	= ERR_PTR(-EINVAL);
}

static void mxr_release_plat_resources(struct mxr_device *mdev)
{
	free_irq(mdev->res.irq, mdev);
	iounmap(mdev->res.vp_regs);
	iounmap(mdev->res.mxr_regs);
}

static void mxr_release_clocks(struct mxr_device *mdev)
{
	struct mxr_resources *res = &mdev->res;

	if (!IS_ERR(res->sclk_dac))
		clk_put(res->sclk_dac);
	if (!IS_ERR(res->sclk_hdmi))
		clk_put(res->sclk_hdmi);
	if (!IS_ERR(res->sclk_mixer))
		clk_put(res->sclk_mixer);
	if (!IS_ERR(res->vp))
		clk_put(res->vp);
	if (!IS_ERR(res->mixer))
		clk_put(res->mixer);
}

static int mxr_acquire_clocks(struct mxr_device *mdev)
{
	struct mxr_resources *res = &mdev->res;
	struct device *dev = mdev->dev;

	mxr_resource_clear_clocks(res);

	res->mixer = clk_get(dev, "mixer");
	if (IS_ERR(res->mixer)) {
		mxr_err(mdev, "failed to get clock 'mixer'\n");
		goto fail;
	}
	res->vp = clk_get(dev, "vp");
	if (IS_ERR(res->vp)) {
		mxr_err(mdev, "failed to get clock 'vp'\n");
		goto fail;
	}
	res->sclk_mixer = clk_get(dev, "sclk_mixer");
	if (IS_ERR(res->sclk_mixer)) {
		mxr_err(mdev, "failed to get clock 'sclk_mixer'\n");
		goto fail;
	}
	res->sclk_hdmi = clk_get(dev, "sclk_hdmi");
	if (IS_ERR(res->sclk_hdmi)) {
		mxr_err(mdev, "failed to get clock 'sclk_hdmi'\n");
		goto fail;
	}
	res->sclk_dac = clk_get(dev, "sclk_dac");
	if (IS_ERR(res->sclk_dac)) {
		mxr_err(mdev, "failed to get clock 'sclk_dac'\n");
		goto fail;
	}

	return 0;
fail:
	mxr_release_clocks(mdev);
	return -ENODEV;
}

static int mxr_acquire_resources(struct mxr_device *mdev,
				 struct platform_device *pdev)
{
	int ret;
	ret = mxr_acquire_plat_resources(mdev, pdev);

	if (ret)
		goto fail;

	ret = mxr_acquire_clocks(mdev);
	if (ret)
		goto fail_plat;

	mxr_info(mdev, "resources acquired\n");
	return 0;

fail_plat:
	mxr_release_plat_resources(mdev);
fail:
	mxr_err(mdev, "resources acquire failed\n");
	return ret;
}

static void mxr_release_resources(struct mxr_device *mdev)
{
	mxr_release_clocks(mdev);
	mxr_release_plat_resources(mdev);
	memset(&mdev->res, 0, sizeof(mdev->res));
	mxr_resource_clear_clocks(&mdev->res);
}

static void mxr_release_layers(struct mxr_device *mdev)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(mdev->layer); ++i)
		if (mdev->layer[i])
			mxr_layer_release(mdev->layer[i]);
}

static int mxr_acquire_layers(struct mxr_device *mdev,
			      struct mxr_platform_data *pdata)
{
	mdev->layer[0] = mxr_graph_layer_create(mdev, 0);
	mdev->layer[1] = mxr_graph_layer_create(mdev, 1);
	mdev->layer[2] = mxr_vp_layer_create(mdev, 0);

	if (!mdev->layer[0] || !mdev->layer[1] || !mdev->layer[2]) {
		mxr_err(mdev, "failed to acquire layers\n");
		goto fail;
	}

	return 0;

fail:
	mxr_release_layers(mdev);
	return -ENODEV;
}

/* ---------- POWER MANAGEMENT ----------- */

static int mxr_runtime_resume(struct device *dev)
{
	struct mxr_device *mdev = to_mdev(dev);
	struct mxr_resources *res = &mdev->res;
	int ret;

	mxr_dbg(mdev, "resume - start\n");
	mutex_lock(&mdev->mutex);
	/* turn clocks on */
	ret = clk_prepare_enable(res->mixer);
	if (ret < 0) {
		dev_err(mdev->dev, "clk_prepare_enable(mixer) failed\n");
		goto fail;
	}
	ret = clk_prepare_enable(res->vp);
	if (ret < 0) {
		dev_err(mdev->dev, "clk_prepare_enable(vp) failed\n");
		goto fail_mixer;
	}
	ret = clk_prepare_enable(res->sclk_mixer);
	if (ret < 0) {
		dev_err(mdev->dev, "clk_prepare_enable(sclk_mixer) failed\n");
		goto fail_vp;
	}
	/* apply default configuration */
	mxr_reg_reset(mdev);
	mxr_dbg(mdev, "resume - finished\n");

	mutex_unlock(&mdev->mutex);
	return 0;

fail_vp:
	clk_disable_unprepare(res->vp);
fail_mixer:
	clk_disable_unprepare(res->mixer);
fail:
	mutex_unlock(&mdev->mutex);
	dev_err(mdev->dev, "resume failed\n");
	return ret;
}

static int mxr_runtime_suspend(struct device *dev)
{
	struct mxr_device *mdev = to_mdev(dev);
	struct mxr_resources *res = &mdev->res;
	mxr_dbg(mdev, "suspend - start\n");
	mutex_lock(&mdev->mutex);
	/* turn clocks off */
	clk_disable_unprepare(res->sclk_mixer);
	clk_disable_unprepare(res->vp);
	clk_disable_unprepare(res->mixer);
	mutex_unlock(&mdev->mutex);
	mxr_dbg(mdev, "suspend - finished\n");
	return 0;
}

static const struct dev_pm_ops mxr_pm_ops = {
	.runtime_suspend = mxr_runtime_suspend,
	.runtime_resume	 = mxr_runtime_resume,
};

/* --------- DRIVER INITIALIZATION ---------- */

static int mxr_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct mxr_platform_data *pdata = dev->platform_data;
	struct mxr_device *mdev;
	int ret;

	/* mdev does not exist yet so no mxr_dbg is used */
	dev_info(dev, "probe start\n");

	mdev = kzalloc(sizeof(*mdev), GFP_KERNEL);
	if (!mdev) {
		dev_err(dev, "not enough memory.\n");
		ret = -ENOMEM;
		goto fail;
	}

	/* setup pointer to master device */
	mdev->dev = dev;

	mutex_init(&mdev->mutex);
	spin_lock_init(&mdev->reg_slock);
	init_waitqueue_head(&mdev->event_queue);

	/* acquire resources: regs, irqs, clocks, regulators */
	ret = mxr_acquire_resources(mdev, pdev);
	if (ret)
		goto fail_mem;

	/* configure resources for video output */
	ret = mxr_acquire_video(mdev, mxr_output_conf,
		ARRAY_SIZE(mxr_output_conf));
	if (ret)
		goto fail_resources;

	/* configure layers */
	ret = mxr_acquire_layers(mdev, pdata);
	if (ret)
		goto fail_video;

	pm_runtime_enable(dev);

	mxr_info(mdev, "probe successful\n");
	return 0;

fail_video:
	mxr_release_video(mdev);

fail_resources:
	mxr_release_resources(mdev);

fail_mem:
	kfree(mdev);

fail:
	dev_info(dev, "probe failed\n");
	return ret;
}

static int mxr_remove(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct mxr_device *mdev = to_mdev(dev);

	pm_runtime_disable(dev);

	mxr_release_layers(mdev);
	mxr_release_video(mdev);
	mxr_release_resources(mdev);

	kfree(mdev);

	dev_info(dev, "remove successful\n");
	return 0;
}

static struct platform_driver mxr_driver __refdata = {
	.probe = mxr_probe,
	.remove = mxr_remove,
	.driver = {
		.name = MXR_DRIVER_NAME,
		.pm = &mxr_pm_ops,
	}
};

static int __init mxr_init(void)
{
	int i, ret;
	static const char banner[] __initconst =
		"Samsung TV Mixer driver, "
		"(c) 2010-2011 Samsung Electronics Co., Ltd.\n";
	pr_info("%s\n", banner);

	/* Loading auxiliary modules */
	for (i = 0; i < ARRAY_SIZE(mxr_output_conf); ++i)
		request_module(mxr_output_conf[i].module_name);

	ret = platform_driver_register(&mxr_driver);
	if (ret != 0) {
		pr_err("s5p-tv: registration of MIXER driver failed\n");
		return -ENXIO;
	}

	return 0;
}
module_init(mxr_init);

static void __exit mxr_exit(void)
{
	platform_driver_unregister(&mxr_driver);
}
module_exit(mxr_exit);
