Example #1
0
ETxnStatus sdioAdapt_Transact (unsigned int  uFuncId,
                               unsigned int  uHwAddr,
                               void *        pHostAddr,
                               unsigned int  uLength,
                               unsigned int  bDirection,
                               unsigned int  bBlkMode,
                               unsigned int  bFixedAddr,
                               unsigned int  bMore)
{
	int iStatus;

	if (bDirection) { /* Read */
		iStatus = sdioDrv_ReadSync (uFuncId, uHwAddr, pHostAddr, uLength, bBlkMode, bFixedAddr, bMore);
		if (iStatus) {
			return TXN_STATUS_ERROR;
		}
		return TXN_STATUS_COMPLETE;
	} else { /* Write */
		iStatus = sdioDrv_WriteSync (uFuncId, uHwAddr, pHostAddr, uLength, bBlkMode, bFixedAddr, bMore);
		if (iStatus) {
			return TXN_STATUS_ERROR;
		}
		return TXN_STATUS_COMPLETE;
	}
}
Example #2
0
void async_write_worker(struct work_struct *work)
{
	int ret;

	ret = sdioDrv_WriteSync(g_drv.async_write_worker_data.uFunc,
			g_drv.async_write_worker_data.uHwAddr,
			g_drv.async_write_worker_data.pData,
			g_drv.async_write_worker_data.uLen,
			g_drv.async_write_worker_data.bIncAddr,
			g_drv.async_write_worker_data.bMore);

	if (g_drv.BusTxnCB)
		g_drv.BusTxnCB(g_drv.BusTxnHandle, ret);
}
Example #3
0
ETxnStatus sdioAdapt_Transact (unsigned int  uFuncId,
                               unsigned int  uHwAddr,
                               void *        pHostAddr,
                               unsigned int  uLength,
                               unsigned int  bDirection,
                               unsigned int  bBlkMode,
                               unsigned int  bFixedAddr,
                               unsigned int  bMore)
{
    int iStatus,i;


    if (bDirection) { /* Read */
		iStatus = sdioDrv_ReadSync (uFuncId, uHwAddr, pHostAddr, uLength, bBlkMode, bFixedAddr, bMore);
		if (iStatus)
		{
			return TXN_STATUS_ERROR;
		}
		return TXN_STATUS_COMPLETE;
    } else { /* Write */
	    if (use52)
	    {
	//    printk("use 52\n");jj = 0;
	        for (i = 0; i < uLength ; ++i)
	        {
	           // printk("uHwAddr = 0x%x *pHostValue = 0x%x\n",uHwAddr,(unsigned char)(*((unsigned char*)pHostAddr)));
	            sdioAdapt_TransactBytes(uFuncId,uHwAddr,pHostAddr,1,bDirection,bMore);
	            uHwAddr += 1;
	            pHostAddr = (void *)((unsigned int)pHostAddr+1);

	        }
	        return TXN_STATUS_COMPLETE;
	    }
	    else
	    {
			iStatus = sdioDrv_WriteSync (uFuncId, uHwAddr, pHostAddr, uLength, bBlkMode, bFixedAddr, bMore);
		}

	    if (iStatus)
		{
			return TXN_STATUS_ERROR;
		}
		return TXN_STATUS_COMPLETE;
    }
}
int sdioAdapt_ConnectBus (void *        fCbFunc,
                          void *        hCbArg,
                          unsigned int  uBlkSizeShift,
                          unsigned int  uSdioThreadPriority,
                          unsigned char **pRxDmaBufAddr,
                          unsigned int  *pRxDmaBufLen,
                          unsigned char **pTxDmaBufAddr,
                          unsigned int  *pTxDmaBufLen)
{
#ifdef PROPRIETARY_SDIO
    unsigned char  uByte;
    unsigned long  uLong;
    unsigned long  uCount = 0;
#endif
    unsigned int   uBlkSize = 1 << uBlkSizeShift;
    int            iStatus;

    if (uBlkSize < SYNC_ASYNC_LENGTH_THRESH) 
    {
        printk("%s(): Block-Size should be bigger than SYNC_ASYNC_LENGTH_THRESH!!\n", __FUNCTION__ );
    }

#ifdef PROPRIETARY_SDIO
    /* Enabling clocks if thet are not enabled */
    sdioDrv_clk_enable();
#endif

    /* Allocate a DMA-able buffer and provide it to the upper layer to be used for all read and write transactions */
    if (pDmaBufAddr == 0) /* allocate only once (in case this function is called multiple times) */
    {
        pDmaBufAddr = kmalloc (MAX_BUS_TXN_SIZE, GFP_ATOMIC | GFP_DMA);
        if (pDmaBufAddr == 0) { return -1; }
    }
    *pRxDmaBufAddr = *pTxDmaBufAddr = pDmaBufAddr;
    *pRxDmaBufLen  = *pTxDmaBufLen  = MAX_BUS_TXN_SIZE;

    /* Init SDIO driver and HW */
    iStatus = sdioDrv_ConnectBus (fCbFunc, hCbArg, uBlkSizeShift, uSdioThreadPriority);
	if (iStatus) { return iStatus; }

#ifndef PROPRIETARY_SDIO
//    iStatus = sdioDrv_EnableFunction(TXN_FUNC_ID_WLAN);
//        if (iStatus) { return iStatus; }
//    iStatus = sdioDrv_SetBlockSize(TXN_FUNC_ID_WLAN, uBlkSize);
//        if (iStatus) { return iStatus; }
#endif

#ifdef PROPRIETARY_SDIO
    /* Send commands sequence: 0, 5, 3, 7 */
    iStatus = sdioDrv_ExecuteCmd (SD_IO_GO_IDLE_STATE, 0, MMC_RSP_NONE, &uByte, sizeof(uByte));
    if (iStatus) {
       printk("%s %d command number: %d failed\n", __FUNCTION__, __LINE__, SD_IO_GO_IDLE_STATE);
       return iStatus;
    }
    iStatus = sdioDrv_ExecuteCmd (SDIO_CMD5, VDD_VOLTAGE_WINDOW, MMC_RSP_R4, &uByte, sizeof(uByte));
    if (iStatus) {
        printk("%s %d command number: %d failed\n", __FUNCTION__, __LINE__, SDIO_CMD5);
        return iStatus; 
    }
    iStatus = sdioDrv_ExecuteCmd (SD_IO_SEND_RELATIVE_ADDR, 0, MMC_RSP_R6, &uLong, sizeof(uLong));
    if (iStatus) {
       printk("%s %d command number: %d failed\n", __FUNCTION__, __LINE__, SD_IO_SEND_RELATIVE_ADDR);
       return iStatus; 
    }
    iStatus = sdioDrv_ExecuteCmd (SD_IO_SELECT_CARD, uLong, MMC_RSP_R6, &uByte, sizeof(uByte));
    if (iStatus) {
       printk("%s %d command number: %d failed\n", __FUNCTION__, __LINE__, SD_IO_SELECT_CARD);
       return iStatus; 
    }

    /* NOTE:
     * =====
     * Each of the following loops is a workaround for a HW bug that will be solved in PG1.1 !!
     * Each write of CMD-52 to function-0 should use it as follows:
     * 1) Write the desired byte using CMD-52
     * 2) Read back the byte using CMD-52
     * 3) Write two dummy bytes to address 0xC8 using CMD-53
     * 4) If the byte read in step 2 is different than the written byte repeat the sequence
     */

    /* set device side bus width to 4 bit (for 1 bit write 0x80 instead of 0x82) */
    do
    {
        uByte = SDIO_BITS_CODE;
        iStatus = sdioDrv_WriteSyncBytes (TXN_FUNC_ID_CTRL, CCCR_BUS_INTERFACE_CONTOROL, &uByte, 1, 1);
        if (iStatus) { return iStatus; }

        iStatus = sdioDrv_ReadSyncBytes (TXN_FUNC_ID_CTRL, CCCR_BUS_INTERFACE_CONTOROL, &uByte, 1, 1);
        if (iStatus) { return iStatus; }
        
        iStatus = sdioDrv_WriteSync (TXN_FUNC_ID_CTRL, 0xC8, &uLong, 2, 1, 1);
        if (iStatus) { return iStatus; }

        uCount++;

    } while ((uByte != SDIO_BITS_CODE) && (uCount < MAX_RETRIES));


    uCount = 0;

    /* allow function 2 */
    do
    {
        uByte = 4;
        iStatus = sdioDrv_WriteSyncBytes (TXN_FUNC_ID_CTRL, CCCR_IO_ENABLE, &uByte, 1, 1);
        if (iStatus) { return iStatus; }

        iStatus = sdioDrv_ReadSyncBytes (TXN_FUNC_ID_CTRL, CCCR_IO_ENABLE, &uByte, 1, 1);
        if (iStatus) { return iStatus; }
        
        iStatus = sdioDrv_WriteSync (TXN_FUNC_ID_CTRL, 0xC8, &uLong, 2, 1, 1);
        if (iStatus) { return iStatus; }

        uCount++;

    } while ((uByte != 4) && (uCount < MAX_RETRIES));


#ifdef SDIO_IN_BAND_INTERRUPT

    uCount = 0;

    do
    {
        uByte = 3;
        iStatus = sdioDrv_WriteSyncBytes (TXN_FUNC_ID_CTRL, CCCR_INT_ENABLE, &uByte, 1, 1);
        if (iStatus) { return iStatus; }

        iStatus = sdioDrv_ReadSyncBytes (TXN_FUNC_ID_CTRL, CCCR_INT_ENABLE, &uByte, 1, 1);
        if (iStatus) { return iStatus; }
        
        iStatus = sdioDrv_WriteSync (TXN_FUNC_ID_CTRL, 0xC8, &uLong, 2, 1, 1);
        if (iStatus) { return iStatus; }

        uCount++;

    } while ((uByte != 3) && (uCount < MAX_RETRIES));


#endif

    uCount = 0;
    
    /* set block size for SDIO block mode */
    do
    {
        uLong = uBlkSize;
        iStatus = sdioDrv_WriteSync (TXN_FUNC_ID_CTRL, FN0_FBR2_REG_108, &uLong, 2, 1, 1);
        if (iStatus) { return iStatus; }

        iStatus = sdioDrv_ReadSync (TXN_FUNC_ID_CTRL, FN0_FBR2_REG_108, &uLong, 2, 1, 1);
        if (iStatus) { return iStatus; }
        
        iStatus = sdioDrv_WriteSync (TXN_FUNC_ID_CTRL, 0xC8, &uLong, 2, 1, 1);
        if (iStatus) { return iStatus; }

        uCount++;

    } while (((uLong & FN0_FBR2_REG_108_BIT_MASK) != uBlkSize) && (uCount < MAX_RETRIES));


    if (uCount >= MAX_RETRIES)
    {
        /* Failed to write CMD52_WRITE to function 0 */
        return (int)uCount;
    }

    /* Disable the clocks for now */
    sdioDrv_clk_disable();

#endif
    return iStatus;
}
ETxnStatus sdioAdapt_Transact (unsigned int  uFuncId,
                               unsigned int  uHwAddr,
                               void *        pHostAddr,
                               unsigned int  uLength,
                               unsigned int  bDirection,
                               unsigned int  bBlkMode,
                               unsigned int  bFixedAddr,
                               unsigned int  bMore)
{
    int iStatus;

#ifdef PROPRIETARY_SDIO
    /* If transction length is below threshold, use Sync methods */
    if (uLength < SYNC_ASYNC_LENGTH_THRESH) 
    {
#endif
        /* Call read or write Sync method */
        if (bDirection) 
        {
            CL_TRACE_START_L2();
            iStatus = sdioDrv_ReadSync (uFuncId, uHwAddr, pHostAddr, uLength, bFixedAddr, bMore);
            CL_TRACE_END_L2("tiwlan_drv.ko", "INHERIT", "SDIO", ".ReadSync");
        }
        else 
        {
            CL_TRACE_START_L2();
            iStatus = sdioDrv_WriteSync (uFuncId, uHwAddr, pHostAddr, uLength, bFixedAddr, bMore);
            CL_TRACE_END_L2("tiwlan_drv.ko", "INHERIT", "SDIO", ".WriteSync");
        }

        /* If failed return ERROR, if succeeded return COMPLETE */
        if (iStatus) 
        {
            return TXN_STATUS_ERROR;
        }
        return TXN_STATUS_COMPLETE;
#ifdef PROPRIETARY_SDIO
    }
#endif

#ifdef PROPRIETARY_SDIO
    /* If transction length is above threshold, use Async methods */
    else 
    {
        /* Call read or write Async method */
        if (bDirection) 
        {
            CL_TRACE_START_L2();
            iStatus = sdioDrv_ReadAsync (uFuncId, uHwAddr, pHostAddr, uLength, bBlkMode, bFixedAddr, bMore);
            CL_TRACE_END_L2("tiwlan_drv.ko", "INHERIT", "SDIO", ".ReadAsync");
        }
        else 
        {
            CL_TRACE_START_L2();
            iStatus = sdioDrv_WriteAsync (uFuncId, uHwAddr, pHostAddr, uLength, bBlkMode, bFixedAddr, bMore);
            CL_TRACE_END_L2("tiwlan_drv.ko", "INHERIT", "SDIO", ".WriteAsync");
        }

        /* If failed return ERROR, if succeeded return PENDING */
        if (iStatus) 
        {
            return TXN_STATUS_ERROR;
        }
        return TXN_STATUS_PENDING;
    }
#endif
}