BOOL STREAM_PREFIX(Deinit)(DWORD DeviceContext) { DBG_PRINT(SDDBG_TRACE,("_Deinit called dc:0x%X \n",DeviceContext)); CleanupSPIHW((SDHCD_HW_DEVICE *)DeviceContext); SDIO_BusDeinit(); SDIO_LibraryDeinit(); return TRUE; }
BOOL STREAM_PREFIX(Deinit)(DWORD DeviceContext) { DBG_PRINT(SDDBG_TRACE,("_Deinit called dc:0x%X \n",DeviceContext)); /* unload any attached clients first */ SDIO_BusUnloadClients(); /* cleanup SPI HW layer, this de-registers the host controller */ CleanupSPIHW((SDHCD_HW_DEVICE *)DeviceContext); SDIO_BusDeinit(); SDIO_LibraryDeinit(); return TRUE; }
SDHCD_HW_DEVICE *InitializeSPIHW(PTSTR pRegPath) { PSDHCD_DEVICE pDevice; SDHCD_HW_DEVICE *pHWDevice; DWORD threadId; SDIO_STATUS status = SDIO_STATUS_SUCCESS; do { /* for now this is a static, single instance allocation */ pHWDevice = &g_HWDevice; ZERO_POBJECT(pHWDevice); pDevice = &pHWDevice->SpiCommon; pHWDevice->pDevice = pDevice; /* set the HW portion */ pDevice->pHWDevice = pHWDevice; pHWDevice = GET_HW_DEVICE(pDevice); SET_SDIO_STACK_VERSION(&pDevice->Hcd); pDevice->Hcd.pName = SDIO_RAW_BD_BASE; pDevice->Hcd.Attributes = 0; pDevice->Hcd.pContext = pDevice; pDevice->Hcd.pRequest = HcdRequest; pDevice->Hcd.pConfigure = HcdConfig; /* TODO : adjust these to match controller hardware */ pDevice->OperationalClock = 12000000; /* 12 mhz */ pDevice->Hcd.MaxBytesPerBlock = 4096; /* used as a hint to indicate max size of common buffer */ pDevice->Hcd.MaxBlocksPerTrans = 1; /* must be one*/ pDevice->Hcd.MaxClockRate = 48000000; /* 48 Mhz */ pDevice->PowerUpDelay = 100; /* set all the supported frame widths the controller can do * 8/16/24/32 bit frames */ pDevice->SpiHWCapabilitiesFlags = HW_SPI_FRAME_WIDTH_8 | HW_SPI_FRAME_WIDTH_16 | HW_SPI_FRAME_WIDTH_24 | HW_SPI_FRAME_WIDTH_32; pDevice->MiscFlags |= MISC_FLAG_DUMP_STATE_ON_SHUTDOWN | MISC_FLAG_RESET_SPI_IF_SHUTDOWN; SDLIB_InitializeWorkerTask(&pHWDevice->IOCompleteWorkTask, IOCompleteWork, pHWDevice); pHWDevice->pWorker = SDLIB_CreateWorker(WORKER_THREAD_PRIORITY); if (NULL == pHWDevice->pWorker) { status = SDIO_STATUS_NO_RESOURCES; break; } /* TODO : allocate hardware resources (I/O , interrupt, DMA etc..) */ /*************************************/ status = HcdInitialize(pDevice); /* initialize common layer */ if (!SDIO_SUCCESS(status)) { DBG_PRINT(SDDBG_ERROR, ("SPI - failed to init common layer, status =%d\n", status)); break; } pHWDevice->InitStateMask |= SDHC_COMMON_INIT; /* create the interrupt event */ pHWDevice->hIstEventSPIGpioIRQ = CreateEvent(NULL, FALSE, FALSE, NULL); if (NULL == pHWDevice->hIstEventSPIGpioIRQ) { status = SDIO_STATUS_NO_RESOURCES; break; } /* TODO set appropriate system interrupt for GPIO IRQ, * GPIO IRQ must be level sensitive, active LOW */ pHWDevice->SysIntrSPIGpioIRQ = 0; /* TODO : uncomment the following to associate the GPIO IRQ to the interrupt event : if (!InterruptInitialize(pHWDevice->SysIntrSPIGpioIRQ, pHWDevice->hIstEventSPIGpioIRQ, NULL, 0)) { DBG_PRINT(SDDBG_ERROR,("SPI HCD: Failed to initialize Interrupt! \n")); status = SDIO_STATUS_NO_RESOURCES; break; } */ /* create the IST thread */ pHWDevice->hIstSPIGpioIRQ = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)SpiGpioIRQInterruptThread, (LPVOID)pHWDevice, 0, &threadId); if (NULL == pHWDevice->hIstSPIGpioIRQ) { status = SDIO_STATUS_NO_RESOURCES; DBG_PRINT(SDDBG_ERROR,("SPI HCD: Failed to Create IST! \n")); break; } /* register with the SDIO bus driver */ if (!SDIO_SUCCESS((status = SDIO_RegisterHostController(&pDevice->Hcd)))) { DBG_PRINT(SDDBG_ERROR, ("SPI HCD: Probe - failed to register with host, status =%d\n",status)); break; } pHWDevice->InitStateMask |= SDHC_REGISTERED; } while (FALSE); if (!SDIO_SUCCESS(status)) { if (pHWDevice != NULL) { CleanupSPIHW(pHWDevice); pHWDevice = NULL; } } else { DBG_PRINT(SDDBG_ERROR, ("SPI - HCD ready! \n")); } DBG_PRINT(SDDBG_TRACE, ("-SPI HCD: Setup - status : %d\n", status)); return SDIO_SUCCESS(status) ? pHWDevice : NULL; }