sdcontrol.c
来自「该BSP是基于PXA270+WINCE的BSP」· C语言 代码 · 共 1,659 行 · 第 1/5 页
C
1,659 行
SDClockOn( pHc );
}
}
///////////////////////////////////////////////////////////////////////////////
// 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 = SDHCDGetAndLockCurrentRequest(pHCContext, 0)) != NULL)
{
DEBUGMSG(SDCARD_ZONE_WARN, (TEXT("SDHCD:SHCDriver() - aborting current request!\r\n")));
SDHCDIndicateBusRequestComplete(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);
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->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;
#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;
//////////////////////////////////////////////////////////
// Configure GPIO_92 as Alternate Function 1 (MMC_DAT0)
// assume that the MMC_CLK is active-high signal driven
dwRegVal = pHardwareContext->pGPIORegisters->GPSR2;
dwRegVal |= 0x10000000;
pHardwareContext->pGPIORegisters->GPSR2 = dwRegVal;
// change the direction to OUT
dwRegVal = pHardwareContext->pGPIORegisters->GPDR2;
dwRegVal |= 0x10000000;
pHardwareContext->pGPIORegisters->GPDR2 = dwRegVal;
// change to Alternate Function 1
dwRegVal = pHardwareContext->pGPIORegisters->GAFR2_U;
dwRegVal = ( dwRegVal & 0xfcffffff ) | 0x01000000;
pHardwareContext->pGPIORegisters->GAFR2_U = dwRegVal;
//////////////////////////////////////////////////////////
// Configure GPIO_109-GPIO_111 as Alternate Function 1 (MMC_DAT1-MMC_DAT3)
// assume that the MMC_CLK is active-high signal driven
dwRegVal = pHardwareContext->pGPIORegisters->GPSR3;
dwRegVal |= 0x0000e000;
pHardwareContext->pGPIORegisters->GPSR3 = dwRegVal;
// change the direction to OUT
dwRegVal = pHardwareContext->pGPIORegisters->GPDR3;
dwRegVal |= 0x0000e000;
pHardwareContext->pGPIORegisters->GPDR3 = dwRegVal;
// change to Alternate Function 1
dwRegVal = pHardwareContext->pGPIORegisters->GAFR3_L;
dwRegVal = ( dwRegVal & 0x03ffffff ) | 0x54000000;
pHardwareContext->pGPIORegisters->GAFR3_L = dwRegVal;
#ifdef DEBUG
DumpRegisters( pHardwareContext );
DumpGPIORegisters( pHardwareContext );
#endif
// allocate the interrupt event
pHardwareContext->hControllerInterruptEvent = CreateEvent(NULL, FALSE, FALSE,NULL);
if (NULL == pHardwareContext->hControllerInterruptEvent) {
status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
goto exitInit;
}
// convert the hardware SD/MMC controller interrupt IRQ into a logical SYSINTR value
dwSDIOIrq = pHardwareContext->dwSDMMCIrq;
if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &dwSDIOIrq, sizeof(DWORD), &(pHardwareContext->dwSysintrSDMMC), sizeof(DWORD), NULL))
{
// invalid SDIO SYSINTR value!
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("Error obtaining SDIO SYSINTR value!\n")));
pHardwareContext->dwSysintrSDMMC = SYSINTR_UNDEFINED;
goto exitInit;
}
// initialize the interrupt event
if (!InterruptInitialize (pHardwareContext->dwSysintrSDMMC,
pHardwareContext->hControllerInterruptEvent,
NULL,
0)) {
status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?