/**************************************************************
***************************************************************
**
** C-SIMULATION, Copyright (C) 2000-2002
** Ikanos Communication, Fremont, CA 
** All rights reserved.
**
**                     afeIntf.c 
**
**  Example code which provides interface functions to read/write 
**     afe registers. 
**
**  Uses function iposDelay while waiting for some afe reg 
**     access to complete.  
**
** The information and contents of this file are the
** proprietary information of Ikanos Communication and may not
** be disclosed or used without the formal written approval of 
** Ikanos Communication
** 
***************************************************************

$Revision: 1.1 $ 
$Date: 2006/10/16 04:34:50 $
**************************************************************/

/*******  Include Files         ***************************************/
#include "stdio.h"

#include "bme_app.h"
#include "mem.h"
#include "afeIntf.h" 
#include "dapi_define.h"
#include "dapi_parms.h"

  // define fn to show log msgs - printf used here 
#define logMsg printf  

int	num_AFEs = 2;  /* set to num of afe's controlled by 1 bme */ 
int     AfeLog = 1;    /* set to 1 to show afe access log msgs */ 
extern int testPIORead (int BmeNum, unsigned long addr);
extern void testPIOWrite_diag (int BmeNum, unsigned long addr, unsigned long data);
extern int bmePioRead (tBmeStruct *, int, char *);
extern void iposDelay (void);
extern void testPIOWrite (int BmeNum, unsigned long addr, unsigned long data);
extern tBmeStruct Bme[5];

BYTE HostCpuEndianType;


static AFE_DATABASE	afeDataBase [NUM_AFE_REGISTERS] = {
	{0x20, TRUE, 	0},			  // 1
	{0x21, TRUE, 	0},			  // 2
	{0x22, TRUE, 	0},			  // 3
	{0x23, TRUE, 	0},			  // 4
	{0x24, TRUE, 	0},			  // 5
	{0x25, TRUE, 	0},			  // 6
	{0x26, TRUE, 	0},			  // 7
	{0x27, TRUE, 	0},			  // 8
	{0x28, TRUE, 	0},			  // 9
	{0x29, TRUE, 	0},			  // 10
	{0x2B, FALSE, 	0},			  // 11
	{0x2C, TRUE, 	0},			  // 12
	{0x2D, TRUE, 	0},			  // 13
	{0x30, TRUE, 	0xc000},	  // 14
	{0x31, FALSE, 	0},			  // 15
	{0x32, TRUE, 	0xc000},	  // 16
	{0x33, FALSE, 	0},			  // 17
	{0x34, TRUE, 	0},			  // 18
	{0x38, TRUE, 	0},			  // 19
	{0x3F, FALSE,	0},			  // 20
	{0x70, TRUE, 	0x10},		  // 21
	{0x72, FALSE, 	0},			  // 22
	{0x74, FALSE, 	0},			  // 23
	{0x76, TRUE, 	0},			  // 24
	{0x78, TRUE, 	0x7fff},	  // 25
	{0x7A, TRUE, 	0},			  // 26
	{0x7C, FALSE, 	0},			  // 27
	{0x80, TRUE, 	0x320c},	  // 28
	{0x81, TRUE, 	0x320c},	  // 29
	{0x82, TRUE, 	0x320c},	  // 30
	{0x83, TRUE, 	0x320c},	  // 31
	{0x84, TRUE, 	0x320c},	  // 32
	{0x85, TRUE, 	0x320c},	  // 33
	{0x86, TRUE, 	0x320c},	  // 34
	{0x87, TRUE, 	0x320c},	  // 35
	{0x88, TRUE, 	0x300c},	  // 36
	{0x89, TRUE, 	0x300c},	  // 37
	{0x8A, TRUE, 	0x4},		  // 38
	{0x90, TRUE, 	0},			  // 39
	{0x91, TRUE, 	0},			  // 40
	{0x92, TRUE, 	0},			  // 41
	{0x93, TRUE, 	0},			  // 42
	{0x94, TRUE, 	0},			  // 43
	{0x9F, TRUE, 	0},			  // 44
	{0xA0, FALSE, 	0},			  // 45
	{0xA1, FALSE, 	0},			  // 46
	{0xA2, FALSE, 	0},			  // 47
	{0xA3, FALSE, 	0},			  // 48
	{0xA4, FALSE, 	0},			  // 49
	{0xA5, FALSE, 	0},			  // 50
	{0xA6, FALSE, 	0},			  // 51
	{0xA7, FALSE, 	0},			  // 52
	{0xA8, TRUE, 	0},			  // 53
	{0xF0, TRUE, 	0},			  // 54
};

void writePIO_SingleRegChannel(int *baseRegAddress, int channel, int data)
{
	HostCpuEndianType = 2;
	Bme[1].BMEbaseAddr = BME_BASE_ADDR;
	Bme[1].BmeNum=1;
	
	testPIOWrite (1,(int)((volatile int *)(baseRegAddress + channel)),data);
}

int readPIO_SingleRegChannel(int *baseRegAddress, int channel)
{
	UINT32 data = 0;	
	HostCpuEndianType = 2;
	Bme[1].BMEbaseAddr = BME_BASE_ADDR;	
	Bme[1].BmeNum=1;

	/* PIO read from DMA_SAR reg */		
	bmePioRead (&Bme[1],  (int)((volatile int *)(baseRegAddress + channel)), (BYTE *)&data);
	//printf("\nRead data 0x%08lx, dest 0x%08lx\n",data,(int)((volatile int *)(baseRegAddress + channel)));

	return(data);	
}
void writePIO_Regs (int *baseRegAddress, int numRegs, int *data)
{
	int	i;


	for (i = 0;i < numRegs;i++)	{

		//	hostPIO_write((int)((volatile int *)(baseRegAddress + i)), data[i]);
	
		testPIOWrite (1,(int)((volatile int *)(baseRegAddress + i)),data[i]);

	}			
}

void readPIO_Regs (int *baseRegAddress, int numRegs, int *data)
{
	int	i;


	for (i = 0;i < numRegs;i++)	{
	//data[i] = hostPIO_read((int)((volatile int *)(baseRegAddress + i)));
	bmePioRead (&Bme[1],  (int)((volatile int *)(baseRegAddress + i)), (BYTE *)&data[i]);

	}

}




/*
************************************************************************
	Function: waitIfAFEBusy
	
	Description: wait for the QUEUE FULL bit to go low 
		Uses iposDelay() to idle. 
		
	Return Value: None 
************************************************************************
*/

void 
waitIfAFEBusy ()
{
	// test if the afe is busy and wait if it is
	volatile unsigned int	afe_status;
	
	while ((afe_status = readPIO_SingleRegChannel((int *)VIF_RASR, 0)) & BIT30)
	{
		iposDelay();
	}
 
}

/*
************************************************************************
        Function: afeWriteReg

        Description: Writes to AFE reg. 
		Input is the reg address and the afe num (from 1..4) , 
			and the data to be written. 

        Return Value: 1 for sucess, 0 for fail 
************************************************************************
*/
int 
afeWriteRegister(int which_reg, int which_afe, int data)
{
	int rwc_reg;

	if (which_afe>num_AFEs-1)
		return(-1);
		
 	// wait for AFE not to be busy
	waitIfAFEBusy ();
	
	// write the data to the RG_WRITE register in PIO space
	writePIO_SingleRegChannel ((int *)VIF_RWDR, 0, data);

	
	// afe register write command in 16..30
	// which afe in 8..15
	// actual address in 0..7
	// 0x10000 is AFE register write
	rwc_reg = (1<<30) + (which_afe << 8) + which_reg; 

	// write the control register	
	writePIO_SingleRegChannel ((int *)VIF_RWCR, 0,rwc_reg);

	//if (AfeLog) 
	//    logMsg("\n afe %d wrt reg 0x%x = 0x%x  ", which_afe, which_reg, data);

	return(0);
}


/*
************************************************************************
        Function: waitForAFEReadDoneBit 

        Description: waits to see if prev afe read was completed by 
		checking the afe read status bit in bme. 
		Uses iposDelay() to idle. 

        Return Value: 1 for success, 0 for fail (read timed out) 
************************************************************************
*/
int 
waitForAFEReadDoneBit ()
{
	// test if the afe is busy and wait if it is
	volatile unsigned int	afe_status;
	int		i;
	
	i = 0;
	while (((afe_status = readPIO_SingleRegChannel ((int *)VIF_RASR, 0))&BIT31) == 0)
	{
		iposDelay();	
		i++;
		if(i>0x1000) {
			logMsg("\n AFE waiting for read done bit timed out");
			return(0);
		}								
	} 
	
	return(1);	
}

/*
************************************************************************
        Function: afeReadReg

        Description: Reads from AFE reg. 
		Input is the reg address and the afe num (from 1..4) , 
			and the data to be written. 

        Return Value: 1 for sucess, 0 for fail 
************************************************************************
*/
int afeReadRegister (int which_reg, int which_afe)
{
	int rwc_reg;
	
	if(which_afe>num_AFEs-1)
		return(-1);
	
	waitIfAFEBusy ();
	// afe register read command in 16..30
	// which afe in 8..15
	// actual address in 0..7
	rwc_reg = (1<<31) + (which_afe << 8) + which_reg; 			

	// write the control register	
	writePIO_SingleRegChannel ((int *)VIF_RWCR, 0,rwc_reg);
	
	if(waitForAFEReadDoneBit ())
		return readPIO_SingleRegChannel ((int *)VIF_RRCR, 0);	
	else {
		logMsg("\n AFE read REG failure");
		return(0);			
	}
}


/*
************************************************************************
	Function: initAFE
	
	Description: init the AFE registers with power-on defaults.
		
	Return Value: 
************************************************************************
*/

void 
initAFE (int tot_afes)
{
	int i,j;

	num_AFEs = tot_afes;
	
	// set all the afe registers to the reset values					 
	for (i = AFEADDR_AFE_ACH1;i<NUM_AFE_REGISTERS;i++)
		for (j = 0;j <num_AFEs;j++)
			if(afeDataBase[i].rw == TRUE)
				afeWriteRegister(afeDataBase[i].address, j, afeDataBase [i].data);
}
 	

