/*
 * U-boot - cmd_bf537led.c
 *
 * Copyright (C) 2006 Aaron Gage, Ocean Optics Inc.
 *
 * 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 <common.h>
#include <config.h>
#include <command.h>
#include <asm/blackfin.h>
#include <asm/string.h>
#ifdef CONFIG_BF537_STAMP_LEDCMD

/* Define the command usage in a reusable way */
#define USAGE_LONG \
	"led <number> <action>\n" \
	"    <number>  - Index (0-5) of LED to change, or \"all\"\n" \
	"    <action>  - Must be one of:\n" \
	"		on off toggle"

/* Number of LEDs supported by the board */
#define NUMBER_LEDS     6
/* The BF537 stamp has 6 LEDs.  This mask indicates that all should be lit. */
#define LED_ALL_MASK    0x003F

void show_cmd_usage(void);
void set_led_state(int index, int state);
void configure_GPIO_to_output(int index);

/* Map of LEDs according to their GPIO ports.  This can be rearranged or
 * otherwise changed to account for different GPIO configurations.
 */
int led_ports[] = { PF6, PF7, PF8, PF9, PF10, PF11 };

#define ACTION_TOGGLE   -1
#define ACTION_OFF      0
#define ACTION_ON       1

#define LED_STATE_OFF   0
#define LED_STATE_ON    1

/* This is a trivial atoi implementation since we don't have one available */
int atoi(char *string)
{
	int length;
	int retval = 0;
	int i;
	int sign = 1;

	length = strlen(string);
	for (i = 0; i < length; i++) {
		if (0 == i && string[0] == '-') {
			sign = -1;
			continue;
		}
		if (string[i] > '9' || string[i] < '0') {
			break;
		}
		retval *= 10;
		retval += string[i] - '0';
	}
	retval *= sign;
	return retval;
}

int do_bf537led(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
{
	int led_mask = 0;
	int led_current_state = 0;
	int action = ACTION_OFF;
	int temp;

	if (3 != argc) {
		/* Not enough arguments, so just show usage information */
		show_cmd_usage();
		return 1;
	}

	if (strcmp(argv[1], "all") == 0) {
		led_mask = LED_ALL_MASK;
	} else {
		temp = atoi(argv[1]);
		if (temp < 0 || temp >= NUMBER_LEDS) {
			printf("Invalid LED number [%s]\n", argv[1]);
			show_cmd_usage();
			return 2;
		}
		led_mask |= (1 << temp);
	}

	if (strcmp(argv[2], "off") == 0) {
		action = ACTION_OFF;
	} else if (strcmp(argv[2], "on") == 0) {
		action = ACTION_ON;
	} else if (strcmp(argv[2], "toggle") == 0) {
		action = ACTION_TOGGLE;
	} else {
		printf("Invalid action [%s]\n", argv[2]);
		show_cmd_usage();
		return 3;
	}

	for (temp = 0; temp < NUMBER_LEDS; temp++) {
		if ((led_mask & (1 << temp)) > 0) {
			/*
			 * It is possible that the user has wired one of PF6-PF11 to
			 * something other than an LED, so this will only change a pin
			 * to output if the user has indicated a state change.  This may
			 * happen a lot, but this way is safer than just setting all pins
			 * to output.
			 */
			configure_GPIO_to_output(temp);

			led_current_state =
			    ((*pPORTFIO & led_ports[temp]) >
			     0) ? LED_STATE_ON : LED_STATE_OFF;
	/*
		printf("LED state for index %d (%x) is %d\n", temp, led_ports[temp],
			led_current_state);
		printf("*pPORTFIO is %x\n", *pPORTFIO);
	*/
			if (ACTION_ON == action
			    || (ACTION_TOGGLE == action
				&& 0 == led_current_state)) {
				printf("Turning LED %d on\n", temp);
				set_led_state(temp, LED_STATE_ON);
			} else {
				printf("Turning LED %d off\n", temp);
				set_led_state(temp, LED_STATE_OFF);
			}
		}
	}

	return 0;
}

/*
 * The GPIO pins that go to the LEDs on the BF537 stamp must be configured
 * as output.  This function simply configures them that way.  This could
 * be done to all of the GPIO lines at once, but if a user is using a
 * custom board, this will try to be nice and only change the GPIO lines
 * that the user specifically names.
 */
void configure_GPIO_to_output(int index)
{
	int port;

	port = led_ports[index];

	/* Clear the Port F Function Enable Register */
	*pPORTF_FER &= ~port;
	/* Set the Port F I/O direction register */
	*pPORTFIO_DIR |= port;
	/* Clear the Port F I/O Input Enable Register */
	*pPORTFIO_INEN &= ~port;
}

/* Enforce the given state on the GPIO line for the indicated LED */
void set_led_state(int index, int state)
{
	int port;

	port = led_ports[index];

	if (LED_STATE_OFF == state) {
		/* Clear the bit to turn off the LED */
		*pPORTFIO &= ~port;
	} else {
		/* Set the bit to turn on the LED */
		*pPORTFIO |= port;
	}
}

/* Display usage information */
void show_cmd_usage()
{
	printf("Usage:\n%s\n", USAGE_LONG);
}

/* Register information for u-boot to find this command */
U_BOOT_CMD(led, 3, 1, do_bf537led,
	   "Control BF537 stamp LEDs", USAGE_LONG);

#endif
