/*
 * Support for SuperH MigoR Quarter VGA LCD Panel
 *
 * Copyright (C) 2008 Magnus Damm
 *
 * Based on lcd_powertip.c from Kenati Technologies Pvt Ltd.
 * Copyright (c) 2007 Ujjwal Pande <ujjwal@kenati.com>,
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include <linux/delay.h>
#include <linux/err.h>
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <asm/sh_mobile_lcdc.h>
#include <asm/migor.h>

/* LCD Module is a PH240320T according to board schematics. This module
 * is made up of a 240x320 LCD hooked up to a R61505U (or HX8347-A01?)
 * Driver IC. This IC is connected to the SH7722 built-in LCDC using a
 * SYS-80 interface configured in 16 bit mode.
 *
 * Index 0: "Device Code Read" returns 0x1505.
 */

static void reset_lcd_module(void)
{
	ctrl_outb(ctrl_inb(PORT_PHDR) & ~0x04, PORT_PHDR);
	mdelay(2);
	ctrl_outb(ctrl_inb(PORT_PHDR) | 0x04, PORT_PHDR);
	mdelay(1);
}

/* DB0-DB7 are connected to D1-D8, and DB8-DB15 to D10-D17 */

static unsigned long adjust_reg18(unsigned short data)
{
	unsigned long tmp1, tmp2;

	tmp1 = (data<<1 | 0x00000001) & 0x000001FF;
	tmp2 = (data<<2 | 0x00000200) & 0x0003FE00;
	return tmp1 | tmp2;
}

static void write_reg(void *sys_ops_handle,
		       struct sh_mobile_lcdc_sys_bus_ops *sys_ops,
		       unsigned short reg, unsigned short data)
{
	sys_ops->write_index(sys_ops_handle, adjust_reg18(reg << 8 | data));
}

static void write_reg16(void *sys_ops_handle,
			struct sh_mobile_lcdc_sys_bus_ops *sys_ops,
			unsigned short reg, unsigned short data)
{
	sys_ops->write_index(sys_ops_handle, adjust_reg18(reg));
	sys_ops->write_data(sys_ops_handle, adjust_reg18(data));
}

static unsigned long read_reg16(void *sys_ops_handle,
				struct sh_mobile_lcdc_sys_bus_ops *sys_ops,
				unsigned short reg)
{
	unsigned long data;

	sys_ops->write_index(sys_ops_handle, adjust_reg18(reg));
	data = sys_ops->read_data(sys_ops_handle);
	return ((data >> 1) & 0xff) | ((data >> 2) & 0xff00);
}

static void migor_lcd_qvga_seq(void *sys_ops_handle,
			       struct sh_mobile_lcdc_sys_bus_ops *sys_ops,
			       unsigned short const *data, int no_data)
{
	int i;

	for (i = 0; i < no_data; i += 2)
		write_reg16(sys_ops_handle, sys_ops, data[i], data[i + 1]);
}

static const unsigned short sync_data[] = {
	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
};

static const unsigned short magic0_data[] = {
	0x0060, 0x2700, 0x0008, 0x0808, 0x0090, 0x001A, 0x0007, 0x0001,
	0x0017, 0x0001, 0x0019, 0x0000, 0x0010, 0x17B0, 0x0011, 0x0116,
	0x0012, 0x0198, 0x0013, 0x1400, 0x0029, 0x000C, 0x0012, 0x01B8,
};

static const unsigned short magic1_data[] = {
	0x0030, 0x0307, 0x0031, 0x0303, 0x0032, 0x0603, 0x0033, 0x0202,
	0x0034, 0x0202, 0x0035, 0x0202, 0x0036, 0x1F1F, 0x0037, 0x0303,
	0x0038, 0x0303, 0x0039, 0x0603, 0x003A, 0x0202, 0x003B, 0x0102,
	0x003C, 0x0204, 0x003D, 0x0000, 0x0001, 0x0100, 0x0002, 0x0300,
	0x0003, 0x5028, 0x0020, 0x00ef, 0x0021, 0x0000, 0x0004, 0x0000,
	0x0009, 0x0000, 0x000A, 0x0008, 0x000C, 0x0000, 0x000D, 0x0000,
	0x0015, 0x8000,
};

static const unsigned short magic2_data[] = {
	0x0061, 0x0001, 0x0092, 0x0100, 0x0093, 0x0001, 0x0007, 0x0021,
};

static const unsigned short magic3_data[] = {
	0x0010, 0x16B0, 0x0011, 0x0111, 0x0007, 0x0061,
};

int migor_lcd_qvga_setup(void *board_data, void *sohandle,
			 struct sh_mobile_lcdc_sys_bus_ops *so)
{
	unsigned long xres = 320;
	unsigned long yres = 240;
	int k;

	reset_lcd_module();
	migor_lcd_qvga_seq(sohandle, so, sync_data, ARRAY_SIZE(sync_data));

	if (read_reg16(sohandle, so, 0) != 0x1505)
		return -ENODEV;

	pr_info("Migo-R QVGA LCD Module detected.\n");

	migor_lcd_qvga_seq(sohandle, so, sync_data, ARRAY_SIZE(sync_data));
	write_reg16(sohandle, so, 0x00A4, 0x0001);
	mdelay(10);

	migor_lcd_qvga_seq(sohandle, so, magic0_data, ARRAY_SIZE(magic0_data));
	mdelay(100);

	migor_lcd_qvga_seq(sohandle, so, magic1_data, ARRAY_SIZE(magic1_data));
	write_reg16(sohandle, so, 0x0050, 0xef - (yres - 1));
	write_reg16(sohandle, so, 0x0051, 0x00ef);
	write_reg16(sohandle, so, 0x0052, 0x0000);
	write_reg16(sohandle, so, 0x0053, xres - 1);

	migor_lcd_qvga_seq(sohandle, so, magic2_data, ARRAY_SIZE(magic2_data));
	mdelay(10);

	migor_lcd_qvga_seq(sohandle, so, magic3_data, ARRAY_SIZE(magic3_data));
	mdelay(40);

	/* clear GRAM to avoid displaying garbage */

	write_reg16(sohandle, so, 0x0020, 0x0000); /* horiz addr */
	write_reg16(sohandle, so, 0x0021, 0x0000); /* vert addr */

	for (k = 0; k < (xres * 256); k++) /* yes, 256 words per line */
		write_reg16(sohandle, so, 0x0022, 0x0000);

	write_reg16(sohandle, so, 0x0020, 0x0000); /* reset horiz addr */
	write_reg16(sohandle, so, 0x0021, 0x0000); /* reset vert addr */
	write_reg16(sohandle, so, 0x0007, 0x0173);
	mdelay(40);

	/* enable display */
	write_reg(sohandle, so, 0x00, 0x22);
	mdelay(100);
	return 0;
}
