/*
 * FB driver for Two KS0108 LCD controllers in AGM1264K-FL display
 *
 * Copyright (C) 2014 ololoshka2871
 *
 * 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.
 *
 * 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.
 */

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

#include "fbtft.h"

/* Uncomment text line to use negative image on display */
/*#define NEGATIVE*/

#define WHITE		0xff
#define BLACK		0

#define DRVNAME		"fb_agm1264k-fl"
#define WIDTH		64
#define HEIGHT		64
#define TOTALWIDTH	(WIDTH * 2)	 /* because 2 x ks0108 in one display */
#define FPS			20

#define EPIN		gpio.wr
#define RS			gpio.dc
#define RW			gpio.aux[2]
#define CS0			gpio.aux[0]
#define CS1			gpio.aux[1]

/* diffusing error (Floyd-Steinberg) */
#define DIFFUSING_MATRIX_WIDTH	2
#define DIFFUSING_MATRIX_HEIGHT	2

static const signed char
diffusing_matrix[DIFFUSING_MATRIX_WIDTH][DIFFUSING_MATRIX_HEIGHT] = {
	{-1, 3},
	{3, 2},
};

static const unsigned char gamma_correction_table[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6,
6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 11, 11, 11, 12, 12, 13,
13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21,
22, 22, 23, 23, 24, 25, 25, 26, 26, 27, 28, 28, 29, 30, 30, 31, 32,
33, 33, 34, 35, 35, 36, 37, 38, 39, 39, 40, 41, 42, 43, 43, 44, 45,
46, 47, 48, 49, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 73, 74, 75, 76, 77, 78, 79, 81,
82, 83, 84, 85, 87, 88, 89, 90, 91, 93, 94, 95, 97, 98, 99, 100, 102,
103, 105, 106, 107, 109, 110, 111, 113, 114, 116, 117, 119, 120, 121,
123, 124, 126, 127, 129, 130, 132, 133, 135, 137, 138, 140, 141, 143,
145, 146, 148, 149, 151, 153, 154, 156, 158, 159, 161, 163, 165, 166,
168, 170, 172, 173, 175, 177, 179, 181, 182, 184, 186, 188, 190, 192,
194, 196, 197, 199, 201, 203, 205, 207, 209, 211, 213, 215, 217, 219,
221, 223, 225, 227, 229, 231, 234, 236, 238, 240, 242, 244, 246, 248,
251, 253, 255
};

static int init_display(struct fbtft_par *par)
{
	u8 i;

	par->fbtftops.reset(par);

	for (i = 0; i < 2; ++i) {
		write_reg(par, i, 0x3f); /* display on */
		write_reg(par, i, 0x40); /* set x to 0 */
		write_reg(par, i, 0xb0); /* set page to 0 */
		write_reg(par, i, 0xc0); /* set start line to 0 */
	}

	return 0;
}

static void reset(struct fbtft_par *par)
{
	if (par->gpio.reset == -1)
		return;

	dev_dbg(par->info->device, "%s()\n", __func__);

	gpio_set_value(par->gpio.reset, 0);
	udelay(20);
	gpio_set_value(par->gpio.reset, 1);
	mdelay(120);
}

/* Check if all necessary GPIOS defined */
static int verify_gpios(struct fbtft_par *par)
{
	int i;

	dev_dbg(par->info->device,
		"%s()\n", __func__);

	if (par->EPIN < 0) {
		dev_err(par->info->device,
			"Missing info about 'wr' (aka E) gpio. Aborting.\n");
		return -EINVAL;
	}
	for (i = 0; i < 8; ++i) {
		if (par->gpio.db[i] < 0) {
			dev_err(par->info->device,
				"Missing info about 'db[%i]' gpio. Aborting.\n",
				i);
			return -EINVAL;
		}
	}
	if (par->CS0 < 0) {
		dev_err(par->info->device,
			"Missing info about 'cs0' gpio. Aborting.\n");
		return -EINVAL;
	}
	if (par->CS1 < 0) {
		dev_err(par->info->device,
			"Missing info about 'cs1' gpio. Aborting.\n");
		return -EINVAL;
	}
	if (par->RW < 0) {
		dev_err(par->info->device,
			"Missing info about 'rw' gpio. Aborting.\n");
		return -EINVAL;
	}

	return 0;
}

static unsigned long
request_gpios_match(struct fbtft_par *par, const struct fbtft_gpio *gpio)
{
	dev_dbg(par->info->device,
		"%s('%s')\n", __func__, gpio->name);

	if (strcasecmp(gpio->name, "wr") == 0) {
		/* left ks0108 E pin */
		par->EPIN = gpio->gpio;
		return GPIOF_OUT_INIT_LOW;
	} else if (strcasecmp(gpio->name, "cs0") == 0) {
		/* left ks0108 controller pin */
		par->CS0 = gpio->gpio;
		return GPIOF_OUT_INIT_HIGH;
	} else if (strcasecmp(gpio->name, "cs1") == 0) {
		/* right ks0108 controller pin */
		par->CS1 = gpio->gpio;
		return GPIOF_OUT_INIT_HIGH;
	}

	/* if write (rw = 0) e(1->0) perform write */
	/* if read (rw = 1) e(0->1) set data on D0-7*/
	else if (strcasecmp(gpio->name, "rw") == 0) {
		par->RW = gpio->gpio;
		return GPIOF_OUT_INIT_LOW;
	}

	return FBTFT_GPIO_NO_MATCH;
}

/* This function oses to enter commands
 * first byte - destination controller 0 or 1
 * following - commands
 */
static void write_reg8_bus8(struct fbtft_par *par, int len, ...)
{
	va_list args;
	int i, ret;
	u8 *buf = par->buf;

	if (unlikely(par->debug & DEBUG_WRITE_REGISTER)) {
		va_start(args, len);
		for (i = 0; i < len; i++)
			buf[i] = (u8)va_arg(args, unsigned int);

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

	va_start(args, len);

	*buf = (u8)va_arg(args, unsigned int);

	if (*buf > 1) {
		va_end(args);
		dev_err(par->info->device,
			"Incorrect chip select request (%d)\n", *buf);
		return;
	}

	/* select chip */
	if (*buf) {
		/* cs1 */
		gpio_set_value(par->CS0, 1);
		gpio_set_value(par->CS1, 0);
	} else {
		/* cs0 */
		gpio_set_value(par->CS0, 0);
		gpio_set_value(par->CS1, 1);
	}

	gpio_set_value(par->RS, 0); /* RS->0 (command mode) */
	len--;

	if (len) {
		i = len;
		while (i--)
			*buf++ = (u8)va_arg(args, unsigned int);
		ret = par->fbtftops.write(par, par->buf, len * (sizeof(u8)));
		if (ret < 0) {
			va_end(args);
			dev_err(par->info->device,
				"write() failed and returned %d\n", ret);
			return;
		}
	}

	va_end(args);
}

static struct
{
	int xs, ys_page, xe, ye_page;
} addr_win;

/* save display writing zone */
static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
{
	addr_win.xs = xs;
	addr_win.ys_page = ys / 8;
	addr_win.xe = xe;
	addr_win.ye_page = ye / 8;
}

static void
construct_line_bitmap(struct fbtft_par *par, u8 *dest, signed short *src,
		      int xs, int xe, int y)
{
	int x, i;

	for (x = xs; x < xe; ++x) {
		u8 res = 0;

		for (i = 0; i < 8; i++)
			if (src[(y * 8 + i) * par->info->var.xres + x])
				res |= 1 << i;
#ifdef NEGATIVE
		*dest++ = res;
#else
		*dest++ = ~res;
#endif
	}
}

static void iterate_diffusion_matrix(u32 xres, u32 yres, int x,
				     int y, signed short *convert_buf,
				     signed short pixel, signed short error)
{
	u16 i, j;

	/* diffusion matrix row */
	for (i = 0; i < DIFFUSING_MATRIX_WIDTH; ++i)
		/* diffusion matrix column */
		for (j = 0; j < DIFFUSING_MATRIX_HEIGHT; ++j) {
			signed short *write_pos;
			signed char coeff;

			/* skip pixels out of zone */
			if (x + i < 0 || x + i >= xres || y + j >= yres)
				continue;
			write_pos = &convert_buf[(y + j) * xres + x + i];
			coeff = diffusing_matrix[i][j];
			if (-1 == coeff)
				/* pixel itself */
				*write_pos = pixel;
			else {
				signed short p = *write_pos + error * coeff;

				if (p > WHITE)
					p = WHITE;
				if (p < BLACK)
					p = BLACK;
				*write_pos = p;
			}
		}
}

static int write_vmem(struct fbtft_par *par, size_t offset, size_t len)
{
	u16 *vmem16 = (u16 *)par->info->screen_buffer;
	u8 *buf = par->txbuf.buf;
	int x, y;
	int ret = 0;

	/* buffer to convert RGB565 -> grayscale16 -> Dithered image 1bpp */
	signed short *convert_buf = kmalloc_array(par->info->var.xres *
		par->info->var.yres, sizeof(signed short), GFP_NOIO);

	if (!convert_buf)
		return -ENOMEM;

	/* converting to grayscale16 */
	for (x = 0; x < par->info->var.xres; ++x)
		for (y = 0; y < par->info->var.yres; ++y) {
			u16 pixel = vmem16[y *  par->info->var.xres + x];
			u16 b = pixel & 0x1f;
			u16 g = (pixel & (0x3f << 5)) >> 5;
			u16 r = (pixel & (0x1f << (5 + 6))) >> (5 + 6);

			pixel = (299 * r + 587 * g + 114 * b) / 200;
			if (pixel > 255)
				pixel = 255;

			/* gamma-correction by table */
			convert_buf[y *  par->info->var.xres + x] =
				(signed short)gamma_correction_table[pixel];
		}

	/* Image Dithering */
	for (x = 0; x < par->info->var.xres; ++x)
		for (y = 0; y < par->info->var.yres; ++y) {
			signed short pixel =
				convert_buf[y *  par->info->var.xres + x];
			signed short error_b = pixel - BLACK;
			signed short error_w = pixel - WHITE;
			signed short error;

			/* what color close? */
			if (abs(error_b) >= abs(error_w)) {
				/* white */
				error = error_w;
				pixel = 0xff;
			} else {
				/* black */
				error = error_b;
				pixel = 0;
			}

			error /= 8;

			iterate_diffusion_matrix(par->info->var.xres,
						 par->info->var.yres,
						 x, y, convert_buf,
						 pixel, error);
		}

	/* 1 string = 2 pages */
	for (y = addr_win.ys_page; y <= addr_win.ye_page; ++y) {
		/* left half of display */
		if (addr_win.xs < par->info->var.xres / 2) {
			construct_line_bitmap(par, buf, convert_buf,
					      addr_win.xs,
					      par->info->var.xres / 2, y);

			len = par->info->var.xres / 2 - addr_win.xs;

			/* select left side (sc0)
			 * set addr
			 */
			write_reg(par, 0x00, BIT(6) | (u8)addr_win.xs);
			write_reg(par, 0x00, (0x17 << 3) | (u8)y);

			/* write bitmap */
			gpio_set_value(par->RS, 1); /* RS->1 (data mode) */
			ret = par->fbtftops.write(par, buf, len);
			if (ret < 0)
				dev_err(par->info->device,
					"write failed and returned: %d\n",
					ret);
		}
		/* right half of display */
		if (addr_win.xe >= par->info->var.xres / 2) {
			construct_line_bitmap(par, buf,
					      convert_buf,
					      par->info->var.xres / 2,
					      addr_win.xe + 1, y);

			len = addr_win.xe + 1 - par->info->var.xres / 2;

			/* select right side (sc1)
			 * set addr
			 */
			write_reg(par, 0x01, 1 << 6);
			write_reg(par, 0x01, (0x17 << 3) | (u8)y);

			/* write bitmap */
			gpio_set_value(par->RS, 1); /* RS->1 (data mode) */
			par->fbtftops.write(par, buf, len);
			if (ret < 0)
				dev_err(par->info->device,
					"write failed and returned: %d\n",
					ret);
		}
	}
	kfree(convert_buf);

	gpio_set_value(par->CS0, 1);
	gpio_set_value(par->CS1, 1);

	return ret;
}

static int write(struct fbtft_par *par, void *buf, size_t len)
{
	fbtft_par_dbg_hex(DEBUG_WRITE, par, par->info->device, u8, buf, len,
			  "%s(len=%d): ", __func__, len);

	gpio_set_value(par->RW, 0); /* set write mode */

	while (len--) {
		u8 i, data;

		data = *(u8 *)buf++;

		/* set data bus */
		for (i = 0; i < 8; ++i)
			gpio_set_value(par->gpio.db[i], data & (1 << i));
		/* set E */
		gpio_set_value(par->EPIN, 1);
		udelay(5);
		/* unset E - write */
		gpio_set_value(par->EPIN, 0);
		udelay(1);
	}

	return 0;
}

static struct fbtft_display display = {
	.regwidth = 8,
	.width = TOTALWIDTH,
	.height = HEIGHT,
	.fps = FPS,
	.fbtftops = {
		.init_display = init_display,
		.set_addr_win = set_addr_win,
		.verify_gpios = verify_gpios,
		.request_gpios_match = request_gpios_match,
		.reset = reset,
		.write = write,
		.write_register = write_reg8_bus8,
		.write_vmem = write_vmem,
	},
};

FBTFT_REGISTER_DRIVER(DRVNAME, "displaytronic,fb_agm1264k-fl", &display);

MODULE_ALIAS("platform:" DRVNAME);

MODULE_DESCRIPTION("Two KS0108 LCD controllers in AGM1264K-FL display");
MODULE_AUTHOR("ololoshka2871");
MODULE_LICENSE("GPL");
