/*
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * 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., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

#include <config.h>
#include <common.h>
#include <command.h>
#include <asm/io.h>
#include <asm/gpio.h>

#define LCD_CMD_ADDR	0x50100002
#define LCD_DATA_ADDR	0x50100003
#define LCD_BLK_CTRL	CPLD_REG1_ADDR

static char *amcc_logo = "AMCC 405EP TAIHU EVALUATION KIT";
static int addr_flag = 0x80;

static void lcd_bl_ctrl(char val)
{
	out_8((u8 *) LCD_BLK_CTRL, in_8((u8 *) LCD_BLK_CTRL) | val);
}

static void lcd_putc(int val)
{
	int i = 100;
	char addr;

	while (i--) {
		if ((in_8((u8 *) LCD_CMD_ADDR) & 0x80) != 0x80) { /*BF = 1 ?*/
			udelay(50);
			break;
		}
		udelay(50);
	}

	if (in_8((u8 *) LCD_CMD_ADDR) & 0x80) {
		printf("LCD is busy\n");
		return;
	}

	addr = in_8((u8 *) LCD_CMD_ADDR);
	udelay(50);
	if ((addr != 0) && (addr % 0x10 == 0)) {
		addr_flag ^= 0x40;
		out_8((u8 *) LCD_CMD_ADDR, addr_flag);
	}

	udelay(50);
	out_8((u8 *) LCD_DATA_ADDR, val);
	udelay(50);
}

static void lcd_puts(char *s)
{
	char *p = s;
	int i = 100;

	while (i--) {
		if ((in_8((u8 *) LCD_CMD_ADDR) & 0x80) != 0x80) { /*BF = 1 ?*/
			udelay(50);
			break;
		}
		udelay(50);
	}

	if (in_8((u8 *) LCD_CMD_ADDR) & 0x80) {
		printf("LCD is busy\n");
		return;
	}

	while (*p)
		lcd_putc(*p++);
}

static void lcd_put_logo(void)
{
	int i = 100;
	char *p = amcc_logo;

	while (i--) {
		if ((in_8((u8 *) LCD_CMD_ADDR) & 0x80) != 0x80) { /*BF = 1 ?*/
			udelay(50);
			break;
		}
		udelay(50);
	}

	if (in_8((u8 *) LCD_CMD_ADDR) & 0x80) {
		printf("LCD is busy\n");
		return;
	}

	out_8((u8 *) LCD_CMD_ADDR, 0x80);
	while (*p)
		lcd_putc(*p++);
}

int lcd_init(void)
{
	puts("LCD: ");
	out_8((u8 *) LCD_CMD_ADDR, 0x38); /* set function:8-bit,2-line,5x7 font type */
	udelay(50);
	out_8((u8 *) LCD_CMD_ADDR, 0x0f); /* set display on,cursor on,blink on */
	udelay(50);
	out_8((u8 *) LCD_CMD_ADDR, 0x01); /* display clear */
	udelay(2000);
	out_8((u8 *) LCD_CMD_ADDR, 0x06); /* set entry */
	udelay(50);
	lcd_bl_ctrl(0x02);		/* set backlight on */
	lcd_put_logo();
	puts("ready\n");

	return 0;
}

static int do_lcd_clear (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
{
	out_8((u8 *) LCD_CMD_ADDR, 0x01);
	udelay(2000);

	return 0;
}

static int do_lcd_puts (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
{
	if (argc < 2) {
		printf("%s", cmdtp->usage);
		return 1;
	}
	lcd_puts(argv[1]);

	return 0;
}

static int do_lcd_putc (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
{
	if (argc < 2) {
		printf("%s", cmdtp->usage);
		return 1;
	}
	lcd_putc((char)argv[1][0]);

	return 0;
}

static int do_lcd_cur (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
{
	ulong count;
	ulong dir;
	char cur_addr;

	if (argc < 3) {
		printf("%s", cmdtp->usage);
		return 1;
	}

	count = simple_strtoul(argv[1], NULL, 16);
	if (count > 31) {
		printf("unable to shift > 0x20\n");
		count = 0;
	}

	dir = simple_strtoul(argv[2], NULL, 16);
	cur_addr = in_8((u8 *) LCD_CMD_ADDR);
	udelay(50);

	if (dir == 0x0) {
		if (addr_flag == 0x80) {
			if (count >= (cur_addr & 0xf)) {
				out_8((u8 *) LCD_CMD_ADDR, 0x80);
				udelay(50);
				count = 0;
			}
		} else {
			if (count >= ((cur_addr & 0x0f) + 0x0f)) {
				out_8((u8 *) LCD_CMD_ADDR, 0x80);
				addr_flag = 0x80;
				udelay(50);
				count = 0x0;
			} else if (count >= ( cur_addr & 0xf)) {
				count -= cur_addr & 0xf ;
				out_8((u8 *) LCD_CMD_ADDR, 0x80 | 0xf);
				addr_flag = 0x80;
				udelay(50);
			}
		}
	} else {
		if (addr_flag == 0x80) {
			if (count >= (0x1f - (cur_addr & 0xf))) {
				count = 0x0;
				addr_flag = 0xc0;
				out_8((u8 *) LCD_CMD_ADDR, 0xc0 | 0xf);
				udelay(50);
			} else if ((count + (cur_addr & 0xf ))>=  0x0f) {
				count = count + (cur_addr & 0xf) - 0x0f;
				addr_flag = 0xc0;
				out_8((u8 *) LCD_CMD_ADDR, 0xc0);
				udelay(50);
			}
		} else if ((count + (cur_addr & 0xf )) >= 0x0f) {
			count = 0x0;
			out_8((u8 *) LCD_CMD_ADDR, 0xC0 | 0x0F);
			udelay(50);
		}
	}
	while (count--) {
		if (dir == 0)
			out_8((u8 *) LCD_CMD_ADDR, 0x10);
		else
			out_8((u8 *) LCD_CMD_ADDR, 0x14);
		udelay(50);
	}

	return 0;
}

U_BOOT_CMD(
	lcd_cls, 1, 1, do_lcd_clear,
	"lcd_cls - lcd clear display\n",
	NULL
	);

U_BOOT_CMD(
	lcd_puts, 2, 1, do_lcd_puts,
	"lcd_puts - display string on lcd\n",
	"<string> - <string> to be displayed\n"
	);

U_BOOT_CMD(
	lcd_putc, 2, 1, do_lcd_putc,
	"lcd_putc - display char on lcd\n",
	"<char> - <char> to be displayed\n"
	);

U_BOOT_CMD(
	lcd_cur, 3, 1, do_lcd_cur,
	"lcd_cur - shift cursor on lcd\n",
	"<count> <dir> - shift cursor on lcd <count> times, direction is <dir> \n"
	" <count> - 0..31\n"
	" <dir>   - 0=backward 1=forward\n"
	);
