⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 spiutil.c

📁 marvell8385 GSPI开发驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
/******************* ?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, &regdata, reg);
	///ssp_read_data_direct(ssphc, &regdata, reg, 1, g_spi_dummy_clk_reg);
	*data = (u8)regdata;
#endif ///PXA270_SPI
#if OMAP730_SPI
      u16	regdata;
       Omap_gspx_read_reg16(pOmaSpiHwInfo,  reg, &regdata);
       *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 + -