📄 spiutil.c
字号:
/******************* ?Marvell Semiconductor, Inc., 2001 - 2003 *************** * * Purpose: * * This module has the implementation of GSPI related utilities * * Notes: * * $Author: $ * * $Date: Nov 01 2005 21:30:10 $ * * $Revision: 1.0 $ * *****************************************************************************/#ifdef IF_GSPI///#include "precomp.h"#include "Firmware.h"///#include "procdef.h"
#include "spi.h"
#if PXA270_SPI#include "pxa-gspi.h"#endif ///PXA270_SPI//#include "spi.h"//#include "CMCSSPI.h"//extern pMCBSPREGS g_pMcBSP2Regs;static NDIS_SPIN_LOCK SpiLock;int g_spi_dummy_clk_reg = 0x05;int g_spi_dummy_clk_data = 0x0e;extern void spi_write16(WORD wValToWrite);extern WORD spi_read16(void);extern WORD spi_writeread16(WORD wWriteValue);extern void EnableCS(BOOL bEnable);
static void sbi_disable_host_int(void);
static void sbi_enable_host_int(void);
#if PXA270_SPIstatic DWORD ssphc = 0;#endif ///PXA270_SPI///crlo:add ++///Delay a while after downloading the firmware#define FMDN_DELAY 1000 ///delay 1ms, trial value///crlo:add --
extern SD_API_STATUS SPINdisInterruptCallback(IN NDIS_HANDLE MiniportAdapterContext);
IF_FW_STATUS spi_Init(void *pSpiParam)
{ ///crlo:verion-check ++ IF_FW_STATUS result = NDIS_STATUS_SUCCESS; ///crlo:verion-check -- NdisAllocateSpinLock(&SpiLock);#if PXA270_SPI ssphc = pxa_gspi_Init();
///crlo:verion-check ++ if (ssphc == 0) { result = NDIS_STATUS_FAILURE; goto funcFinal; } ///crlo:verion-check -- pxa_gspi_register_isr(ssphc, pSpiParam, (ISRFUNC)SPINdisInterruptCallback);
#endif /// PXA270_SPI ///crlo:verion-check ++funcFinal: return result; ///crlo:verion-check --}// SPI#if OMAPvoid mcbsp_write(u16 outdata){#if OMAP spi_write16(outdata);#endif#if 0 while (((*(volatile u16*)McBSP_SPCR2) & SPCR2_XRDY) == 0); *(volatile u16 *)McBSP_DXR1 = outdata;#endif}u16 mcbsp_read(void){#if OMAP return spi_read16();#else return 0;#endif#if 0 while (((*(volatile u16*)McBSP_SPCR1) & SPCR1_RRDY) == 0); return *(volatile u16 *)McBSP_DRR1;#endif}#define GPIO(n) (n)inline void gpio_set_low(int gpionum){#if OMAP EnableCS(TRUE);#endif}inline void gpio_set_high(int gpionum){#if OMAP EnableCS(FALSE);#endif}u16 mcbsp_writeRead(u16 outdata){ return spi_writeread16(outdata);#if 0 //chenglong mcbsp_write(outdata); return mcbsp_read();#endif}#endif ///OMAPvoid gspi_read_reg32(u16 reg, u32 *data){#if OMAP u16 data0; u16 data1; int i; NdisAcquireSpinLock(&SpiLock); gpio_set_low(GPIO(0)); mcbsp_writeRead(reg); for (i=0; i<g_spi_dummy_clk_reg; i++) mcbsp_writeRead(0); //dummy data0=mcbsp_writeRead(0); data1=mcbsp_writeRead(0); *data = ((u32)data0) | (((u32)data1)<<16); gpio_set_high(GPIO(0)); NdisReleaseSpinLock(&SpiLock);#endif ///OMAP#if PXA270_SPI u16 *regaddr = (u16 *)reg; u16 *regdatPt = (u16*)data; ssp_read_register(ssphc, regdatPt, (WORD)regaddr); ///ssp_read_data_direct(ssphc, regdatPt, (WORD)regaddr, 1, g_spi_dummy_clk_reg); ssp_read_register(ssphc, (regdatPt+1), (WORD)(regaddr+1)); ///ssp_read_data_direct(ssphc, (regdatPt+1), (WORD)(regaddr+1), 1, g_spi_dummy_clk_reg); return;#endif ///PXA270_SPI}IF_API_STATUS spi_ReadRegister(u16 reg, u16 *data){#if OMAP int i; NdisAcquireSpinLock(&SpiLock); gpio_set_low(GPIO(0)); mcbsp_writeRead(reg); for (i=0; i<g_spi_dummy_clk_reg; i++) { mcbsp_writeRead(0); //dummy //*data=mcbsp_writeRead(0); //dummy ////NKDbgPrintfW(TEXT("spi_ReadRegister: read dummy data is %x \r\n!!"),*data); } *data=mcbsp_writeRead(0); ////NKDbgPrintfW(TEXT("spi_ReadRegister: read data is %x \r\n"),*data); gpio_set_high(GPIO(0)); NdisReleaseSpinLock(&SpiLock); return 0;#endif ///OMAP#if PXA270_SPI return ssp_read_register(ssphc, data, reg); ///return ssp_read_data_direct(ssphc, data, reg, 1, g_spi_dummy_clk_reg);#endif ///PXA270_SPI}void gspi_read_reg8(u16 reg, u8 *data){#if OMAP u16 data16; spi_ReadRegister(reg, &data16); *data = (u8)(data16 & 0xFF);#endif ///OMAP#if PXA270_SPI u16 regdata; ssp_read_register(ssphc, ®data, reg); ///ssp_read_data_direct(ssphc, ®data, reg, 1, g_spi_dummy_clk_reg); *data = (u8)regdata;#endif ///PXA270_SPI return;}
IF_API_STATUS spi_GetDataBlock(VOID *pSpiParam, USHORT usLength, IF_PKT_TYPE ucCardStatus, UCHAR *p_pkt)///void gspi_read_data_direct(u8 *data, u16 reg, u16 size){
IF_API_STATUS result = IF_SUCCESS;
u8 *data = p_pkt;
u16 size = usLength;
u16 reg = (ucCardStatus == IF_CMD_PKT) ? (CMD_RDWRPORT_REG) : (DATA_RDWRPORT_REG);
#if OMAP int i; u16 data1; NdisAcquireSpinLock(&SpiLock); gpio_set_low(GPIO(0)); mcbsp_writeRead(reg); ////NKDbgPrintfW(TEXT("[1]gspi_read_data_direct is %x \r\n!!"),data1); for (i=0; i<g_spi_dummy_clk_data; i++) { mcbsp_writeRead(0); //dummy ////NKDbgPrintfW(TEXT("[2]gspi_read_data_direct is %x \r\n!!"),data1); } for (i=0; i<size; i++) { data1=mcbsp_writeRead(0); ////NKDbgPrintfW(TEXT("[3]gspi_read_data_direct is %x \r\n!!"),data1); data[2*i] = data1 & 0xFF; data[2*i+1] = (data1>>8) & 0xFF; } gpio_set_high(GPIO(0)); NdisReleaseSpinLock(&SpiLock);#endif ///OMAP#if PXA270_SPI ///ssp_read_data_direct(ssphc, (WORD*)data, reg, size, g_spi_dummy_clk_data); ssp_read_data(ssphc, (WORD*)data, reg, size);#endif ///PXA270_SPI
return result;}IF_API_STATUS spi_WriteRegister(u16 reg, u16 data){#if OMAP NdisAcquireSpinLock(&SpiLock); gpio_set_low(GPIO(0)); reg |= GSPI_WRITE; mcbsp_writeRead(reg); mcbsp_writeRead(data); gpio_set_high(GPIO(0)); NdisReleaseSpinLock(&SpiLock); return 0;#endif ///OMAP#if PXA270_SPI return ssp_write_register(ssphc, reg, &data);#endif ///PXA270_SPI}void gspi_write_data(u16 *data, u16 size){#if OMAP u16 i; NdisAcquireSpinLock(&SpiLock); gpio_set_low(GPIO(0)); data[0] |= GSPI_WRITE; for (i=0; i<size; i++) { mcbsp_writeRead(data[i]); } gpio_set_high(GPIO(0)); NdisReleaseSpinLock(&SpiLock);#endif //OMAP#if PXA270_SPI ///crlo:Note: 0x24 = Data Port ssp_write_data(ssphc, data, 0x24, size);#endif ///PXA270_SPI return;}void gspi_write_data_direct(u16 *data, u16 reg, u16 size){#if OMAP#if 0 //DMA NdisAcquireSpinLock(&SpiLock); gpio_set_low(GPIO(0)); reg |= GSPI_WRITE; mcbsp_writeRead(reg); spi_write_noread_direct(data, size/2); if (size&0x01) { mcbsp_writeRead((u16)(data[i]&0xFF)); ////NKDbgPrintfW(TEXT("[3]gspi_write_data_direct is %x \r\n!!"),data[i+2]); } gpio_set_high(GPIO(0)); NdisReleaseSpinLock(&SpiLock);#endif#if 1 //PIO u16 i; NdisAcquireSpinLock(&SpiLock); gpio_set_low(GPIO(0)); reg |= GSPI_WRITE; ////NKDbgPrintfW(TEXT("[1]gspi_write_data_direct is %x \r\n!!"),reg); mcbsp_writeRead(reg); for (i=0; i<size/2; i++) { //data16 = ((u16)data[i]) + (((u16)data[i+1])<<8); ////NKDbgPrintfW(TEXT("[2]gspi_write_data_direct is %x \r\n!!"),data16); mcbsp_writeRead(data[i]); } if (size&0x01) { mcbsp_writeRead((u16)(data[i]&0xFF)); ////NKDbgPrintfW(TEXT("[3]gspi_write_data_direct is %x \r\n!!"),data[i+2]); } gpio_set_high(GPIO(0)); NdisReleaseSpinLock(&SpiLock);#endif#endif ///OMAP#if PXA270_SPI u16 nw = size >> 1; ///ssp_write_data(ssphc, data, size); ssp_write_data(ssphc, data, reg, ((size%2)?(nw+1):nw)); ///ssp_write_data_direct(ssphc, data, reg, ((size%2)?(nw+1):nw));#endif ///PXA270_SPI return;}///============================================================================void gspi_UshortRegSetBits(u16 reg, u16 bits){ u16 data; spi_ReadRegister(reg, &data); data |= bits; spi_WriteRegister(reg, data);}int wait_for_hostintstatus(void){ int i,timeout=100; u16 stat; for(i=0;i<timeout;++i) { spi_ReadRegister(HOST_INT_STATUS_REG, &stat); if(stat & CIC_CmdDnLdOvr) return 1; NdisStallExecution(100); // stall for 10 us
// NdisStallExecution(1000); // stall for 10 us
} NKDbgPrintfW(TEXT("HOST_INT_STATUS_REG: %xh, timeout\n"), stat); return 0;}void sbi_disable_host_int(void){ spi_WriteRegister(HOST_INT_STATUS_MASK_REG, 0x00);}void sbi_enable_host_int(void){ u16 hicr; spi_WriteRegister(HOST_INT_STATUS_MASK_REG, 0x1f); spi_ReadRegister(HOST_INT_CTRL_REG, &hicr); ////NKDbgPrintfW(TEXT ("sbi_enable_host_int 1 HOST_INT_CTRL_REG = %x\n"),hicr); spi_WriteRegister(HOST_INT_CTRL_REG, hicr&~(0x01e0)); //spi_ReadRegister(HOST_INT_CTRL_REG, &hicr); ////NKDbgPrintfW(TEXT ("sbi_enable_host_int 2 HOST_INT_CTRL_REG = %x\n"),hicr);}/** * This function is used for transferring firmware from the host to the * client. */int sbi_prog_firmware_image(const u8 *firmware, int firmwarelen){ int ret = 0; u16 dlimage[SPI_FW_DOWNLOAD_PKTCNT]; int index=0,j; int fwblknow;
for(fwblknow = 0;fwblknow < firmwarelen;fwblknow += SPI_FW_DOWNLOAD_PKTCNT) { memset(dlimage, 0, SPI_FW_DOWNLOAD_PKTCNT); spi_WriteRegister(SCRATCH_1_REG, SPI_FW_DOWNLOAD_PKTCNT); if(!wait_for_hostintstatus()) { NKDbgPrintfW(TEXT ("Helper Firmware download died ......\n")); return -1; }// dlimage[0] = CMD_RDWRPORT_REG; for(j=0;j<(SPI_FW_DOWNLOAD_PKTCNT/2);++j) { dlimage[j] = firmware[index++]; dlimage[j] |= (firmware[index++] << 8); } gspi_write_data_direct(dlimage, CMD_RDWRPORT_REG, SPI_FW_DOWNLOAD_PKTCNT);
spi_WriteRegister(HOST_INT_STATUS_REG, 0x0000);
spi_WriteRegister(CARD_INT_CAUSE_REG, CIC_CmdDnLdOvr); ///NKDbgPrintfW(TEXT (".")); }
///////////////
///crlo:test ++
/*
if (fwblknow > firmwarelen) {
///Downloading the last segment
NKDbgPrintfW(TEXT ("Downloading the last segment"));
fwblknow -= SPI_FW_DOWNLOAD_PKTCNT;
memset(dlimage, 0, SPI_FW_DOWNLOAD_PKTCNT);
spi_WriteRegister(SCRATCH_1_REG, firmwarelen-fwblknow);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -