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 #define LOG_TAG "NxpEseHal" 19 #include <log/log.h> 20 21 #include <errno.h> 22 #include <fcntl.h> 23 #include <phNxpEsePal.h> 24 #include <phNxpEse_Internal.h> 25 #include <sys/ioctl.h> 26 #include <sys/stat.h> 27 #include <sys/types.h> 28 #include <unistd.h> 29 #include "phNxpEseFeatures.h" 30 #include "phNxpEse_Spm.h" 31 32 /*********************** Global Variables *************************************/ 33 extern bool ese_debug_enabled; 34 35 static void* pEseDeviceHandle = NULL; 36 #define MAX_ESE_ACCESS_TIME_OUT_MS 2000 /*2 seconds*/ 37 38 /** 39 * \addtogroup SPI_Power_Management 40 * 41 * @{ */ 42 /****************************************************************************** 43 \section Introduction Introduction 44 45 * This module provide power request to Pn54x nfc-i2c driver, it cheks if 46 * wired access is already granted. It should have access to pn54x drive. 47 * Below are the apis provided by the SPM module. 48 ******************************************************************************/ 49 /****************************************************************************** 50 * Function phNxpEse_SPM_Init 51 * 52 * Description This function opens the nfc i2c driver to manage power 53 * and synchronization for ese secure element. 54 * 55 * Returns On Success ESESTATUS_SUCCESS else proper error code 56 * 57 ******************************************************************************/ 58 ESESTATUS phNxpEse_SPM_Init(void* pDevHandle) { 59 ESESTATUS status = ESESTATUS_SUCCESS; 60 pEseDeviceHandle = pDevHandle; 61 if (NULL == pEseDeviceHandle) { 62 ALOGE("%s : failed, device handle is null", __FUNCTION__); 63 status = ESESTATUS_FAILED; 64 } 65 ALOGD_IF(ese_debug_enabled, "%s : exit status = %d", __FUNCTION__, status); 66 67 return status; 68 } 69 70 /****************************************************************************** 71 * Function phNxpEse_SPM_DeInit 72 * 73 * Description This function closes the nfc i2c driver node. 74 * 75 * Returns Always returns ESESTATUS_SUCCESS 76 * 77 ******************************************************************************/ 78 ESESTATUS phNxpEse_SPM_DeInit(void) { 79 pEseDeviceHandle = NULL; 80 return ESESTATUS_SUCCESS; 81 } 82 83 /****************************************************************************** 84 * Function phNxpEse_SPM_ConfigPwr 85 * 86 * Description This function request to the nfc i2c driver 87 * to enable/disable power to ese. This api should be called 88 *before 89 * sending any apdu to ese/once apdu exchange is done. 90 * 91 * Returns On Success ESESTATUS_SUCCESS else proper error code 92 * 93 ******************************************************************************/ 94 ESESTATUS phNxpEse_SPM_ConfigPwr(spm_power_t arg) { 95 int32_t ret = -1; 96 ESESTATUS wSpmStatus = ESESTATUS_SUCCESS; 97 spm_state_t current_spm_state = SPM_STATE_INVALID; 98 99 ret = phPalEse_ioctl(phPalEse_e_ChipRst, pEseDeviceHandle, arg); 100 switch (arg) { 101 case SPM_POWER_DISABLE: { 102 if (ret < 0) { 103 ALOGE("%s : failed errno = 0x%x", __FUNCTION__, errno); 104 wSpmStatus = ESESTATUS_FAILED; 105 } 106 } break; 107 case SPM_POWER_ENABLE: { 108 if (ret < 0) { 109 ALOGE("%s : failed errno = 0x%x", __FUNCTION__, errno); 110 if (errno == -EBUSY) { 111 wSpmStatus = phNxpEse_SPM_GetState(¤t_spm_state); 112 if (wSpmStatus != ESESTATUS_SUCCESS) { 113 ALOGE(" %s : phNxpEse_SPM_GetPwrState Failed", __FUNCTION__); 114 return wSpmStatus; 115 } else { 116 if (current_spm_state & SPM_STATE_DWNLD) { 117 wSpmStatus = ESESTATUS_DWNLD_BUSY; 118 } else { 119 wSpmStatus = ESESTATUS_BUSY; 120 } 121 } 122 123 } else { 124 wSpmStatus = ESESTATUS_FAILED; 125 } 126 } 127 } break; 128 case SPM_POWER_RESET: { 129 if (ret < 0) { 130 ALOGE("%s : failed errno = 0x%x", __FUNCTION__, errno); 131 if (errno == -EBUSY) { 132 wSpmStatus = phNxpEse_SPM_GetState(¤t_spm_state); 133 if (wSpmStatus != ESESTATUS_SUCCESS) { 134 ALOGE(" %s : phNxpEse_SPM_GetPwrState Failed", __FUNCTION__); 135 return wSpmStatus; 136 } else { 137 if (current_spm_state & SPM_STATE_DWNLD) { 138 wSpmStatus = ESESTATUS_DWNLD_BUSY; 139 } else { 140 wSpmStatus = ESESTATUS_BUSY; 141 } 142 } 143 } else { 144 wSpmStatus = ESESTATUS_FAILED; 145 } 146 } 147 } break; 148 case SPM_POWER_PRIO_ENABLE: { 149 if (ret < 0) { 150 ALOGE("%s : failed errno = 0x%x", __FUNCTION__, errno); 151 if (errno == -EBUSY) { 152 wSpmStatus = phNxpEse_SPM_GetState(¤t_spm_state); 153 if (wSpmStatus != ESESTATUS_SUCCESS) { 154 ALOGE(" %s : phNxpEse_SPM_GetPwrState Failed", __FUNCTION__); 155 return wSpmStatus; 156 } else { 157 if (current_spm_state & SPM_STATE_DWNLD) { 158 wSpmStatus = ESESTATUS_DWNLD_BUSY; 159 } else { 160 wSpmStatus = ESESTATUS_BUSY; 161 } 162 } 163 164 } else { 165 wSpmStatus = ESESTATUS_FAILED; 166 } 167 } 168 } break; 169 case SPM_POWER_PRIO_DISABLE: { 170 if (ret < 0) { 171 ALOGE("%s : failed errno = 0x%x", __FUNCTION__, errno); 172 wSpmStatus = ESESTATUS_FAILED; 173 } 174 } break; 175 } 176 return wSpmStatus; 177 } 178 179 /****************************************************************************** 180 * Function phNxpEse_SPM_EnablePwr 181 * 182 * Description This function request to the nfc i2c driver 183 * to enable power to ese. This api should be called before 184 * sending any apdu to ese. 185 * 186 * Returns On Success ESESTATUS_SUCCESS else proper error code 187 * 188 ******************************************************************************/ 189 ESESTATUS phNxpEse_SPM_EnablePwr(void) { 190 int32_t ret = -1; 191 ESESTATUS wSpmStatus = ESESTATUS_SUCCESS; 192 spm_state_t current_spm_state = SPM_STATE_INVALID; 193 ALOGD_IF(ese_debug_enabled, "%s : phNxpEse_SPM_EnablePwr is set to = 0x%d", 194 __FUNCTION__, 0); 195 ret = phPalEse_ioctl(phPalEse_e_ChipRst, pEseDeviceHandle, 0); 196 if (ret < 0) { 197 ALOGE("%s : failed errno = 0x%x", __FUNCTION__, errno); 198 if (errno == -EBUSY) { 199 wSpmStatus = phNxpEse_SPM_GetState(¤t_spm_state); 200 if (wSpmStatus != ESESTATUS_SUCCESS) { 201 ALOGE(" %s : phNxpEse_SPM_GetPwrState Failed", __FUNCTION__); 202 return wSpmStatus; 203 } else { 204 if (current_spm_state == SPM_STATE_DWNLD) { 205 wSpmStatus = ESESTATUS_DWNLD_BUSY; 206 } else { 207 wSpmStatus = ESESTATUS_BUSY; 208 } 209 } 210 211 } else { 212 wSpmStatus = ESESTATUS_FAILED; 213 } 214 } 215 216 return wSpmStatus; 217 } 218 219 /****************************************************************************** 220 * Function phNxpEse_SPM_DisablePwr 221 * 222 * Description This function request to the nfc i2c driver 223 * to disable power to ese. This api should be called 224 * once apdu exchange is done. 225 * 226 * Returns On Success ESESTATUS_SUCCESS else proper error code 227 * 228 ******************************************************************************/ 229 ESESTATUS phNxpEse_SPM_DisablePwr(void) { 230 int32_t ret = -1; 231 ESESTATUS status = ESESTATUS_SUCCESS; 232 ALOGD_IF(ese_debug_enabled, "%s : phNxpEse_SPM_DisablePwr is set to = 0x%d", 233 __FUNCTION__, 1); 234 ret = phPalEse_ioctl(phPalEse_e_ChipRst, pEseDeviceHandle, 1); 235 if (ret < 0) { 236 ALOGE("%s : failed errno = 0x%x", __FUNCTION__, errno); 237 status = ESESTATUS_FAILED; 238 } 239 240 return status; 241 } 242 /****************************************************************************** 243 * Function phNxpEse_SPM_SetPwrScheme 244 * 245 * Description This function request to the nfc i2c driver 246 * to set the chip type and power scheme. 247 * 248 * Returns On Success ESESTATUS_SUCCESS else proper error code 249 * 250 ******************************************************************************/ 251 ESESTATUS phNxpEse_SPM_SetPwrScheme(long arg) { 252 int32_t ret = -1; 253 ESESTATUS status = ESESTATUS_SUCCESS; 254 255 ALOGD_IF(ese_debug_enabled, "%s : Power scheme is set to = 0x%ld", 256 __FUNCTION__, arg); 257 ret = phPalEse_ioctl(phPalEse_e_SetPowerScheme, pEseDeviceHandle, arg); 258 if (ret < 0) { 259 ALOGE("%s : failed errno = 0x%x", __FUNCTION__, errno); 260 status = ESESTATUS_FAILED; 261 } 262 263 return status; 264 } 265 266 /****************************************************************************** 267 * Function phNxpEseP61_SPM_EnableDisablePwrCntrl 268 * 269 * Description This function request to the nfc i2c driver 270 * to set the chip type and power scheme. 271 * 272 * Returns On Success ESESTATUS_SUCCESS else proper error code 273 * 274 ******************************************************************************/ 275 ESESTATUS phNxpEse_SPM_DisablePwrControl(unsigned long arg) { 276 int32_t ret = -1; 277 ESESTATUS status = ESESTATUS_SUCCESS; 278 279 ALOGD_IF(ese_debug_enabled, "%s : Inhibit power control is set to = 0x%ld", 280 __FUNCTION__, arg); 281 ret = phPalEse_ioctl(phPalEse_e_DisablePwrCntrl, pEseDeviceHandle, arg); 282 if (ret < 0) { 283 ALOGE("%s : failed errno = 0x%x", __FUNCTION__, errno); 284 status = ESESTATUS_FAILED; 285 } 286 287 return status; 288 } 289 290 /****************************************************************************** 291 * Function phNxpEse_SPM_GetState 292 * 293 * Description This function gets the current power state of ESE 294 * 295 * Returns On Success ESESTATUS_SUCCESS else proper error code 296 * 297 ******************************************************************************/ 298 ESESTATUS phNxpEse_SPM_GetState(spm_state_t* current_state) { 299 int32_t ret = -1; 300 ESESTATUS status = ESESTATUS_SUCCESS; 301 spm_state_t ese_current_state; 302 303 if (current_state == NULL) { 304 ALOGE("%s : failed Invalid argument", __FUNCTION__); 305 return ESESTATUS_FAILED; 306 } 307 ret = phPalEse_ioctl(phPalEse_e_GetSPMStatus, pEseDeviceHandle, 308 (unsigned long)&ese_current_state); 309 if (ret < 0) { 310 ALOGE("%s : failed errno = 0x%x", __FUNCTION__, errno); 311 status = ESESTATUS_FAILED; 312 } else { 313 *current_state = ese_current_state; /* Current ESE state */ 314 } 315 316 return status; 317 } 318 #ifdef NXP_ESE_JCOP_DWNLD_PROTECTION 319 /****************************************************************************** 320 * Function phNxpEse_SPM_SetJcopDwnldState 321 * 322 * Description This function is used to set the JCOP OS download state 323 * 324 * Returns On Success ESESTATUS_SUCCESS else proper error code 325 * 326 ******************************************************************************/ 327 ESESTATUS phNxpEse_SPM_SetJcopDwnldState(long arg) { 328 int ret = -1; 329 ESESTATUS status = ESESTATUS_SUCCESS; 330 331 ALOGD_IF(ese_debug_enabled, "%s :phNxpEse_SPM_SetJcopDwnldState = 0x%ld", 332 __FUNCTION__, arg); 333 ret = phPalEse_ioctl(phPalEse_e_SetJcopDwnldState, pEseDeviceHandle, arg); 334 if (ret < 0) { 335 ALOGE("%s : failed errno = 0x%x", __FUNCTION__, errno); 336 status = ESESTATUS_FAILED; 337 } 338 339 return status; 340 } 341 #endif