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; }
BOOL hifDeviceInserted(SDFUNCTION *function, SDDEVICE *handle) { A_UINT32 count; HIF_DEVICE *device; BOOL accepted = FALSE; AR_DEBUG_ASSERT(function != NULL); AR_DEBUG_ASSERT(handle != NULL); do { device = (HIF_DEVICE *)KernelAlloc(sizeof(HIF_DEVICE)); if (NULL == device) { break; } AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("Device: %p\n", device)); ZERO_POBJECT(device); CriticalSectionInit(&device->lock); device->busrequestfreelist = NULL; device->handle = handle; device->enabledSpiInts = ATH_SPI_INTR_PKT_AVAIL | ATH_SPI_INTR_CPU_INTR; /* set the IRQ Handler which associates the instance with the SDDEVICE */ SDDEVICE_SET_IRQ_HANDLER(device->handle, hifIRQHandler, device); AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("Device: %p\n", device)); if (handle->pId[0].CardFlags & CARD_RAW) { if (strstr(SDDEVICE_GET_HCDNAME(handle), SDIO_RAW_BD_BASE) == NULL) { /* Not supported */ break; } } /* Card identification */ AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("SPI card: %s\n", SDDEVICE_GET_HCDNAME(handle))); /* Version information */ AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("Stack version: %d.%d\n", SDDEVICE_GET_VERSION_MAJOR(handle), SDDEVICE_GET_VERSION_MINOR(handle))); /* Get the maximum block size supported */ AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("Maximum block length: %d bytes\n", SDDEVICE_GET_MAX_BLOCK_LEN(handle))); device->curBlockSize = SDDEVICE_GET_OPER_BLOCK_LEN(handle); AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("Current block length: %d bytes\n", device->curBlockSize)); /* Allocate the bus requests to be used later */ for (count = 0; count < BUS_REQUEST_MAX_NUM_TOTAL; count ++) { if ((device->busrequestblob[count].request = SDDeviceAllocRequest(handle)) == NULL){ AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("Unable to allocate bus request\n")); break; } /* free to the list */ hifFreeBusRequest(device, &device->busrequestblob[count]); } if (count != BUS_REQUEST_MAX_NUM_TOTAL) { break; } /* Configure the SPI interface */ if ((hifConfigureSPI(device)) != A_OK) { AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("Failed to configure the device\n")); break; } /* Inform HTC */ if ((osdrvCallbacks.deviceInsertedHandler(osdrvCallbacks.context, (void *)device)) != A_OK) { AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("Device rejected\n")); return FALSE; } accepted = TRUE; } while (FALSE); if (!accepted & (device != NULL)) { /* cleanup device */ hifCleanupDevice(device); } return accepted; }