Beispiel #1
0
/**
 *  \brief Close Instance of the I2C device
 *
 *  This function closes the device for data transfers and usage by the
 *  upper layer driver software. The hardware is programmed to stop/abort data
 *  transfer (depending upon the type of device and its specifics) and the
 *  device ISR is "disabled" by the upper layer driver software after the
 *  completion of this call. After the successful completion of this call, the
 *  device cannot perform any data IO.
 *
 *  \param  handle [IN]         I2C Driver Instance Handle
 *  \return PSP_SOK or PSP Error code
 */
PSP_Result PSP_i2cClose(PSP_Handle handle)
{
    DDC_I2cDriverObject   *pi2cHandle;
    DDC_I2cObject *i2cObj;
    Uint32 cookie;
    Int retVal;
    Int retCode;

    retVal  = PSP_SOK;
    retCode = 0;
    /* Check state of handle */
    if (handle == NULL) {
        retVal = (PSP_E_INVAL_PARAM);
    }
    else {
        pi2cHandle = (DDC_I2cDriverObject *)handle;
        if (pi2cHandle == ((DDC_I2cDriverObject *) NULL)) {
            retVal = (PSP_E_INVAL_PARAM);
        }
        else {
            i2cObj =  pi2cHandle->pi2cInstHandle;
            if (i2cObj == ((DDC_I2cObject *) NULL)) {
                retVal = (PSP_E_INVAL_PARAM);
            }
            else {
                /* Check for the validity of the I2C STATE */
                if ( i2cObj->state != I2C_OPENED ) {
                    retVal = (PSP_E_INVAL_STATE);
                }
            }
        }
    }

    if (retVal == PSP_SOK) {
        /*  Check for any IO is pending, if yes then cancel io */
        if ( i2cObj->pendingState == TRUE ){
                retCode = PSP_i2cIoctl(handle,PSP_I2C_IOCTL_CANCEL_PENDING_IO, NULL, NULL);
                if(retCode != PSP_SOK){
                    retVal = retCode;
                }
        }
        /* Start of Critical Section */
        PAL_osProtectEntry(PAL_OSPROTECT_INTERRUPT, &cookie);
        /* Decrease the Number of Opens */
        i2cObj->numOpens = i2cObj->numOpens - 1u;
        pi2cHandle->pi2cInstHandle = NULL;
        pi2cHandle = NULL;

        PAL_osProtectExit(PAL_OSPROTECT_INTERRUPT, cookie);
        if (i2cObj->numOpens == 0)
        {
            /* Put the device in reset and quit */
            i2cObj->i2cRegs->ICMDR = 0;
            i2cObj->state = I2C_CLOSED;
        }
    }/* retVal */
    return (retVal);
}
Beispiel #2
0
/*! \fn int DbridgeEsafe_AddNetDev(struct net_device* ptr_net_dev,
 *                                  unsigned int esafe_type,int (*push)(struct sk_buff* skb))                                     
 **************************************************************************
 *  \brief Connect target device interface to esafe (EMTA,EPS,ESTB_IP,ESTB_DSG,ETEA)
 *  \param[in] ptr_net_dev - pointer to target  device interface.
 *  \param[in] esafe_type - EMTA -1, EPS -2, ESTB_IP-3, ESTB_DSG-4 ,ETEA-5.
 *  \param[in] push - push function to send packet from esafe to target device interface.
 *  \return OK=0 or error status.
 **************************************************************************/
int DbridgeEsafe_AddNetDev(struct net_device* ptr_net_dev,unsigned int esafe_type,int (*push)(struct sk_buff* skb))
{
	Uint32 lockKey;
    int res = -1;
	PAL_osProtectEntry(PAL_OSPROTECT_INTERRUPT, &lockKey);

    if (esafe_table_insert < DBR_MAX_ESAFE_INTERFACES)
    {
        if (ptr_net_dev)
        {
            /* create and register esafe interface */
            struct net_device *esafe_net_device;
            esafe_net_device = DbridgeEsafe_CreateDev(esafe_table_insert);
            if (esafe_net_device)
            {
                DbridgeDb_DevAdd(esafe_net_device,DbridgeEsafe_NetifReceive,DBR_ESAFE_NET_DEV_TYPE);
                DbridgeEsafeDeviceTable[esafe_table_insert].ptr_esafeInterface = esafe_net_device;
                DbridgeEsafeDeviceTable[esafe_table_insert].ptr_targetInterface = ptr_net_dev;
                DbridgeEsafeDeviceTable[esafe_table_insert].dbridgeDevice = DbridgeDb_DevGetByInterface(esafe_net_device);
                DbridgeEsafeDeviceTable[esafe_table_insert].eSafeType = esafe_type;
                DbridgeEsafeDeviceTable[esafe_table_insert].push = push;
                esafe_table_insert++;
                rtnl_lock();
                res = dev_open(esafe_net_device);
                rtnl_unlock();
                if (res == 0)
                {
                    PAL_osProtectExit(PAL_OSPROTECT_INTERRUPT, lockKey);
                    return res;
                }
                else
                    printk(KERN_WARNING "DUnable to open device %s\n",esafe_net_device->name);
            }
            else
            {
                printk(KERN_WARNING "DbridgeEsafe_CreateDev Fail\n");    
            }
        }
        else
        {
            printk(KERN_WARNING "input ptr_net_dev is NULL\n");    
        }
    }
    else
    {
        printk(KERN_WARNING "Device table is full\n");    
    }
    PAL_osProtectExit(PAL_OSPROTECT_INTERRUPT, lockKey);
    return res;
}
Beispiel #3
0
/** I2C driver Transfer [internal to DDC where actual transfer happens]
 *
 *  This is the function in which a tuall data transfer happens.
 *  In this function it validates input parameters set the parameter values in
 *  to the registers and starts transmission
 *
 * \param       handle     [IN]     I2C Driver Instance Handle
 * \param       slaveAddr  [IN]     Slave address (only valid in Master mode)
 * \param       buffer     [IN]     Buffer (to read into or write from)
 * \param       bufLen     [IN]     Buffer length - number of bytes to transact
 * \param       flags      [IN]     Flags to specify mode of operation
 * \param       timeout    [IN]     Timeout for i2c transaction
 * \param       param      [IN]     Extra paramter for future usage
 * \param       xferActual [IN]     Gives number of bytes actually transferred
 *
 * \return      Interger Value > 0 - Number of bytes transferred.
 *
 */
static Int DDC_i2cTransfer (PSP_Handle handle,
                     Uint32     slaveAddr,
                     Uint16     *buffer,
                     Uint32     bufLen,
                     Uint32     flags,
                     Int32      timeout,
                     Ptr        param,
                     Ptr        xferActual)
{
    DDC_I2cObject   *i2cObj;
    Uint32          cnt;
    Uint32          icmdr;
    Uint32          status;
    PSP_Result      retCode;
    Uint32          cookie;
    Int             retVal;
    volatile Uint16    looper;
#ifdef BIOS_BUILD
    Uint32          timeCnt;
#endif

    cnt = 0;
    icmdr = 0;
    retCode = 0;
    retVal = 0;

    /* Check the state of handle */
    if (((handle == NULL) || (buffer == NULL)) || (xferActual == NULL)) {
        retVal = (PSP_E_INVAL_PARAM);
    }
    else {
        i2cObj =  (DDC_I2cObject *) handle;
        if (i2cObj == ((DDC_I2cObject *) NULL)) {
            retVal = (PSP_E_INVAL_PARAM);
        }
        /* Check user has not set both read and write flag at same time*/
        else if (((flags & PSP_I2C_READ) != 0) && ((flags & PSP_I2C_WRITE) != 0)) {
            retVal = (PSP_E_INVAL_PARAM);
        }
        else if ( ( (buffer == NULL) || (bufLen == 0) ) ||
                    (bufLen > DDC_I2C_BUFFER_MAXLENGTH) ) {
            retVal = (PSP_E_INVAL_PARAM);
        }
        else if (i2cObj->repeatMode == TRUE) {
            if ( (bufLen > 0) && ((flags & PSP_I2C_STOP) != 0)) {
                retVal = (PSP_E_INVAL_PARAM);
            }
        }
        else {
            /* Check for Bus Busy if not restarting */
            if (((flags & PSP_I2C_RESTART) == 0) && ((flags & PSP_I2C_IGNORE_BUS_BUSY) == 0)) {
                /* Loop on busy condition */
                if (i2cObj->mode == PSP_OPMODE_POLLED) {
                    retCode = i2cWaitForBB(i2cObj, PSP_I2C_BUS_BUSY_TIMEOUT_CNT, 0);
                    if ( retCode != 0 ) {
                        retVal = (PSP_I2C_BUS_BUSY_ERR);
                    }
                } else {
                    retCode = i2cWaitForBB(i2cObj, PSP_I2C_BUS_BUSY_TIMEOUT_MSECS, 1u);
                    if ( retCode != 0 ) {
                        retVal = (PSP_I2C_BUS_BUSY_ERR);
                    }
                }
                /* Enters this condition if i2c bus is busy */
            }
        } /* else */
    } /* retVal */

    if (retVal == 0) {
        /* Set count for data transfer and init mode control register */
        i2cObj->i2cRegs->ICCNT = (bufLen & DDC_I2C_BUFFER_MAXLENGTH);

        /* Check flags and set accordingly */
        if ((flags & PSP_I2C_MASTER)  != 0) {
            i2cObj->i2cRegs->ICMDR |= CSL_I2C_ICMDR_MST_MASK;
        }
        if ((flags & PSP_I2C_START)  != 0) {
            icmdr |= CSL_I2C_ICMDR_STT_MASK;
        }
        if ((flags & PSP_I2C_STOP) != 0) {
            icmdr |= CSL_I2C_ICMDR_STP_MASK;
        }
        if ((flags & PSP_I2C_WRITE) != 0) {
            i2cObj->i2cRegs->ICMDR |= CSL_I2C_ICMDR_TRX_MASK;
        }
        if ((flags & PSP_I2C_READ) != 0) {
            i2cObj->i2cRegs->ICMDR &= ~CSL_I2C_ICMDR_TRX_MASK;
        }

        /* Write slave address - restrict to 10 bits */
        i2cObj->i2cRegs->ICSAR = (((Uint)slaveAddr) & DDC_I2C_SLAVEADRR_10BIT);
        /* Check if restart required to set the bus busy */
        if ((flags & PSP_I2C_RESTART) != 0) {
            i2cObj->i2cRegs->ICSTR |= CSL_I2C_ICSTR_BB_MASK;
            icmdr |= CSL_I2C_ICMDR_STT_MASK;
        }
        /* To make transaction is in progress */
        i2cObj->pendingState = TRUE;
        /* If polled mode, wait for data transfer and completion,
         * else wait (on a semaphore) for transaction to complete */
        if (i2cObj->mode == PSP_OPMODE_POLLED)
        {
            i2cObj->i2cRegs->ICIMR = 0;        /* Mask all interrupts - :)
                                                * just to make sure */
            i2cObj->i2cRegs->ICMDR |= icmdr;    /* Start bit set here to
                                                * start transaction */
#ifdef BIOS_BUILD
            timeCnt = PAL_osGetCurrentTick();
#endif

            while (cnt < bufLen)
            {
                if ( retCode == 0 )
                {
                    if ((flags & PSP_I2C_WRITE) != 0)
                    {
                        /* Transmit */
                        if ((i2cObj->i2cRegs->ICSTR & CSL_I2C_ICSTR_ICXRDY_MASK) != 0) {
                            i2cObj->i2cRegs->ICDXR = (*buffer & 0x00FF); /* Transmit 8-bit data */
                            buffer = buffer + 1u;
                            cnt = cnt + 1u;
                        }

                    } else {
                        /* Receive */
                        if ((i2cObj->i2cRegs->ICSTR & CSL_I2C_ICIMR_ICRRDY_MASK) != 0) {
                            *buffer = (Uint8) i2cObj->i2cRegs->ICDRR;
                            buffer = buffer + 1u;
                            cnt = cnt + 1u;
                        }
                    }

                    /* Check for Arbitration loss, transmit underflow and
                     * receive overflow errors */
                    status = i2cObj->i2cRegs->ICSTR;
                    if ((status & CSL_I2C_ICSTR_AL_MASK) != 0) {
                        retCode = PSP_I2C_ARBITRATION_LOSS_ERR;
                    }
                    else if ((status & CSL_I2C_ICSTR_RSFULL_MASK) != 0) {
                        retCode = PSP_I2C_RECEIVE_OVERFLOW_ERR;
                    }
                    /* Check for NACK error
                     */
                    else{
                        if ((status & CSL_I2C_ICSTR_NACK_MASK) != 0){
                            retCode = PSP_I2C_NACK_ERR;
                         }
                    }
                }
                else
                {
                    if (retCode == PSP_SOK) {
                        retCode = PSP_E_TIMEOUT;
                    }
                    break;
                }
//                PAL_osWaitMsecs(1u);
                for(looper = 0;looper < 2000;looper++)
                {
                    asm("\tNOP;");
                }
            } /* While number of byte to be transmitted/received loop */
        } /* if polled mode */
        else
        {
            /* Set the current buffer params correctly */
            i2cObj->currError = 0;
            i2cObj->currFlags = flags;
            i2cObj->currBuffer = (buffer+cnt);
            i2cObj->currBufferLen = (bufLen-cnt);

            if (i2cObj->currBufferLen > 0) {
                /* Enable interrupts */
                i2cObj->i2cRegs->ICIMR = ( CSL_I2C_ICIMR_AL_MASK |
                                                /* Arbitration lost */
                                        CSL_I2C_ICIMR_NACK_MASK |
                                                /* NACK received/not received */
                                        CSL_I2C_ICIMR_AAS_MASK);
                                                /* Addressed as Slave */

            if ((flags & PSP_I2C_WRITE) != 0){
                    i2cObj->i2cRegs->ICIMR |= CSL_I2C_ICIMR_ICXRDY_MASK ;
                                                        /* Transmit ready */
                }else if((flags & PSP_I2C_READ) != 0){
                    i2cObj->i2cRegs->ICIMR |= CSL_I2C_ICIMR_ICRRDY_MASK ;
            }                                       /* Receive ready */

                /* Start I2C transaction */
                i2cObj->i2cRegs->ICIVR = 0; /* Clear IVR before doing a start */
                i2cObj->i2cRegs->ICMDR |= icmdr; /* Start bit set here to start
                                                 * transaction */

                /* Take completion semaphore */
                retCode = PAL_osSemTake(i2cObj->completionSem,
                                    _DDA_i2cOsGetTicks( timeout) );
                if (retCode != PAL_SOK) {
                    /* Entry of Critical Section */
                    PAL_osProtectEntry(PAL_OSPROTECT_INTERRUPT, &cookie);
                    cnt = bufLen - i2cObj->currBufferLen;
                    i2cObj->currBufferLen = 0 ;
                    i2cObj->currBuffer = NULL;
                    i2cObj->currError = PSP_E_TIMEOUT;
                    i2cObj->i2cRegs->ICIMR &= ~CSL_I2C_ICIMR_ICXRDY_MASK;
                                                    /* Disable Transmit interrupt */
                    i2cObj->i2cRegs->ICIMR &= ~CSL_I2C_ICIMR_ICRRDY_MASK;
                                                    /* Disable Receive interrupt */

                    /*wait till data is shifted out of shift register*/
                    if ((flags & PSP_I2C_WRITE) != 0) {
                        while (( (i2cObj->i2cRegs->ICSTR) & (CSL_I2C_ICSTR_ICXRDY_MASK) ) == 0) {
                        }
                    }
                    /*Put the module in reset mode*/
                    i2cObj->i2cRegs->ICMDR &= ~( DDC_I2C_RESET);
                    /*Bring the module out of reset*/
                    i2cObj->i2cRegs->ICMDR |=  DDC_I2C_RESET;
                    /* Exit of Critical Section */
                    PAL_osProtectExit(PAL_OSPROTECT_INTERRUPT, cookie);
                } else {
                    /* Return error code (if error) or number of bytes transmitted */
                    retCode = i2cObj->currError;
                    /* Disable the interrupts once it comes out of ISR */
                    i2cObj->i2cRegs->ICIMR = 0;
                }
            }
            /* Return error code (if error) or number of bytes transmitted */
            cnt = bufLen - i2cObj->currBufferLen;
        }
#ifdef BIOS_BUILD
        if (1u == bufLen) {
            timeCnt = PAL_osGetCurrentTick();
            /* This Delay is given to ensure whether there is check for any errors */
             while(FALSE == PAL_osCheckTimeOut(timeCnt,1)){
            }
        }
#endif
        /* Check for Arbitration loss, transmit underflow and
         * receive overflow errors( this checking is for the reason that updating
         * ICSTR depends on the clock frequency and speed of slave */
        if ((i2cObj->i2cRegs->ICSTR & CSL_I2C_ICSTR_AL_MASK) != 0) {
            retCode = PSP_I2C_ARBITRATION_LOSS_ERR;
        } else if ((i2cObj->i2cRegs->ICSTR & CSL_I2C_ICSTR_RSFULL_MASK) != 0) {
            retCode = PSP_I2C_RECEIVE_OVERFLOW_ERR;
        }
        /* Check for NACK error
         */
        else {
            if ((i2cObj->i2cRegs->ICSTR & CSL_I2C_ICSTR_NACK_MASK) != 0) {
                retCode = PSP_I2C_NACK_ERR;
            }
        }
        if ( retCode != 0) {
            i2c_cancelIO(i2cObj);
            retVal = retCode;
        }
        *(Uint32 *)xferActual = cnt;
        i2cObj->pendingState=FALSE;
    } /* retVal */
    return retVal;
}
Beispiel #4
0
/**
 *  \brief Open Instance of the I2C device
 *
 *  This function prepares the device hardware for data transfers and
 *  usage by the upper layer driver software. The DDA layer is expected
 *  to install the ISR and enable it only after the completion of this
 *  call. The function prepares the driver instance for data transfers
 *  and returns an handle to the driver instance.
 *
 * Note: The driver can be opened multiple times
 *  \param  instanceId [IN]    I2C instance number
 *  \param  callback   [IN]    Callback function for events notification
 *  \param  appHandle  [IN]    This appHandle will be provided by user and
 *                             will be returned along with call back
 *  \return PSP_Handle [OUT]   If successful positive Driver Instance Handle
 *                             else return the NULL pointer.
 */
PSP_Handle  PSP_i2cOpen(Uint32 instanceId, PSP_I2cAppCallback callback,
                                                                Ptr appHandle)
{
    DDC_I2cObject *i2cObj;
    DDC_I2cDriverObject   *i2cHandle;
    Uint32 psc, clk, cnt;
    Uint32 cookie;

    i2cHandle = NULL;

    /* Validate instance ID */
    if (instanceId < PSP_I2C_NUM_INSTANCES) {
        i2cObj = &ddcI2CObj[instanceId];
        if ( ((i2cObj != NULL) && (i2cObj->state != I2C_DELETED)) &&
             (i2cObj->numOpens < PSP_I2C_NUM_OPENS) )
        {
            /* Create i2c driver object */
            for (cnt=0; cnt < PSP_I2C_NUM_OPENS; cnt++)
            {
                    ddcI2CDriver[i2cObj->instanceId][cnt].callBack          = callback;
                    ddcI2CDriver[i2cObj->instanceId][cnt].appHandle         = appHandle;
                    ddcI2CDriver[i2cObj->instanceId][cnt].pi2cInstHandle    = i2cObj;
                    i2cHandle = &ddcI2CDriver[i2cObj->instanceId][cnt];
                    break;
            }
        }
    }

    if (i2cHandle != NULL) {
        /* Start of critical section */
        PAL_osProtectEntry(PAL_OSPROTECT_INTERRUPT, &cookie);

        /* Init hardware if first open */
        if (i2cObj->numOpens == 0)
        {
            i2cObj->instanceId = instanceId;
            switch (instanceId)
            {
                case 0:
                    i2cObj->i2cRegs = (CSL_I2cDrvRegs *) CSL_I2C_REGS;
                    break;

                default:
                    i2cHandle = NULL;
                    break;
            }

            if (i2cHandle != NULL) {
                /* Put the module in reset */
                i2cObj->i2cRegs->ICMDR = 0;

                if(i2cCalculateClockSettings(i2cObj , &psc, &clk) != 0 )
                {
                    i2cHandle = NULL;
                } else {
                    i2cObj->i2cRegs->ICPSC = psc;
                    i2cObj->i2cRegs->ICCLKH = clk;
                    i2cObj->i2cRegs->ICCLKL = clk;

                    /* Set own address and bits/byte */
                    i2cObj->i2cRegs->ICOAR = i2cObj->i2cOwnAddr;
                    i2cObj->i2cRegs->ICMDR = (i2cObj->numBits & 0x7u) | CSL_I2C_ICMDR_MST_MASK;

                    /* Enable/Disable Repeat,DLB and 7/10 bit addressing modes */
                    if ((Bool)TRUE == i2cObj->dlb) {
                        i2cObj->i2cRegs->ICMDR |= CSL_I2C_ICMDR_DLB_MASK;
                    } else  {
                        i2cObj->i2cRegs->ICMDR &= ~(CSL_I2C_ICMDR_DLB_MASK);
                    }

                    if ( ((Bool)TRUE == i2cObj->repeatMode) )   {
                        i2cObj->i2cRegs->ICMDR |= CSL_I2C_ICMDR_RM_MASK;
                    } else {
                        i2cObj->i2cRegs->ICMDR &= (~(CSL_I2C_ICMDR_RM_MASK));
                    }

                    if ((Bool)TRUE == i2cObj->addressing)   {
                        i2cObj->i2cRegs->ICMDR |= CSL_I2C_ICMDR_XA_MASK;
                    } else {
                        i2cObj->i2cRegs->ICMDR &= (~(CSL_I2C_ICMDR_XA_MASK));
                    }
                    /* Bring module out of reset */
                    i2cObj->i2cRegs->ICMDR |= CSL_I2C_ICMDR_IRS_MASK;

                    /* Set the backward compatibility mode off - this is critical to get
                     * interrupts correctly */
                    i2cObj->i2cRegs->ICEMDR = 0;
                } /* else retCode */
            } /* retVal = NULL in side if first oprn */
        } /* First open initialization */
        /* End of critical section */
        PAL_osProtectExit(PAL_OSPROTECT_INTERRUPT, cookie);
    } /* retVal = NULL before firstt open */

    if (i2cHandle != NULL) {
        /* Increment open count and return driver handle */
        i2cObj->numOpens = i2cObj->numOpens + 1u;

        /* Updated the driver state */
        i2cObj->state = I2C_OPENED;
    }

    return (PSP_Handle)i2cHandle;
}