/*
 * DVI output support
 *
 * Copyright (C) 2011 Texas Instruments Inc
 * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
 *
 * 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/module.h>
#include <linux/slab.h>
#include <video/omapdss.h>
#include <linux/i2c.h>
#include <drm/drm_edid.h>

#include <video/omap-panel-dvi.h>

static const struct omap_video_timings panel_dvi_default_timings = {
	.x_res		= 640,
	.y_res		= 480,

	.pixel_clock	= 23500,

	.hfp		= 48,
	.hsw		= 32,
	.hbp		= 80,

	.vfp		= 3,
	.vsw		= 4,
	.vbp		= 7,
};

struct panel_drv_data {
	struct omap_dss_device *dssdev;

	struct mutex lock;
};

static inline struct panel_dvi_platform_data
*get_pdata(const struct omap_dss_device *dssdev)
{
	return dssdev->data;
}

static int panel_dvi_power_on(struct omap_dss_device *dssdev)
{
	struct panel_dvi_platform_data *pdata = get_pdata(dssdev);
	int r;

	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
		return 0;

	r = omapdss_dpi_display_enable(dssdev);
	if (r)
		goto err0;

	if (pdata->platform_enable) {
		r = pdata->platform_enable(dssdev);
		if (r)
			goto err1;
	}

	return 0;
err1:
	omapdss_dpi_display_disable(dssdev);
err0:
	return r;
}

static void panel_dvi_power_off(struct omap_dss_device *dssdev)
{
	struct panel_dvi_platform_data *pdata = get_pdata(dssdev);

	if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
		return;

	if (pdata->platform_disable)
		pdata->platform_disable(dssdev);

	omapdss_dpi_display_disable(dssdev);
}

static int panel_dvi_probe(struct omap_dss_device *dssdev)
{
	struct panel_drv_data *ddata;

	ddata = kzalloc(sizeof(*ddata), GFP_KERNEL);
	if (!ddata)
		return -ENOMEM;

	dssdev->panel.timings = panel_dvi_default_timings;
	dssdev->panel.config = OMAP_DSS_LCD_TFT;

	ddata->dssdev = dssdev;
	mutex_init(&ddata->lock);

	dev_set_drvdata(&dssdev->dev, ddata);

	return 0;
}

static void __exit panel_dvi_remove(struct omap_dss_device *dssdev)
{
	struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);

	mutex_lock(&ddata->lock);

	dev_set_drvdata(&dssdev->dev, NULL);

	mutex_unlock(&ddata->lock);

	kfree(ddata);
}

static int panel_dvi_enable(struct omap_dss_device *dssdev)
{
	struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
	int r;

	mutex_lock(&ddata->lock);

	r = panel_dvi_power_on(dssdev);
	if (r == 0)
		dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;

	mutex_unlock(&ddata->lock);

	return r;
}

static void panel_dvi_disable(struct omap_dss_device *dssdev)
{
	struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);

	mutex_lock(&ddata->lock);

	panel_dvi_power_off(dssdev);

	dssdev->state = OMAP_DSS_DISPLAY_DISABLED;

	mutex_unlock(&ddata->lock);
}

static int panel_dvi_suspend(struct omap_dss_device *dssdev)
{
	struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);

	mutex_lock(&ddata->lock);

	panel_dvi_power_off(dssdev);

	dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;

	mutex_unlock(&ddata->lock);

	return 0;
}

static int panel_dvi_resume(struct omap_dss_device *dssdev)
{
	struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
	int r;

	mutex_lock(&ddata->lock);

	r = panel_dvi_power_on(dssdev);
	if (r == 0)
		dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;

	mutex_unlock(&ddata->lock);

	return r;
}

static void panel_dvi_set_timings(struct omap_dss_device *dssdev,
		struct omap_video_timings *timings)
{
	struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);

	mutex_lock(&ddata->lock);
	dpi_set_timings(dssdev, timings);
	mutex_unlock(&ddata->lock);
}

static void panel_dvi_get_timings(struct omap_dss_device *dssdev,
		struct omap_video_timings *timings)
{
	struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);

	mutex_lock(&ddata->lock);
	*timings = dssdev->panel.timings;
	mutex_unlock(&ddata->lock);
}

static int panel_dvi_check_timings(struct omap_dss_device *dssdev,
		struct omap_video_timings *timings)
{
	struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
	int r;

	mutex_lock(&ddata->lock);
	r = dpi_check_timings(dssdev, timings);
	mutex_unlock(&ddata->lock);

	return r;
}


static int panel_dvi_ddc_read(struct i2c_adapter *adapter,
		unsigned char *buf, u16 count, u8 offset)
{
	int r, retries;

	for (retries = 3; retries > 0; retries--) {
		struct i2c_msg msgs[] = {
			{
				.addr   = DDC_ADDR,
				.flags  = 0,
				.len    = 1,
				.buf    = &offset,
			}, {
				.addr   = DDC_ADDR,
				.flags  = I2C_M_RD,
				.len    = count,
				.buf    = buf,
			}
		};

		r = i2c_transfer(adapter, msgs, 2);
		if (r == 2)
			return 0;

		if (r != -EAGAIN)
			break;
	}

	return r < 0 ? r : -EIO;
}

static int panel_dvi_read_edid(struct omap_dss_device *dssdev,
		u8 *edid, int len)
{
	struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
	struct panel_dvi_platform_data *pdata = get_pdata(dssdev);
	struct i2c_adapter *adapter;
	int r, l, bytes_read;

	mutex_lock(&ddata->lock);

	if (pdata->i2c_bus_num == 0) {
		r = -ENODEV;
		goto err;
	}

	adapter = i2c_get_adapter(pdata->i2c_bus_num);
	if (!adapter) {
		dev_err(&dssdev->dev, "Failed to get I2C adapter, bus %d\n",
				pdata->i2c_bus_num);
		r = -EINVAL;
		goto err;
	}

	l = min(EDID_LENGTH, len);
	r = panel_dvi_ddc_read(adapter, edid, l, 0);
	if (r)
		goto err;

	bytes_read = l;

	/* if there are extensions, read second block */
	if (len > EDID_LENGTH && edid[0x7e] > 0) {
		l = min(EDID_LENGTH, len - EDID_LENGTH);

		r = panel_dvi_ddc_read(adapter, edid + EDID_LENGTH,
				l, EDID_LENGTH);
		if (r)
			goto err;

		bytes_read += l;
	}

	mutex_unlock(&ddata->lock);

	return bytes_read;

err:
	mutex_unlock(&ddata->lock);
	return r;
}

static bool panel_dvi_detect(struct omap_dss_device *dssdev)
{
	struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
	struct panel_dvi_platform_data *pdata = get_pdata(dssdev);
	struct i2c_adapter *adapter;
	unsigned char out;
	int r;

	mutex_lock(&ddata->lock);

	if (pdata->i2c_bus_num == 0)
		goto out;

	adapter = i2c_get_adapter(pdata->i2c_bus_num);
	if (!adapter)
		goto out;

	r = panel_dvi_ddc_read(adapter, &out, 1, 0);

	mutex_unlock(&ddata->lock);

	return r == 0;

out:
	mutex_unlock(&ddata->lock);
	return true;
}

static struct omap_dss_driver panel_dvi_driver = {
	.probe		= panel_dvi_probe,
	.remove		= __exit_p(panel_dvi_remove),

	.enable		= panel_dvi_enable,
	.disable	= panel_dvi_disable,
	.suspend	= panel_dvi_suspend,
	.resume		= panel_dvi_resume,

	.set_timings	= panel_dvi_set_timings,
	.get_timings	= panel_dvi_get_timings,
	.check_timings	= panel_dvi_check_timings,

	.read_edid	= panel_dvi_read_edid,
	.detect		= panel_dvi_detect,

	.driver         = {
		.name   = "dvi",
		.owner  = THIS_MODULE,
	},
};

static int __init panel_dvi_init(void)
{
	return omap_dss_register_driver(&panel_dvi_driver);
}

static void __exit panel_dvi_exit(void)
{
	omap_dss_unregister_driver(&panel_dvi_driver);
}

module_init(panel_dvi_init);
module_exit(panel_dvi_exit);
MODULE_LICENSE("GPL");
