📄 spiutil.c
字号:
/******************* ?Marvell Semiconductor, Inc., 2001 - 2003 ***************
*
* Purpose:
*
* This module has the implementation of SDIO related utilities
*
* Notes:
*
* $Author: xiaojie $
*
* $Date: 2006/07/18 11:11:20 $
*
* $Revision: 1.1 $
*
*****************************************************************************/
#ifdef IF_SPI
#include "precomp.h"
#include "Firmware.h"
#include "procdef.h"
#if PXA270_SPI
#include "pxa-gspi.h"
#endif ///PXA270_SPI
#if OMAP730_SPI
#include "omap730_gspx.h"
#endif //OMAP730_SPI
//#include "spi.h"
//#include "CMCSSPI.h"
//extern pMCBSPREGS g_pMcBSP2Regs;
//static NDIS_SPIN_LOCK SpiLock;
BOOLEAN bInterruptInitialize = FALSE; //add panyf
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);
#if PXA270_SPI
static DWORD ssphc = 0;
#endif ///PXA270_SPI
#if OMAP730_SPI
static PGSPI_HW_INFO pOmaSpiHwInfo;
#endif ///OMAP730_SPI
///crlo:add ++
///Delay a while after downloading the firmware
#define FMDN_DELAY 1000 ///delay 1ms, trial value
///crlo:add --
int spi_init(PMRVDRV_ADAPTER Adapter)
{
//NdisAllocateSpinLock(&SpiLock);
#if PXA270_SPI
ssphc = pxa_gspi_Init();
pxa_gspi_register_isr(ssphc, (void*)Adapter, (ISRFUNC)SPINdisInterruptCallback);
#endif /// PXA270_SPI
#if OMAP730_SPI
pOmaSpiHwInfo =(PGSPI_HW_INFO) Omap_gspx_init();
Omap_gspi_register_isr(pOmaSpiHwInfo, (void*)Adapter, (ISRFUNC)SPINdisInterruptCallback);
#endif
return NDIS_STATUS_SUCCESS;
}
// SPI
#if CMCS
void mcbsp_write(u16 outdata)
{
#if CMCS
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 CMCS
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 CMCS
EnableCS(TRUE);
#endif
}
inline void gpio_set_high(int gpionum)
{
#if CMCS
EnableCS(FALSE);
#endif
}
u16 mcbsp_writeRead(u16 outdata)
{
return spi_writeread16(outdata);
#if 0 //chenglong
mcbsp_write(outdata);
return mcbsp_read();
#endif
}
#endif ///CMCS
void gspi_read_reg32(u16 reg, u32 *data)
{
#if CMCS
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 ///CMCS
#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 OMAP730_SPI
Omap_gspx_read_reg32(pOmaSpiHwInfo, reg, data);
return;
#endif
}
int gspi_read_reg16(u16 reg, u16 *data)
{
#if CMCS
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("gspi_read_reg16: read dummy data is %x \r\n!!"),*data);
}
*data=mcbsp_writeRead(0);
////NKDbgPrintfW(TEXT("gspi_read_reg16: read data is %x \r\n"),*data);
gpio_set_high(GPIO(0));
//NdisReleaseSpinLock(&SpiLock);
return 0;
#endif ///CMCS
#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
#if OMAP730_SPI
return Omap_gspx_read_reg16(pOmaSpiHwInfo, reg, data);
#endif
}
void gspi_read_reg8(u16 reg, u8 *data)
{
#if CMCS
u16 data16;
gspi_read_reg16(reg, &data16);
*data = (u8)(data16 & 0xFF);
#endif ///CMCS
#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
#if OMAP730_SPI
u16 regdata;
Omap_gspx_read_reg16(pOmaSpiHwInfo, reg, ®data);
*data = (u8)regdata;
#endif
return;
}
void gspi_read_data_direct(u8 *data, u16 reg, u16 size)
{
#if CMCS
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<10; i++) //g_spi_dummy_clk_data -> 10,panyufeng
{
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 ///CMCS
#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
#if OMAP730_SPI
Omap_gspx_read_mem(pOmaSpiHwInfo, reg, size, data);
#endif
}
int gspi_write_reg(u16 reg, u16 data)
{
#if CMCS
//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 ///CMCS
#if PXA270_SPI
return ssp_write_register(ssphc, reg, &data);
#endif ///PXA270_SPI
#if OMAP730_SPI
return Omap_gspx_write_reg16(pOmaSpiHwInfo, reg, data);
#endif ///PXA270_SPI
}
void gspi_write_data(u16 *data, u16 size)
{
#if CMCS
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 //CMCS
#if PXA270_SPI
///crlo:Note: 0x24 = Data Port
ssp_write_data(ssphc, data, 0x24, size);
#endif ///PXA270_SPI
#if OMAP730_SPI
UCHAR * MyData;
MyData = (UCHAR * )data;
Omap_gspx_write_mem(pOmaSpiHwInfo, 0x24, size, MyData);
#endif
return;
}
void gspi_write_data_direct(u16 *data, u16 reg, u16 size)
{
#if CMCS
#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 ///CMCS
#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
#if OMAP730_SPI
u16 nw = size >> 1;
u16 writesize=(size%2) ? (nw+1) : nw;
UCHAR * Data8;
Data8 = (UCHAR * )data;
Omap_gspx_write_mem(pOmaSpiHwInfo, reg, writesize, Data8);
#endif
return;
}
///============================================================================
void gspi_UshortRegSetBits(u16 reg, u16 bits)
{
u16 data;
gspi_read_reg16(reg, &data);
data |= bits;
gspi_write_reg(reg, data);
}
int wait_for_hostintstatus(void)
{
int i,timeout=100;
u16 stat;
for(i=0;i<timeout;++i) {
gspi_read_reg16(HOST_INT_STATUS_REG, &stat);
if(stat & CIC_CmdDnLdOvr)
return 1;
NdisStallExecution(10); // stall for 10 us
}
return 0;
}
void sbi_disable_host_int(void)
{
gspi_write_reg(HOST_INT_STATUS_MASK_REG, 0x00);
}
void sbi_enable_host_int(void)
{
u16 hicr;
gspi_write_reg(HOST_INT_STATUS_MASK_REG, 0x1f);
gspi_read_reg16(HOST_INT_CTRL_REG, &hicr);
////NKDbgPrintfW(TEXT ("sbi_enable_host_int 1 HOST_INT_CTRL_REG = %x\n"),hicr);
gspi_write_reg(HOST_INT_CTRL_REG, hicr&~(0x01e0));
//gspi_read_reg16(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);
gspi_write_reg(SCRATCH_1_REG, SPI_FW_DOWNLOAD_PKTCNT);
if(!wait_for_hostintstatus())
{
NKDbgPrintfW(TEXT ("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);
gspi_write_reg(HOST_INT_STATUS_REG, 0x0000);
gspi_write_reg(CARD_INT_CAUSE_REG, CIC_CmdDnLdOvr);
////NKDbgPrintfW(TEXT ("."));
}
////NKDbgPrintfW(TEXT ("\nDownload %d bytes of firmware\n",firmwarelen));
//NKDbgPrintfW(TEXT("\nDownload %d bytes of firmware\r\n"),firmwarelen);
/* Writing 0 to Scr1 is to indicate the end of Firmware dwld */
gspi_write_reg(SCRATCH_1_REG, FIRMWARE_DNLD_END);
gspi_write_reg(HOST_INT_STATUS_REG, 0x0000);
gspi_write_reg(CARD_INT_CAUSE_REG, CIC_CmdDnLdOvr);
ret = 0;
return ret;
}
static int sbi_download_wlan_fw_image(const u8 *firmware, int firmwarelen)
{
int ret,j, index = 0;
u16 dlimage[1024];
u16 len;
u32 cnt=0;
DWORD dwTick1,dwTick2;
// u32 dwTemp;
////NKDbgPrintfW(TEXT ("WLAN_FW: Downloading firmware of size %d bytes\n", firmwarelen));
//NKDbgPrintfW(TEXT("WLAN_FW: Downloading firmware of size %d bytes\r\n!!"),firmwarelen);
/* Wait initially for the first non-zero value */
do {
NdisStallExecution(10); // stall for 10 us
gspi_read_reg16(SCRATCH_1_REG, &len);
} while(!len);
dwTick1 = GetTickCount();
for(;;) {
memset(dlimage, 0, SPI_FW_DOWNLOAD_PKTCNT);
if(!wait_for_hostintstatus()) {
//NKDbgPrintfW(TEXT ("Firmware download died ......\n"));
return -1;
}
gspi_read_reg16(SCRATCH_1_REG, &len);
////NKDbgPrintfW(TEXT ("len = %d\n"),len);
cnt += len;
if(!len) {
// //NKDbgPrintfW(TEXT ("\nFirmware download complete \n"));
break;
}
if(len & 1) {
//NKDbgPrintfW(TEXT ("CRC Error\n"));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -