/*
 * 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) {
		cmd_usage(cmdtp);
		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) {
		cmd_usage(cmdtp);
		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) {
		cmd_usage(cmdtp);
		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 clear display",
	NULL
	);

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

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

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