/*
 * avr.c
 *
 * AVR functions
 *
 * Copyright (C) 2006 Mihai Georgian <u-boot@linuxnotincluded.org.uk>
 *
 * 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 <common.h>
#include <ns16550.h>
#include <console.h>

/* Button codes from the AVR */
#define PWRR			0x20		/* Power button release	*/
#define PWRP			0x21		/* Power button push	*/
#define RESR			0x22		/* Reset button release	*/
#define RESP			0x23		/* Reset button push	*/
#define AVRINIT			0x33		/* Init complete	*/
#define AVRRESET		0x31		/* Reset request	*/

/* LED commands */
#define PWRBLINKSTRT		'['		/* Blink power LED	*/
#define PWRBLINKSTOP		'Z'		/* Solid power LED	*/
#define HDDLEDON		'W'		/* HDD LED on		*/
#define HDDLEDOFF		'V'		/* HDD LED off		*/
#define HDDBLINKSTRT		'Y'		/* HDD LED start blink	*/
#define HDDBLINKSTOP		'X'		/* HDD LED stop blink	*/

/* Timings for LEDs blinking to show choice */
#define PULSETIME		250		/* msecs		*/
#define LONGPAUSE		(5 * PULSETIME)

/* Button press times */
#define PUSHHOLD		1000		/* msecs		*/
#define NOBUTTON		(6 * (LONGPAUSE+PULSETIME))

/* Boot and console choices */
#define MAX_BOOT_CHOICE		3

static char *consoles[] = {
	"serial",
#if defined(CONFIG_NETCONSOLE)
	"nc",
#endif
};
#define MAX_CONS_CHOICE		(sizeof(consoles)/sizeof(char *))

#if !defined(CONFIG_NETCONSOLE)
#define DEF_CONS_CHOICE		0
#else
#define DEF_CONS_CHOICE		1
#endif

#define perror(fmt, args...) printf("%s: " fmt, __FUNCTION__ , ##args)

extern void miconCntl_SendCmd(unsigned char dat);
extern void miconCntl_DisWDT(void);

static int boot_stop;

static int boot_choice = 1;
static int cons_choice = DEF_CONS_CHOICE;

static char envbuffer[16];

void init_AVR_DUART (void)
{
	NS16550_t AVR_port = (NS16550_t) CONFIG_SYS_NS16550_COM2;
	int clock_divisor = CONFIG_SYS_NS16550_CLK / 16 / 9600;

	/*
	 * AVR port init sequence taken from
	 * the original Linkstation init code
	 * Normal U-Boot serial reinit doesn't
	 * work because the AVR uses even parity
	 */
	AVR_port->lcr = 0x00;
	AVR_port->ier = 0x00;
	AVR_port->lcr = UART_LCR_BKSE;
	AVR_port->dll = clock_divisor & 0xff;
	AVR_port->dlm = (clock_divisor >> 8) & 0xff;
	AVR_port->lcr = UART_LCR_WLS_8 | UART_LCR_PEN | UART_LCR_EPS;
	AVR_port->mcr = 0x00;
	AVR_port->fcr = UART_FCR_FIFO_EN | UART_FCR_RXSR | UART_FCR_TXSR;

	miconCntl_DisWDT();

	boot_stop = 0;
	miconCntl_SendCmd(PWRBLINKSTRT);
}

static inline int avr_tstc(void)
{
	return (NS16550_tstc((NS16550_t)CONFIG_SYS_NS16550_COM2));
}

static inline char avr_getc(void)
{
	return (NS16550_getc((NS16550_t)CONFIG_SYS_NS16550_COM2));
}

static int push_timeout(char button_code)
{
	ulong push_start = get_timer(0);
	while (get_timer(push_start) <= PUSHHOLD)
		if (avr_tstc() && avr_getc() == button_code)
			return 0;
	return 1;
}

static void next_boot_choice(void)
{
	ulong return_start;
	ulong pulse_start;
	int on_times;
	int button_on;
	int led_state;
	char c;

	button_on = 0;
	return_start = get_timer(0);

	on_times = boot_choice;
	led_state = 0;
	miconCntl_SendCmd(HDDLEDOFF);
	pulse_start = get_timer(0);

	while (get_timer(return_start) <= NOBUTTON || button_on) {
		if (avr_tstc()) {
			c = avr_getc();
			if (c == PWRP)
				button_on = 1;
			else if (c == PWRR) {
				button_on = 0;
				return_start = get_timer(0);
				if (++boot_choice > MAX_BOOT_CHOICE)
					boot_choice = 1;
				sprintf(envbuffer, "bootcmd%d", boot_choice);
				if (getenv(envbuffer)) {
					sprintf(envbuffer, "run bootcmd%d", boot_choice);
					setenv("bootcmd", envbuffer);
				}
				on_times = boot_choice;
				led_state = 1;
				miconCntl_SendCmd(HDDLEDON);
				pulse_start = get_timer(0);
			} else {
				perror("Unexpected code: 0x%02X\n", c);
			}
		}
		if (on_times && get_timer(pulse_start) > PULSETIME) {
			if (led_state == 1) {
				--on_times;
				led_state = 0;
				miconCntl_SendCmd(HDDLEDOFF);
			} else {
				led_state = 1;
				miconCntl_SendCmd(HDDLEDON);
			}
			pulse_start = get_timer(0);
		}
		if (!on_times && get_timer(pulse_start) > LONGPAUSE) {
			on_times = boot_choice;
			led_state = 1;
			miconCntl_SendCmd(HDDLEDON);
			pulse_start = get_timer(0);
		}
	}
	if (led_state)
		miconCntl_SendCmd(HDDLEDOFF);
}

void next_cons_choice(int console)
{
	ulong return_start;
	ulong pulse_start;
	int on_times;
	int button_on;
	int led_state;
	char c;

	button_on = 0;
	cons_choice = console;
	return_start = get_timer(0);

	on_times = cons_choice+1;
	led_state = 1;
	miconCntl_SendCmd(HDDLEDON);
	pulse_start = get_timer(0);

	while (get_timer(return_start) <= NOBUTTON || button_on) {
		if (avr_tstc()) {
			c = avr_getc();
			if (c == RESP)
				button_on = 1;
			else if (c == RESR) {
				button_on = 0;
				return_start = get_timer(0);
				cons_choice = (cons_choice + 1) % MAX_CONS_CHOICE;
				console_assign(stdin, consoles[cons_choice]);
				console_assign(stdout, consoles[cons_choice]);
				console_assign(stderr, consoles[cons_choice]);
				on_times = cons_choice+1;
				led_state = 0;
				miconCntl_SendCmd(HDDLEDOFF);
				pulse_start = get_timer(0);
			} else {
				perror("Unexpected code: 0x%02X\n", c);
			}
		}
		if (on_times && get_timer(pulse_start) > PULSETIME) {
			if (led_state == 0) {
				--on_times;
				led_state = 1;
				miconCntl_SendCmd(HDDLEDON);
			} else {
				led_state = 0;
				miconCntl_SendCmd(HDDLEDOFF);
			}
			pulse_start = get_timer(0);
		}
		if (!on_times && get_timer(pulse_start) > LONGPAUSE) {
			on_times = cons_choice+1;
			led_state = 0;
			miconCntl_SendCmd(HDDLEDOFF);
			pulse_start = get_timer(0);
		}
	}
	if (led_state);
	miconCntl_SendCmd(HDDLEDOFF);
}

int avr_input(void)
{
	char avr_button;

	if (!avr_tstc())
		return 0;

	avr_button = avr_getc();
	switch (avr_button) {
	case PWRP:
		if (push_timeout(PWRR)) {
			/* Timeout before power button release */
			boot_stop = ~boot_stop;
			if (boot_stop)
				miconCntl_SendCmd(PWRBLINKSTOP);
			else
				miconCntl_SendCmd(PWRBLINKSTRT);
			/* Wait for power button release */
			while (avr_getc() != PWRR)
				;
		} else
			/* Power button released */
			next_boot_choice();
		break;
	case RESP:
		/* Wait for Reset button release */
		while (avr_getc() != RESR)
			;
		next_cons_choice(cons_choice);
		break;
	case AVRINIT:
		return 0;
	default:
		perror("Unexpected code: 0x%02X\n", avr_button);
		return 0;
	}
	if (boot_stop)
		return (-3);
	else
		return (-2);
}

void avr_StopBoot(void)
{
	boot_stop = ~0;
	miconCntl_SendCmd(PWRBLINKSTOP);
}
