/*
 * FB driver for the UC1701 LCD Controller
 *
 * The display is monochrome and the video memory is RGB565.
 * Any pixel value except 0 turns the pixel on.
 *
 * Copyright (C) 2014 Juergen Holzmann
 *
 * 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/spi/spi.h>
#include <linux/delay.h>

#include "fbtft.h"

#define DRVNAME	"fb_uc1701"
#define WIDTH	  102
#define HEIGHT	 64
#define PAGES	  (HEIGHT / 8)

/* 1: Display on/off */
#define LCD_DISPLAY_ENABLE    0xAE
/* 2: display start line set */
#define LCD_START_LINE	0x40
/* 3: Page address set (lower 4 bits select one of the pages) */
#define LCD_PAGE_ADDRESS      0xB0
/* 4: column address */
#define LCD_COL_ADDRESS       0x10
/* 8: select orientation */
#define LCD_BOTTOMVIEW	0xA0
/* 9: inverted display */
#define LCD_DISPLAY_INVERT    0xA6
/* 10: show memory content or switch all pixels on */
#define LCD_ALL_PIXEL	 0xA4
/* 11: lcd bias set */
#define LCD_BIAS	      0xA2
/* 14: Reset Controller */
#define LCD_RESET_CMD	 0xE2
/* 15: output mode select (turns display upside-down) */
#define LCD_SCAN_DIR	  0xC0
/* 16: power control set */
#define LCD_POWER_CONTROL     0x28
/* 17: voltage regulator resistor ratio set */
#define LCD_VOLTAGE	   0x20
/* 18: Volume mode set */
#define LCD_VOLUME_MODE       0x81
/* 22: NOP command */
#define LCD_NO_OP	     0xE3
/* 25: advanced program control */
#define LCD_ADV_PROG_CTRL     0xFA
/* 25: advanced program control2 */
#define LCD_ADV_PROG_CTRL2    0x10
#define LCD_TEMPCOMP_HIGH     0x80
/* column offset for normal orientation */
#define SHIFT_ADDR_NORMAL     0
/* column offset for bottom view orientation */
#define SHIFT_ADDR_TOPVIEW    30

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

	/* softreset of LCD */
	write_reg(par, LCD_RESET_CMD);
	mdelay(10);

	/* set startpoint */
	write_reg(par, LCD_START_LINE);

	/* select orientation BOTTOMVIEW */
	write_reg(par, LCD_BOTTOMVIEW | 1);

	/* output mode select (turns display upside-down) */
	write_reg(par, LCD_SCAN_DIR | 0x00);

	/* Normal Pixel mode */
	write_reg(par, LCD_ALL_PIXEL | 0);

	/* positive display */
	write_reg(par, LCD_DISPLAY_INVERT | 0);

	/* bias 1/9 */
	write_reg(par, LCD_BIAS | 0);

	/* power control mode: all features on */
	write_reg(par, LCD_POWER_CONTROL | 0x07);

	/* set voltage regulator R/R */
	write_reg(par, LCD_VOLTAGE | 0x07);

	/* volume mode set */
	write_reg(par, LCD_VOLUME_MODE);
	write_reg(par, 0x09);
	write_reg(par, LCD_NO_OP);

	/* advanced program control */
	write_reg(par, LCD_ADV_PROG_CTRL);
	write_reg(par, LCD_ADV_PROG_CTRL2 | LCD_TEMPCOMP_HIGH);

	/* enable display */
	write_reg(par, LCD_DISPLAY_ENABLE | 1);

	return 0;
}

static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
{
	/* goto address */
	write_reg(par, LCD_PAGE_ADDRESS);
	write_reg(par, 0x00);
	write_reg(par, LCD_COL_ADDRESS);
}

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, i;
	int ret = 0;

	for (y = 0; y < PAGES; y++) {
		buf = par->txbuf.buf;
		for (x = 0; x < WIDTH; x++) {
			*buf = 0x00;
			for (i = 0; i < 8; i++)
				*buf |= (vmem16[((y * 8 * WIDTH) +
						 (i * WIDTH)) + x] ?
					 1 : 0) << i;
			buf++;
		}

		write_reg(par, LCD_PAGE_ADDRESS | (u8)y);
		write_reg(par, 0x00);
		write_reg(par, LCD_COL_ADDRESS);
		gpio_set_value(par->gpio.dc, 1);
		ret = par->fbtftops.write(par, par->txbuf.buf, WIDTH);
		gpio_set_value(par->gpio.dc, 0);
	}

	if (ret < 0)
		dev_err(par->info->device, "write failed and returned: %d\n",
			ret);

	return ret;
}

static struct fbtft_display display = {
	.regwidth = 8,
	.width = WIDTH,
	.height = HEIGHT,
	.fbtftops = {
		.init_display = init_display,
		.set_addr_win = set_addr_win,
		.write_vmem = write_vmem,
	},
	.backlight = 1,
};

FBTFT_REGISTER_DRIVER(DRVNAME, "UltraChip,uc1701", &display);

MODULE_ALIAS("spi:" DRVNAME);
MODULE_ALIAS("spi:uc1701");

MODULE_DESCRIPTION("FB driver for the UC1701 LCD Controller");
MODULE_AUTHOR("Juergen Holzmann");
MODULE_LICENSE("GPL");
