/*
 * TFP410 DPI-to-DVI chip
 *
 * 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 <linux/gpio.h>
#include <drm/drm_edid.h>

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

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

	.pixel_clock	= 23500,

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

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

	.vsync_level	= OMAPDSS_SIG_ACTIVE_HIGH,
	.hsync_level	= OMAPDSS_SIG_ACTIVE_HIGH,
	.data_pclk_edge	= OMAPDSS_DRIVE_SIG_RISING_EDGE,
	.de_level	= OMAPDSS_SIG_ACTIVE_HIGH,
	.sync_pclk_edge	= OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
};

struct panel_drv_data {
	struct omap_dss_device *dssdev;

	struct mutex lock;

	int pd_gpio;

	struct i2c_adapter *i2c_adapter;
};

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

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

	omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
	omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines);

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

	if (gpio_is_valid(ddata->pd_gpio))
		gpio_set_value_cansleep(ddata->pd_gpio, 1);

	return 0;
err0:
	return r;
}

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

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

	if (gpio_is_valid(ddata->pd_gpio))
		gpio_set_value_cansleep(ddata->pd_gpio, 0);

	omapdss_dpi_display_disable(dssdev);
}

static int tfp410_probe(struct omap_dss_device *dssdev)
{
	struct panel_drv_data *ddata;
	int r;
	int i2c_bus_num;

	ddata = devm_kzalloc(dssdev->dev, sizeof(*ddata), GFP_KERNEL);
	if (!ddata)
		return -ENOMEM;

	dssdev->panel.timings = tfp410_default_timings;

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

	if (dssdev->data) {
		struct tfp410_platform_data *pdata = dssdev->data;

		ddata->pd_gpio = pdata->power_down_gpio;
		i2c_bus_num = pdata->i2c_bus_num;
	} else {
		ddata->pd_gpio = -1;
		i2c_bus_num = -1;
	}

	if (gpio_is_valid(ddata->pd_gpio)) {
		r = devm_gpio_request_one(dssdev->dev, ddata->pd_gpio,
				GPIOF_OUT_INIT_LOW, "tfp410 pd");
		if (r) {
			dev_err(dssdev->dev, "Failed to request PD GPIO %d\n",
					ddata->pd_gpio);
			return r;
		}
	}

	if (i2c_bus_num != -1) {
		struct i2c_adapter *adapter;

		adapter = i2c_get_adapter(i2c_bus_num);
		if (!adapter) {
			dev_err(dssdev->dev, "Failed to get I2C adapter, bus %d\n",
					i2c_bus_num);
			return -EPROBE_DEFER;
		}

		ddata->i2c_adapter = adapter;
	}

	dev_set_drvdata(dssdev->dev, ddata);

	return 0;
}

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

	mutex_lock(&ddata->lock);

	if (ddata->i2c_adapter)
		i2c_put_adapter(ddata->i2c_adapter);

	dev_set_drvdata(dssdev->dev, NULL);

	mutex_unlock(&ddata->lock);
}

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

	mutex_lock(&ddata->lock);

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

	mutex_unlock(&ddata->lock);

	return r;
}

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

	mutex_lock(&ddata->lock);

	tfp410_power_off(dssdev);

	dssdev->state = OMAP_DSS_DISPLAY_DISABLED;

	mutex_unlock(&ddata->lock);
}

static void tfp410_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);
	omapdss_dpi_set_timings(dssdev, timings);
	dssdev->panel.timings = *timings;
	mutex_unlock(&ddata->lock);
}

static void tfp410_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 tfp410_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 tfp410_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 tfp410_read_edid(struct omap_dss_device *dssdev,
		u8 *edid, int len)
{
	struct panel_drv_data *ddata = dev_get_drvdata(dssdev->dev);
	int r, l, bytes_read;

	mutex_lock(&ddata->lock);

	if (!ddata->i2c_adapter) {
		r = -ENODEV;
		goto err;
	}

	l = min(EDID_LENGTH, len);
	r = tfp410_ddc_read(ddata->i2c_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 = tfp410_ddc_read(ddata->i2c_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 tfp410_detect(struct omap_dss_device *dssdev)
{
	struct panel_drv_data *ddata = dev_get_drvdata(dssdev->dev);
	unsigned char out;
	int r;

	mutex_lock(&ddata->lock);

	if (!ddata->i2c_adapter)
		goto out;

	r = tfp410_ddc_read(ddata->i2c_adapter, &out, 1, 0);

	mutex_unlock(&ddata->lock);

	return r == 0;

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

static struct omap_dss_driver tfp410_driver = {
	.probe		= tfp410_probe,
	.remove		= __exit_p(tfp410_remove),

	.enable		= tfp410_enable,
	.disable	= tfp410_disable,

	.set_timings	= tfp410_set_timings,
	.get_timings	= tfp410_get_timings,
	.check_timings	= tfp410_check_timings,

	.read_edid	= tfp410_read_edid,
	.detect		= tfp410_detect,

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

static int __init tfp410_init(void)
{
	return omap_dss_register_driver(&tfp410_driver);
}

static void __exit tfp410_exit(void)
{
	omap_dss_unregister_driver(&tfp410_driver);
}

module_init(tfp410_init);
module_exit(tfp410_exit);
MODULE_LICENSE("GPL");
