/*
 * FB driver for the SSD1289 LCD Controller
 *
 * Copyright (C) 2013 Noralf Tronnes
 *
 * Init sequence taken from ITDB02_Graph16.cpp - (C)2010-2011 Henning Karlsen
 *
 * 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 "fbtft.h"

#define DRVNAME		"fb_ssd1289"
#define WIDTH		240
#define HEIGHT		320
#define DEFAULT_GAMMA	"02 03 2 5 7 7 4 2 4 2\n" \
			"02 03 2 5 7 5 4 2 4 2"

static unsigned reg11 = 0x6040;
module_param(reg11, uint, 0);
MODULE_PARM_DESC(reg11, "Register 11h value");

static int init_display(struct fbtft_par *par)
{
	par->fbtftops.reset(par);

	if (par->gpio.cs != -1)
		gpio_set_value(par->gpio.cs, 0);  /* Activate chip */

	write_reg(par, 0x00, 0x0001);
	write_reg(par, 0x03, 0xA8A4);
	write_reg(par, 0x0C, 0x0000);
	write_reg(par, 0x0D, 0x080C);
	write_reg(par, 0x0E, 0x2B00);
	write_reg(par, 0x1E, 0x00B7);
	write_reg(par, 0x01,
		(1 << 13) | (par->bgr << 11) | (1 << 9) | (HEIGHT - 1));
	write_reg(par, 0x02, 0x0600);
	write_reg(par, 0x10, 0x0000);
	write_reg(par, 0x05, 0x0000);
	write_reg(par, 0x06, 0x0000);
	write_reg(par, 0x16, 0xEF1C);
	write_reg(par, 0x17, 0x0003);
	write_reg(par, 0x07, 0x0233);
	write_reg(par, 0x0B, 0x0000);
	write_reg(par, 0x0F, 0x0000);
	write_reg(par, 0x41, 0x0000);
	write_reg(par, 0x42, 0x0000);
	write_reg(par, 0x48, 0x0000);
	write_reg(par, 0x49, 0x013F);
	write_reg(par, 0x4A, 0x0000);
	write_reg(par, 0x4B, 0x0000);
	write_reg(par, 0x44, 0xEF00);
	write_reg(par, 0x45, 0x0000);
	write_reg(par, 0x46, 0x013F);
	write_reg(par, 0x23, 0x0000);
	write_reg(par, 0x24, 0x0000);
	write_reg(par, 0x25, 0x8000);
	write_reg(par, 0x4f, 0x0000);
	write_reg(par, 0x4e, 0x0000);
	write_reg(par, 0x22);
	return 0;
}

static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
{
	switch (par->info->var.rotate) {
	/* R4Eh - Set GDDRAM X address counter */
	/* R4Fh - Set GDDRAM Y address counter */
	case 0:
		write_reg(par, 0x4e, xs);
		write_reg(par, 0x4f, ys);
		break;
	case 180:
		write_reg(par, 0x4e, par->info->var.xres - 1 - xs);
		write_reg(par, 0x4f, par->info->var.yres - 1 - ys);
		break;
	case 270:
		write_reg(par, 0x4e, par->info->var.yres - 1 - ys);
		write_reg(par, 0x4f, xs);
		break;
	case 90:
		write_reg(par, 0x4e, ys);
		write_reg(par, 0x4f, par->info->var.xres - 1 - xs);
		break;
	}

	/* R22h - RAM data write */
	write_reg(par, 0x22);
}

static int set_var(struct fbtft_par *par)
{
	if (par->fbtftops.init_display != init_display) {
		/* don't risk messing up register 11h */
		fbtft_par_dbg(DEBUG_INIT_DISPLAY, par,
			"%s: skipping since custom init_display() is used\n",
			__func__);
		return 0;
	}

	switch (par->info->var.rotate) {
	case 0:
		write_reg(par, 0x11, reg11 | 0x30);
		break;
	case 270:
		write_reg(par, 0x11, reg11 | 0x28);
		break;
	case 180:
		write_reg(par, 0x11, reg11 | 0x00);
		break;
	case 90:
		write_reg(par, 0x11, reg11 | 0x18);
		break;
	}

	return 0;
}

/*
  Gamma string format:
    VRP0 VRP1 PRP0 PRP1 PKP0 PKP1 PKP2 PKP3 PKP4 PKP5
    VRN0 VRN1 PRN0 PRN1 PKN0 PKN1 PKN2 PKN3 PKN4 PKN5
*/
#define CURVE(num, idx)  curves[num * par->gamma.num_values + idx]
static int set_gamma(struct fbtft_par *par, unsigned long *curves)
{
	unsigned long mask[] = {
		0x1f, 0x1f, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
		0x1f, 0x1f, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
	};
	int i, j;

	/* apply mask */
	for (i = 0; i < 2; i++)
		for (j = 0; j < 10; j++)
			CURVE(i, j) &= mask[i * par->gamma.num_values + j];

	write_reg(par, 0x0030, CURVE(0, 5) << 8 | CURVE(0, 4));
	write_reg(par, 0x0031, CURVE(0, 7) << 8 | CURVE(0, 6));
	write_reg(par, 0x0032, CURVE(0, 9) << 8 | CURVE(0, 8));
	write_reg(par, 0x0033, CURVE(0, 3) << 8 | CURVE(0, 2));
	write_reg(par, 0x0034, CURVE(1, 5) << 8 | CURVE(1, 4));
	write_reg(par, 0x0035, CURVE(1, 7) << 8 | CURVE(1, 6));
	write_reg(par, 0x0036, CURVE(1, 9) << 8 | CURVE(1, 8));
	write_reg(par, 0x0037, CURVE(1, 3) << 8 | CURVE(1, 2));
	write_reg(par, 0x003A, CURVE(0, 1) << 8 | CURVE(0, 0));
	write_reg(par, 0x003B, CURVE(1, 1) << 8 | CURVE(1, 0));

	return 0;
}
#undef CURVE

static struct fbtft_display display = {
	.regwidth = 16,
	.width = WIDTH,
	.height = HEIGHT,
	.gamma_num = 2,
	.gamma_len = 10,
	.gamma = DEFAULT_GAMMA,
	.fbtftops = {
		.init_display = init_display,
		.set_addr_win = set_addr_win,
		.set_var = set_var,
		.set_gamma = set_gamma,
	},
};

FBTFT_REGISTER_DRIVER(DRVNAME, "solomon,ssd1289", &display);

MODULE_ALIAS("spi:" DRVNAME);
MODULE_ALIAS("platform:" DRVNAME);
MODULE_ALIAS("spi:ssd1289");
MODULE_ALIAS("platform:ssd1289");

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