/*
 * LCD panel driver for Sharp LS037V7DW01
 *
 * Copyright (C) 2008 Nokia Corporation
 * Author: Tomi Valkeinen <tomi.valkeinen@nokia.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/delay.h>
#include <linux/device.h>
#include <linux/fb.h>
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/gpio.h>

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

static struct omap_video_timings sharp_ls_timings = {
	.x_res = 480,
	.y_res = 640,

	.pixel_clock	= 19200,

	.hsw		= 2,
	.hfp		= 1,
	.hbp		= 28,

	.vsw		= 1,
	.vfp		= 1,
	.vbp		= 1,

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

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

static int sharp_ls_panel_probe(struct omap_dss_device *dssdev)
{
	struct panel_sharp_ls037v7dw01_data *pd = get_panel_data(dssdev);
	int r;

	if (!pd)
		return -EINVAL;

	dssdev->panel.timings = sharp_ls_timings;

	if (gpio_is_valid(pd->mo_gpio)) {
		r = devm_gpio_request_one(&dssdev->dev, pd->mo_gpio,
				GPIOF_OUT_INIT_LOW, "lcd MO");
		if (r)
			return r;
	}

	if (gpio_is_valid(pd->lr_gpio)) {
		r = devm_gpio_request_one(&dssdev->dev, pd->lr_gpio,
				GPIOF_OUT_INIT_HIGH, "lcd LR");
		if (r)
			return r;
	}

	if (gpio_is_valid(pd->ud_gpio)) {
		r = devm_gpio_request_one(&dssdev->dev, pd->ud_gpio,
				GPIOF_OUT_INIT_HIGH, "lcd UD");
		if (r)
			return r;
	}

	if (gpio_is_valid(pd->resb_gpio)) {
		r = devm_gpio_request_one(&dssdev->dev, pd->resb_gpio,
				GPIOF_OUT_INIT_LOW, "lcd RESB");
		if (r)
			return r;
	}

	if (gpio_is_valid(pd->ini_gpio)) {
		r = devm_gpio_request_one(&dssdev->dev, pd->ini_gpio,
				GPIOF_OUT_INIT_LOW, "lcd INI");
		if (r)
			return r;
	}

	return 0;
}

static void __exit sharp_ls_panel_remove(struct omap_dss_device *dssdev)
{
}

static int sharp_ls_power_on(struct omap_dss_device *dssdev)
{
	struct panel_sharp_ls037v7dw01_data *pd = get_panel_data(dssdev);
	int r = 0;

	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;

	/* wait couple of vsyncs until enabling the LCD */
	msleep(50);

	if (gpio_is_valid(pd->resb_gpio))
		gpio_set_value_cansleep(pd->resb_gpio, 1);

	if (gpio_is_valid(pd->ini_gpio))
		gpio_set_value_cansleep(pd->ini_gpio, 1);

	return 0;
err0:
	return r;
}

static void sharp_ls_power_off(struct omap_dss_device *dssdev)
{
	struct panel_sharp_ls037v7dw01_data *pd = get_panel_data(dssdev);

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

	if (gpio_is_valid(pd->ini_gpio))
		gpio_set_value_cansleep(pd->ini_gpio, 0);

	if (gpio_is_valid(pd->resb_gpio))
		gpio_set_value_cansleep(pd->resb_gpio, 0);

	/* wait at least 5 vsyncs after disabling the LCD */

	msleep(100);

	omapdss_dpi_display_disable(dssdev);
}

static int sharp_ls_panel_enable(struct omap_dss_device *dssdev)
{
	int r;
	r = sharp_ls_power_on(dssdev);
	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
	return r;
}

static void sharp_ls_panel_disable(struct omap_dss_device *dssdev)
{
	sharp_ls_power_off(dssdev);
	dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
}

static struct omap_dss_driver sharp_ls_driver = {
	.probe		= sharp_ls_panel_probe,
	.remove		= __exit_p(sharp_ls_panel_remove),

	.enable		= sharp_ls_panel_enable,
	.disable	= sharp_ls_panel_disable,

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

static int __init sharp_ls_panel_drv_init(void)
{
	return omap_dss_register_driver(&sharp_ls_driver);
}

static void __exit sharp_ls_panel_drv_exit(void)
{
	omap_dss_unregister_driver(&sharp_ls_driver);
}

module_init(sharp_ls_panel_drv_init);
module_exit(sharp_ls_panel_drv_exit);
MODULE_LICENSE("GPL");
