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