// SPDX-License-Identifier: GPL-2.0+
/*
 * FB driver for the Watterott LCD Controller
 *
 * Copyright (C) 2013 Noralf Tronnes
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/delay.h>

#include "fbtft.h"

#define DRVNAME			"fb_watterott"
#define WIDTH			320
#define HEIGHT			240
#define FPS			5
#define TXBUFLEN		1024
#define DEFAULT_BRIGHTNESS	50

#define CMD_VERSION		0x01
#define CMD_LCD_LED		0x10
#define CMD_LCD_RESET		0x11
#define CMD_LCD_ORIENTATION	0x20
#define CMD_LCD_DRAWIMAGE	0x27
#define COLOR_RGB323		8
#define COLOR_RGB332		9
#define COLOR_RGB233		10
#define COLOR_RGB565		16

static short mode = 565;
module_param(mode, short, 0000);
MODULE_PARM_DESC(mode, "RGB color transfer mode: 332, 565 (default)");

static void write_reg8_bus8(struct fbtft_par *par, int len, ...)
{
	va_list args;
	int i, ret;
	u8 *buf = par->buf;

	va_start(args, len);
	for (i = 0; i < len; i++)
		*buf++ = (u8)va_arg(args, unsigned int);
	va_end(args);

	fbtft_par_dbg_hex(DEBUG_WRITE_REGISTER, par,
			  par->info->device, u8, par->buf,
			  len, "%s: ", __func__);

	ret = par->fbtftops.write(par, par->buf, len);
	if (ret < 0) {
		dev_err(par->info->device,
			"write() failed and returned %d\n", ret);
		return;
	}
}

static int write_vmem(struct fbtft_par *par, size_t offset, size_t len)
{
	unsigned int start_line, end_line;
	u16 *vmem16 = (u16 *)(par->info->screen_buffer + offset);
	__be16 *pos = par->txbuf.buf + 1;
	__be16 *buf16 = par->txbuf.buf + 10;
	int i, j;
	int ret = 0;

	start_line = offset / par->info->fix.line_length;
	end_line = start_line + (len / par->info->fix.line_length) - 1;

	/* Set command header. pos: x, y, w, h */
	((u8 *)par->txbuf.buf)[0] = CMD_LCD_DRAWIMAGE;
	pos[0] = 0;
	pos[2] = cpu_to_be16(par->info->var.xres);
	pos[3] = cpu_to_be16(1);
	((u8 *)par->txbuf.buf)[9] = COLOR_RGB565;

	for (i = start_line; i <= end_line; i++) {
		pos[1] = cpu_to_be16(i);
		for (j = 0; j < par->info->var.xres; j++)
			buf16[j] = cpu_to_be16(*vmem16++);
		ret = par->fbtftops.write(par,
			par->txbuf.buf, 10 + par->info->fix.line_length);
		if (ret < 0)
			return ret;
		udelay(300);
	}

	return 0;
}

static inline int rgb565_to_rgb332(u16 c)
{
	return ((c & 0xE000) >> 8) | ((c & 000700) >> 6) | ((c & 0x0018) >> 3);
}

static int write_vmem_8bit(struct fbtft_par *par, size_t offset, size_t len)
{
	unsigned int start_line, end_line;
	u16 *vmem16 = (u16 *)(par->info->screen_buffer + offset);
	__be16 *pos = par->txbuf.buf + 1;
	u8 *buf8 = par->txbuf.buf + 10;
	int i, j;
	int ret = 0;

	start_line = offset / par->info->fix.line_length;
	end_line = start_line + (len / par->info->fix.line_length) - 1;

	/* Set command header. pos: x, y, w, h */
	((u8 *)par->txbuf.buf)[0] = CMD_LCD_DRAWIMAGE;
	pos[0] = 0;
	pos[2] = cpu_to_be16(par->info->var.xres);
	pos[3] = cpu_to_be16(1);
	((u8 *)par->txbuf.buf)[9] = COLOR_RGB332;

	for (i = start_line; i <= end_line; i++) {
		pos[1] = cpu_to_be16(i);
		for (j = 0; j < par->info->var.xres; j++) {
			buf8[j] = rgb565_to_rgb332(*vmem16);
			vmem16++;
		}
		ret = par->fbtftops.write(par,
			par->txbuf.buf, 10 + par->info->var.xres);
		if (ret < 0)
			return ret;
		udelay(700);
	}

	return 0;
}

static unsigned int firmware_version(struct fbtft_par *par)
{
	u8 rxbuf[4] = {0, };

	write_reg(par, CMD_VERSION);
	par->fbtftops.read(par, rxbuf, 4);
	if (rxbuf[1] != '.')
		return 0;

	return (rxbuf[0] - '0') << 8 | (rxbuf[2] - '0') << 4 | (rxbuf[3] - '0');
}

static int init_display(struct fbtft_par *par)
{
	int ret;
	unsigned int version;
	u8 save_mode;

	/* enable SPI interface by having CS and MOSI low during reset */
	save_mode = par->spi->mode;
	/*
	 * Set CS active inverse polarity: just setting SPI_CS_HIGH does not
	 * work with GPIO based chip selects that are logically active high
	 * but inverted inside the GPIO library, so enforce inverted
	 * semantics.
	 */
	par->spi->mode ^= SPI_CS_HIGH;
	ret = spi_setup(par->spi);
	if (ret) {
		dev_err(par->info->device,
			"Could not set inverse CS polarity\n");
		return ret;
	}
	write_reg(par, 0x00); /* make sure mode is set */

	mdelay(50);
	par->fbtftops.reset(par);
	mdelay(1000);
	par->spi->mode = save_mode;
	ret = spi_setup(par->spi);
	if (ret) {
		dev_err(par->info->device, "Could not restore SPI mode\n");
		return ret;
	}
	write_reg(par, 0x00);

	version = firmware_version(par);
	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "Firmware version: %x.%02x\n",
		      version >> 8, version & 0xFF);

	if (mode == 332)
		par->fbtftops.write_vmem = write_vmem_8bit;
	return 0;
}

static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
{
	/* not used on this controller */
}

static int set_var(struct fbtft_par *par)
{
	u8 rotate;

	/* this controller rotates clock wise */
	switch (par->info->var.rotate) {
	case 90:
		rotate = 27;
		break;
	case 180:
		rotate = 18;
		break;
	case 270:
		rotate = 9;
		break;
	default:
		rotate = 0;
	}
	write_reg(par, CMD_LCD_ORIENTATION, rotate);

	return 0;
}

static int verify_gpios(struct fbtft_par *par)
{
	if (!par->gpio.reset) {
		dev_err(par->info->device, "Missing 'reset' gpio. Aborting.\n");
		return -EINVAL;
	}
	return 0;
}

#ifdef CONFIG_FB_BACKLIGHT
static int backlight_chip_update_status(struct backlight_device *bd)
{
	struct fbtft_par *par = bl_get_data(bd);
	int brightness = bd->props.brightness;

	fbtft_par_dbg(DEBUG_BACKLIGHT, par,
		      "%s: brightness=%d, power=%d, fb_blank=%d\n", __func__,
		      bd->props.brightness, bd->props.power,
		      bd->props.fb_blank);

	if (bd->props.power != FB_BLANK_UNBLANK)
		brightness = 0;

	if (bd->props.fb_blank != FB_BLANK_UNBLANK)
		brightness = 0;

	write_reg(par, CMD_LCD_LED, brightness);

	return 0;
}

static const struct backlight_ops bl_ops = {
	.update_status = backlight_chip_update_status,
};

static void register_chip_backlight(struct fbtft_par *par)
{
	struct backlight_device *bd;
	struct backlight_properties bl_props = { 0, };

	bl_props.type = BACKLIGHT_RAW;
	bl_props.power = FB_BLANK_POWERDOWN;
	bl_props.max_brightness = 100;
	bl_props.brightness = DEFAULT_BRIGHTNESS;

	bd = backlight_device_register(dev_driver_string(par->info->device),
				       par->info->device, par, &bl_ops,
				       &bl_props);
	if (IS_ERR(bd)) {
		dev_err(par->info->device,
			"cannot register backlight device (%ld)\n",
			PTR_ERR(bd));
		return;
	}
	par->info->bl_dev = bd;

	if (!par->fbtftops.unregister_backlight)
		par->fbtftops.unregister_backlight = fbtft_unregister_backlight;
}
#else
#define register_chip_backlight NULL
#endif

static struct fbtft_display display = {
	.regwidth = 8,
	.buswidth = 8,
	.width = WIDTH,
	.height = HEIGHT,
	.fps = FPS,
	.txbuflen = TXBUFLEN,
	.fbtftops = {
		.write_register = write_reg8_bus8,
		.write_vmem = write_vmem,
		.init_display = init_display,
		.set_addr_win = set_addr_win,
		.set_var = set_var,
		.verify_gpios = verify_gpios,
		.register_backlight = register_chip_backlight,
	},
};

FBTFT_REGISTER_DRIVER(DRVNAME, "watterott,openlcd", &display);

MODULE_ALIAS("spi:" DRVNAME);

MODULE_DESCRIPTION("FB driver for the Watterott LCD Controller");
MODULE_AUTHOR("Noralf Tronnes");
MODULE_LICENSE("GPL");
