www.pudn.com > DMBDRV.rar > SpiHw.c


 
 
 
#include "SianoSPI.h" 
#include "PxaRegs.h" 
#include "PXA_SSP.h" 
 
#include "xllp_defs.h" 
 
#include "SpiHw.h" 
 
#include  
#include  
#include "pkfuncs.h" 
#include  "memmap.h" 
#include "Gpio.h" 
#include  
#include  
 
 
 
#define PXA270 
 
 
#define SPI_ACTIVATION_PREAMBLE1 0xc1de0000 
#define SPI_ACTIVATION_PREAMBLE2 0xedf151a5 
#define SPI_COMMAND_PREAMBLE	 0x7ee75aa5 
 
 typedef struct SmsMsgHdr_S 
 { 
     UINT16	msgType; 
     UINT8  	msgSrcId; 
     UINT8 	msgDstId; 
     UINT16	msgLength;	// Length is of the entire message, including header 
     UINT16	msgFlags; 
 
 } SmsMsgHdr_ST; 
 
 
typedef struct SmsMsgData_S 
{ 
	SmsMsgHdr_ST	xMsgHeader; 
	UINT32			msgData[1]; 
} SmsMsgData_ST; 
 
#define SMS_MAX_PAYLOAD_SIZE	    240 
 
typedef struct SmsDataDownload_S 
{ 
	SmsMsgHdr_ST	xMsgHeader; 
	UINT32			MemAddr; 
	UINT32			Payload[SMS_MAX_PAYLOAD_SIZE/4]; 
} SmsDataDownload_ST; 
 
 
#define MSG_SMS_DATA_DOWNLOAD_REQ		660 
#define MSG_SMS_SWDOWNLOAD_TRIGGER_REQ	664 
#define MSG_SMS_SPI_INT_LINE_SET_REQ   	710 
 
 
 
 
#define POLLING_TIMEOUT 500000 
#define XLLP_SSCR0_SSE  (0x1<<7)         // 1 -- SSP operation is enabled 
 
/* 
 * SSP Serial Port Registers 
 * PXA250, PXA255, PXA26x and PXA27x SSP controllers are all slightly different. 
 * PXA255, PXA26x and PXA27x have extra ports, registers and bits. 
 */ 
 
 /* Common PXA2xx bits first */ 
#define SSCR0_DataSize(x)  ((x) - 1)	/* Data Size Select [4..16] */ 
#define SSCR0_Motorola	(0x0 << 4)	/* Motorola's Serial Peripheral Interface (SPI) */ 
 
#define SSCR1_RIE	(1 << 0)	/* Receive FIFO Interrupt Enable */ 
#define SSCR1_TIE	(1 << 1)	/* Transmit FIFO Interrupt Enable */ 
#define SSCR1_LBM	(1 << 2)	/* Loop-Back Mode */ 
#define SSCR1_SPO	(1 << 3)	/* Motorola SPI SSPSCLK polarity setting */ 
#define SSCR1_SPH	(1 << 4)	/* Motorola SPI SSPSCLK phase setting */ 
#define SSCR1_MWDS	(1 << 5)	/* Microwire Transmit Data Size */ 
#define SSCR1_TFT	(0x000003c0)	/* Transmit FIFO Threshold (mask) */ 
#define SSCR1_TxTresh(x) (((x) - 1) << 6) /* level [1..16] */ 
#define SSCR1_RFT	(0x00003c00)	/* Receive FIFO Threshold (mask) */ 
#define SSCR1_RxTresh(x) (((x) - 1) << 10) /* level [1..16] */ 
 
#define SSSR_TNF	(1 << 2)	/* Transmit FIFO Not Full */ 
#define SSSR_RNE	(1 << 3)	/* Receive FIFO Not Empty */ 
#define SSSR_BSY	(1 << 4)	/* SSP Busy */ 
#define SSSR_TFS	(1 << 5)	/* Transmit FIFO Service Request */ 
#define SSSR_RFS	(1 << 6)	/* Receive FIFO Service Request */ 
#define SSSR_ROR	(1 << 7)	/* Receive FIFO Overrun */ 
 
#define SSCR0_RIM		(1 << 22)	/* Receive FIFO Over Run interrupt Mask */ 
#define SSCR0_NCS		(1 << 21)	/* Network Clock Select */ 
#define SSCR0_EDSS		(1 << 20)	/* Extended Data Size Select */ 
 
/* extra bits in PXA255, PXA26x and PXA27x SSP ports */ 
#define SSCR1_TRAIL		(1 << 22)	/* Trailing Byte */ 
#define SSCR1_TSRE		(1 << 21)	/* Transmit Service Request Enable */ 
#define SSCR1_RSRE		(1 << 20)	/* Receive Service Request Enable */ 
#define SSCR1_TINTE		(1 << 19)	/* Receiver Time-out Interrupt enable */ 
#define SSCR1_PINTE		(1 << 18)	/* Peripheral Trailing Byte Interupt Enable */ 
#define SSCR1_STRF		(1 << 15)	/* Select FIFO or EFWR */ 
#define SSCR1_EFWR		(1 << 14)	/* Enable FIFO Write/Read */ 
 
#define XLLP_CLKEN_SSP1		    (0x1u << 23) 
#define XLLP_CLKEN_SSP2		    (0x1u << 3) 
#define XLLP_CLKEN_SSP3		    (0x1u << 4) 
#define XLLP_CLKEN_SSP4                 (0x1u << 5) 
 
 
 
 
 
typedef struct 
 
{ 
 
    XLLP_VUINT32_T    cccr;                   // Core Clock Configuration register 
 
    XLLP_VUINT32_T    cken;                   // Clock Enable register 
 
    XLLP_VUINT32_T    oscc;                   // Oscillator Configuration register 
 
    XLLP_VUINT32_T    ccsr;                   // Core Clock Status register 
 
 } XLLP_CLKMGR_T, *P_XLLP_CLKMGR_T;   
 
 
#define fwmin(a,b)         (a> 8) |	\ 
					 (((x)&0xff000000) >> 24)) 
 
#define MIN_BUFF_PARTITION 256 
#define FW_STEP 4 
 
#define GET_GPIOXX_2_IRQ 
#define CONFIGURE_GPIO 
#define USE_CONSO_DEFAULT 
 
 
 
typedef struct 
{ 
	DWORD					useSSPPort; 
	CHAR					DmaDllName[MAX_REG_PATH_SIZE]; 
	DEVICE_DMA_SERVICE_ST     *dmaService; 
	volatile XLLP_SSP_REGS        *sspCtrl; 
	DWORD					sspDataRegPhy; 
	HANDLE					rxEvent; 
	HANDLE					SmsInterruptEvent; 
	DWORD					spiSysIntr; 
	DWORD					RxInterruptCnt;		//For debug 
	BOOL					drvActive; 
	HANDLE					RxIST; 
	PVOID					intrContext; 
	BOOL					novaDevice; 
	DWORD					novaIntrPin; 
	void(*InterruptCallback)(void*); 
}SPIPHY, *PSPIPHY; 
 
volatile XLLP_CLKMGR_T *v_pClkRegs		 = NULL; 
volatile XLLP_GPIO_T   *v_pGPIORegisters   = NULL; 
// for PXA300 
#ifndef PXA270 
    volatile UINT32                 *v_pMFPRRegisters = NULL; 
#endif 
 
DWORD useSSPPort; 
 
extern  PVOID VirtualAllocCopy(unsigned size,char *str,PVOID pVirtualAddress);  
extern  void msWait(UINT ms);  
 
static DWORD GetSpiPortNum() 
{ 
	DWORD SpiPortNum; 
 
		if(SSPCLK==23) 
			SpiPortNum = 1; 
		else if(SSPCLK==36) 
			SpiPortNum = 2; 
		else if(SSPCLK==52) 
			SpiPortNum = 3; 
	        else  
	                SpiPortNum = 4; 
	  
	return  SpiPortNum;	 
} 
	 
//writing to SPI device 
static void SSPWriteDWord(PSPIPHY pSpiPhy,DWORD dwVal) 
{ 
	 
	DWORD sb;	 
	sb = SWAP32(dwVal); 
	pSpiPhy->sspCtrl->ssdr = sb;	 
} 
 
//reading from SPI device 
static DWORD SSPReadDWord(PSPIPHY pSpiPhy) 
{ 
	DWORD sb;	 
	DWORD v = pSpiPhy->sspCtrl->ssdr; 
	sb = SWAP32(v); 
	return sb; 
} 
 
//write and read to/from SPI device 
static DWORD ReadWriteDWord(PSPIPHY pSpiPhy,DWORD dwInVal) 
{ 
	DWORD dwRetVal; 
	DWORD timeout; 
	 
	 
	timeout = POLLING_TIMEOUT;	 
	//Loop while there is any data in the fifo 
	while(!(pSpiPhy->sspCtrl->ssr & SSSR_TNF) && timeout--); 
	if (timeout == -1) 
		return 0; 
	SSPWriteDWord(pSpiPhy,dwInVal); 
	 
	timeout = POLLING_TIMEOUT; 
	while(!(pSpiPhy->sspCtrl->ssr & SSSR_RNE) && timeout--); 
	if (timeout == -1) 
		return 0; 
	//RETAILMSG(1, (TEXT("ReadWriteDWord call read  ..\r\n"))); 
	dwRetVal = SSPReadDWord(pSpiPhy); 
 
	return dwRetVal; 
} 
 
 
static void endOfDmaTransfer(DWORD	transactionId, DWORD status) 
{ 
	//RETAILMSG(1, (TEXT("SmsSpi:  DMA transaction end.\r\n"))); 
	SetEvent((HANDLE)transactionId); 
} 
 
 
static BOOL spiPhyGetRegistrySettings(PVOID Context, PSPIPHY pSpiPhy ) 
{ 
	TCHAR*	regKey; 
	BOOL	st; 
	HKEY	hKey; 
	DWORD	dataSize, type; 
	regKey = (TCHAR *)LocalAlloc (LPTR, MAX_REG_KEY_SIZE); 
	if (regKey == NULL) 
	{ 
		RETAILMSG(1, (TEXT("Siano SPI - ERROR!! Allocating memory for registry reading failed.\r\n"))); 
		return FALSE; 
	} 
 
 
	st = RegOpenKeyEx(HKEY_LOCAL_MACHINE, (LPCWSTR)Context, 0, 0, &hKey);						 
	if(st != ERROR_SUCCESS) 
	{ 
		RETAILMSG(1, (TEXT("Siano SPI - ERROR!! Could not open registry key.\r\n"))); 
		LocalFree(regKey); 
		return (FALSE); 
	} 
 
	dataSize=MAX_REG_KEY_SIZE; 
	st = RegQueryValueEx(	hKey,  
							TEXT("Key"),  
							NULL, 
							&type,  
							(LPBYTE)regKey,  
							&dataSize); 
	 
	RegCloseKey(hKey); 
	if(st!=ERROR_SUCCESS)	 
	{ 
		RETAILMSG(1,  (TEXT("Siano SPI - ERROR!! Could not get registry key name.\r\n"))); 
		LocalFree(regKey); 
		return (FALSE); 
	} 
	 
	// Now - read all the needed parameters for the driver from the registry. 
 
 
	st = RegOpenKeyEx(HKEY_LOCAL_MACHINE, regKey, 0, 0, &hKey); 
	if(st != ERROR_SUCCESS) 
	{ 
		RETAILMSG(1, (TEXT("Siano SPI - ERROR!! Could not open registry key.\r\n"))); 
		LocalFree(regKey); 
		return (FALSE); 
	} 
 
 
	dataSize=MAX_REG_PATH_SIZE; 
	st = RegQueryValueEx( hKey,  
						  L"DmaServicesPlugin",  
						  0,  
						  &type,  
						  (LPBYTE)&pSpiPhy->DmaDllName,  
						  &dataSize); 
	if(st != ERROR_SUCCESS) 
	{ //Set default value if registry entry is not found. 
		pSpiPhy->DmaDllName[0] = 0; 
	} 
 
 
	/* 
	dataSize = sizeof(pSpiPhy->useSSPPort);	 
	st = RegQueryValueEx( hKey,  
					  L"useSSPPort",  
					  0,  
					  &type,  
					  (LPBYTE)&pSpiPhy->useSSPPort,  
					  &dataSize); 
 
	if(st != ERROR_SUCCESS) 
	{ //Set default value if registry entry is not found. 
		pSpiPhy->useSSPPort = 1; 
		RETAILMSG(1, (TEXT("Siano SPI :useSSPPort = 1\r\n"))); 
		 
	}	 
 
	dataSize = sizeof(pSpiPhy->spiSysIntr); 
	st = RegQueryValueEx( hKey,  
					  L"useSysIntr",  
					  0,  
					  &type,  
					  (LPBYTE)&pSpiPhy->spiSysIntr,  
					  &dataSize); 
 
	if(st != ERROR_SUCCESS) 
	{ //Set default value if registry entry is not found. 
		pSpiPhy->spiSysIntr = 34; 
	} 
	if (pSpiPhy->spiSysIntr == 0xffff) 
	{ 
		DWORD Irq_GpioXX_2; 
		Irq_GpioXX_2 = DEFAULT_IRQ_GPIOXX_2;//consonance irq number 
		RETAILMSG(1, (TEXT("Irq Number = %d!!!\r\n"),DEFAULT_IRQ_GPIOXX_2)); 
		if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &Irq_GpioXX_2, sizeof(DWORD), &pSpiPhy->spiSysIntr, sizeof(DWORD), NULL)) 
		{ 
			RETAILMSG(1,  (TEXT("SPI : IOCTL_HAL_REQUEST_SYSINTR failed (x%08x)\r\n"), GetLastError())); 
		} 
		else 
		{ 
			RETAILMSG(1, (TEXT("SPI : IOCTL_HAL_REQUEST_SYSINTR Succeded SysIntr %d\r\n"), pSpiPhy->spiSysIntr)); 
		} 
	} 
 
	dataSize = sizeof(pSpiPhy->novaDevice); 
	st = RegQueryValueEx( hKey,  
					  L"novaDevice",  
					  0,  
					  &type,  
					  (LPBYTE)&pSpiPhy->novaDevice,  
					  &dataSize); 
 
	if(st != ERROR_SUCCESS) 
	{ //Set default value if registry entry is not found. 
		pSpiPhy->novaDevice = FALSE; 
	} 
	 
	dataSize = sizeof(pSpiPhy->novaIntrPin); 
	st = RegQueryValueEx( hKey,  
					  L"novaIntrPin",  
					  0,  
					  &type,  
					  (LPBYTE)&pSpiPhy->novaIntrPin,  
					  &dataSize); 
 
	if(st != ERROR_SUCCESS) 
	{ //Set default value if registry entry is not found. 
		pSpiPhy->novaIntrPin = 16; 
	} 
	 
	*/ 
	 
	st = RegCloseKey(hKey); 
	if(st!=ERROR_SUCCESS)	 
	{ 
		RETAILMSG(1, (TEXT("Siano SPI - ERROR!! Could not get registry key name.\r\n"))); 
		LocalFree(regKey); 
		return (FALSE); 
	} 
 
	LocalFree(regKey); 
	return (TRUE); 
 
} 
 
 
 
static BOOL	activateDMAService(PSPIPHY pSpiPhy) 
{ 
	DMA_INIT_PARAMS_ST dmaSetUp; 
	 
	if (pSpiPhy->DmaDllName[0] == 0) 
	{ 
		RETAILMSG(1,  (TEXT("SmsSpi: activateDMAService() There is no DMA service name.\r\n"))); 
		return FALSE; 
	} 
	 
	pSpiPhy->dmaService = (DEVICE_DMA_SERVICE_ST*)LocalAlloc(LPTR, sizeof(DEVICE_DMA_SERVICE_ST)); 
	if (pSpiPhy->dmaService == NULL) 
	{ 
		RETAILMSG(1,  (TEXT("SmsSpi: activateDMAService() Could not allocate DMA service structure.\r\n"))); 
		return FALSE; 
	} 
	 
	pSpiPhy->dmaService->hdl = LoadLibrary((LPCWSTR)pSpiPhy->DmaDllName); 
	if (pSpiPhy->dmaService->hdl == NULL) 
	{ 
		RETAILMSG(1, (TEXT("SmsSpi: activateDMAService() Could not load DMA service library.\r\n"))); 
		LocalFree(pSpiPhy->dmaService); 
		pSpiPhy->dmaService = NULL; 
		return FALSE; 
	} 
 
	pSpiPhy->dmaService->dmaSetUpChannel = (DMA_SetUpChannelF)GetProcAddress(pSpiPhy->dmaService->hdl, TEXT("DMA_SetUpChannel")); 
	pSpiPhy->dmaService->dmaConfigChannel = (DMA_ConfigChannelF)GetProcAddress(pSpiPhy->dmaService->hdl, TEXT("DMA_ConfigChannel")); 
	pSpiPhy->dmaService->dmaRemoveChannel = (DMA_RemoveChannelF)GetProcAddress(pSpiPhy->dmaService->hdl, TEXT("DMA_RemoveChannel")); 
	if (pSpiPhy->dmaService->dmaSetUpChannel == NULL || 
		pSpiPhy->dmaService->dmaConfigChannel == NULL || 
		pSpiPhy->dmaService->dmaRemoveChannel == NULL) 
	{ 
		RETAILMSG(1, (TEXT("SmsSpi: activateDMAService() Could not find DMA library routines.\r\n"))); 
		FreeLibrary(pSpiPhy->dmaService->hdl); 
		LocalFree(pSpiPhy->dmaService); 
		pSpiPhy->dmaService = NULL; 
		return FALSE; 
	} 
 
 
	dmaSetUp.flags = DMA_USE_HW_FLOW_CTRL; 
	if (useSSPPort == 1)	 
		dmaSetUp.dmaReq = SSP1_TX_CMR; 
	else if (useSSPPort == 2)	 
		dmaSetUp.dmaReq = SSP2_TX_CMR; 
       else if (useSSPPort == 3)	 
                dmaSetUp.dmaReq = SSP3_TX_CMR; 
       else if (useSSPPort == 4)	 
                dmaSetUp.dmaReq = SSP4_TX_CMR; 
        dmaSetUp.burstSize = DMA_BURST_8_BYTES; 
	dmaSetUp.busWidth = DMA_BUS_WIDTH_4_BYTE; 
	pSpiPhy->dmaService->txDmaDevice=pSpiPhy->dmaService->dmaSetUpChannel(&dmaSetUp); 
 
	dmaSetUp.flags = DMA_USE_HW_FLOW_CTRL; 
	 if (useSSPPort == 1)	 
              dmaSetUp.dmaReq = SSP1_RX_CMR; 
        else if (useSSPPort == 2)	 
            dmaSetUp.dmaReq = SSP2_RX_CMR; 
        else if (useSSPPort == 3)	 
            dmaSetUp.dmaReq = SSP3_RX_CMR; 
        else if (useSSPPort == 4)	 
            dmaSetUp.dmaReq = SSP4_RX_CMR; 
   	dmaSetUp.burstSize = DMA_BURST_8_BYTES; 
	dmaSetUp.busWidth = DMA_BUS_WIDTH_4_BYTE; 
	pSpiPhy->dmaService->rxDmaDevice=pSpiPhy->dmaService->dmaSetUpChannel(&dmaSetUp); 
	return TRUE; 
} 
 
 
static BOOL	deactivateDMAService(PSPIPHY pSpiPhy) 
{ 
	if (pSpiPhy->dmaService != NULL) 
	{ 
		if (pSpiPhy->dmaService->rxDmaDevice) 
			pSpiPhy->dmaService->dmaRemoveChannel(pSpiPhy->dmaService->rxDmaDevice); 
		if (pSpiPhy->dmaService->txDmaDevice) 
			pSpiPhy->dmaService->dmaRemoveChannel(pSpiPhy->dmaService->txDmaDevice); 
		if (pSpiPhy->dmaService->hdl) 
			FreeLibrary(pSpiPhy->dmaService->hdl); 
		LocalFree(pSpiPhy->dmaService); 
		pSpiPhy->dmaService = NULL; 
	} 
	return TRUE; 
} 
 
 
VOID SpiRxIST(PVOID pArg) 
{ 
	PSPIPHY pSpiPhy = (PSPIPHY)pArg; 
 
	pSpiPhy->RxInterruptCnt = 0; 
	while (1) 
	{ 
		WaitForSingleObject(pSpiPhy->SmsInterruptEvent,INFINITE); 
		if (pSpiPhy->drvActive == FALSE) 
		{ 
			return; 
		} 
		pSpiPhy->RxInterruptCnt++;		 
		if (pSpiPhy->InterruptCallback) 
			pSpiPhy->InterruptCallback(pSpiPhy->intrContext); 
		 
		InterruptDone(pSpiPhy->spiSysIntr); 
		 
	} 
} 
 
// loopBackTest1 for spi test 
BOOL loopBackTest1(PSPIPHY pSpiPhy) 
	{ 
		int i; 
		DWORD wrd; 
		DWORD  Tx_loopbuf[64]= {0}; 
		DWORD  Rx_loopbuf[64]= {0}; 
		DWORD err_cnt=0; 
		for ( i= 0; i< 64; i ++) 
		{ 
		Tx_loopbuf[i] = (4*i+3)<<12| (4*i+2)<<8| (4*i+1)<<4|4*i; 
		Rx_loopbuf[i] = 0; 
		} 
		//send 256 bytes 
		for(i=0; i<64; i++) 
		{ 
	//		wrd=ReadWriteDWord(pSpiPhy,0xa55ae77e+i); 
			wrd=ReadWriteDWord(pSpiPhy, (DWORD)Tx_loopbuf[i]); 
			 
		} 
	    Sleep(100);	 
		//send and receive 256 bytes 
		for(i=0; i<64; i++) 
		{ 
	//		wrd = ReadWriteDWord(pSpiPhy,0xa55ae77e+i); 
			wrd=ReadWriteDWord(pSpiPhy, (DWORD)Tx_loopbuf[i]); 
			Rx_loopbuf[i] = wrd; 
			RETAILMSG( 1, (TEXT("%d loopBackTest222 get 0x%x\r\n"),i,wrd)); 
		} 
			 
		for(i=0; i<64; i++) 
		{ 
				RETAILMSG( 1, (TEXT("%d loopBackTest222 get 0x%x\r\n"),i, Rx_loopbuf[i])); 
				 
				if (Rx_loopbuf[i] != Tx_loopbuf[i]) 
				{ 
					err_cnt ++; 
					RETAILMSG( 1, (TEXT("loop back error cnt :%d\n"),err_cnt)); 
				} 
		 
		 
		} 
	 
		return TRUE; 
	} 
 
BOOL loopBackTest2(PSPIPHY pSpiPhy) 
{ 
	int i; 
	DWORD wrd; 
	DWORD  Tx_loopbuf[64]= {0}; 
	DWORD  Rx_loopbuf[64]= {0}; 
	DWORD err_cnt=0; 
	 
	 
	for ( i= 0; i< 64; i ++) 
	{ 
	   
	Tx_loopbuf[i] = (4*i+3)<<24| (4*i+2)<<16| (4*i+1)<<8|4*i; 
	 
	//RETAILMSG( 1, (TEXT("%d TX buffer 0x%x\r\n"),i,Tx_loopbuf[i])); 
	Rx_loopbuf[i] = 0; 
//	RETAILMSG( 1, (TEXT("%d TX buffer 0x%x\r\n"),i,Tx_loopbuf[i])); 
	} 
	 
	//send 256 bytes 
	for(i=0; i<64; i++) 
	{ 
//		wrd=ReadWriteDWord(pSpiPhy,0xa55ae77e+i); 
		wrd=ReadWriteDWord(pSpiPhy, (DWORD)Tx_loopbuf[i]); 
		 
	} 
 
	Sleep(100); 
	//send and receive 256 bytes 
	for(i=0; i<64; i++) 
	{ 
//		wrd = ReadWriteDWord(pSpiPhy,0xa55ae77e+i); 
		wrd=ReadWriteDWord(pSpiPhy, (DWORD)Tx_loopbuf[i]); 
		Rx_loopbuf[i] = wrd; 
//		RETAILMSG( 1, (TEXT("%d loopBackTest222 get 0x%x\r\n"),i,wrd)); 
	} 
	 
	for(i=0; i<64; i++) 
	{ 
			if (Rx_loopbuf[i] != Tx_loopbuf[i]) 
			{ 
				err_cnt ++; 
				RETAILMSG( 1, (TEXT("loop back error cnt :%d\n"),err_cnt)); 
				RETAILMSG( 1, (TEXT("%d, TX buffer 0x%x, RX buffer 0x%x\r\n"), i, Tx_loopbuf[i], Rx_loopbuf[i])); 
			} 
	 
	 
	} 
 
	return TRUE; 
} 
 
 
BOOL loopBackTest(PSPIPHY pSpiPhy) 
{ 
	int i; 
	DWORD wrd; 
	 
	//send 256 bytes 
	for(i=0; i<64; i++) 
	{ 
		wrd=ReadWriteDWord(pSpiPhy,0xa55ae77e+i); 
		 
	} 
 
	//send and receive 256 bytes 
	for(i=0; i<64; i++) 
	{ 
		wrd = ReadWriteDWord(pSpiPhy,0xa55ae77e+i); 
		RETAILMSG( 1, (TEXT("%d loopBackTest222 get 0x%x\r\n"),i,wrd)); 
	} 
 
	return TRUE; 
} 
 
////////////////////////////   Internal fucntions ///////////////////////////////// 
 
 
/************************************************************************************* 
FUNCTION NAME:	WriteFW 
 
DESCRIPTION:	the actual writing to the firmwere 
*************************************************************************************/ 
 
VOID WriteFWtoStellar(PSPIPHY pSpiPhy,BYTE* pFW,DWORD Len) 
{ 
	DWORD Padding; 
	DWORD Cnt = 0; 
	DWORD *pPos = (DWORD*)pFW; 
	int LeftOver; 
	DWORD i=0; 
//	RETAILMSG( 1, (TEXT("SmsSpi: WriteFW :pSpiPhy->sspCtrl->ssr:0x%x ,pSpiPhy->sspCtrl->ssdr:0x%x,*pFW :0x%x ,Len:0x%x.\r\n"),pSpiPhy->sspCtrl->ssr, 
//		                                    pSpiPhy->sspCtrl->ssdr,*pFW,Len)); 
//	RETAILMSG( 1, (TEXT("SmsSpi: WriteFW :pSpiPhy->sspCtrl->sscr0:0x%x,pSpiPhy->sspCtrl->sscr10x%x \r\n"),pSpiPhy->sspCtrl->sscr0,pSpiPhy->sspCtrl->sscr1)); 
 
	 
	//Data Must be sent in 256 Bytes chuncks --- CHANGED: Pre DMA init in Siano device, pass the exact file size. 
	Padding = Len%MIN_BUFF_PARTITION; 
	if(Padding) 
		Padding = MIN_BUFF_PARTITION - Padding;//to complete to 256; 
	RETAILMSG( 1, (TEXT("SmsSpi: WriteFW :Len %d bytes Padding %d Bytes\r\n"),Len,Padding)); 
 
	//1st Phaze 
	RETAILMSG( 1, (TEXT("SmsSpi: WriteFW :Entering Phaze 1\r\n"))); 
	while((Cnt+FW_STEP)<=Len) 
	{ 
		//actual Device Writing 
		//no need checking the data received from the device 
			 
		DWORD ret = ReadWriteDWord(pSpiPhy,*pPos); 
		 
		//Change Stats 
		Cnt+=fwmin(FW_STEP,Len-Cnt); 
		pPos++;//+4 
		i++; 
 
	} 
 
	//2nd Phaze 
	//Check if we have left over data we didn't send 
	RETAILMSG( 1, (TEXT("SPI!WriteFW :Entering Phaze 2\r\n"))); 
	LeftOver = (Len - Cnt); 
	RETAILMSG( 1, (TEXT("SPI!WriteFW :LeftOver Data Len %d Bytes\r\n"),LeftOver)); 
	if (LeftOver>0) 
	{ 
		DWORD dwval; 
		pPos = (DWORD*)(pFW+Cnt); 
		dwval= ReadWriteDWord(pSpiPhy,*pPos); 
	} 
	Sleep(100); 
 
#if 0	 
	 for ( Cnt = 0 ; Cnt < 100; Cnt++) 
	{ 
	RETAILMSG( 1, (TEXT("test time: %d\r\n"),Cnt)); 
	 loopBackTest2( pSpiPhy); 
	} 
	 while(1); 
#endif 
} 
 
 
static BOOL enableDisableSSPClock(PSPIPHY pSpiPhy, BOOL enable) 
{ 
	volatile XLLP_CLKMGR_T *v_pClkRegs		 = NULL; 
 
	//volatile XLLP_CLKMGR_T          *v_pClkRegs		 = NULL; 
	PHYSICAL_ADDRESS    PhysicalBase; 
 
	PhysicalBase.QuadPart = CLK_BASE_PHYSICAL; 
		 
 
	//v_pClkRegs= (XLLP_CLKMGR_T *)MmMapIoSpace(PhysicalBase,sizeof(XLLP_CLKMGR_T),FALSE); 
	v_pClkRegs= (XLLP_CLKMGR_T *)VirtualAllocCopy(sizeof(XLLP_CLKMGR_T),"clk registers",(PVOID)(CLK_BASE_U_VIRTUAL)); 	 
 
 
	if (!v_pClkRegs) 
	{ 
		return FALSE; 
	} 
 
    switch (pSpiPhy->useSSPPort) 
    { 
    case 1: 
		if (enable) 
			v_pClkRegs->cken  |=   XLLP_CLKEN_SSP1; 
		else 
			v_pClkRegs->cken &=   ~XLLP_CLKEN_SSP1; 
        break; 
    case 2: 
		if (enable) 
			v_pClkRegs->cken |=   XLLP_CLKEN_SSP2; 
		else 
			v_pClkRegs->cken &=   ~XLLP_CLKEN_SSP2; 
        break; 
    case 3: 
		if (enable) 
			v_pClkRegs->cken |=   XLLP_CLKEN_SSP3; 
		else 
			v_pClkRegs->cken &=   ~XLLP_CLKEN_SSP3; 
        break; 
    default: //other than 4 will fail earlier therefore default = 4. 
		if (enable) 
			v_pClkRegs->cken |=   XLLP_CLKEN_SSP4; 
		else 
			v_pClkRegs->cken &=   ~XLLP_CLKEN_SSP4; 
    } 
	//MmUnmapIoSpace((PVOID)v_pClkRegs,sizeof(XLLP_CLKMGR_T)); 
	VirtualFree((PVOID)(v_pClkRegs),0,MEM_RELEASE); 
	v_pClkRegs = NULL; 
 
	return TRUE; 
 
} 
 
VOID WriteFWtoNova(PSPIPHY pSpiPhy,BYTE* pFW,DWORD Len) 
{ 
	PDWORD fwBuf; 
	PBYTE ptr; 
	DWORD count, dstAddr, i; 
        SmsDataDownload_ST  *dnlMsg; 
	SmsMsgData_ST		*trigMsg; 
	SmsMsgData_ST		*setIntMsg; 
	DWORD entryPoint; 
 
 
	pSpiPhy->sspCtrl->sscr0 &= ~XLLP_SSCR0_SSE; 
	/* Reduce the SPI Clock to download speed.*/ 
	if (!enableDisableSSPClock(pSpiPhy, FALSE)) 
	{ 
		return; 
	} 
	// Set register SSCR0 
	pSpiPhy->sspCtrl->sscr0 &= 0xfff000ff; 
	pSpiPhy->sspCtrl->sscr0 |=1<<8; // Divide the clock by 2 
	if (!enableDisableSSPClock(pSpiPhy, TRUE)) 
	{ 
		return; 
	} 
	pSpiPhy->sspCtrl->sscr0 |=XLLP_SSCR0_SSE; 
 
	ReadWriteDWord(pSpiPhy,SPI_ACTIVATION_PREAMBLE1); 
	ReadWriteDWord(pSpiPhy,SPI_ACTIVATION_PREAMBLE2); 
 
	fwBuf = LocalAlloc(LPTR, SPI_PACKET_SIZE); 
	entryPoint = ((DWORD*)pFW)[2]; 
	Len -= 12; 
	ptr = pFW + 12; 
	dstAddr = entryPoint; 
 
	 
	fwBuf[0] = SPI_COMMAND_PREAMBLE; 
 
	dnlMsg = (SmsDataDownload_ST*)&fwBuf[1]; 
	dnlMsg->xMsgHeader.msgType = MSG_SMS_DATA_DOWNLOAD_REQ; 
	dnlMsg->xMsgHeader.msgSrcId = 0; 
	dnlMsg->xMsgHeader.msgDstId = 11; 
	dnlMsg->xMsgHeader.msgFlags = 0; 
 
	while (Len > 0) 
	{ 
		count = min(Len, SMS_MAX_PAYLOAD_SIZE);  
		dnlMsg->xMsgHeader.msgLength = (UINT16)(count + sizeof(SmsMsgHdr_ST) + sizeof(dnlMsg->MemAddr)); 
		dnlMsg->MemAddr = dstAddr; 
		memcpy(dnlMsg->Payload, ptr, count); 
		ptr += count; 
		dstAddr += count; 
		Len -= count; 
		for (i = 0; i < (SPI_PACKET_SIZE / sizeof(DWORD)); i++) 
		{ 
			DWORD ret = ReadWriteDWord(pSpiPhy,fwBuf[i]); 
		} 
	} 
 
	/*Trigger the downloaded code execution*/ 
	trigMsg = (SmsMsgData_ST*)&fwBuf[1]; 
	trigMsg->xMsgHeader.msgType = MSG_SMS_SWDOWNLOAD_TRIGGER_REQ; 
	trigMsg->xMsgHeader.msgDstId = 11;			// to MSGPROC_TASK 
	trigMsg->xMsgHeader.msgSrcId = 0;			// to MSGPROC_TASK 
	trigMsg->xMsgHeader.msgFlags = 0; 
	trigMsg->xMsgHeader.msgLength = sizeof(SmsMsgHdr_ST) + 5 * sizeof(UINT32); 
	trigMsg->msgData[0] = entryPoint;	// Task function 
	trigMsg->msgData[1] = 3;						// Task priority 
	trigMsg->msgData[2] = 0x200;					// Task stack 
	trigMsg->msgData[3] = 0;						// Task creation parameter 
	trigMsg->msgData[4] = 1;						// Task application ID 
 
	for (i = 0; i < (SPI_PACKET_SIZE / sizeof(DWORD)); i++) 
	{ 
		DWORD ret = ReadWriteDWord(pSpiPhy,fwBuf[i]); 
	} 
	Sleep(10); 
	setIntMsg = (SmsMsgData_ST*)&fwBuf[1]; 
	setIntMsg->xMsgHeader.msgType = MSG_SMS_SPI_INT_LINE_SET_REQ; 
	setIntMsg->xMsgHeader.msgDstId = 11;			// to MSGPROC_TASK 
	setIntMsg->xMsgHeader.msgSrcId = 0;			// to MSGPROC_TASK 
	setIntMsg->xMsgHeader.msgFlags = 0; 
	setIntMsg->xMsgHeader.msgLength = sizeof(SmsMsgHdr_ST) + 3 * sizeof(UINT32); 
	setIntMsg->msgData[0] = 0;				// Main Spi Controller (0)  
	setIntMsg->msgData[1] = pSpiPhy->novaIntrPin;				// Interrupt GPIO. 
	setIntMsg->msgData[2] = 0;				// Default pulse width. 
	for (i = 0; i < (SPI_PACKET_SIZE / sizeof(DWORD)); i++) 
	{ 
		DWORD ret = ReadWriteDWord(pSpiPhy,fwBuf[i]); 
	} 
 
	pSpiPhy->sspCtrl->sscr0 &= ~XLLP_SSCR0_SSE; 
	/* Increase the SPI Clock to working speed.*/ 
	if (!enableDisableSSPClock(pSpiPhy, FALSE)) 
	{ 
		return; 
	} 
	// Set register SSCR0 
	pSpiPhy->sspCtrl->sscr0 &= 0xfff000ff; 
	if (!enableDisableSSPClock(pSpiPhy, TRUE)) 
	{ 
		return; 
	} 
	pSpiPhy->sspCtrl->sscr0 |=XLLP_SSCR0_SSE; 
 
	LocalFree(fwBuf); 
 
} 
 
 
 
void smsspibus_xfer(void* context,  
				   unsigned char * txbuf, unsigned long txbuf_phy_addr,  
				   unsigned char* rxbuf, unsigned long rxbuf_phy_addr,  
				   int len) 
{ 
	PSPIPHY pSpiPhy = (PSPIPHY)context; 
	DWORD timeout; 
	DWORD* pdw; 
	 
	if (txbuf) 
	{ 
		//RETAILMSG(1,  (TEXT("transfer buf starting with: 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x.\r\n"), txbuf[0],  
		//txbuf[1], txbuf[2], txbuf[3], txbuf[4], txbuf[5], txbuf[6], txbuf[7])); 
	} 
	if (pSpiPhy->dmaService == NULL) 
	{ //No DMA service - copy using CPU 
		//Loop as long as the TX packet has not been completly trasmitterd, or  
		//until the RX FIFO is emty 
		//RETAILMSG(1, (TEXT("transfer %d bytes without DMA.\r\n"), len)); 
		pdw = (DWORD*)rxbuf; 
		while(len > 0) 
		{ 
			//Loop while there is any data in the fifo 
			while(!(pSpiPhy->sspCtrl->ssr & SSSR_TNF)); 
			if(txbuf) 
			{ 
				DWORD sb = *((DWORD*)txbuf); 
				SSPWriteDWord(pSpiPhy,sb); 
				txbuf+=4; 
			} 
			else 
			{ 
				SSPWriteDWord(pSpiPhy,0);						 
			} 
			timeout = POLLING_TIMEOUT; 
			while(!(pSpiPhy->sspCtrl->ssr & SSSR_RNE)&& timeout--); 
			if (timeout == -1)	//This is for debugginf - timeout should never expire. If it does - SSP controler is not working. 
				timeout = 0; 
			*pdw = SSPReadDWord(pSpiPhy); 
			pdw++;//pointer to DWORD inc by 4 
			len-=4;					 
		} 
	} 
	else // Using DMA 
	{ 
		DMA_PARAMS_ST dmaParams; 
		int i, tmp; 
 
		if(txbuf) 
		{ 
			//Set the Tx buffer DMA transaction. 
			for (i = 0; i < (len+3)>>2; i++) 
				((DWORD*)txbuf)[i] = SWAP32(((DWORD*)txbuf)[i]);										 
		} 
		 
 
		/*Activate the DMA for the recieve of bytes*/ 
		 dmaParams.srcAddr = pSpiPhy->sspDataRegPhy; 
		dmaParams.dstAddr = rxbuf_phy_addr; 
		dmaParams.len = len; 
		dmaParams.flags = DMA_USE_SRC_FLOW_CONTROL | DMA_INC_DST_ADDR; 
		dmaParams.transactionId = (DWORD)pSpiPhy->rxEvent; 
		dmaParams.callBack = endOfDmaTransfer; 
		pSpiPhy->dmaService->dmaConfigChannel((LPVOID)pSpiPhy->dmaService->rxDmaDevice, &dmaParams); 
		//DBGMSG( 1, (TEXT("DMA transfer src=0x%x, dst=0x%x, len=%d \r\n"), dmaParams.srcAddr, dmaParams.dstAddr, len)); 
 
		/*Activate the DMA for the transmit of bytes*/ 
		dmaParams.srcAddr = txbuf_phy_addr; 
		dmaParams.dstAddr = pSpiPhy->sspDataRegPhy;		 
		dmaParams.len = len; 
		dmaParams.flags = DMA_USE_DST_FLOW_CONTROL | DMA_INC_SRC_ADDR; 
		dmaParams.transactionId = 0; 
		dmaParams.callBack = NULL; 
		pSpiPhy->dmaService->dmaConfigChannel((LPVOID)pSpiPhy->dmaService->txDmaDevice, &dmaParams); 
		//DBGMSG( 1, (TEXT("DMA transfer src=0x%x, dst=0x%x, len=%d \r\n"), dmaParams.srcAddr, dmaParams.dstAddr, len)); 
 
		 
 
				 
		// Moving 256 Bytes through SPI using 6.5Mbps takes ~0.3mS, so we wait much longer than that. 
		if (WaitForSingleObject(pSpiPhy->rxEvent, 5000) == WAIT_OBJECT_0) 
		{ 
//					DBGMSG( ZONE_INFO, (TEXT("-----------DMA transfer ended   at %d\r\n"), GetTickCount())); 
			for (i = 0; i < len>>2; i++) 
			{ 
				tmp =((DWORD*)rxbuf)[i]; 
				((DWORD*)rxbuf)[i] =  SWAP32(tmp); 
			} 
		} 
		else 
			RETAILMSG(1, (TEXT("SPI!Read from device :Recieved Timeout for DMA transfer.\r\n"))); 
	} 
} 
 
 
 
void smsspiphy_deinit(PVOID context) 
{ 
	DWORD	exitCode; 
	PSPIPHY pSpiPhy = (PSPIPHY)context; 
	if (pSpiPhy) 
	{ 
		pSpiPhy->drvActive = FALSE; 
		if (pSpiPhy->RxIST) 
		{ 
			if (pSpiPhy->SmsInterruptEvent) // Set an event to start the thread. 
				SetEvent(pSpiPhy->SmsInterruptEvent); 
			CloseHandle(pSpiPhy->RxIST); 
			while (GetExitCodeThread(pSpiPhy->RxIST, &exitCode) == STILL_ACTIVE); 
			pSpiPhy->RxIST = NULL; 
		} 
 
		if (pSpiPhy->dmaService) 
		{ 
			deactivateDMAService(pSpiPhy); 
		} 
		if (pSpiPhy->rxEvent) 
		{ 
			CloseHandle(pSpiPhy->rxEvent); 
			pSpiPhy->rxEvent = NULL; 
 
		} 
		if (pSpiPhy->SmsInterruptEvent) 
		{ 
			CloseHandle(pSpiPhy->SmsInterruptEvent); 
			pSpiPhy->SmsInterruptEvent = NULL; 
 
		} 
		 
		LocalFree(pSpiPhy); 
	} 
#ifdef GET_GPIOXX_2_IRQ 
	//disable the hardware interrupt and to deregister the event  
	InterruptDisable(pSpiPhy->spiSysIntr); 
#endif						   
	//cancel all Threads...ISRThread 
	//cancel all Events... 
 
//unmapping all physical addresses used to access register.... 
	//unmapping SSP registers 
	/* 
	MmUnmapIoSpace((PVOID)pSpiPhy->sspCtrl ,sizeof(XLLP_SSP_REGS)); 
	MmUnmapIoSpace((PVOID)v_pGPIORegisters,sizeof(XLLP_GPIO_T)); 
	MmUnmapIoSpace((PVOID)v_pClkRegs,sizeof(XLLP_CLKMGR_T)); 
	*/ 
	if(v_pGPIORegisters) 
	{ 
		VirtualFree((PVOID)(v_pGPIORegisters),0,MEM_RELEASE); 
		v_pGPIORegisters = NULL; 
	} 
	if(pSpiPhy->sspCtrl) 
	{ 
		VirtualFree((PVOID)(pSpiPhy->sspCtrl),0,MEM_RELEASE); 
		pSpiPhy->sspCtrl = NULL; 
	} 
	 
	if(v_pClkRegs) 
	{ 
		VirtualFree((PVOID)(v_pClkRegs),0,MEM_RELEASE); 
		v_pClkRegs = NULL; 
	} 
	//for PXA300 
#ifndef PXA270 
        if(v_pMFPRRegisters) 
        { 
   		MmUnmapIoSpace((PVOID)v_pMFPRRegisters,sizeof(XLLP_GPIO_T)); 
                v_pMFPRRegisters = NULL; 
        } 
#endif	 
 
} 
 
void* smsspiphy_init(PVOID Context, void(*smsspi_interruptHandler)(void*), PVOID intrContext) 
{ 
 
	DWORD SPICDSysIntr; 
	 
	PSPIPHY pSpiPhy = (PSPIPHY)LocalAlloc(LPTR,sizeof(SPIPHY)); 
	 
	useSSPPort = GetSpiPortNum();	 
	RETAILMSG(1, (TEXT("useSSPPort = %d.\r\n"), useSSPPort)); 
	 
	 v_pGPIORegisters =(volatile XLLP_GPIO_T*)VirtualAllocCopy(sizeof(XLLP_GPIO_T),"GPIO_BASE_U_VIRTUAL",(PVOID)(GPIO_BASE_U_VIRTUAL)); 
	    
	switch(useSSPPort)	 
	{ 
		case 1:        
		        pSpiPhy->sspCtrl= (volatile XLLP_SSP_REGS *)VirtualAllocCopy(sizeof(XLLP_SSP_REGS),"SSP1_BASE_U_VIRTUAL",(PVOID)(SSP1_BASE_U_VIRTUAL)); 
                        pSpiPhy->sspDataRegPhy = SSP1_BASE_PHYSICAL+((DWORD)(&pSpiPhy->sspCtrl->ssdr) - (DWORD)(pSpiPhy->sspCtrl)); 
			break; 
		case 2: 
			 pSpiPhy->sspCtrl= (volatile XLLP_SSP_REGS *)VirtualAllocCopy(sizeof(XLLP_SSP_REGS),"SSP2_BASE_U_VIRTUAL",(PVOID)(SSP2_BASE_U_VIRTUAL)); 
			 pSpiPhy->sspDataRegPhy = SSP2_BASE_PHYSICAL+((DWORD)(&pSpiPhy->sspCtrl->ssdr) - (DWORD)(pSpiPhy->sspCtrl)); 
			break; 
		case 3: 
			 pSpiPhy->sspCtrl= (volatile XLLP_SSP_REGS *)VirtualAllocCopy(sizeof(XLLP_SSP_REGS),"SSP3_BASE_U_VIRTUAL",(PVOID)(SSP3_BASE_U_VIRTUAL)); 
			 pSpiPhy->sspDataRegPhy = SSP3_BASE_PHYSICAL+((DWORD)(&pSpiPhy->sspCtrl->ssdr) - (DWORD)(pSpiPhy->sspCtrl)); 
			break; 
	  #ifndef PXA270 
		 case 4: 
		        pSpiPhy->sspCtrl= (volatile XLLP_SSP_REGS *)VirtualAllocCopy(sizeof(XLLP_SSP_REGS),"SSP4_BASE_U_VIRTUAL",(PVOID)(SSP4_BASE_U_VIRTUAL)); 
			pSpiPhy->sspDataRegPhy = SSP4_BASE_PHYSICAL+((DWORD)(&pSpiPhy->sspCtrl->ssdr) - (DWORD)(pSpiPhy->sspCtrl)); 
			break; 
	   #endif 
 
		default: 
			smsspiphy_deinit(pSpiPhy); 
	                return NULL; 
	} 
	RETAILMSG(1, (TEXT("lINe %d.\r\n"), __LINE__)); 
	if (!pSpiPhy->sspCtrl) 
	{ 
		smsspiphy_deinit(pSpiPhy); 
		return NULL; 
	}	 
      v_pClkRegs= (XLLP_CLKMGR_T *)VirtualAllocCopy(sizeof(XLLP_CLKMGR_T),"clk registers",(PVOID)(CLK_BASE_U_VIRTUAL)); 	 
		 
 
	pSpiPhy->intrContext = intrContext; 
	spiPhyGetRegistrySettings(Context, pSpiPhy); 
       activateDMAService(pSpiPhy); 
	pSpiPhy->InterruptCallback = smsspi_interruptHandler; 
	pSpiPhy->drvActive = TRUE; 
 
	pSpiPhy->SmsInterruptEvent = CreateEvent(NULL, FALSE, FALSE, NULL); 
	if (pSpiPhy->SmsInterruptEvent == NULL) 
	{ 
		RETAILMSG(1, (TEXT("SmsSpi: smsspiphy_init() failed to create SmsInterruptEvent event.\r\n"))); 
		smsspiphy_deinit(pSpiPhy); 
		return NULL; 
	} 
 
	pSpiPhy->rxEvent = CreateEvent(NULL, FALSE, FALSE, NULL); 
	RETAILMSG(1, (TEXT("lINe %d.\r\n"), __LINE__)); 
	if (pSpiPhy->rxEvent == NULL) 
	{ 
		RETAILMSG(1, (TEXT("SmsSpi: smsspiphy_init() failed to create rxEvent event.\r\n"))); 
		smsspiphy_deinit(pSpiPhy); 
		return NULL; 
	} 
	 
#ifdef PXA270 
	  //for PXA270 
	   GPIOSetController( (XLLP_GPIO_T *)v_pGPIORegisters,SSPCLK|GPIO_AF2|GPIO_OUT); 
	   GPIOSetController( (XLLP_GPIO_T *)v_pGPIORegisters,SSPSFRM|GPIO_AF2|GPIO_OUT); 
	   GPIOSetController( (XLLP_GPIO_T *)v_pGPIORegisters,SSPTXD|GPIO_AF2|GPIO_OUT); 
	   GPIOSetController( (XLLP_GPIO_T *)v_pGPIORegisters,SSPRXD|GPIO_AF1|GPIO_IN); 
	   GPIOSetController( (XLLP_GPIO_T *)v_pGPIORegisters, DMBINT0 | GPIO_AF0 |GPIO_IN); 
	   GPIOSetController( (XLLP_GPIO_T *)v_pGPIORegisters, DMB_PWREN | GPIO_AF0 |GPIO_OUT); 
	   GPIOSetControllerValue((XLLP_GPIO_T *)v_pGPIORegisters, DMB_PWREN |GPIO_OUT_1); 
	   GPIOSetController( (XLLP_GPIO_T *)v_pGPIORegisters, nDMB_PD | GPIO_AF0 |GPIO_OUT); 
	   GPIOSetControllerValue((XLLP_GPIO_T *)v_pGPIORegisters, nDMB_PD |GPIO_OUT_1); 
	   GPIOSetController( (XLLP_GPIO_T *)v_pGPIORegisters, nDMB_RESET | GPIO_AF0 |GPIO_OUT); 
	   GPIOSetControllerValue((XLLP_GPIO_T *)v_pGPIORegisters, nDMB_RESET |GPIO_OUT_1); 
	   msWait(10); 
	   GPIOSetControllerValue((XLLP_GPIO_T *)v_pGPIORegisters, nDMB_RESET |GPIO_OUT_0); 
	   msWait(10); 
	   GPIOSetControllerValue((XLLP_GPIO_T *)v_pGPIORegisters, nDMB_RESET |GPIO_OUT_1); 
	   msWait(10); 
#else 
      //for PXA300 
	switch (useSSPPort) 
	   { 
	   case 1: 
		   v_pMFPRRegisters[SSP1_MFPR_TX ] = SSP1_AF | FAST3MA; 
		   v_pMFPRRegisters[SSP1_MFPR_RX ] = SSP1_AF | FAST3MA; 
		   v_pMFPRRegisters[SSP1_MFPR_CLK] = SSP1_AF | FAST3MA; 
		   v_pMFPRRegisters[SSP1_MFPR_FRM] = SSP1_AF | FAST3MA; 
 
		   v_pGPIORegisters->SSP1_GPDR_TX  |= (XLLP_GPIO_BIT_SSP1_TXD); 
		   v_pGPIORegisters->SSP1_GPDR_CLK |= (XLLP_GPIO_BIT_SSP1_CLK); 
		   v_pGPIORegisters->SSP1_GPDR_FRM |= (XLLP_GPIO_BIT_SSP1_FRM); 
		   v_pGPIORegisters->SSP1_GPDR_RX  &= ~(XLLP_GPIO_BIT_SSP1_RXD); 
		   break; 
	   case 2: 
		   v_pMFPRRegisters[SSP2_MFPR_TX ] = SSP2_AF | FAST3MA; 
		   v_pMFPRRegisters[SSP2_MFPR_RX ] = SSP2_AF | FAST3MA; 
		   v_pMFPRRegisters[SSP2_MFPR_CLK] = SSP2_AF | FAST3MA; 
		   v_pMFPRRegisters[SSP2_MFPR_FRM] = SSP2_AF | FAST3MA; 
 
		   v_pGPIORegisters->SSP2_GPDR_TX  |= (XLLP_GPIO_BIT_SSP2TXD); 
		   v_pGPIORegisters->SSP2_GPDR_CLK |= (XLLP_GPIO_BIT_SSP2CLK); 
		   v_pGPIORegisters->SSP2_GPDR_FRM |= (XLLP_GPIO_BIT_SSP2FRM); 
		   v_pGPIORegisters->SSP2_GPDR_RX  &= ~(XLLP_GPIO_BIT_SSP2RXD); 
		   break; 
	   case 3: 
		   v_pMFPRRegisters[SSP3_MFPR_TX ] = SSP3_AF | FAST3MA; 
		   v_pMFPRRegisters[SSP3_MFPR_RX ] = SSP3_AF | FAST3MA; 
		   v_pMFPRRegisters[SSP3_MFPR_CLK] = SSP3_AF | FAST3MA; 
		   v_pMFPRRegisters[SSP3_MFPR_FRM] = SSP3_AF | FAST3MA; 
 
		   v_pGPIORegisters->SSP3_GPDR_TX  |= (XLLP_GPIO_BIT_SSP3TXD); 
		   v_pGPIORegisters->SSP3_GPDR_CLK |= (XLLP_GPIO_BIT_SSP3CLK); 
		   v_pGPIORegisters->SSP3_GPDR_FRM |= (XLLP_GPIO_BIT_SSP3FRM); 
		   v_pGPIORegisters->SSP3_GPDR_RX  &= ~(XLLP_GPIO_BIT_SSP3RXD); 
		   break; 
	   default: 
		   v_pMFPRRegisters[SSP4_MFPR_TX ] = SSP4_AF | FAST3MA; 
		   v_pMFPRRegisters[SSP4_MFPR_RX ] = SSP4_AF | FAST3MA; 
		   v_pMFPRRegisters[SSP4_MFPR_CLK] = SSP4_AF | FAST3MA; 
		   v_pMFPRRegisters[SSP4_MFPR_FRM] = SSP4_AF | FAST3MA; 
 
		   v_pGPIORegisters->SSP4_GPDR_TX  |= (XLLP_GPIO_BIT_SSP4TXD); 
		   v_pGPIORegisters->SSP4_GPDR_CLK |= (XLLP_GPIO_BIT_SSP4CLK); 
		   v_pGPIORegisters->SSP4_GPDR_FRM |= (XLLP_GPIO_BIT_SSP4FRM); 
		   v_pGPIORegisters->SSP4_GPDR_RX  &= ~(XLLP_GPIO_BIT_SSP4RXD); 
	   } 
#endif	 
 
switch (useSSPPort) 
{ 
	case 1:		 
	    v_pClkRegs->cken &=   ~XLLP_CLKEN_SSP1; 
	    break; 
	case 2: 
	    v_pClkRegs->cken &=   ~XLLP_CLKEN_SSP2; 
	    break; 
	case 3: 
	    v_pClkRegs->cken &=   ~XLLP_CLKEN_SSP3; 
	    break; 
	default: 
	    v_pClkRegs->cken &=   ~XLLP_CLKEN_SSP4; 
} 
 
	// Set register SSCR0 
	//pSpiPhy->sspCtrl->sscr0 = 0; 
	//pSpiPhy->sspCtrl->sscr1 = 0; 
	//pSpiPhy->sspCtrl->ssdr = 0; 
	//pSpiPhy->sspCtrl->ssr=0; 
	pSpiPhy->sspCtrl->sscr0 = SSCR0_Motorola | SSCR0_DataSize(16) | SSCR0_EDSS;//32bit words in the fifo 
 	pSpiPhy->sspCtrl->sscr0 |=3<<8; // Divide the clock by 3 
 
	// Set register SSCR1 
	pSpiPhy->sspCtrl->sscr1 = (SSCR1_TRAIL|SSCR1_RIE|SSCR1_TIE|SSCR1_TSRE | SSCR1_RSRE |SSCR1_RxTresh(1) | SSCR1_TxTresh(7));  
	 
	// Set register SSITR 
	pSpiPhy->sspCtrl->ssitr = 0;  
 
	// Set register SSTO 
	pSpiPhy->sspCtrl->ssto = 0; //No timeout. always send/recieve the same amount of bytes. 
 
	 switch (useSSPPort) 
	 { 
		 case 1:	  
			 v_pClkRegs->cken  |=   XLLP_CLKEN_SSP1; 
			 break; 
		 case 2: 
			 v_pClkRegs->cken  |=   XLLP_CLKEN_SSP2; 
			 break; 
		 case 3: 
			 v_pClkRegs->cken  |=   XLLP_CLKEN_SSP3; 
			 break; 
		 default: 
			 v_pClkRegs->cken  |=   XLLP_CLKEN_SSP4; 
	 } 
 
 
	//Activate SSP channel 
        pSpiPhy->sspCtrl->sscr0 |=XLLP_SSCR0_SSE;  // 1 -- SSP operation is enabled 
	    
 
	pSpiPhy->spiSysIntr =SYSINTR_DMB; 
	SPICDSysIntr = pSpiPhy->spiSysIntr; 
 
	DBGMSG(1, (TEXT("SPI : InterruptInitialize(sysInt =%d, Event=0x%x)\r\n"),  
               SPICDSysIntr, pSpiPhy->SmsInterruptEvent)); 
 
	if (!InterruptInitialize(SPICDSysIntr,pSpiPhy->SmsInterruptEvent,0,0)) 
       { 
               RETAILMSG(1, (TEXT("SPI : InterruptInitialize(sysInt =%d, Event=0x%x) failed (status =%d)\r\n"),  
               pSpiPhy->spiSysIntr, pSpiPhy->SmsInterruptEvent, GetLastError())); 
       } 
		 
	pSpiPhy->RxIST = CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE)SpiRxIST, pSpiPhy, 0, NULL); 
	RETAILMSG(1, (TEXT("lINe %d.\r\n"), __LINE__)); 
	if (pSpiPhy->RxIST == NULL) 
	{ 
		DBGMSG(ZONE_INIT | ZONE_ERROR, (TEXT("SmsSpi: smsspiphy_init() failed to create transferThread thread.\r\n"))); 
		smsspiphy_deinit(pSpiPhy); 
		return 0; 
	} 
	RETAILMSG(1, (TEXT("lINe %d.\r\n"), __LINE__)); 
	if (CeSetThreadPriority(pSpiPhy->RxIST, 0) == FALSE) 
	{ 
		RETAILMSG(1, (TEXT("SmsSpi: smsspiphy_init() failed to set Interrupt thread priority.\r\n"))); 
		smsspiphy_deinit(pSpiPhy); 
		return 0; 
	} 
	RETAILMSG(1, (TEXT("SPI init pSpiPhy->sspCtrl->ssdr--2:0x%x\r\n"),pSpiPhy->sspCtrl->ssdr )); 
 
	return pSpiPhy; 
} 
 
void smschipreset(PVOID context) 
{ 
}