Example #1
0
/*  Driver_SetAddressWindowRegister - Utility function to set the window
 *	 register. This is used for diagnostic reads and writes.
 *      void *pCxt - the driver context.
 *		uint32_t RegisterAddr - The window register address.
 *		uint32_t Address - the target address.
 *****************************************************************************/
static A_STATUS Driver_SetAddressWindowRegister(void *pCxt, uint32_t RegisterAddr, uint32_t Address)
{
    A_STATUS status;
    A_NETBUF_DECLARE req;
    void *pReq = (void *)&req;

    Address = A_CPU2LE32(Address);

    do
    {
        A_NETBUF_CONFIGURE(pReq, (((uint8_t *)(&Address)) + 1), (sizeof(uint32_t) - 1));
        ATH_SET_PIO_EXTERNAL_WRITE_OPERATION(pReq, RegisterAddr + 1, true, (sizeof(uint32_t) - 1));

        if (A_OK != (status = Hcd_DoPioExternalAccess(pCxt, pReq)))
        {
            break;
        }

        A_NETBUF_CONFIGURE(pReq, ((uint8_t *)(&Address)), sizeof(uint8_t));
        ATH_SET_PIO_EXTERNAL_WRITE_OPERATION(pReq, RegisterAddr, true, sizeof(uint8_t));

        if (A_OK != (status = Hcd_DoPioExternalAccess(pCxt, pReq)))
        {
            break;
        }
    } while (0);

    return status;
}
Example #2
0
/*  Driver_WriteRegDiag - Writes four bytes of data to the specified chip
 *	 device address.
 *      void *pCxt - the driver context.
 *		uint32_t address - the device chip address to start the write.
 *		uint8_t *data - the start of data source buffer.
 *****************************************************************************/
A_STATUS
Driver_WriteRegDiag(void *pCxt, uint32_t *address, uint32_t *data)
{
    A_STATUS status;

    A_NETBUF_DECLARE req;
    void *pReq = (void *)&req;

    A_NETBUF_CONFIGURE(pReq, data, 0, sizeof(uint32_t), sizeof(uint32_t));

    ATH_SET_PIO_EXTERNAL_WRITE_OPERATION(pReq, WINDOW_DATA_ADDRESS, true, sizeof(uint32_t));

    do
    {
        if (A_OK != (status = Hcd_DoPioExternalAccess(pCxt, pReq)))
        {
            break;
        }
        /* set window register, which starts the write cycle */
        if (A_OK != (status = Driver_SetAddressWindowRegister(pCxt, WINDOW_WRITE_ADDR_ADDRESS, *address)))
        {
            break;
        }
    } while (0);

    return status;
}
Example #3
0
/*  Driver_SetAddressWindowRegister - Utility function to set the window
 *	 register. This is used for diagnostic reads and writes.
 *      void *pCxt - the driver context.
 *		uint32_t RegisterAddr - The window register address.
 *		uint32_t Address - the target address.
 *****************************************************************************/
static A_STATUS Driver_SetAddressWindowRegister(void *pCxt, uint32_t RegisterAddr, uint32_t Address)
{
    A_STATUS status;
    uint8_t addrValue[4];
    int32_t i;
    A_NETBUF_DECLARE req;
    void *pReq = (void *)&req;

    /* write bytes 1,2,3 of the register to set the upper address bytes, the LSB is written
     * last to initiate the access cycle */
    Address = A_CPU2LE32(Address);

    for (i = 1; i <= 3; i++)
    {
        /* fill the buffer with the address byte value we want to hit 4 times*/
        addrValue[0] = ((uint8_t *)&Address)[i];
        addrValue[1] = addrValue[0];
        addrValue[2] = addrValue[0];
        addrValue[3] = addrValue[0];

        A_NETBUF_CONFIGURE(pReq, (void *)addrValue, 0, 4, 4);
        ATH_SET_PIO_EXTERNAL_WRITE_OPERATION(pReq, RegisterAddr + i, false, 4);

        if (A_OK != (status = Hcd_DoPioExternalAccess(pCxt, pReq)))
        {
            break;
        }
    }

    if (status != A_OK)
    {
        return status;
    }

    A_NETBUF_CONFIGURE(pReq, (void *)&Address, 0, 4, 4);
    ATH_SET_PIO_EXTERNAL_WRITE_OPERATION(pReq, RegisterAddr, true, 4);
    status = Hcd_DoPioExternalAccess(pCxt, pReq);

    return status;
}
Example #4
0
A_STATUS HIFReadWrite(HIF_DEVICE *device, 
                      A_UINT32 address, 
                      A_UCHAR *buffer, 
                      A_UINT32 length, 
                      A_UINT32 request, 
                      void *context) 
{
    SDIO_STATUS status;
    SDREQUEST   *sdrequest;
    BUS_REQUEST *busrequest = NULL;
    A_STATUS    a_status = A_OK;
    
    /* Return any new requests if the shutdown is already in progress */
    if (device->shutdownInProgress) {
        if (request & HIF_ASYNCHRONOUS) {
            device->htcCallbacks.rwCompletionHandler(context, A_ERROR);
            return A_PENDING;
        }
        return A_ERROR;
    }

    AR_DEBUG_ASSERT(device != NULL);
    AR_DEBUG_ASSERT(device->handle != NULL);
    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("Device: %p\n", device));

    if (length > device->curBlockSize) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("Invalid data length: %d\n", length));
        return A_ERROR;
    }

    /* 
     * We do not differentiate between the extended and the basic I/O so 
     * we do not process the request type.
     */

    /*
     * We do not differentiate between the byte and block data mode so
     * we do not process the request dmode.
     */

    do {
        /* Addressing mode */
        if (request & HIF_FIXED_ADDRESS) {
            AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("Address mode: Fixed\n"));
        } else if (request & HIF_INCREMENTAL_ADDRESS) {
            AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("Address mode: Incremental\n"));
        } else {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, 
                            ("Invalid address mode: 0x%08x\n", request));
            a_status = A_ERROR;
            break;
        }

        /* 
         * Mailbox write. Adjust the address so that the last byte 
         * falls on the EOM address.
         */
        if (request & HIF_WRITE) { 
            if ((address >= HIF_MBOX_START_ADDR(0)) && 
                (address <= HIF_MBOX_END_ADDR(3)))
            {
                DBG_ASSERT(length <= HIF_MBOX_WIDTH);
                address += (HIF_MBOX_WIDTH - length);
            }
        }

        /* Allocate a new bus request */ 
        busrequest = hifAllocateBusRequest(device);
        if (busrequest == NULL) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("Unable to allocate bus request\n"));
            a_status = A_ERROR;
            break;
        }
    
        sdrequest = busrequest->request;
        sdrequest->pDataBuffer = buffer;
    
        if (request & HIF_SYNCHRONOUS) {
            AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("Execution mode: Synchronous\n"));
            sdrequest->Flags = SDREQ_FLAGS_RAW;
            sdrequest->pCompleteContext = NULL;
            sdrequest->pCompletion = NULL;
        } else if (request & HIF_ASYNCHRONOUS) {
                /* Populate the bus request to be passed in as context */
            AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("Execution mode: Asynchronous\n"));
                /* setup async context */
            busrequest->device = device;
            busrequest->context = context;
            sdrequest->pCompleteContext = busrequest;
            sdrequest->Flags = SDREQ_FLAGS_RAW | SDREQ_FLAGS_TRANS_ASYNC;
            sdrequest->pCompletion = hifRWCompletionHandler;
        }
        
            /* Indicate to the bus driver if its a read or a write */
        if (request & HIF_WRITE) {
            AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("Direction: Write\n"));
            if (((address >= HIF_MBOX_START_ADDR(0)) &&
                 (address <= HIF_MBOX_END_ADDR(3)))) {  
                
                /* trapping HTC WRITE to mailbox, these will use the special DMA operation */                               
                AR_DEBUG_PRINTF(ATH_DEBUG_TRC, 
                            ("--- MAILBOX WRITE ACCESS!!!!\n"));
                            
                ATH_SET_DMA_OPERATION(sdrequest,ATH_TRANS_WRITE,address,length);

            } else {
                ATH_SET_PIO_EXTERNAL_WRITE_OPERATION(sdrequest,
                                                     address,
                                                     (request & HIF_INCREMENTAL_ADDRESS) ? TRUE : FALSE,
                                                     length);
                
            }       
        } else if (request & HIF_READ) {
            AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("Direction: Read\n"));
            if (((address >= HIF_MBOX_START_ADDR(0)) &&
                 (address <= HIF_MBOX_END_ADDR(3)))) {   
                                     
                 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, 
                            (" --- MAILBOX READ ACCESS!!!!\n"));
                /*  trapping on HTC READ mailbox , these will use the special DMA operation */
               ATH_SET_DMA_OPERATION(sdrequest,ATH_TRANS_READ,address,length);
            } else { 
                ATH_SET_PIO_EXTERNAL_READ_OPERATION(sdrequest,
                                                    address,
                                                    request & HIF_INCREMENTAL_ADDRESS ? TRUE : FALSE,
                                                    length);
            }
            
        } else {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, 
                            ("Invalid direction: 0x%08x\n", request));
            a_status = A_ERROR;
            break;
        }

            /* issue the request */
        status = SDDEVICE_CALL_REQUEST_FUNC(device->handle, sdrequest);
        if (!SDIO_SUCCESS(status)) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, 
                            ("HIF Read/Write failure: %d\n", status));
            a_status = A_ERROR;
        }
       
    } while (FALSE);
    
    if ((busrequest != NULL) && (request & HIF_SYNCHRONOUS)) {
        hifFreeBusRequest(device,busrequest);
    }   

    return a_status;
}