/*
 * Support for the camera device found on Marvell MMP processors; known
 * to work with the Armada 610 as used in the OLPC 1.75 system.
 *
 * Copyright 2011 Jonathan Corbet <corbet@lwn.net>
 *
 * This file may be distributed under the terms of the GNU General
 * Public License, version 2.
 */

#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/i2c-gpio.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <linux/slab.h>
#include <linux/videodev2.h>
#include <media/v4l2-device.h>
#include <media/mmp-camera.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/io.h>
#include <linux/delay.h>
#include <linux/list.h>
#include <linux/pm.h>
#include <linux/clk.h>

#include "mcam-core.h"

MODULE_ALIAS("platform:mmp-camera");
MODULE_AUTHOR("Jonathan Corbet <corbet@lwn.net>");
MODULE_LICENSE("GPL");

static char *mcam_clks[] = {"CCICAXICLK", "CCICFUNCLK", "CCICPHYCLK"};

struct mmp_camera {
	void *power_regs;
	struct platform_device *pdev;
	struct mcam_camera mcam;
	struct list_head devlist;
	struct clk *mipi_clk;
	int irq;
};

static inline struct mmp_camera *mcam_to_cam(struct mcam_camera *mcam)
{
	return container_of(mcam, struct mmp_camera, mcam);
}

/*
 * A silly little infrastructure so we can keep track of our devices.
 * Chances are that we will never have more than one of them, but
 * the Armada 610 *does* have two controllers...
 */

static LIST_HEAD(mmpcam_devices);
static struct mutex mmpcam_devices_lock;

static void mmpcam_add_device(struct mmp_camera *cam)
{
	mutex_lock(&mmpcam_devices_lock);
	list_add(&cam->devlist, &mmpcam_devices);
	mutex_unlock(&mmpcam_devices_lock);
}

static void mmpcam_remove_device(struct mmp_camera *cam)
{
	mutex_lock(&mmpcam_devices_lock);
	list_del(&cam->devlist);
	mutex_unlock(&mmpcam_devices_lock);
}

/*
 * Platform dev remove passes us a platform_device, and there's
 * no handy unused drvdata to stash a backpointer in.  So just
 * dig it out of our list.
 */
static struct mmp_camera *mmpcam_find_device(struct platform_device *pdev)
{
	struct mmp_camera *cam;

	mutex_lock(&mmpcam_devices_lock);
	list_for_each_entry(cam, &mmpcam_devices, devlist) {
		if (cam->pdev == pdev) {
			mutex_unlock(&mmpcam_devices_lock);
			return cam;
		}
	}
	mutex_unlock(&mmpcam_devices_lock);
	return NULL;
}




/*
 * Power-related registers; this almost certainly belongs
 * somewhere else.
 *
 * ARMADA 610 register manual, sec 7.2.1, p1842.
 */
#define CPU_SUBSYS_PMU_BASE	0xd4282800
#define REG_CCIC_DCGCR		0x28	/* CCIC dyn clock gate ctrl reg */
#define REG_CCIC_CRCR		0x50	/* CCIC clk reset ctrl reg	*/
#define REG_CCIC2_CRCR		0xf4	/* CCIC2 clk reset ctrl reg	*/

static void mcam_clk_enable(struct mcam_camera *mcam)
{
	unsigned int i;

	for (i = 0; i < NR_MCAM_CLK; i++) {
		if (!IS_ERR(mcam->clk[i]))
			clk_prepare_enable(mcam->clk[i]);
	}
}

static void mcam_clk_disable(struct mcam_camera *mcam)
{
	int i;

	for (i = NR_MCAM_CLK - 1; i >= 0; i--) {
		if (!IS_ERR(mcam->clk[i]))
			clk_disable_unprepare(mcam->clk[i]);
	}
}

/*
 * Power control.
 */
static void mmpcam_power_up_ctlr(struct mmp_camera *cam)
{
	iowrite32(0x3f, cam->power_regs + REG_CCIC_DCGCR);
	iowrite32(0x3805b, cam->power_regs + REG_CCIC_CRCR);
	mdelay(1);
}

static int mmpcam_power_up(struct mcam_camera *mcam)
{
	struct mmp_camera *cam = mcam_to_cam(mcam);
	struct mmp_camera_platform_data *pdata;

/*
 * Turn on power and clocks to the controller.
 */
	mmpcam_power_up_ctlr(cam);
/*
 * Provide power to the sensor.
 */
	mcam_reg_write(mcam, REG_CLKCTRL, 0x60000002);
	pdata = cam->pdev->dev.platform_data;
	gpio_set_value(pdata->sensor_power_gpio, 1);
	mdelay(5);
	mcam_reg_clear_bit(mcam, REG_CTRL1, 0x10000000);
	gpio_set_value(pdata->sensor_reset_gpio, 0); /* reset is active low */
	mdelay(5);
	gpio_set_value(pdata->sensor_reset_gpio, 1); /* reset is active low */
	mdelay(5);

	mcam_clk_enable(mcam);

	return 0;
}

static void mmpcam_power_down(struct mcam_camera *mcam)
{
	struct mmp_camera *cam = mcam_to_cam(mcam);
	struct mmp_camera_platform_data *pdata;
/*
 * Turn off clocks and set reset lines
 */
	iowrite32(0, cam->power_regs + REG_CCIC_DCGCR);
	iowrite32(0, cam->power_regs + REG_CCIC_CRCR);
/*
 * Shut down the sensor.
 */
	pdata = cam->pdev->dev.platform_data;
	gpio_set_value(pdata->sensor_power_gpio, 0);
	gpio_set_value(pdata->sensor_reset_gpio, 0);

	mcam_clk_disable(mcam);
}

void mcam_ctlr_reset(struct mcam_camera *mcam)
{
	unsigned long val;
	struct mmp_camera *cam = mcam_to_cam(mcam);

	if (mcam->ccic_id) {
		/*
		 * Using CCIC2
		 */
		val = ioread32(cam->power_regs + REG_CCIC2_CRCR);
		iowrite32(val & ~0x2, cam->power_regs + REG_CCIC2_CRCR);
		iowrite32(val | 0x2, cam->power_regs + REG_CCIC2_CRCR);
	} else {
		/*
		 * Using CCIC1
		 */
		val = ioread32(cam->power_regs + REG_CCIC_CRCR);
		iowrite32(val & ~0x2, cam->power_regs + REG_CCIC_CRCR);
		iowrite32(val | 0x2, cam->power_regs + REG_CCIC_CRCR);
	}
}

/*
 * calc the dphy register values
 * There are three dphy registers being used.
 * dphy[0] - CSI2_DPHY3
 * dphy[1] - CSI2_DPHY5
 * dphy[2] - CSI2_DPHY6
 * CSI2_DPHY3 and CSI2_DPHY6 can be set with a default value
 * or be calculated dynamically
 */
void mmpcam_calc_dphy(struct mcam_camera *mcam)
{
	struct mmp_camera *cam = mcam_to_cam(mcam);
	struct mmp_camera_platform_data *pdata = cam->pdev->dev.platform_data;
	struct device *dev = &cam->pdev->dev;
	unsigned long tx_clk_esc;

	/*
	 * If CSI2_DPHY3 is calculated dynamically,
	 * pdata->lane_clk should be already set
	 * either in the board driver statically
	 * or in the sensor driver dynamically.
	 */
	/*
	 * dphy[0] - CSI2_DPHY3:
	 *  bit 0 ~ bit 7: HS Term Enable.
	 *   defines the time that the DPHY
	 *   wait before enabling the data
	 *   lane termination after detecting
	 *   that the sensor has driven the data
	 *   lanes to the LP00 bridge state.
	 *   The value is calculated by:
	 *   (Max T(D_TERM_EN)/Period(DDR)) - 1
	 *  bit 8 ~ bit 15: HS_SETTLE
	 *   Time interval during which the HS
	 *   receiver shall ignore any Data Lane
	 *   HS transistions.
	 *   The vaule has been calibrated on
	 *   different boards. It seems to work well.
	 *
	 *  More detail please refer
	 *  MIPI Alliance Spectification for D-PHY
	 *  document for explanation of HS-SETTLE
	 *  and D-TERM-EN.
	 */
	switch (pdata->dphy3_algo) {
	case DPHY3_ALGO_PXA910:
		/*
		 * Calculate CSI2_DPHY3 algo for PXA910
		 */
		pdata->dphy[0] =
			(((1 + (pdata->lane_clk * 80) / 1000) & 0xff) << 8)
			| (1 + pdata->lane_clk * 35 / 1000);
		break;
	case DPHY3_ALGO_PXA2128:
		/*
		 * Calculate CSI2_DPHY3 algo for PXA2128
		 */
		pdata->dphy[0] =
			(((2 + (pdata->lane_clk * 110) / 1000) & 0xff) << 8)
			| (1 + pdata->lane_clk * 35 / 1000);
		break;
	default:
		/*
		 * Use default CSI2_DPHY3 value for PXA688/PXA988
		 */
		dev_dbg(dev, "camera: use the default CSI2_DPHY3 value\n");
	}

	/*
	 * mipi_clk will never be changed, it is a fixed value on MMP
	 */
	if (IS_ERR(cam->mipi_clk))
		return;

	/* get the escape clk, this is hard coded */
	clk_prepare_enable(cam->mipi_clk);
	tx_clk_esc = (clk_get_rate(cam->mipi_clk) / 1000000) / 12;
	clk_disable_unprepare(cam->mipi_clk);
	/*
	 * dphy[2] - CSI2_DPHY6:
	 * bit 0 ~ bit 7: CK Term Enable
	 *  Time for the Clock Lane receiver to enable the HS line
	 *  termination. The value is calculated similarly with
	 *  HS Term Enable
	 * bit 8 ~ bit 15: CK Settle
	 *  Time interval during which the HS receiver shall ignore
	 *  any Clock Lane HS transitions.
	 *  The value is calibrated on the boards.
	 */
	pdata->dphy[2] =
		((((534 * tx_clk_esc) / 2000 - 1) & 0xff) << 8)
		| (((38 * tx_clk_esc) / 1000 - 1) & 0xff);

	dev_dbg(dev, "camera: DPHY sets: dphy3=0x%x, dphy5=0x%x, dphy6=0x%x\n",
		pdata->dphy[0], pdata->dphy[1], pdata->dphy[2]);
}

static irqreturn_t mmpcam_irq(int irq, void *data)
{
	struct mcam_camera *mcam = data;
	unsigned int irqs, handled;

	spin_lock(&mcam->dev_lock);
	irqs = mcam_reg_read(mcam, REG_IRQSTAT);
	handled = mccic_irq(mcam, irqs);
	spin_unlock(&mcam->dev_lock);
	return IRQ_RETVAL(handled);
}

static void mcam_init_clk(struct mcam_camera *mcam)
{
	unsigned int i;

	for (i = 0; i < NR_MCAM_CLK; i++) {
		if (mcam_clks[i] != NULL) {
			/* Some clks are not necessary on some boards
			 * We still try to run even it fails getting clk
			 */
			mcam->clk[i] = devm_clk_get(mcam->dev, mcam_clks[i]);
			if (IS_ERR(mcam->clk[i]))
				dev_warn(mcam->dev, "Could not get clk: %s\n",
						mcam_clks[i]);
		}
	}
}

static int mmpcam_probe(struct platform_device *pdev)
{
	struct mmp_camera *cam;
	struct mcam_camera *mcam;
	struct resource *res;
	struct mmp_camera_platform_data *pdata;
	int ret;

	pdata = pdev->dev.platform_data;
	if (!pdata)
		return -ENODEV;

	cam = devm_kzalloc(&pdev->dev, sizeof(*cam), GFP_KERNEL);
	if (cam == NULL)
		return -ENOMEM;
	cam->pdev = pdev;
	INIT_LIST_HEAD(&cam->devlist);

	mcam = &cam->mcam;
	mcam->plat_power_up = mmpcam_power_up;
	mcam->plat_power_down = mmpcam_power_down;
	mcam->ctlr_reset = mcam_ctlr_reset;
	mcam->calc_dphy = mmpcam_calc_dphy;
	mcam->dev = &pdev->dev;
	mcam->use_smbus = 0;
	mcam->ccic_id = pdev->id;
	mcam->mclk_min = pdata->mclk_min;
	mcam->mclk_src = pdata->mclk_src;
	mcam->mclk_div = pdata->mclk_div;
	mcam->bus_type = pdata->bus_type;
	mcam->dphy = pdata->dphy;
	if (mcam->bus_type == V4L2_MBUS_CSI2) {
		cam->mipi_clk = devm_clk_get(mcam->dev, "mipi");
		if ((IS_ERR(cam->mipi_clk) && mcam->dphy[2] == 0))
			return PTR_ERR(cam->mipi_clk);
	}
	mcam->mipi_enabled = false;
	mcam->lane = pdata->lane;
	mcam->chip_id = MCAM_ARMADA610;
	mcam->buffer_mode = B_DMA_sg;
	strlcpy(mcam->bus_info, "platform:mmp-camera", sizeof(mcam->bus_info));
	spin_lock_init(&mcam->dev_lock);
	/*
	 * Get our I/O memory.
	 */
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	mcam->regs = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(mcam->regs))
		return PTR_ERR(mcam->regs);
	mcam->regs_size = resource_size(res);
	/*
	 * Power/clock memory is elsewhere; get it too.  Perhaps this
	 * should really be managed outside of this driver?
	 */
	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	cam->power_regs = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(cam->power_regs))
		return PTR_ERR(cam->power_regs);
	/*
	 * Find the i2c adapter.  This assumes, of course, that the
	 * i2c bus is already up and functioning.
	 */
	mcam->i2c_adapter = platform_get_drvdata(pdata->i2c_device);
	if (mcam->i2c_adapter == NULL) {
		dev_err(&pdev->dev, "No i2c adapter\n");
		return -ENODEV;
	}
	/*
	 * Sensor GPIO pins.
	 */
	ret = devm_gpio_request(&pdev->dev, pdata->sensor_power_gpio,
							"cam-power");
	if (ret) {
		dev_err(&pdev->dev, "Can't get sensor power gpio %d",
				pdata->sensor_power_gpio);
		return ret;
	}
	gpio_direction_output(pdata->sensor_power_gpio, 0);
	ret = devm_gpio_request(&pdev->dev, pdata->sensor_reset_gpio,
							"cam-reset");
	if (ret) {
		dev_err(&pdev->dev, "Can't get sensor reset gpio %d",
				pdata->sensor_reset_gpio);
		return ret;
	}
	gpio_direction_output(pdata->sensor_reset_gpio, 0);

	mcam_init_clk(mcam);

	/*
	 * Power the device up and hand it off to the core.
	 */
	ret = mmpcam_power_up(mcam);
	if (ret)
		return ret;
	ret = mccic_register(mcam);
	if (ret)
		goto out_power_down;
	/*
	 * Finally, set up our IRQ now that the core is ready to
	 * deal with it.
	 */
	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (res == NULL) {
		ret = -ENODEV;
		goto out_unregister;
	}
	cam->irq = res->start;
	ret = devm_request_irq(&pdev->dev, cam->irq, mmpcam_irq, IRQF_SHARED,
					"mmp-camera", mcam);
	if (ret == 0) {
		mmpcam_add_device(cam);
		return 0;
	}

out_unregister:
	mccic_shutdown(mcam);
out_power_down:
	mmpcam_power_down(mcam);
	return ret;
}


static int mmpcam_remove(struct mmp_camera *cam)
{
	struct mcam_camera *mcam = &cam->mcam;

	mmpcam_remove_device(cam);
	mccic_shutdown(mcam);
	mmpcam_power_down(mcam);
	return 0;
}

static int mmpcam_platform_remove(struct platform_device *pdev)
{
	struct mmp_camera *cam = mmpcam_find_device(pdev);

	if (cam == NULL)
		return -ENODEV;
	return mmpcam_remove(cam);
}

/*
 * Suspend/resume support.
 */
#ifdef CONFIG_PM

static int mmpcam_suspend(struct platform_device *pdev, pm_message_t state)
{
	struct mmp_camera *cam = mmpcam_find_device(pdev);

	if (state.event != PM_EVENT_SUSPEND)
		return 0;
	mccic_suspend(&cam->mcam);
	return 0;
}

static int mmpcam_resume(struct platform_device *pdev)
{
	struct mmp_camera *cam = mmpcam_find_device(pdev);

	/*
	 * Power up unconditionally just in case the core tries to
	 * touch a register even if nothing was active before; trust
	 * me, it's better this way.
	 */
	mmpcam_power_up_ctlr(cam);
	return mccic_resume(&cam->mcam);
}

#endif


static struct platform_driver mmpcam_driver = {
	.probe		= mmpcam_probe,
	.remove		= mmpcam_platform_remove,
#ifdef CONFIG_PM
	.suspend	= mmpcam_suspend,
	.resume		= mmpcam_resume,
#endif
	.driver = {
		.name	= "mmp-camera",
	}
};


static int __init mmpcam_init_module(void)
{
	mutex_init(&mmpcam_devices_lock);
	return platform_driver_register(&mmpcam_driver);
}

static void __exit mmpcam_exit_module(void)
{
	platform_driver_unregister(&mmpcam_driver);
	/*
	 * platform_driver_unregister() should have emptied the list
	 */
	if (!list_empty(&mmpcam_devices))
		printk(KERN_ERR "mmp_camera leaving devices behind\n");
}

module_init(mmpcam_init_module);
module_exit(mmpcam_exit_module);
