/*
 * 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 transferring 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)
{
	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;
}

static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int 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)
{
	/* 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[] = {
		0x0f, 0x0f, 0x1f, 0x0f, 0x0f, 0x0f, 0x1f, 0x07, 0x07, 0x07,
		0x07, 0x07, 0x07, 0x03, 0x03, 0x0f, 0x0f, 0x1f, 0x0f, 0x0f,
		0x0f, 0x1f, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x00, 0x00,
	};
	int i, j;

	/* 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");
