/* most of this is taken from the file */
/* hal/powerpc/cogent/current/src/hal_diag.c in the */
/* Cygnus eCos source. Here is the copyright notice: */
/* */
/*============================================================================= */
/* */
/*      hal_diag.c */
/* */
/*      HAL diagnostic output code */
/* */
/*============================================================================= */
/*####COPYRIGHTBEGIN#### */
/* */
/* ------------------------------------------- */
/* The contents of this file are subject to the Cygnus eCos Public License */
/* Version 1.0 (the "License"); you may not use this file except in */
/* compliance with the License.  You may obtain a copy of the License at */
/* http://sourceware.cygnus.com/ecos */
/* */
/* Software distributed under the License is distributed on an "AS IS" */
/* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the */
/* License for the specific language governing rights and limitations under */
/* the License. */
/* */
/* The Original Code is eCos - Embedded Cygnus Operating System, released */
/* September 30, 1998. */
/* */
/* The Initial Developer of the Original Code is Cygnus.  Portions created */
/* by Cygnus are Copyright (C) 1998,1999 Cygnus Solutions.  All Rights Reserved. */
/* ------------------------------------------- */
/* */
/*####COPYRIGHTEND#### */
/*============================================================================= */
/*#####DESCRIPTIONBEGIN#### */
/* */
/* Author(s):    nickg, jskov */
/* Contributors: nickg, jskov */
/* Date:         1999-03-23 */
/* Purpose:      HAL diagnostic output */
/* Description:  Implementations of HAL diagnostic output support. */
/* */
/*####DESCRIPTIONEND#### */
/* */
/*============================================================================= */

/*----------------------------------------------------------------------------- */
/* Cogent board specific LCD code */

#include <common.h>
#include <stdarg.h>
#include <board/cogent/lcd.h>

static char lines[2][LCD_LINE_LENGTH+1];
static int curline;
static int linepos;
static int heartbeat_active;
/* make the next two strings exactly LCD_LINE_LENGTH (16) chars long */
/* pad to the right with spaces if necessary */
static char init_line0[LCD_LINE_LENGTH+1] = "U-Boot Cogent  ";
static char init_line1[LCD_LINE_LENGTH+1] = "mjj, 11 Aug 2000";

static inline unsigned char
lcd_read_status(cma_mb_lcd *clp)
{
    /* read the Busy Status Register */
    return (cma_mb_reg_read(&clp->lcd_bsr));
}

static inline void
lcd_wait_not_busy(cma_mb_lcd *clp)
{
    /*
     * wait for not busy
     * Note: It seems that the LCD isn't quite ready to process commands
     * when it clears the BUSY flag. Reading the status address an extra
     * time seems to give it enough breathing room.
     */

    while (lcd_read_status(clp) & LCD_STAT_BUSY)
	;

    (void)lcd_read_status(clp);
}

static inline void
lcd_write_command(cma_mb_lcd *clp, unsigned char cmd)
{
    lcd_wait_not_busy(clp);

    /* write the Command Register */
    cma_mb_reg_write(&clp->lcd_cmd, cmd);
}

static inline void
lcd_write_data(cma_mb_lcd *clp, unsigned char data)
{
    lcd_wait_not_busy(clp);

    /* write the Current Character Register */
    cma_mb_reg_write(&clp->lcd_ccr, data);
}

static inline void
lcd_dis(int addr, char *string)
{
    cma_mb_lcd *clp = (cma_mb_lcd *)CMA_MB_LCD_BASE;
    int pos, linelen;

    linelen = LCD_LINE_LENGTH;
    if (heartbeat_active && addr == LCD_LINE0)
	linelen--;

    lcd_write_command(clp, LCD_CMD_ADD + addr);
    for (pos = 0; *string != '\0' && pos < linelen; pos++)
	lcd_write_data(clp, *string++);
}

void
lcd_init(void)
{
    cma_mb_lcd *clp = (cma_mb_lcd *)CMA_MB_LCD_BASE;
    int i;

    /* configure the lcd for 8 bits/char, 2 lines and 5x7 dot matrix */
    lcd_write_command(clp, LCD_CMD_MODE);

    /* turn the LCD display on */
    lcd_write_command(clp, LCD_CMD_DON);

    curline = 0;
    linepos = 0;

    for (i = 0; i < LCD_LINE_LENGTH; i++) {
	lines[0][i] = init_line0[i];
	lines[1][i] = init_line1[i];
    }

    lines[0][LCD_LINE_LENGTH] = lines[1][LCD_LINE_LENGTH] = 0;

    lcd_dis(LCD_LINE0, lines[0]);
    lcd_dis(LCD_LINE1, lines[1]);

    printf("HD44780 2 line x %d char display\n", LCD_LINE_LENGTH);
}

void
lcd_write_char(const char c)
{
    int i, linelen;

    /* ignore CR */
    if (c == '\r')
	return;

    linelen = LCD_LINE_LENGTH;
    if (heartbeat_active && curline == 0)
	linelen--;

    if (c == '\n') {
	lcd_dis(LCD_LINE0, &lines[curline^1][0]);
	lcd_dis(LCD_LINE1, &lines[curline][0]);

	/* Do a line feed */
	curline ^= 1;
	linelen = LCD_LINE_LENGTH;
	if (heartbeat_active && curline == 0)
	    linelen--;
	linepos = 0;

	for (i = 0; i < linelen; i++)
	    lines[curline][i] = ' ';

	return;
    }

    /* Only allow to be output if there is room on the LCD line */
    if (linepos < linelen)
	lines[curline][linepos++] = c;
}

void
lcd_flush(void)
{
    lcd_dis(LCD_LINE1, &lines[curline][0]);
}

void
lcd_write_string(const char *s)
{
    char *p;

    for (p = (char *)s; *p != '\0'; p++)
	lcd_write_char(*p);
}

void
lcd_printf(const char *fmt, ...)
{
    va_list args;
    char buf[CFG_PBSIZE];

    va_start(args, fmt);
    (void)vsprintf(buf, fmt, args);
    va_end(args);

    lcd_write_string(buf);
}

void
lcd_heartbeat(void)
{
    cma_mb_lcd *clp = (cma_mb_lcd *)CMA_MB_LCD_BASE;
#if 0
    static char rotchars[] = { '|', '/', '-', '\\' };
#else
    /* HD44780 Rom Code A00 has no backslash */
    static char rotchars[] = { '|', '/', '-', '\315' };
#endif
    static int rotator_index = 0;

    heartbeat_active = 1;

    /* write the address */
    lcd_write_command(clp, LCD_CMD_ADD + LCD_LINE0 + (LCD_LINE_LENGTH - 1));

    /* write the next char in the sequence */
    lcd_write_data(clp, rotchars[rotator_index]);

    if (++rotator_index >= (sizeof rotchars / sizeof rotchars[0]))
	rotator_index = 0;
}

#ifdef CONFIG_SHOW_ACTIVITY
void board_show_activity (ulong timestamp)
{
#ifdef CONFIG_STATUS_LED
	if ((timestamp % (CFG_HZ / 2) == 0)
		lcd_heartbeat ();
#endif
}

void show_activity(int arg)
{
}
#endif
