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

📄 sdcontrol.c

📁 Windows CE 6.0 BSP for VOIP sample phone. Intel PXA270 platform.
💻 C
📖 第 1 页 / 共 5 页
字号:
    SDClockOff(pHc);

    rate = *pRate;
    if( rate > pHc->dwMaximumSDClockFrequency )
        rate = pHc->dwMaximumSDClockFrequency;
   
        // check to see if the rate is below the first entry in the table
    if (rate <= SDClockTable[0].Frequency) {
        ii = 0;
    } else {

            // scan through the table looking for a frequency that
            // is close to the requested rate
        for (ii = 0; ii < (NUM_CLOCK_ENTRIES - 1); ii++) {
            if ((rate >= SDClockTable[ii].Frequency) &&
                (rate < SDClockTable[ii+1].Frequency)) {
                break;
            } 
        }
    }

    DbgPrintZo(SDH_CLOCK_ZONE, (TEXT("SDClockOn - Requested Rate: %d, Setting clock rate to %d Hz \n"),
           *pRate, SDClockTable[ii].Frequency ));

        // return the actual fruency
    *pRate = SDClockTable[ii].Frequency;

         // set the clock rate
    WRITE_MMC_REGISTER_DWORD(pHc, MMC_CLKRT, SDClockTable[ii].ControlValue);
    pHc->dwSDClockFrequency = SDClockTable[ii].Frequency;
        
    if( fClockRunning )
    {
        SDClockOn( pHc );
    }
}
static BOOL IndicateBusRequestComplete(PSDCARD_HC_CONTEXT pHCContext,
                                    PSD_BUS_REQUEST pRequest,
                                    SD_API_STATUS      Status)
{
    BOOL fRet = FALSE;
    PSDH_HARDWARE_CONTEXT pController = GetExtensionFromHCDContext(PSDH_HARDWARE_CONTEXT, pHCContext);
    if (pController && pController->pCurrentRequest == pRequest) {
        DbgPrintZo(SDH_SDBUS_INTERACTION_ZONE, (TEXT("IndicateBusRequestComplete - pRequest = %x, Status = %d\n"),pRequest,Status));
        pController->pCurrentRequest = NULL;
        if (pController->fCurrentRequestFastPath ) {
            if (Status == SD_API_STATUS_SUCCESS) {
                Status = SD_API_STATUS_FAST_PATH_SUCCESS;
            }
            pController->FastPathStatus = Status ;
        }
        else 
            SDHCDIndicateBusRequestComplete(pHCContext,pRequest,Status);
        fRet = TRUE;
    }
    ASSERT(fRet);
    return fRet;
}


///////////////////////////////////////////////////////////////////////////////
//  SDDeInitialize - Deinitialize the the MMC Controller
//  Input:  pHCContext - Host controller context
//          
//  Output: 
//  Return: SD_API_STATUS code
//  Notes:  
//         
//
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS SDDeinitialize(PSDCARD_HC_CONTEXT pHCContext)
{
    PSDH_HARDWARE_CONTEXT pHardwareContext; // hardware context
    PSD_BUS_REQUEST     pRequest = NULL;       // the request to complete

    pHardwareContext = GetExtensionFromHCDContext(PSDH_HARDWARE_CONTEXT, pHCContext);

        // mark for shutdown
    pHardwareContext->DriverShutdown = TRUE;

    if( pHardwareContext->hControllerInterruptEvent )
    {
        // wake up the controller IST
        SetEvent(pHardwareContext->hControllerInterruptEvent);
    }

    if (NULL != pHardwareContext->hDMAInterruptEvent) 
    {
        // wake up the DMA IST
        SetEvent(pHardwareContext->hDMAInterruptEvent);
    }

    // clean up controller IST
    if (NULL != pHardwareContext->hControllerInterruptThread) {
            // wait for the thread to exit
        WaitForSingleObject(pHardwareContext->hControllerInterruptThread, INFINITE); 
        CloseHandle(pHardwareContext->hControllerInterruptThread);
        pHardwareContext->hControllerInterruptThread = NULL;
    }
        
    // clean up DMA IST
    if (NULL != pHardwareContext->hDmaInterruptThread) {
        // wait for the thread to exit
        WaitForSingleObject(pHardwareContext->hDmaInterruptThread, INFINITE); 
        CloseHandle(pHardwareContext->hDmaInterruptThread);
        pHardwareContext->hDmaInterruptThread = NULL;
    }
        
        // free controller interrupt event
    if (NULL != pHardwareContext->hControllerInterruptEvent) {
        CloseHandle(pHardwareContext->hControllerInterruptEvent);
        pHardwareContext->hControllerInterruptEvent = NULL;
    }

        // free the DMA interrupt event
    if( pHardwareContext->hDMAInterruptEvent )
    {
        CloseHandle(pHardwareContext->hDMAInterruptEvent);
        pHardwareContext->hDMAInterruptEvent = NULL;
    }

        // make sure all interrupt sources are disabled
    if( pHardwareContext->dwSysintrSDMMC != SYSINTR_UNDEFINED )
    {
        InterruptDisable (pHardwareContext->dwSysintrSDMMC);
        KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR, &pHardwareContext->dwSysintrSDMMC, sizeof(DWORD), NULL, 0, NULL);
        pHardwareContext->dwSysintrSDMMC = SYSINTR_UNDEFINED;
    }
    if( pHardwareContext->dwDmaSysIntr != SYSINTR_UNDEFINED )
    {
        InterruptDisable (pHardwareContext->dwDmaSysIntr);
        KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR, &pHardwareContext->dwDmaSysIntr, sizeof(DWORD), NULL, 0, NULL);
        pHardwareContext->dwDmaSysIntr = SYSINTR_UNDEFINED;
    }

        // unload the DMA ISR DLL
    if( pHardwareContext->hDMAIsrHandler )
    {
        FreeIntChainHandler(pHardwareContext->hDMAIsrHandler);
        pHardwareContext->hDMAIsrHandler = NULL;
    }

        // free the DMA buffer
    if( pHardwareContext->pDMABuffer )
    {
        HalFreeCommonBuffer( NULL, 0, pHardwareContext->pDMABufferPhys, pHardwareContext->pDMABuffer, FALSE );
        pHardwareContext->pDMABuffer = NULL;
        pHardwareContext->dwDmaBufferSize = 0;
    }

        // free the DMA descriptors buffer
    if( pHardwareContext->pDMADescriptors )
    {
        DEBUGMSG(SDCARD_ZONE_WARN, (TEXT("SHCDriver: - Unable to allocate memory for DMA descriptors!\r\n")));
        HalFreeCommonBuffer( NULL, 0, pHardwareContext->pDMADescriptorsPhys, (PVOID)pHardwareContext->pDMADescriptors, FALSE );
        pHardwareContext->pDMADescriptors = NULL;
    }

        // clean up card insertion IST and free card insertion interrupt
    CleanupCardDetectIST();

        // turn the hardware off
    SDClockOff( pHardwareContext );
    MMCPowerControl( FALSE );

        // if there is a pending request, cancel it
    if( pHardwareContext && (pRequest = pHardwareContext->pCurrentRequest) != NULL)
    {
        DEBUGMSG(SDCARD_ZONE_WARN, (TEXT("SDHCD:SHCDriver() - aborting current request!\r\n")));
        IndicateBusRequestComplete(pHCContext, pRequest, SD_API_STATUS_SHUT_DOWN);
    }


        // If a card is inserted, signal that it was ejected...
    if(pHardwareContext && pHardwareContext->DevicePresent)
    {
        // indicate the slot change 
        SDHCDIndicateSlotStateChange(pHCContext, 0, DeviceEjected); 
        pHardwareContext->DevicePresent = FALSE;
    }

        // free memory mapped resources

    if (NULL != pHardwareContext->pSDMMCRegisters) {
        MmUnmapIoSpace((PVOID)pHardwareContext->pSDMMCRegisters, sizeof(BULVERDE_MMC_REG));
        pHardwareContext->pSDMMCRegisters = NULL;
    }

    if (NULL != pHardwareContext->pGPIORegisters) {
        MmUnmapIoSpace((PVOID)pHardwareContext->pGPIORegisters, sizeof(BULVERDE_GPIO_REG));
        pHardwareContext->pGPIORegisters = NULL;
    }

    if (NULL != pHardwareContext->pClkMgrRegisters) {
        MmUnmapIoSpace((PVOID)pHardwareContext->pClkMgrRegisters, sizeof(BULVERDE_CLKMGR_REG));
        pHardwareContext->pClkMgrRegisters = NULL;
    }

    if (NULL != pHardwareContext->pDMARegisters) {
        MmUnmapIoSpace((PVOID)pHardwareContext->pDMARegisters, sizeof(BULVERDE_DMA_REG));
        pHardwareContext->pDMARegisters = NULL;
    }

    if(NULL != pHardwareContext->hBusAccessHandle) {
        CloseBusAccessHandle(pHardwareContext->hBusAccessHandle);
        pHardwareContext->hBusAccessHandle = NULL;
    }
    UnInitializeHardware();

    DeleteCriticalSection(&pHardwareContext->ControllerCriticalSection);
    DeleteCriticalSection(&pHardwareContext->intrRegCriticalSection);

    return SD_API_STATUS_SUCCESS;
}


///////////////////////////////////////////////////////////////////////////////
//  SDInitialize - Initialize the the MMC Controller
//  Input:  pHardwareContext - newly allocated hardware context
//          
//  Output: 
//  Return: SD_API_STATUS code
//  Notes:  
//          
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS SDInitialize(PSDCARD_HC_CONTEXT pHCContext)
{
    ULONG fInIOSpace;
    DWORD dwSDIOIrq;
    DWORD dwRegVal;                                 // intermediate value
    SD_API_STATUS status = SD_API_STATUS_SUCCESS;   // intermediate status
    DWORD         threadID;                         // thread ID
    PSDH_HARDWARE_CONTEXT pHardwareContext;       // hardware context
    PHYSICAL_ADDRESS Bulverde_GPIO_Base = {BULVERDE_BASE_REG_PA_GPIO};
    PHYSICAL_ADDRESS Bulverde_SDMMC_Base = {BULVERDE_BASE_REG_PA_MMC};
    PHYSICAL_ADDRESS Bulverde_CLKMGR_Base = {BULVERDE_BASE_REG_PA_CLKMGR};
    PHYSICAL_ADDRESS Bulverde_DMA_Base = {BULVERDE_BASE_REG_PA_DMAC};

    pHardwareContext = GetExtensionFromHCDContext(PSDH_HARDWARE_CONTEXT, pHCContext);

    InitializeCriticalSection(&pHardwareContext->ControllerCriticalSection);

    pHardwareContext->fSDIOEnabled = FALSE;
    pHardwareContext->pCurrentRequest = NULL ;
    pHardwareContext->fSDIOInterruptPending = FALSE;
    pHardwareContext->f4BitMode = FALSE;
    pHardwareContext->DevicePresent = FALSE;
    pHardwareContext->hDMAInterruptEvent = NULL;
    pHardwareContext->hDMAIsrHandler = NULL;
    pHardwareContext->DriverShutdown = FALSE;
    pHardwareContext->hDMAInterruptEvent = NULL;
    pHardwareContext->hDmaInterruptThread = NULL;
    pHardwareContext->pDMABuffer = NULL;
    pHardwareContext->pDMADescriptors = NULL;
    pHardwareContext->dwControllerIstTimeout = INFINITE;
    InitializeCriticalSection(&pHardwareContext->intrRegCriticalSection);

#ifdef DEBUG
    pHardwareContext->fDMATransferInProgress = FALSE;
#endif
    
    GetSystemInfo( &pHardwareContext->systemInfo );

    if( !InitializeHardware( pHardwareContext->hBusAccessHandle ) )
    {
		DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("InitializeHardware:: Error initializing platform specific hardware\r\n")));
        goto exitInit;
    }

    if( !BusTransBusAddrToVirtual( pHardwareContext->hBusAccessHandle, Internal, 0, Bulverde_GPIO_Base, sizeof(BULVERDE_GPIO_REG), &fInIOSpace, (PPVOID)&(pHardwareContext->pGPIORegisters) ) )
	{
		DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("InitializeHardware:: Error allocating Bulverde GPIO registers\r\n")));
        goto exitInit;
	}

    if( !BusTransBusAddrToVirtual( pHardwareContext->hBusAccessHandle, Internal, 0, Bulverde_SDMMC_Base, sizeof(BULVERDE_MMC_REG), &fInIOSpace, (PPVOID)&(pHardwareContext->pSDMMCRegisters) ) )
	{
		DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("InitializeHardware:: Error allocating Bulverde SD/MMC registers\r\n")));
        goto exitInit;
	}

    if( !BusTransBusAddrToVirtual( pHardwareContext->hBusAccessHandle, Internal, 0, Bulverde_CLKMGR_Base, sizeof(BULVERDE_CLKMGR_REG), &fInIOSpace, (PPVOID)&(pHardwareContext->pClkMgrRegisters) ) )
	{
		DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("InitializeHardware:: Error allocating Bulverde Clock control registers\r\n")));
        goto exitInit;
	}

    if( !BusTransBusAddrToVirtual( pHardwareContext->hBusAccessHandle, Internal, 0, Bulverde_DMA_Base, sizeof(BULVERDE_DMA_REG), &fInIOSpace, (PPVOID)&(pHardwareContext->pDMARegisters) ) )
	{
		DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("InitializeHardware:: Error allocating Bulverde DMA control registers\r\n")));
        goto exitInit;
	}

    // enable the MMC Unit Clock
    dwRegVal = pHardwareContext->pClkMgrRegisters->cken;
    dwRegVal |= (1 << 12);
    pHardwareContext->pClkMgrRegisters->cken = dwRegVal;

    //////////////////////////////////////////////////////////
    // Configure GPIO_32 as Alternate Function 2 out (MMC_CLK)

    // assume that the MMC_CLK is active-low signal driven
    dwRegVal = pHardwareContext->pGPIORegisters->GPCR1;
    dwRegVal |= 0x00000001;
    pHardwareContext->pGPIORegisters->GPCR1 = dwRegVal;
    // change the direction to OUT
    dwRegVal = pHardwareContext->pGPIORegisters->GPDR1;
    dwRegVal |= 0x00000001;
    pHardwareContext->pGPIORegisters->GPDR1 = dwRegVal;
    // change to Alternate Function 2
    dwRegVal = pHardwareContext->pGPIORegisters->GAFR1_L;
    dwRegVal = ( dwRegVal & 0xfffffffc ) | 0x00000002;
    pHardwareContext->pGPIORegisters->GAFR1_L = dwRegVal;
    
    //////////////////////////////////////////////////////////
    // Configure GPIO_112 as Alternate Function 1 (MMC_CMD)

    // assume that the MMC_CLK is active-high signal driven
    dwRegVal = pHardwareContext->pGPIORegisters->GPSR3;
    dwRegVal |= 0x00010000;
    pHardwareContext->pGPIORegisters->GPSR3 = dwRegVal;
    // change the direction to OUT
    dwRegVal = pHardwareContext->pGPIORegisters->GPDR3;
    dwRegVal |= 0x00010000;
    pHardwareContext->pGPIORegisters->GPDR3 = dwRegVal;
    // change to Alternate Function 1
    dwRegVal = pHardwareContext->pGPIORegisters->GAFR3_U;
    dwRegVal = ( dwRegVal & 0xfffffffc ) | 0x00000001;
    pHardwareContext->pGPIORegisters->GAFR3_U = dwRegVal;
    
    //////////////////////////////////////////////////////////

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -