
/*****************************************************************************
* Copyright (c) 2003 Digi International Inc., All Rights Reserved
* 
* This software contains proprietary and confidential information of Digi
* International Inc.  By accepting transfer of this copy, Recipient agrees
* to retain this software in confidence, to prevent disclosure to others,
* and to make no use of this software other than that for which it was
* delivered.  This is an unpublished copyrighted work of Digi International
* Inc.  Except as permitted by federal law, 17 USC 117, copying is strictly
* prohibited.
* 
* Restricted Rights Legend
*
* Use, duplication, or disclosure by the Government is subject to
* restrictions set forth in sub-paragraph (c)(1)(ii) of The Rights in
* Technical Data and Computer Software clause at DFARS 252.227-7031 or
* subparagraphs (c)(1) and (2) of the Commercial Computer Software -
* Restricted Rights at 48 CFR 52.227-19, as applicable.
*
* Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343
*
*****************************************************************************/

#include <assert.h>
#include <processorgpio.h>
#include <NA_ISR.h>
#include <reg_def.h>

#define GPIO_MODE(x) (((x)<<24) & NARM_PORT_MODE)
#define GPIO_DIR(x)  (((x)<<16) & NARM_PORT_DIR)
#define GPIO_SF(x)   (((x)<<8)  & NARM_PORT_SF)
#define GPIO_DATA(x) (((x)<<0)  & NARM_PORT_DATA)

int ProcessorGpioSetInput(unsigned long addr, unsigned long bit)
{
    unsigned char mask = 1 << bit;
    unsigned long fullmask;

    fullmask = GPIO_MODE(mask) | GPIO_DIR(mask) | GPIO_SF(mask)
       	| GPIO_DATA(mask);
    WriteRegMaskData(addr, fullmask, 0x00000000);
    return TRUE;
}

int ProcessorGpioSetOutput(unsigned long addr, unsigned long bit, unsigned long default_value)
{
    unsigned char mask = 1 << bit;
    unsigned long fullmask;

    fullmask = GPIO_MODE(mask) | GPIO_DIR(mask) | GPIO_SF(mask)
       	| GPIO_DATA(mask);
    WriteRegMaskData(addr, fullmask | mask, GPIO_DIR(mask) | (default_value ? mask : 0));
    return TRUE;
}

unsigned long ProcessorGpioGetValue(unsigned long addr, unsigned long bit)
{
    unsigned char mask = 1 << bit;
    return ReadRegMask(addr, mask);
}

int ProcessorGpioSetOutputValue(unsigned long addr, unsigned long bit, unsigned long value)
{
    unsigned char mask = 1 << bit;
    WriteRegMaskData(addr, mask, value ? mask : 0);
    return TRUE;
}

#ifndef BOOT_CODE
/* This is the table for ns7520. */
typedef struct interrupt_table_t {
    unsigned long addr;	    /* Address of GPIO pins 0-15. */
    unsigned long bit;	    /* Bit 0-7 of GPIO pins 0-15. */
    int irq;		    /* IRQ SOURCE */
} interrupt_table_t;

interrupt_table_t ns7520_interrupt_table[] = {
/* addr, bit, irq */
    {(unsigned long )NARM_PORTC_ADDR, 0, PCPC0_INT},
    {(unsigned long )NARM_PORTC_ADDR, 1, PCPC1_INT},
    {(unsigned long )NARM_PORTC_ADDR, 2, PCPC2_INT},
    {(unsigned long )NARM_PORTC_ADDR, 3, PCPC3_INT},
};


int ProcessorGpioSetInterrupt(unsigned long addr, unsigned long bit, int level, int edge_trigger)
{
    int i;

    if (edge_trigger == 1)
	return -1;	/* 7520 can't do edge at all. */

    for (i = 0; i < (int)(sizeof(ns7520_interrupt_table)
	    /sizeof(ns7520_interrupt_table[0])); ++i)
    {
	if (addr == ns7520_interrupt_table[i].addr && bit == ns7520_interrupt_table[i].bit)
	{
	    unsigned char mask = 1 << bit;
	    unsigned long fullmask;

	    fullmask = GPIO_MODE(mask) | GPIO_DIR(mask) | GPIO_SF(mask)
	       	| GPIO_DATA(mask);
	    WriteRegMaskData(addr, fullmask,
		    GPIO_MODE(mask) | (level ? GPIO_DIR(mask) : 0));
	    return ns7520_interrupt_table[i].irq;
	}
    }
    return -1;
}
#endif /* BOOT_CODE */

#define NA_MAX_GPIO	15

int ProcessorGpioPin(int pin, unsigned long *addr, unsigned long *gpio_pin)
{
    NA_ASSERT(pin >= 0 && pin <= NA_MAX_GPIO);
    if (pin < 0 || pin > NA_MAX_GPIO)
	return FALSE;
    *addr = (unsigned long)((pin / 8) ? NARM_PORTC_ADDR : NARM_PORTA_ADDR);
    *gpio_pin = pin % 8;
    return TRUE;
}
