Exemplo n.º 1
0
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;  
}    
Exemplo n.º 2
0
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;
}