/*
 * LCD panel driver for TPO TD043MTEA1
 *
 * Author: Gražvydas Ignotas <notasas@gmail.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 Foundation; either version 2 of the License, or
 * (at your option) any later version.
 */

#include <linux/module.h>
#include <linux/delay.h>
#include <linux/spi/spi.h>
#include <linux/regulator/consumer.h>
#include <linux/gpio.h>
#include <linux/err.h>
#include <linux/slab.h>

#include <video/omapdss.h>

#define TPO_R02_MODE(x)		((x) & 7)
#define TPO_R02_MODE_800x480	7
#define TPO_R02_NCLK_RISING	BIT(3)
#define TPO_R02_HSYNC_HIGH	BIT(4)
#define TPO_R02_VSYNC_HIGH	BIT(5)

#define TPO_R03_NSTANDBY	BIT(0)
#define TPO_R03_EN_CP_CLK	BIT(1)
#define TPO_R03_EN_VGL_PUMP	BIT(2)
#define TPO_R03_EN_PWM		BIT(3)
#define TPO_R03_DRIVING_CAP_100	BIT(4)
#define TPO_R03_EN_PRE_CHARGE	BIT(6)
#define TPO_R03_SOFTWARE_CTL	BIT(7)

#define TPO_R04_NFLIP_H		BIT(0)
#define TPO_R04_NFLIP_V		BIT(1)
#define TPO_R04_CP_CLK_FREQ_1H	BIT(2)
#define TPO_R04_VGL_FREQ_1H	BIT(4)

#define TPO_R03_VAL_NORMAL (TPO_R03_NSTANDBY | TPO_R03_EN_CP_CLK | \
			TPO_R03_EN_VGL_PUMP |  TPO_R03_EN_PWM | \
			TPO_R03_DRIVING_CAP_100 | TPO_R03_EN_PRE_CHARGE | \
			TPO_R03_SOFTWARE_CTL)

#define TPO_R03_VAL_STANDBY (TPO_R03_DRIVING_CAP_100 | \
			TPO_R03_EN_PRE_CHARGE | TPO_R03_SOFTWARE_CTL)

static const u16 tpo_td043_def_gamma[12] = {
	105, 315, 381, 431, 490, 537, 579, 686, 780, 837, 880, 1023
};

struct tpo_td043_device {
	struct spi_device *spi;
	struct regulator *vcc_reg;
	int nreset_gpio;
	u16 gamma[12];
	u32 mode;
	u32 hmirror:1;
	u32 vmirror:1;
	u32 powered_on:1;
	u32 spi_suspended:1;
	u32 power_on_resume:1;
};

static int tpo_td043_write(struct spi_device *spi, u8 addr, u8 data)
{
	struct spi_message	m;
	struct spi_transfer	xfer;
	u16			w;
	int			r;

	spi_message_init(&m);

	memset(&xfer, 0, sizeof(xfer));

	w = ((u16)addr << 10) | (1 << 8) | data;
	xfer.tx_buf = &w;
	xfer.bits_per_word = 16;
	xfer.len = 2;
	spi_message_add_tail(&xfer, &m);

	r = spi_sync(spi, &m);
	if (r < 0)
		dev_warn(&spi->dev, "failed to write to LCD reg (%d)\n", r);
	return r;
}

static void tpo_td043_write_gamma(struct spi_device *spi, u16 gamma[12])
{
	u8 i, val;

	/* gamma bits [9:8] */
	for (val = i = 0; i < 4; i++)
		val |= (gamma[i] & 0x300) >> ((i + 1) * 2);
	tpo_td043_write(spi, 0x11, val);

	for (val = i = 0; i < 4; i++)
		val |= (gamma[i+4] & 0x300) >> ((i + 1) * 2);
	tpo_td043_write(spi, 0x12, val);

	for (val = i = 0; i < 4; i++)
		val |= (gamma[i+8] & 0x300) >> ((i + 1) * 2);
	tpo_td043_write(spi, 0x13, val);

	/* gamma bits [7:0] */
	for (val = i = 0; i < 12; i++)
		tpo_td043_write(spi, 0x14 + i, gamma[i] & 0xff);
}

static int tpo_td043_write_mirror(struct spi_device *spi, bool h, bool v)
{
	u8 reg4 = TPO_R04_NFLIP_H | TPO_R04_NFLIP_V | \
		TPO_R04_CP_CLK_FREQ_1H | TPO_R04_VGL_FREQ_1H;
	if (h)
		reg4 &= ~TPO_R04_NFLIP_H;
	if (v)
		reg4 &= ~TPO_R04_NFLIP_V;

	return tpo_td043_write(spi, 4, reg4);
}

static int tpo_td043_set_hmirror(struct omap_dss_device *dssdev, bool enable)
{
	struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev);

	tpo_td043->hmirror = enable;
	return tpo_td043_write_mirror(tpo_td043->spi, tpo_td043->hmirror,
			tpo_td043->vmirror);
}

static bool tpo_td043_get_hmirror(struct omap_dss_device *dssdev)
{
	struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev);

	return tpo_td043->hmirror;
}

static ssize_t tpo_td043_vmirror_show(struct device *dev,
	struct device_attribute *attr, char *buf)
{
	struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev);

	return snprintf(buf, PAGE_SIZE, "%d\n", tpo_td043->vmirror);
}

static ssize_t tpo_td043_vmirror_store(struct device *dev,
	struct device_attribute *attr, const char *buf, size_t count)
{
	struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev);
	int val;
	int ret;

	ret = kstrtoint(buf, 0, &val);
	if (ret < 0)
		return ret;

	val = !!val;

	ret = tpo_td043_write_mirror(tpo_td043->spi, tpo_td043->hmirror, val);
	if (ret < 0)
		return ret;

	tpo_td043->vmirror = val;

	return count;
}

static ssize_t tpo_td043_mode_show(struct device *dev,
	struct device_attribute *attr, char *buf)
{
	struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev);

	return snprintf(buf, PAGE_SIZE, "%d\n", tpo_td043->mode);
}

static ssize_t tpo_td043_mode_store(struct device *dev,
	struct device_attribute *attr, const char *buf, size_t count)
{
	struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev);
	long val;
	int ret;

	ret = kstrtol(buf, 0, &val);
	if (ret != 0 || val & ~7)
		return -EINVAL;

	tpo_td043->mode = val;

	val |= TPO_R02_NCLK_RISING;
	tpo_td043_write(tpo_td043->spi, 2, val);

	return count;
}

static ssize_t tpo_td043_gamma_show(struct device *dev,
	struct device_attribute *attr, char *buf)
{
	struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev);
	ssize_t len = 0;
	int ret;
	int i;

	for (i = 0; i < ARRAY_SIZE(tpo_td043->gamma); i++) {
		ret = snprintf(buf + len, PAGE_SIZE - len, "%u ",
				tpo_td043->gamma[i]);
		if (ret < 0)
			return ret;
		len += ret;
	}
	buf[len - 1] = '\n';

	return len;
}

static ssize_t tpo_td043_gamma_store(struct device *dev,
	struct device_attribute *attr, const char *buf, size_t count)
{
	struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev);
	unsigned int g[12];
	int ret;
	int i;

	ret = sscanf(buf, "%u %u %u %u %u %u %u %u %u %u %u %u",
			&g[0], &g[1], &g[2], &g[3], &g[4], &g[5],
			&g[6], &g[7], &g[8], &g[9], &g[10], &g[11]);

	if (ret != 12)
		return -EINVAL;

	for (i = 0; i < 12; i++)
		tpo_td043->gamma[i] = g[i];

	tpo_td043_write_gamma(tpo_td043->spi, tpo_td043->gamma);

	return count;
}

static DEVICE_ATTR(vmirror, S_IRUGO | S_IWUSR,
		tpo_td043_vmirror_show, tpo_td043_vmirror_store);
static DEVICE_ATTR(mode, S_IRUGO | S_IWUSR,
		tpo_td043_mode_show, tpo_td043_mode_store);
static DEVICE_ATTR(gamma, S_IRUGO | S_IWUSR,
		tpo_td043_gamma_show, tpo_td043_gamma_store);

static struct attribute *tpo_td043_attrs[] = {
	&dev_attr_vmirror.attr,
	&dev_attr_mode.attr,
	&dev_attr_gamma.attr,
	NULL,
};

static struct attribute_group tpo_td043_attr_group = {
	.attrs = tpo_td043_attrs,
};

static const struct omap_video_timings tpo_td043_timings = {
	.x_res		= 800,
	.y_res		= 480,

	.pixel_clock	= 36000,

	.hsw		= 1,
	.hfp		= 68,
	.hbp		= 214,

	.vsw		= 1,
	.vfp		= 39,
	.vbp		= 34,

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

static int tpo_td043_power_on(struct tpo_td043_device *tpo_td043)
{
	int nreset_gpio = tpo_td043->nreset_gpio;
	int r;

	if (tpo_td043->powered_on)
		return 0;

	r = regulator_enable(tpo_td043->vcc_reg);
	if (r != 0)
		return r;

	/* wait for panel to stabilize */
	msleep(160);

	if (gpio_is_valid(nreset_gpio))
		gpio_set_value(nreset_gpio, 1);

	tpo_td043_write(tpo_td043->spi, 2,
			TPO_R02_MODE(tpo_td043->mode) | TPO_R02_NCLK_RISING);
	tpo_td043_write(tpo_td043->spi, 3, TPO_R03_VAL_NORMAL);
	tpo_td043_write(tpo_td043->spi, 0x20, 0xf0);
	tpo_td043_write(tpo_td043->spi, 0x21, 0xf0);
	tpo_td043_write_mirror(tpo_td043->spi, tpo_td043->hmirror,
			tpo_td043->vmirror);
	tpo_td043_write_gamma(tpo_td043->spi, tpo_td043->gamma);

	tpo_td043->powered_on = 1;
	return 0;
}

static void tpo_td043_power_off(struct tpo_td043_device *tpo_td043)
{
	int nreset_gpio = tpo_td043->nreset_gpio;

	if (!tpo_td043->powered_on)
		return;

	tpo_td043_write(tpo_td043->spi, 3,
			TPO_R03_VAL_STANDBY | TPO_R03_EN_PWM);

	if (gpio_is_valid(nreset_gpio))
		gpio_set_value(nreset_gpio, 0);

	/* wait for at least 2 vsyncs before cutting off power */
	msleep(50);

	tpo_td043_write(tpo_td043->spi, 3, TPO_R03_VAL_STANDBY);

	regulator_disable(tpo_td043->vcc_reg);

	tpo_td043->powered_on = 0;
}

static int tpo_td043_enable_dss(struct omap_dss_device *dssdev)
{
	struct tpo_td043_device *tpo_td043 = 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 (dssdev->platform_enable) {
		r = dssdev->platform_enable(dssdev);
		if (r)
			goto err1;
	}

	/*
	 * If we are resuming from system suspend, SPI clocks might not be
	 * enabled yet, so we'll program the LCD from SPI PM resume callback.
	 */
	if (!tpo_td043->spi_suspended) {
		r = tpo_td043_power_on(tpo_td043);
		if (r)
			goto err1;
	}

	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;

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

static void tpo_td043_disable_dss(struct omap_dss_device *dssdev)
{
	struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev);

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

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

	omapdss_dpi_display_disable(dssdev);

	if (!tpo_td043->spi_suspended)
		tpo_td043_power_off(tpo_td043);
}

static int tpo_td043_enable(struct omap_dss_device *dssdev)
{
	dev_dbg(&dssdev->dev, "enable\n");

	return tpo_td043_enable_dss(dssdev);
}

static void tpo_td043_disable(struct omap_dss_device *dssdev)
{
	dev_dbg(&dssdev->dev, "disable\n");

	tpo_td043_disable_dss(dssdev);

	dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
}

static int tpo_td043_probe(struct omap_dss_device *dssdev)
{
	struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev);
	int nreset_gpio = dssdev->reset_gpio;
	int ret = 0;

	dev_dbg(&dssdev->dev, "probe\n");

	if (tpo_td043 == NULL) {
		dev_err(&dssdev->dev, "missing tpo_td043_device\n");
		return -ENODEV;
	}

	dssdev->panel.timings = tpo_td043_timings;
	dssdev->ctrl.pixel_size = 24;

	tpo_td043->mode = TPO_R02_MODE_800x480;
	memcpy(tpo_td043->gamma, tpo_td043_def_gamma, sizeof(tpo_td043->gamma));

	tpo_td043->vcc_reg = regulator_get(&dssdev->dev, "vcc");
	if (IS_ERR(tpo_td043->vcc_reg)) {
		dev_err(&dssdev->dev, "failed to get LCD VCC regulator\n");
		ret = PTR_ERR(tpo_td043->vcc_reg);
		goto fail_regulator;
	}

	if (gpio_is_valid(nreset_gpio)) {
		ret = gpio_request_one(nreset_gpio, GPIOF_OUT_INIT_LOW,
					"lcd reset");
		if (ret < 0) {
			dev_err(&dssdev->dev, "couldn't request reset GPIO\n");
			goto fail_gpio_req;
		}
	}

	ret = sysfs_create_group(&dssdev->dev.kobj, &tpo_td043_attr_group);
	if (ret)
		dev_warn(&dssdev->dev, "failed to create sysfs files\n");

	return 0;

fail_gpio_req:
	regulator_put(tpo_td043->vcc_reg);
fail_regulator:
	kfree(tpo_td043);
	return ret;
}

static void tpo_td043_remove(struct omap_dss_device *dssdev)
{
	struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev);
	int nreset_gpio = dssdev->reset_gpio;

	dev_dbg(&dssdev->dev, "remove\n");

	sysfs_remove_group(&dssdev->dev.kobj, &tpo_td043_attr_group);
	regulator_put(tpo_td043->vcc_reg);
	if (gpio_is_valid(nreset_gpio))
		gpio_free(nreset_gpio);
}

static void tpo_td043_set_timings(struct omap_dss_device *dssdev,
		struct omap_video_timings *timings)
{
	omapdss_dpi_set_timings(dssdev, timings);

	dssdev->panel.timings = *timings;
}

static int tpo_td043_check_timings(struct omap_dss_device *dssdev,
		struct omap_video_timings *timings)
{
	return dpi_check_timings(dssdev, timings);
}

static struct omap_dss_driver tpo_td043_driver = {
	.probe		= tpo_td043_probe,
	.remove		= tpo_td043_remove,

	.enable		= tpo_td043_enable,
	.disable	= tpo_td043_disable,
	.set_mirror	= tpo_td043_set_hmirror,
	.get_mirror	= tpo_td043_get_hmirror,

	.set_timings	= tpo_td043_set_timings,
	.check_timings	= tpo_td043_check_timings,

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

static int tpo_td043_spi_probe(struct spi_device *spi)
{
	struct omap_dss_device *dssdev = spi->dev.platform_data;
	struct tpo_td043_device *tpo_td043;
	int ret;

	if (dssdev == NULL) {
		dev_err(&spi->dev, "missing dssdev\n");
		return -ENODEV;
	}

	spi->bits_per_word = 16;
	spi->mode = SPI_MODE_0;

	ret = spi_setup(spi);
	if (ret < 0) {
		dev_err(&spi->dev, "spi_setup failed: %d\n", ret);
		return ret;
	}

	tpo_td043 = kzalloc(sizeof(*tpo_td043), GFP_KERNEL);
	if (tpo_td043 == NULL)
		return -ENOMEM;

	tpo_td043->spi = spi;
	tpo_td043->nreset_gpio = dssdev->reset_gpio;
	dev_set_drvdata(&spi->dev, tpo_td043);
	dev_set_drvdata(&dssdev->dev, tpo_td043);

	omap_dss_register_driver(&tpo_td043_driver);

	return 0;
}

static int tpo_td043_spi_remove(struct spi_device *spi)
{
	struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&spi->dev);

	omap_dss_unregister_driver(&tpo_td043_driver);
	kfree(tpo_td043);

	return 0;
}

#ifdef CONFIG_PM_SLEEP
static int tpo_td043_spi_suspend(struct device *dev)
{
	struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev);

	dev_dbg(dev, "tpo_td043_spi_suspend, tpo %p\n", tpo_td043);

	tpo_td043->power_on_resume = tpo_td043->powered_on;
	tpo_td043_power_off(tpo_td043);
	tpo_td043->spi_suspended = 1;

	return 0;
}

static int tpo_td043_spi_resume(struct device *dev)
{
	struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev);
	int ret;

	dev_dbg(dev, "tpo_td043_spi_resume\n");

	if (tpo_td043->power_on_resume) {
		ret = tpo_td043_power_on(tpo_td043);
		if (ret)
			return ret;
	}
	tpo_td043->spi_suspended = 0;

	return 0;
}
#endif

static SIMPLE_DEV_PM_OPS(tpo_td043_spi_pm,
	tpo_td043_spi_suspend, tpo_td043_spi_resume);

static struct spi_driver tpo_td043_spi_driver = {
	.driver = {
		.name	= "tpo_td043mtea1_panel_spi",
		.owner	= THIS_MODULE,
		.pm	= &tpo_td043_spi_pm,
	},
	.probe	= tpo_td043_spi_probe,
	.remove	= tpo_td043_spi_remove,
};

module_spi_driver(tpo_td043_spi_driver);

MODULE_AUTHOR("Gražvydas Ignotas <notasas@gmail.com>");
MODULE_DESCRIPTION("TPO TD043MTEA1 LCD Driver");
MODULE_LICENSE("GPL");
