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; } }
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); }
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 }