/*
 * FB driver for the HX8340BN LCD Controller
 *
 * This display uses 9-bit SPI: Data/Command bit + 8 data bits
 * For platforms that doesn't support 9-bit, the driver is capable
 * of emulating this using 8-bit transfer.
 * This is done by transfering eight 9-bit words in 9 bytes.
 *
 * Copyright (C) 2013 Noralf Tronnes
 *
 * 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

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

#include "fbtft.h"

#define DRVNAME		"fb_hx8340bn"
#define WIDTH		176
#define HEIGHT		220
#define TXBUFLEN	(4 * PAGE_SIZE)
#define DEFAULT_GAMMA	"1 3 0E 5 0 2 09 0 6 1 7 1 0 2 2\n" \
			"3 3 17 8 4 7 05 7 6 0 3 1 6 0 0 "


static bool emulate;
module_param(emulate, bool, 0);
MODULE_PARM_DESC(emulate, "Force emulation in 9-bit mode");


static int init_display(struct fbtft_par *par)
{
	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);

	par->fbtftops.reset(par);

	/* BTL221722-276L startup sequence, from datasheet */

	/* SETEXTCOM: Set extended command set (C1h)
	   This command is used to set extended command set access enable.
	   Enable: After command (C1h), must write: ffh,83h,40h */
	write_reg(par, 0xC1, 0xFF, 0x83, 0x40);

	/* Sleep out
	   This command turns off sleep mode.
	   In this mode the DC/DC converter is enabled, Internal oscillator
	   is started, and panel scanning is started. */
	write_reg(par, 0x11);
	mdelay(150);

	/* Undoc'd register? */
	write_reg(par, 0xCA, 0x70, 0x00, 0xD9);

	/* SETOSC: Set Internal Oscillator (B0h)
	   This command is used to set internal oscillator related settings */
	/*	OSC_EN: Enable internal oscillator */
	/*	Internal oscillator frequency: 125% x 2.52MHz */
	write_reg(par, 0xB0, 0x01, 0x11);

	/* Drive ability setting */
	write_reg(par, 0xC9, 0x90, 0x49, 0x10, 0x28, 0x28, 0x10, 0x00, 0x06);
	mdelay(20);

	/* SETPWCTR5: Set Power Control 5(B5h)
	   This command is used to set VCOM Low and VCOM High Voltage */
	/* VCOMH 0110101 :  3.925 */
	/* VCOML 0100000 : -1.700 */
	/* 45h=69  VCOMH: "VMH" + 5d   VCOML: "VMH" + 5d */
	write_reg(par, 0xB5, 0x35, 0x20, 0x45);

	/* SETPWCTR4: Set Power Control 4(B4h)
		VRH[4:0]:	Specify the VREG1 voltage adjusting.
				VREG1 voltage is for gamma voltage setting.
		BT[2:0]:	Switch the output factor of step-up circuit 2
				for VGH and VGL voltage generation. */
	write_reg(par, 0xB4, 0x33, 0x25, 0x4C);
	mdelay(10);

	/* Interface Pixel Format (3Ah)
	   This command is used to define the format of RGB picture data,
	   which is to be transfer via the system and RGB interface. */
	/* RGB interface: 16 Bit/Pixel	*/
	write_reg(par, 0x3A, 0x05);

	/* Display on (29h)
	   This command is used to recover from DISPLAY OFF mode.
	   Output from the Frame Memory is enabled. */
	write_reg(par, 0x29);
	mdelay(10);

	return 0;
}

void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
{
	fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
		"%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);

	write_reg(par, FBTFT_CASET, 0x00, xs, 0x00, xe);
	write_reg(par, FBTFT_RASET, 0x00, ys, 0x00, ye);
	write_reg(par, FBTFT_RAMWR);
}

static int set_var(struct fbtft_par *par)
{
	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);

	/* MADCTL - Memory data access control */
	/* RGB/BGR can be set with H/W pin SRGB and MADCTL BGR bit */
#define MY (1 << 7)
#define MX (1 << 6)
#define MV (1 << 5)
	switch (par->info->var.rotate) {
	case 0:
		write_reg(par, 0x36, (par->bgr << 3));
		break;
	case 270:
		write_reg(par, 0x36, MX | MV | (par->bgr << 3));
		break;
	case 180:
		write_reg(par, 0x36, MX | MY | (par->bgr << 3));
		break;
	case 90:
		write_reg(par, 0x36, MY | MV | (par->bgr << 3));
		break;
	}

	return 0;
}

/*
  Gamma Curve selection, GC (only GC0 can be customized):
    0 = 2.2, 1 = 1.8, 2 = 2.5, 3 = 1.0
  Gamma string format:
    OP0 OP1 CP0 CP1 CP2 CP3 CP4 MP0 MP1 MP2 MP3 MP4 MP5 CGM0 CGM1
    ON0 ON1 CN0 CN1 CN2 CN3 CN4 MN0 MN1 MN2 MN3 MN4 MN5 XXXX  GC
*/
#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[] = {
		0b1111, 0b1111, 0b11111, 0b1111, 0b1111, 0b1111, 0b11111,
		0b111, 0b111, 0b111, 0b111, 0b111, 0b111, 0b11, 0b11,
		0b1111, 0b1111, 0b11111, 0b1111, 0b1111, 0b1111, 0b11111,
		0b111, 0b111, 0b111, 0b111, 0b111, 0b111, 0b0, 0b0 };
	int i, j;

	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);

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

	write_reg(par, 0x26, 1 << CURVE(1, 14)); /* Gamma Set (26h) */

	if (CURVE(1, 14))
		return 0; /* only GC0 can be customized */

	write_reg(par, 0xC2,
		(CURVE(0, 8) << 4) | CURVE(0, 7),
		(CURVE(0, 10) << 4) | CURVE(0, 9),
		(CURVE(0, 12) << 4) | CURVE(0, 11),
		CURVE(0, 2),
		(CURVE(0, 4) << 4) | CURVE(0, 3),
		CURVE(0, 5),
		CURVE(0, 6),
		(CURVE(0, 1) << 4) | CURVE(0, 0),
		(CURVE(0, 14) << 2) | CURVE(0, 13));

	write_reg(par, 0xC3,
		(CURVE(1, 8) << 4) | CURVE(1, 7),
		(CURVE(1, 10) << 4) | CURVE(1, 9),
		(CURVE(1, 12) << 4) | CURVE(1, 11),
		CURVE(1, 2),
		(CURVE(1, 4) << 4) | CURVE(1, 3),
		CURVE(1, 5),
		CURVE(1, 6),
		(CURVE(1, 1) << 4) | CURVE(1, 0));

	mdelay(10);

	return 0;
}
#undef CURVE


static struct fbtft_display display = {
	.regwidth = 8,
	.width = WIDTH,
	.height = HEIGHT,
	.txbuflen = TXBUFLEN,
	.gamma_num = 2,
	.gamma_len = 15,
	.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, "himax,hx8340bn", &display);

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

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