// SPDX-License-Identifier: GPL-2.0-only
/* drivers/video/backlight/ili9320.c
 *
 * ILI9320 LCD controller driver core.
 *
 * Copyright 2007 Simtec Electronics
 *	http://armlinux.simtec.co.uk/
 *	Ben Dooks <ben@simtec.co.uk>
*/

#include <linux/delay.h>
#include <linux/err.h>
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/lcd.h>
#include <linux/module.h>
#include <linux/slab.h>

#include <linux/spi/spi.h>

#include <video/ili9320.h>

#include "ili9320.h"


static inline int ili9320_write_spi(struct ili9320 *ili,
				    unsigned int reg,
				    unsigned int value)
{
	struct ili9320_spi *spi = &ili->access.spi;
	unsigned char *addr = spi->buffer_addr;
	unsigned char *data = spi->buffer_data;

	/* spi message consits of:
	 * first byte: ID and operation
	 */

	addr[0] = spi->id | ILI9320_SPI_INDEX | ILI9320_SPI_WRITE;
	addr[1] = reg >> 8;
	addr[2] = reg;

	/* second message is the data to transfer */

	data[0] = spi->id | ILI9320_SPI_DATA  | ILI9320_SPI_WRITE;
	data[1] = value >> 8;
	data[2] = value;

	return spi_sync(spi->dev, &spi->message);
}

int ili9320_write(struct ili9320 *ili, unsigned int reg, unsigned int value)
{
	dev_dbg(ili->dev, "write: reg=%02x, val=%04x\n", reg, value);
	return ili->write(ili, reg, value);
}
EXPORT_SYMBOL_GPL(ili9320_write);

int ili9320_write_regs(struct ili9320 *ili,
		       const struct ili9320_reg *values,
		       int nr_values)
{
	int index;
	int ret;

	for (index = 0; index < nr_values; index++, values++) {
		ret = ili9320_write(ili, values->address, values->value);
		if (ret != 0)
			return ret;
	}

	return 0;
}
EXPORT_SYMBOL_GPL(ili9320_write_regs);

static void ili9320_reset(struct ili9320 *lcd)
{
	struct ili9320_platdata *cfg = lcd->platdata;

	cfg->reset(1);
	mdelay(50);

	cfg->reset(0);
	mdelay(50);

	cfg->reset(1);
	mdelay(100);
}

static inline int ili9320_init_chip(struct ili9320 *lcd)
{
	int ret;

	ili9320_reset(lcd);

	ret = lcd->client->init(lcd, lcd->platdata);
	if (ret != 0) {
		dev_err(lcd->dev, "failed to initialise display\n");
		return ret;
	}

	lcd->initialised = 1;
	return 0;
}

static inline int ili9320_power_on(struct ili9320 *lcd)
{
	if (!lcd->initialised)
		ili9320_init_chip(lcd);

	lcd->display1 |= (ILI9320_DISPLAY1_D(3) | ILI9320_DISPLAY1_BASEE);
	ili9320_write(lcd, ILI9320_DISPLAY1, lcd->display1);

	return 0;
}

static inline int ili9320_power_off(struct ili9320 *lcd)
{
	lcd->display1 &= ~(ILI9320_DISPLAY1_D(3) | ILI9320_DISPLAY1_BASEE);
	ili9320_write(lcd, ILI9320_DISPLAY1, lcd->display1);

	return 0;
}

#define POWER_IS_ON(pwr)	((pwr) <= FB_BLANK_NORMAL)

static int ili9320_power(struct ili9320 *lcd, int power)
{
	int ret = 0;

	dev_dbg(lcd->dev, "power %d => %d\n", lcd->power, power);

	if (POWER_IS_ON(power) && !POWER_IS_ON(lcd->power))
		ret = ili9320_power_on(lcd);
	else if (!POWER_IS_ON(power) && POWER_IS_ON(lcd->power))
		ret = ili9320_power_off(lcd);

	if (ret == 0)
		lcd->power = power;
	else
		dev_warn(lcd->dev, "failed to set power mode %d\n", power);

	return ret;
}

static inline struct ili9320 *to_our_lcd(struct lcd_device *lcd)
{
	return lcd_get_data(lcd);
}

static int ili9320_set_power(struct lcd_device *ld, int power)
{
	struct ili9320 *lcd = to_our_lcd(ld);

	return ili9320_power(lcd, power);
}

static int ili9320_get_power(struct lcd_device *ld)
{
	struct ili9320 *lcd = to_our_lcd(ld);

	return lcd->power;
}

static struct lcd_ops ili9320_ops = {
	.get_power	= ili9320_get_power,
	.set_power	= ili9320_set_power,
};

static void ili9320_setup_spi(struct ili9320 *ili,
					struct spi_device *dev)
{
	struct ili9320_spi *spi = &ili->access.spi;

	ili->write = ili9320_write_spi;
	spi->dev = dev;

	/* fill the two messages we are going to use to send the data
	 * with, the first the address followed by the data. The datasheet
	 * says they should be done as two distinct cycles of the SPI CS line.
	 */

	spi->xfer[0].tx_buf = spi->buffer_addr;
	spi->xfer[1].tx_buf = spi->buffer_data;
	spi->xfer[0].len = 3;
	spi->xfer[1].len = 3;
	spi->xfer[0].bits_per_word = 8;
	spi->xfer[1].bits_per_word = 8;
	spi->xfer[0].cs_change = 1;

	spi_message_init(&spi->message);
	spi_message_add_tail(&spi->xfer[0], &spi->message);
	spi_message_add_tail(&spi->xfer[1], &spi->message);
}

int ili9320_probe_spi(struct spi_device *spi,
				struct ili9320_client *client)
{
	struct ili9320_platdata *cfg = dev_get_platdata(&spi->dev);
	struct device *dev = &spi->dev;
	struct ili9320 *ili;
	struct lcd_device *lcd;
	int ret = 0;

	/* verify we where given some information */

	if (cfg == NULL) {
		dev_err(dev, "no platform data supplied\n");
		return -EINVAL;
	}

	if (cfg->hsize <= 0 || cfg->vsize <= 0 || cfg->reset == NULL) {
		dev_err(dev, "invalid platform data supplied\n");
		return -EINVAL;
	}

	/* allocate and initialse our state */

	ili = devm_kzalloc(&spi->dev, sizeof(struct ili9320), GFP_KERNEL);
	if (ili == NULL)
		return -ENOMEM;

	ili->access.spi.id = ILI9320_SPI_IDCODE | ILI9320_SPI_ID(1);

	ili->dev = dev;
	ili->client = client;
	ili->power = FB_BLANK_POWERDOWN;
	ili->platdata = cfg;

	spi_set_drvdata(spi, ili);

	ili9320_setup_spi(ili, spi);

	lcd = devm_lcd_device_register(&spi->dev, "ili9320", dev, ili,
					&ili9320_ops);
	if (IS_ERR(lcd)) {
		dev_err(dev, "failed to register lcd device\n");
		return PTR_ERR(lcd);
	}

	ili->lcd = lcd;

	dev_info(dev, "initialising %s\n", client->name);

	ret = ili9320_power(ili, FB_BLANK_UNBLANK);
	if (ret != 0) {
		dev_err(dev, "failed to set lcd power state\n");
		return ret;
	}

	return 0;
}
EXPORT_SYMBOL_GPL(ili9320_probe_spi);

int ili9320_remove(struct ili9320 *ili)
{
	ili9320_power(ili, FB_BLANK_POWERDOWN);
	return 0;
}
EXPORT_SYMBOL_GPL(ili9320_remove);

#ifdef CONFIG_PM_SLEEP
int ili9320_suspend(struct ili9320 *lcd)
{
	int ret;

	ret = ili9320_power(lcd, FB_BLANK_POWERDOWN);

	if (lcd->platdata->suspend == ILI9320_SUSPEND_DEEP) {
		ili9320_write(lcd, ILI9320_POWER1, lcd->power1 |
			      ILI9320_POWER1_SLP |
			      ILI9320_POWER1_DSTB);
		lcd->initialised = 0;
	}

	return ret;
}
EXPORT_SYMBOL_GPL(ili9320_suspend);

int ili9320_resume(struct ili9320 *lcd)
{
	dev_info(lcd->dev, "resuming from power state %d\n", lcd->power);

	if (lcd->platdata->suspend == ILI9320_SUSPEND_DEEP)
		ili9320_write(lcd, ILI9320_POWER1, 0x00);

	return ili9320_power(lcd, FB_BLANK_UNBLANK);
}
EXPORT_SYMBOL_GPL(ili9320_resume);
#endif

/* Power down all displays on reboot, poweroff or halt */
void ili9320_shutdown(struct ili9320 *lcd)
{
	ili9320_power(lcd, FB_BLANK_POWERDOWN);
}
EXPORT_SYMBOL_GPL(ili9320_shutdown);

MODULE_AUTHOR("Ben Dooks <ben-linux@fluff.org>");
MODULE_DESCRIPTION("ILI9320 LCD Driver");
MODULE_LICENSE("GPL v2");
