/*
 * (C) Copyright 2003, Li-Pro.Net <www.li-pro.net>
 * Stephan Linz <linz@li-pro.net>
 *
 * 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
 *
 * common/sevenseg.c
 *
 * NIOS PIO based seven segment led support functions
 */

#include <common.h>
#include <nios-io.h>

#ifdef	CONFIG_SEVENSEG

#define SEVENDEG_MASK_DP	((SEVENSEG_DIGIT_DP << 8) | SEVENSEG_DIGIT_DP)

#ifdef	SEVENSEG_WRONLY	/* emulate read access */
#if (SEVENSEG_ACTIVE == 0)
static unsigned int sevenseg_portval = ~0;
#else
static unsigned int sevenseg_portval = 0;
#endif
#endif

static int sevenseg_init_done = 0;

static inline void __sevenseg_set_masked (unsigned int mask, int value)
{
	nios_pio_t *piop __attribute__((unused)) = (nios_pio_t*)SEVENSEG_BASE;

#ifdef	SEVENSEG_WRONLY	/* emulate read access */

#if (SEVENSEG_ACTIVE == 0)
	if (value)
		sevenseg_portval &= ~mask;
	else
		sevenseg_portval |= mask;
#else
	if (value)
		sevenseg_portval |= mask;
	else
		sevenseg_portval &= ~mask;
#endif

	piop->data = sevenseg_portval;

#else	/* !SEVENSEG_WRONLY */

#if (SEVENSEG_ACTIVE == 0)
	if (value)
		piop->data &= ~mask;
	else
		piop->data |= mask;
#else
	if (value)
		piop->data |= mask;
	else
		piop->data &= ~mask;
#endif

#endif	/* SEVENSEG_WRONLY */
}

static inline void __sevenseg_toggle_masked (unsigned int mask)
{
	nios_pio_t *piop = (nios_pio_t*)SEVENSEG_BASE;

#ifdef	SEVENSEG_WRONLY	/* emulate read access */

	sevenseg_portval ^= mask;
	piop->data = sevenseg_portval;

#else	/* !SEVENSEG_WRONLY */

	piop->data ^= mask;

#endif	/* SEVENSEG_WRONLY */
}

static inline void __sevenseg_set (unsigned int value)
{
	nios_pio_t *piop __attribute__((unused)) = (nios_pio_t*)SEVENSEG_BASE;

#ifdef	SEVENSEG_WRONLY	/* emulate read access */

#if (SEVENSEG_ACTIVE == 0)
	sevenseg_portval = (sevenseg_portval &   SEVENDEG_MASK_DP)
		         | ((~value)         & (~SEVENDEG_MASK_DP));
#else
	sevenseg_portval = (sevenseg_portval & SEVENDEG_MASK_DP)
		         | (value);
#endif

	piop->data = sevenseg_portval;

#else	/* !SEVENSEG_WRONLY */

#if (SEVENSEG_ACTIVE == 0)
	piop->data = (piop->data &   SEVENDEG_MASK_DP)
		   | ((~value)   & (~SEVENDEG_MASK_DP));
#else
	piop->data = (piop->data & SEVENDEG_MASK_DP)
		   | (value);
#endif

#endif	/* SEVENSEG_WRONLY */
}

static inline void __sevenseg_init (void)
{
	nios_pio_t *piop __attribute__((unused)) = (nios_pio_t*)SEVENSEG_BASE;

	__sevenseg_set(0);

#ifndef	SEVENSEG_WRONLY	/* setup direction */

	piop->direction |= mask;

#endif	/* SEVENSEG_WRONLY */
}


void sevenseg_set(int value)
{
	unsigned char	digits[] = {
		SEVENSEG_DIGITS_0,
		SEVENSEG_DIGITS_1,
		SEVENSEG_DIGITS_2,
		SEVENSEG_DIGITS_3,
		SEVENSEG_DIGITS_4,
		SEVENSEG_DIGITS_5,
		SEVENSEG_DIGITS_6,
		SEVENSEG_DIGITS_7,
		SEVENSEG_DIGITS_8,
		SEVENSEG_DIGITS_9,
		SEVENSEG_DIGITS_A,
		SEVENSEG_DIGITS_B,
		SEVENSEG_DIGITS_C,
		SEVENSEG_DIGITS_D,
		SEVENSEG_DIGITS_E,
		SEVENSEG_DIGITS_F
	};

	if (!sevenseg_init_done) {
		__sevenseg_init();
		sevenseg_init_done++;
	}

	switch (value & SEVENSEG_MASK_CTRL) {

		case SEVENSEG_RAW:
			__sevenseg_set( (
				(digits[((value & SEVENSEG_MASK_VAL) >>  4)] << 8) |
				digits[((value & SEVENSEG_MASK_VAL) & 0xf)] ) );
			return;
			break;	/* paranoia */

		case SEVENSEG_OFF:
			__sevenseg_set(0);
			__sevenseg_set_masked(SEVENDEG_MASK_DP, 0);
			return;
			break;	/* paranoia */

		case SEVENSEG_SET_DPL:
			__sevenseg_set_masked(SEVENSEG_DIGIT_DP, 1);
			return;
			break;	/* paranoia */

		case SEVENSEG_SET_DPH:
			__sevenseg_set_masked((SEVENSEG_DIGIT_DP << 8), 1);
			return;
			break;	/* paranoia */

		case SEVENSEG_RES_DPL:
			__sevenseg_set_masked(SEVENSEG_DIGIT_DP, 0);
			return;
			break;	/* paranoia */

		case SEVENSEG_RES_DPH:
			__sevenseg_set_masked((SEVENSEG_DIGIT_DP << 8), 0);
			return;
			break;	/* paranoia */

		case SEVENSEG_TOG_DPL:
			__sevenseg_toggle_masked(SEVENSEG_DIGIT_DP);
			return;
			break;	/* paranoia */

		case SEVENSEG_TOG_DPH:
			__sevenseg_toggle_masked((SEVENSEG_DIGIT_DP << 8));
			return;
			break;	/* paranoia */

		case SEVENSEG_LO:
		case SEVENSEG_HI:
		case SEVENSEG_STR:
		default:
			break;
	}
}

#endif	/* CONFIG_SEVENSEG */
