Home | History | Annotate | Download | only in spi
      1 /******************************************************************************
      2  *
      3  *  Copyright 2018 NXP
      4  *
      5  *  Licensed under the Apache License, Version 2.0 (the "License");
      6  *  you may not use this file except in compliance with the License.
      7  *  You may obtain a copy of the License at
      8  *
      9  *  http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *  See the License for the specific language governing permissions and
     15  *  limitations under the License.
     16  *
     17  ******************************************************************************/
     18 
     19 /*
     20  * DAL spi port implementation for linux
     21  *
     22  * Project: Trusted ESE Linux
     23  *
     24  */
     25 #define LOG_TAG "NxpEseHal"
     26 #include <log/log.h>
     27 
     28 #include <errno.h>
     29 #include <fcntl.h>
     30 #include <stdlib.h>
     31 #include <sys/ioctl.h>
     32 #include <unistd.h>
     33 
     34 #include <ese_config.h>
     35 #include <hardware/nfc.h>
     36 #include <phEseStatus.h>
     37 #include <phNxpEsePal.h>
     38 #include <phNxpEsePal_spi.h>
     39 #include <string.h>
     40 #include "NfcAdaptation.h"
     41 #include "hal_nxpese.h"
     42 #include "phNxpEse_Api.h"
     43 
     44 #define MAX_RETRY_CNT 10
     45 #define HAL_NFC_SPI_DWP_SYNC 21
     46 #define RF_ON 1
     47 
     48 extern int omapi_status;
     49 extern bool ese_debug_enabled;
     50 
     51 static int rf_status;
     52 unsigned long int configNum1, configNum2;
     53 // Default max retry count for SPI CLT write blocked in secs
     54 static const uint8_t DEFAULT_MAX_SPI_WRITE_RETRY_COUNT_RF_ON = 10;
     55 static const uint8_t MAX_SPI_WRITE_RETRY_COUNT_HW_ERR = 3;
     56 /*******************************************************************************
     57 **
     58 ** Function         phPalEse_spi_close
     59 **
     60 ** Description      Closes PN547 device
     61 **
     62 ** Parameters       pDevHandle - device handle
     63 **
     64 ** Returns          None
     65 **
     66 *******************************************************************************/
     67 void phPalEse_spi_close(void* pDevHandle) {
     68   ese_nxp_IoctlInOutData_t inpOutData;
     69   static uint8_t cmd_omapi_concurrent[] = {0x2F, 0x01, 0x01, 0x00};
     70   int retval;
     71   ALOGD_IF(ese_debug_enabled, "halimpl close enter.");
     72 
     73   NfcAdaptation& pNfcAdapt = NfcAdaptation::GetInstance();
     74   pNfcAdapt.Initialize();
     75   // nxpesehal_ctrl.p_ese_stack_cback = p_cback;
     76   // nxpesehal_ctrl.p_ese_stack_data_cback = p_data_cback;
     77   memset(&inpOutData, 0x00, sizeof(ese_nxp_IoctlInOutData_t));
     78   inpOutData.inp.data.nxpCmd.cmd_len = sizeof(cmd_omapi_concurrent);
     79   inpOutData.inp.data_source = 1;
     80   memcpy(inpOutData.inp.data.nxpCmd.p_cmd, cmd_omapi_concurrent,
     81          sizeof(cmd_omapi_concurrent));
     82   retval = pNfcAdapt.HalIoctl(HAL_NFC_SPI_DWP_SYNC, &inpOutData);
     83   ALOGD_IF(ese_debug_enabled, "_spi_close() status %x", retval);
     84 
     85   if (NULL != pDevHandle) {
     86     close((intptr_t)pDevHandle);
     87   }
     88   ALOGD_IF(ese_debug_enabled, "halimpl close exit.");
     89   return;
     90 }
     91 ESESTATUS phNxpEse_spiIoctl(uint64_t ioctlType, void* p_data) {
     92   ese_nxp_IoctlInOutData_t* inpOutData = (ese_nxp_IoctlInOutData_t*)p_data;
     93   rf_status = inpOutData->inp.data.nxpCmd.p_cmd[0];
     94   if (rf_status == 1) {
     95     ALOGD_IF(ese_debug_enabled,
     96              "******************RF IS ON*************************************");
     97   } else {
     98     ALOGD_IF(
     99         ese_debug_enabled,
    100         "******************RF IS OFF*************************************");
    101   }
    102   if (p_data != NULL) {
    103     ALOGD_IF(ese_debug_enabled,
    104              "halimpl phNxpEse_spiIoctl p_data is not null ioctltyp: %ld",
    105              (long)ioctlType);
    106   }
    107   return ESESTATUS_SUCCESS;
    108 }
    109 
    110 /*******************************************************************************
    111 **
    112 ** Function         phPalEse_spi_open_and_configure
    113 **
    114 ** Description      Open and configure pn547 device
    115 **
    116 ** Parameters       pConfig     - hardware information
    117 **                  pLinkHandle - device handle
    118 **
    119 ** Returns          ESE status:
    120 **                  ESESTATUS_SUCCESS            - open_and_configure operation
    121 *success
    122 **                  ESESTATUS_INVALID_DEVICE     - device open operation failure
    123 **
    124 *******************************************************************************/
    125 ESESTATUS phPalEse_spi_open_and_configure(pphPalEse_Config_t pConfig) {
    126   int nHandle;
    127   int retryCnt = 0, nfc_access_retryCnt = 0;
    128   int retval;
    129   ese_nxp_IoctlInOutData_t inpOutData;
    130   NfcAdaptation& pNfcAdapt = NfcAdaptation::GetInstance();
    131   pNfcAdapt.Initialize();
    132   static uint8_t cmd_omapi_concurrent[] = {0x2F, 0x01, 0x01, 0x01};
    133 
    134   if (EseConfig::hasKey(NAME_NXP_SOF_WRITE)) {
    135     configNum1 = EseConfig::getUnsigned(NAME_NXP_SOF_WRITE);
    136     ALOGD_IF(ese_debug_enabled, "NXP_SOF_WRITE value from config file = %ld",
    137              configNum1);
    138   }
    139 
    140   if (EseConfig::hasKey(NAME_NXP_SPI_WRITE_TIMEOUT)) {
    141     configNum2 = EseConfig::getUnsigned(NAME_NXP_SPI_WRITE_TIMEOUT);
    142     ALOGD_IF(ese_debug_enabled,
    143              "NXP_SPI_WRITE_TIMEOUT value from config file = %ld", configNum2);
    144   }
    145   ALOGD_IF(ese_debug_enabled, "halimpl open enter.");
    146   memset(&inpOutData, 0x00, sizeof(ese_nxp_IoctlInOutData_t));
    147   inpOutData.inp.data.nxpCmd.cmd_len = sizeof(cmd_omapi_concurrent);
    148   inpOutData.inp.data_source = 1;
    149   memcpy(inpOutData.inp.data.nxpCmd.p_cmd, cmd_omapi_concurrent,
    150          sizeof(cmd_omapi_concurrent));
    151 
    152 retry_nfc_access:
    153   omapi_status = ESESTATUS_FAILED;
    154   retval = pNfcAdapt.HalIoctl(HAL_NFC_SPI_DWP_SYNC, &inpOutData);
    155   if (omapi_status != 0) {
    156     ALOGD_IF(ese_debug_enabled, "omapi_status return failed.");
    157     nfc_access_retryCnt++;
    158     phPalEse_sleep(2000000);
    159     if (nfc_access_retryCnt < 5) goto retry_nfc_access;
    160     return ESESTATUS_FAILED;
    161   }
    162 
    163   ALOGD_IF(ese_debug_enabled, "Opening port=%s\n", pConfig->pDevName);
    164 /* open port */
    165 
    166 retry:
    167   nHandle = open((char const*)pConfig->pDevName, O_RDWR);
    168   if (nHandle < 0) {
    169     ALOGE("%s : failed errno = 0x%x", __FUNCTION__, errno);
    170     if (errno == -EBUSY || errno == EBUSY) {
    171       retryCnt++;
    172       ALOGE("Retry open eSE driver, retry cnt : %d", retryCnt);
    173       if (retryCnt < MAX_RETRY_CNT) {
    174         phPalEse_sleep(1000000);
    175         goto retry;
    176       }
    177     }
    178     ALOGE("_spi_open() Failed: retval %x", nHandle);
    179     pConfig->pDevHandle = NULL;
    180     return ESESTATUS_INVALID_DEVICE;
    181   }
    182   ALOGD_IF(ese_debug_enabled, "eSE driver opened :: fd = [%d]", nHandle);
    183   pConfig->pDevHandle = (void*)((intptr_t)nHandle);
    184   return ESESTATUS_SUCCESS;
    185 }
    186 
    187 /*******************************************************************************
    188 **
    189 ** Function         phPalEse_spi_read
    190 **
    191 ** Description      Reads requested number of bytes from pn547 device into given
    192 *buffer
    193 **
    194 ** Parameters       pDevHandle       - valid device handle
    195 **                  pBuffer          - buffer for read data
    196 **                  nNbBytesToRead   - number of bytes requested to be read
    197 **
    198 ** Returns          numRead   - number of successfully read bytes
    199 **                  -1        - read operation failure
    200 **
    201 *******************************************************************************/
    202 int phPalEse_spi_read(void* pDevHandle, uint8_t* pBuffer, int nNbBytesToRead) {
    203   int ret = -1;
    204   ALOGD_IF(ese_debug_enabled, "%s Read Requested %d bytes", __FUNCTION__,
    205            nNbBytesToRead);
    206   ret = read((intptr_t)pDevHandle, (void*)pBuffer, (nNbBytesToRead));
    207   ALOGD_IF(ese_debug_enabled, "Read Returned = %d", ret);
    208   return ret;
    209 }
    210 
    211 /*******************************************************************************
    212 **
    213 ** Function         phPalEse_spi_write
    214 **
    215 ** Description      Writes requested number of bytes from given buffer into
    216 *pn547 device
    217 **
    218 ** Parameters       pDevHandle       - valid device handle
    219 **                  pBuffer          - buffer for read data
    220 **                  nNbBytesToWrite  - number of bytes requested to be written
    221 **
    222 ** Returns          numWrote   - number of successfully written bytes
    223 **                  -1         - write operation failure
    224 **
    225 *******************************************************************************/
    226 int phPalEse_spi_write(void* pDevHandle, uint8_t* pBuffer,
    227                        int nNbBytesToWrite) {
    228   int ret = -1;
    229   int numWrote = 0;
    230   unsigned long int retryCount = 0;
    231   if (NULL == pDevHandle) {
    232     return -1;
    233   }
    234 
    235   if (configNum1 == 1) {
    236     /* Appending SOF for SPI write */
    237     pBuffer[0] = SEND_PACKET_SOF;
    238   } else {
    239     /* Do Nothing */
    240   }
    241 
    242   unsigned int maxRetryCount = 0, retryDelay = 0;
    243   while (numWrote < nNbBytesToWrite) {
    244     // usleep(5000);
    245     if (rf_status != RF_ON) {
    246       ret = write((intptr_t)pDevHandle, pBuffer + numWrote,
    247                   nNbBytesToWrite - numWrote);
    248     } else {
    249       ret = -1;
    250     }
    251     if (ret > 0) {
    252       numWrote += ret;
    253     } else if (ret == 0) {
    254       ALOGE("_spi_write() EOF");
    255       return -1;
    256     } else {
    257       ALOGE("_spi_write() errno : %x", errno);
    258 
    259       if (rf_status == RF_ON) {
    260         maxRetryCount = (configNum2 > 0)
    261                             ? configNum2
    262                             : DEFAULT_MAX_SPI_WRITE_RETRY_COUNT_RF_ON;
    263         retryDelay = 1000 * WRITE_WAKE_UP_DELAY;
    264         ALOGD_IF(ese_debug_enabled, "spi_Write failed as RF is ON.");
    265       } else {
    266         maxRetryCount = MAX_SPI_WRITE_RETRY_COUNT_HW_ERR;
    267         retryDelay = WRITE_WAKE_UP_DELAY;
    268         ALOGD_IF(ese_debug_enabled, "spi_write failed");
    269       }
    270 
    271       if (retryCount < maxRetryCount) {
    272         retryCount++;
    273         /*wait for eSE wake up*/
    274         phPalEse_sleep(retryDelay);
    275         ALOGE("_spi_write() failed. Going to retry, counter:%ld !", retryCount);
    276         continue;
    277       }
    278       return -1;
    279     }
    280   }
    281   return numWrote;
    282 }
    283 
    284 /*******************************************************************************
    285 **
    286 ** Function         phPalEse_spi_ioctl
    287 **
    288 ** Description      Exposed ioctl by p61 spi driver
    289 **
    290 ** Parameters       pDevHandle     - valid device handle
    291 **                  level          - reset level
    292 **
    293 ** Returns           0   - ioctl operation success
    294 **                  -1   - ioctl operation failure
    295 **
    296 *******************************************************************************/
    297 ESESTATUS phPalEse_spi_ioctl(phPalEse_ControlCode_t eControlCode,
    298                              void* pDevHandle, long level) {
    299   ESESTATUS ret = ESESTATUS_IOCTL_FAILED;
    300   ALOGD_IF(ese_debug_enabled, "phPalEse_spi_ioctl(), ioctl %x , level %lx",
    301            eControlCode, level);
    302   ese_nxp_IoctlInOutData_t inpOutData;
    303   inpOutData.inp.level = level;
    304   NfcAdaptation& pNfcAdapt = NfcAdaptation::GetInstance();
    305   if (NULL == pDevHandle) {
    306     return ESESTATUS_IOCTL_FAILED;
    307   }
    308   switch (eControlCode) {
    309     // Nfc Driver communication part
    310     case phPalEse_e_ChipRst:
    311       ret = pNfcAdapt.HalIoctl(HAL_NFC_SET_SPM_PWR, &inpOutData);
    312       break;
    313 
    314     case phPalEse_e_SetPowerScheme:
    315       // ret = sendIoctlData(p, HAL_NFC_SET_POWER_SCHEME, &inpOutData);
    316       ret = ESESTATUS_SUCCESS;
    317       break;
    318 
    319     case phPalEse_e_GetSPMStatus:
    320       // ret = sendIoctlData(p, HAL_NFC_GET_SPM_STATUS, &inpOutData);
    321       ret = ESESTATUS_SUCCESS;
    322       break;
    323 
    324     case phPalEse_e_GetEseAccess:
    325       // ret = sendIoctlData(p, HAL_NFC_GET_ESE_ACCESS, &inpOutData);
    326       ret = ESESTATUS_SUCCESS;
    327       break;
    328 #ifdef NXP_ESE_JCOP_DWNLD_PROTECTION
    329     case phPalEse_e_SetJcopDwnldState:
    330       // ret = sendIoctlData(p, HAL_NFC_SET_DWNLD_STATUS, &inpOutData);
    331       ret = ESESTATUS_SUCCESS;
    332       break;
    333 #endif
    334     case phPalEse_e_DisablePwrCntrl:
    335       ret = pNfcAdapt.HalIoctl(HAL_NFC_INHIBIT_PWR_CNTRL, &inpOutData);
    336       break;
    337     default:
    338       ret = ESESTATUS_IOCTL_FAILED;
    339       break;
    340   }
    341   return ret;
    342 }
    343