/*******************************************************************************
**
** Function         phTmlNfc_CleanUp
**
** Description      Clears all handles opened during TML initialization
**
** Parameters       None
**
** Returns          None
**
*******************************************************************************/
static void phTmlNfc_CleanUp(void)
{
    NFCSTATUS wRetval = NFCSTATUS_SUCCESS;

    if (NULL != gpphTmlNfc_Context->pDevHandle)
    {
        (void) phTmlNfc_i2c_reset(gpphTmlNfc_Context->pDevHandle, 0);
        gpphTmlNfc_Context->bThreadDone = 0;
    }
    sem_destroy(&gpphTmlNfc_Context->rxSemaphore);
    sem_destroy(&gpphTmlNfc_Context->txSemaphore);
    sem_destroy(&gpphTmlNfc_Context->postMsgSemaphore);
    phTmlNfc_i2c_close(gpphTmlNfc_Context->pDevHandle);
    gpphTmlNfc_Context->pDevHandle = NULL;
    /* Clear memory allocated for storing Context variables */
    free((void *) gpphTmlNfc_Context);
    /* Set the pointer to NULL to indicate De-Initialization */
    gpphTmlNfc_Context = NULL;

    return;
}
/*******************************************************************************
**
** Function         phTmlNfc_IoCtl
**
** Description      Resets device when insisted by upper layer
**                  Number of bytes to be read and buffer are passed by upper layer
**                  Enables reader thread if there are no read requests pending
**                  Returns successfully once read operation is completed
**                  Notifies upper layer using callback mechanism
**
** Parameters       eControlCode       - control code for a specific operation
**
** Returns          NFC status:
**                  NFCSTATUS_SUCCESS  - ioctl command completed successfully
**                  NFCSTATUS_FAILED   - ioctl command request failed
**
*******************************************************************************/
NFCSTATUS phTmlNfc_IoCtl(phTmlNfc_ControlCode_t eControlCode)
{
    NFCSTATUS wStatus = NFCSTATUS_SUCCESS;

    if (NULL == gpphTmlNfc_Context)
    {
        wStatus = NFCSTATUS_FAILED;
    }
    else
    {
        switch (eControlCode)
        {
            case phTmlNfc_e_ResetDevice:
                {
                    /*Reset PN54X*/
                    phTmlNfc_i2c_reset(gpphTmlNfc_Context->pDevHandle, 1);
                    usleep(100 * 1000);
                    phTmlNfc_i2c_reset(gpphTmlNfc_Context->pDevHandle, 0);
                    usleep(100 * 1000);
                    phTmlNfc_i2c_reset(gpphTmlNfc_Context->pDevHandle, 1);
                    break;
                }
            case phTmlNfc_e_EnableNormalMode:
                {
                    /*Reset PN54X*/
                    phTmlNfc_i2c_reset(gpphTmlNfc_Context->pDevHandle, 0);
                    usleep(10 * 1000);
                    phTmlNfc_i2c_reset(gpphTmlNfc_Context->pDevHandle, 1);
                    usleep(100 * 1000);
                    break;
                }
            case phTmlNfc_e_EnableDownloadMode:
                {
                    phTmlNfc_ConfigNciPktReTx(phTmlNfc_e_DisableRetrans, 0);
                    (void)phTmlNfc_i2c_reset(gpphTmlNfc_Context->pDevHandle,2);
                    usleep(100 * 1000);
                    break;
                }
#if(NFC_NXP_ESE == TRUE)
            case phTmlNfc_e_SetNfcServicePid:
            {
                wStatus = phTmlNfc_set_pid(gpphTmlNfc_Context->pDevHandle, nfc_service_pid);
                break;
            }
            case phTmlNfc_e_GetP61PwrMode:
            {
                wStatus = phTmlNfc_i2c_get_p61_power_state(gpphTmlNfc_Context->pDevHandle);
                break;
            }
            case phTmlNfc_e_SetP61WiredMode:
            {
                wStatus = phTmlNfc_i2c_set_p61_power_state(gpphTmlNfc_Context->pDevHandle, 1);
                break;
            }
            case phTmlNfc_e_SetP61IdleMode:
            {
                wStatus = phTmlNfc_i2c_set_p61_power_state(gpphTmlNfc_Context->pDevHandle, 0);
                break;
            }
            case phTmlNfc_e_SetP61DisableMode:
            {
                wStatus = phTmlNfc_i2c_set_p61_power_state(gpphTmlNfc_Context->pDevHandle, 2);
                break;
            }
            case phTmlNfc_e_SetP61EnableMode:
            {
                wStatus = phTmlNfc_i2c_set_p61_power_state(gpphTmlNfc_Context->pDevHandle, 3);
                break;
            }
#endif
            default:
                {
                    wStatus = NFCSTATUS_INVALID_PARAMETER;
                    break;
                }
        }
    }

    return wStatus;
}
/*******************************************************************************
**
** Function         phTmlNfc_i2c_open_and_configure
**
** Description      Open and configure PN54X device
**
** Parameters       pConfig     - hardware information
**                  pLinkHandle - device handle
**
** Returns          NFC status:
**                  NFCSTATUS_SUCCESS            - open_and_configure operation success
**                  NFCSTATUS_INVALID_DEVICE     - device open operation failure
**
*******************************************************************************/
NFCSTATUS phTmlNfc_i2c_open_and_configure(pphTmlNfc_Config_t pConfig, void ** pLinkHandle)
{
#ifdef PHFL_TML_ALT_NFC
    NXPLOG_TML_D("phTmlNfc_i2c_open_and_configure Alternative NFC\n");
    NXPLOG_TML_D( "NFC - Assign IO pins\n");
    // Assign IO pins
    iInterruptFd = verifyPin( PIN_INT,    0, EDGE_RISING );
    iEnableFd    = verifyPin( PIN_ENABLE, 1, EDGE_NONE   );
    NXPLOG_TML_D( "NFCHW - open I2C bus - %s\n", I2C_BUS);

    // I2C bus
    iI2CFd = open( I2C_BUS, O_RDWR | O_NOCTTY);
    if (iI2CFd < 0) {
        NXPLOG_TML_E( "Could not open I2C bus '%s' (%s)", I2C_BUS, strerror(errno));
        if ( iEnableFd    ) close(iEnableFd);
        if ( iInterruptFd ) close(iInterruptFd);
        return( NFCSTATUS_INVALID_DEVICE );
    }

    NXPLOG_TML_D( "NFC - open I2C device - 0x%02x\n", I2C_ADDRESS);

    // I2C slave address
    if (ioctl(iI2CFd, I2C_SLAVE, I2C_ADDRESS) < 0) {
        NXPLOG_TML_E( "Cannot select I2C address (%s)\n", strerror(errno));
        if ( iEnableFd    ) close(iEnableFd);
        if ( iInterruptFd ) close(iInterruptFd);
        close(iI2CFd);
        return( NFCSTATUS_INVALID_DEVICE );
    }

    /*Reset NFC Controller */
    pnOn();
    usleep(100 * 1000);
    pnOff();
    usleep(100 * 1000);
    pnOn();
    
    *pLinkHandle = (void*) ((intptr_t)dummyHandle);
#else
    int nHandle;
    NXPLOG_TML_D("phTmlNfc_i2c_open_and_configure\n");
    NXPLOG_TML_D("Opening port=%s\n", pConfig->pDevName);
    /* open port */
    nHandle = open((char const *)pConfig->pDevName, O_RDWR);
    if (nHandle < 0)
    {
        NXPLOG_TML_E("_i2c_open() Failed: retval %x",nHandle);
        *pLinkHandle = NULL;
        return NFCSTATUS_INVALID_DEVICE;
    }

    *pLinkHandle = (void*) ((intptr_t)nHandle);

    /*Reset PN54X*/
    phTmlNfc_i2c_reset((void *)((intptr_t)nHandle), 1);
    usleep(100 * 1000);
    phTmlNfc_i2c_reset((void *)((intptr_t)nHandle), 0);
    usleep(100 * 1000);
    phTmlNfc_i2c_reset((void *)((intptr_t)nHandle), 1);
#endif

    return NFCSTATUS_SUCCESS;
}