Home | History | Annotate | Download | only in adaptation
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 2012 Broadcom Corporation
      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  *
     21  *  HAL Adaptation Interface (HAI). This interface regulates the interaction
     22  *  between standard Android HAL and Broadcom-specific HAL.  It adapts
     23  *  Broadcom-specific features to the Android framework.
     24  *
     25  ******************************************************************************/
     26 #define LOG_TAG "NfcNciHal"
     27 #include "HalAdaptation.h"
     28 #include <cutils/properties.h>
     29 #include <errno.h>
     30 #include <pthread.h>
     31 #include "SyncEvent.h"
     32 #include "_OverrideLog.h"
     33 #include "android_logmsg.h"
     34 #include "buildcfg.h"
     35 #include "config.h"
     36 #include "nfc_hal_int.h"
     37 #include "nfc_hal_post_reset.h"
     38 extern void delete_hal_non_volatile_store(bool forceDelete);
     39 extern void verify_hal_non_volatile_store();
     40 extern void resetConfig();
     41 extern "C" {
     42 #include "userial.h"
     43 }
     44 
     45 extern void configureCrystalFrequency();
     46 
     47 ///////////////////////////////////////
     48 // private declaration, definition
     49 
     50 static nfc_stack_callback_t* gAndroidHalCallback = NULL;
     51 static nfc_stack_data_callback_t* gAndroidHalDataCallback = NULL;
     52 static SyncEvent gOpenCompletedEvent;
     53 static SyncEvent gPostInitCompletedEvent;
     54 static SyncEvent gCloseCompletedEvent;
     55 
     56 uint32_t ScrProtocolTraceFlag = SCR_PROTO_TRACE_ALL;  // 0x017F00;
     57 
     58 static void BroadcomHalCallback(uint8_t event, tHAL_NFC_STATUS status);
     59 static void BroadcomHalDataCallback(uint16_t data_len, uint8_t* p_data);
     60 
     61 static bool isColdBoot = true;
     62 
     63 extern tNFC_HAL_CFG* p_nfc_hal_cfg;
     64 extern const uint8_t nfca_version_string[];
     65 extern const uint8_t nfa_version_string[];
     66 
     67 tNFC_HAL_DM_PRE_SET_MEM nfc_hal_pre_set_mem_20795a1[] = {
     68     {0x0016403c, 0x00000008},
     69     {0x0016403c, 0x00000000},
     70     {0x0014008c, 0x00000001},
     71     {0, 0}};
     72 
     73 extern tNFC_HAL_DM_PRE_SET_MEM* p_nfc_hal_dm_pre_set_mem;
     74 
     75 ///////////////////////////////////////
     76 
     77 int HaiInitializeLibrary(const bcm2079x_dev_t* device) {
     78   ALOGD("%s: enter", __func__);
     79   ALOGE("%s: ver=%s nfa=%s", __func__, nfca_version_string, nfa_version_string);
     80   int retval = EACCES;
     81   unsigned long freq = 0;
     82   unsigned long num = 0;
     83   char temp[120];
     84   int8_t prop_value;
     85   uint8_t logLevel = 0;
     86 
     87   logLevel = InitializeGlobalAppLogLevel();
     88 
     89   if (GetNumValue(NAME_GLOBAL_RESET, &num, sizeof(num))) {
     90     if (num == 1) {
     91       // Send commands to disable boc
     92       p_nfc_hal_dm_pre_set_mem = nfc_hal_pre_set_mem_20795a1;
     93     }
     94   }
     95 
     96   configureCrystalFrequency();
     97   verify_hal_non_volatile_store();
     98   if (GetNumValue(NAME_PRESERVE_STORAGE, (char*)&num, sizeof(num)) &&
     99       (num == 1))
    100     ALOGD("%s: preserve HAL NV store", __func__);
    101   else {
    102     delete_hal_non_volatile_store(false);
    103   }
    104 
    105   if (GetNumValue(NAME_USE_RAW_NCI_TRACE, &num, sizeof(num))) {
    106     if (num == 1) {
    107       // display protocol traces in raw format
    108       ProtoDispAdapterUseRawOutput(TRUE);
    109     }
    110   }
    111 
    112   // Initialize protocol logging level
    113   InitializeProtocolLogLevel();
    114 
    115   tUSERIAL_OPEN_CFG cfg;
    116   struct tUART_CONFIG uart;
    117 
    118   if (GetStrValue(NAME_UART_PARITY, temp, sizeof(temp))) {
    119     if (strcmp(temp, "even") == 0)
    120       uart.m_iParity = USERIAL_PARITY_EVEN;
    121     else if (strcmp(temp, "odd") == 0)
    122       uart.m_iParity = USERIAL_PARITY_ODD;
    123     else if (strcmp(temp, "none") == 0)
    124       uart.m_iParity = USERIAL_PARITY_NONE;
    125   } else
    126     uart.m_iParity = USERIAL_PARITY_NONE;
    127 
    128   if (GetStrValue(NAME_UART_STOPBITS, temp, sizeof(temp))) {
    129     if (strcmp(temp, "1") == 0)
    130       uart.m_iStopbits = USERIAL_STOPBITS_1;
    131     else if (strcmp(temp, "2") == 0)
    132       uart.m_iStopbits = USERIAL_STOPBITS_2;
    133     else if (strcmp(temp, "1.5") == 0)
    134       uart.m_iStopbits = USERIAL_STOPBITS_1_5;
    135   } else if (GetNumValue(NAME_UART_STOPBITS, &num, sizeof(num))) {
    136     if (num == 1)
    137       uart.m_iStopbits = USERIAL_STOPBITS_1;
    138     else if (num == 2)
    139       uart.m_iStopbits = USERIAL_STOPBITS_2;
    140   } else
    141     uart.m_iStopbits = USERIAL_STOPBITS_1;
    142 
    143   if (GetNumValue(NAME_UART_DATABITS, &num, sizeof(num))) {
    144     if (5 <= num && num <= 8) uart.m_iDatabits = (1 << (num + 1));
    145   } else
    146     uart.m_iDatabits = USERIAL_DATABITS_8;
    147 
    148   if (GetNumValue(NAME_UART_BAUD, &num, sizeof(num))) {
    149     if (num == 300)
    150       uart.m_iBaudrate = USERIAL_BAUD_300;
    151     else if (num == 600)
    152       uart.m_iBaudrate = USERIAL_BAUD_600;
    153     else if (num == 1200)
    154       uart.m_iBaudrate = USERIAL_BAUD_1200;
    155     else if (num == 2400)
    156       uart.m_iBaudrate = USERIAL_BAUD_2400;
    157     else if (num == 9600)
    158       uart.m_iBaudrate = USERIAL_BAUD_9600;
    159     else if (num == 19200)
    160       uart.m_iBaudrate = USERIAL_BAUD_19200;
    161     else if (num == 57600)
    162       uart.m_iBaudrate = USERIAL_BAUD_57600;
    163     else if (num == 115200)
    164       uart.m_iBaudrate = USERIAL_BAUD_115200;
    165     else if (num == 230400)
    166       uart.m_iBaudrate = USERIAL_BAUD_230400;
    167     else if (num == 460800)
    168       uart.m_iBaudrate = USERIAL_BAUD_460800;
    169     else if (num == 921600)
    170       uart.m_iBaudrate = USERIAL_BAUD_921600;
    171   } else if (GetStrValue(NAME_UART_BAUD, temp, sizeof(temp))) {
    172     if (strcmp(temp, "auto") == 0) uart.m_iBaudrate = USERIAL_BAUD_AUTO;
    173   } else
    174     uart.m_iBaudrate = USERIAL_BAUD_115200;
    175 
    176   memset(&cfg, 0, sizeof(tUSERIAL_OPEN_CFG));
    177   cfg.fmt = uart.m_iDatabits | uart.m_iParity | uart.m_iStopbits;
    178   cfg.baud = uart.m_iBaudrate;
    179 
    180   ALOGD("%s: uart config=0x%04x, %d\n", __func__, cfg.fmt, cfg.baud);
    181   USERIAL_Init(&cfg);
    182 
    183   if (GetNumValue(NAME_NFCC_ENABLE_TIMEOUT, &num, sizeof(num))) {
    184     p_nfc_hal_cfg->nfc_hal_nfcc_enable_timeout = num;
    185   }
    186 
    187   if (GetNumValue(NAME_NFA_MAX_EE_SUPPORTED, &num, sizeof(num)) && num == 0) {
    188     // Since NFA_MAX_EE_SUPPORTED is explicetly set to 0, no UICC support is
    189     // needed.
    190     p_nfc_hal_cfg->nfc_hal_hci_uicc_support = 0;
    191   }
    192 
    193   prop_value = property_get_bool("nfc.bcm2079x.isColdboot", 0);
    194   if (prop_value) {
    195     isColdBoot = true;
    196     property_set("nfc.bcm2079x.isColdboot", "0");
    197   }
    198   // Set 'first boot' flag based on static variable that will get set to false
    199   // after the stack has first initialized the EE.
    200   p_nfc_hal_cfg->nfc_hal_first_boot = isColdBoot ? TRUE : FALSE;
    201 
    202   HAL_NfcInitialize();
    203   HAL_NfcSetTraceLevel(logLevel);  // Initialize HAL's logging level
    204 
    205   retval = 0;
    206   ALOGD("%s: exit %d", __func__, retval);
    207   return retval;
    208 }
    209 
    210 int HaiTerminateLibrary() {
    211   int retval = EACCES;
    212   ALOGD("%s: enter", __func__);
    213 
    214   HAL_NfcTerminate();
    215   gAndroidHalCallback = NULL;
    216   gAndroidHalDataCallback = NULL;
    217   GKI_shutdown();
    218   resetConfig();
    219   retval = 0;
    220   ALOGD("%s: exit %d", __func__, retval);
    221   return retval;
    222 }
    223 
    224 int HaiOpen(const bcm2079x_dev_t* device, nfc_stack_callback_t* halCallbackFunc,
    225             nfc_stack_data_callback_t* halDataCallbackFunc) {
    226   ALOGD("%s: enter", __func__);
    227   int retval = EACCES;
    228 
    229   gAndroidHalCallback = halCallbackFunc;
    230   gAndroidHalDataCallback = halDataCallbackFunc;
    231 
    232   SyncEventGuard guard(gOpenCompletedEvent);
    233   HAL_NfcOpen(BroadcomHalCallback, BroadcomHalDataCallback);
    234   gOpenCompletedEvent.wait();
    235 
    236   retval = 0;
    237   ALOGD("%s: exit %d", __func__, retval);
    238   return retval;
    239 }
    240 
    241 void BroadcomHalCallback(uint8_t event, tHAL_NFC_STATUS status) {
    242   ALOGD("%s: enter; event=0x%X", __func__, event);
    243   switch (event) {
    244     case HAL_NFC_OPEN_CPLT_EVT: {
    245       ALOGD("%s: HAL_NFC_OPEN_CPLT_EVT; status=0x%X", __func__, status);
    246       SyncEventGuard guard(gOpenCompletedEvent);
    247       gOpenCompletedEvent.notifyOne();
    248       break;
    249     }
    250 
    251     case HAL_NFC_POST_INIT_CPLT_EVT: {
    252       ALOGD("%s: HAL_NFC_POST_INIT_CPLT_EVT", __func__);
    253       SyncEventGuard guard(gPostInitCompletedEvent);
    254       gPostInitCompletedEvent.notifyOne();
    255       break;
    256     }
    257 
    258     case HAL_NFC_CLOSE_CPLT_EVT: {
    259       ALOGD("%s: HAL_NFC_CLOSE_CPLT_EVT", __func__);
    260       SyncEventGuard guard(gCloseCompletedEvent);
    261       gCloseCompletedEvent.notifyOne();
    262       break;
    263     }
    264 
    265     case HAL_NFC_ERROR_EVT: {
    266       ALOGD("%s: HAL_NFC_ERROR_EVT", __func__);
    267       {
    268         SyncEventGuard guard(gOpenCompletedEvent);
    269         gOpenCompletedEvent.notifyOne();
    270       }
    271       {
    272         SyncEventGuard guard(gPostInitCompletedEvent);
    273         gPostInitCompletedEvent.notifyOne();
    274       }
    275       {
    276         SyncEventGuard guard(gCloseCompletedEvent);
    277         gCloseCompletedEvent.notifyOne();
    278       }
    279       break;
    280     }
    281   }
    282   gAndroidHalCallback(event, status);
    283   ALOGD("%s: exit; event=0x%X", __func__, event);
    284 }
    285 
    286 void BroadcomHalDataCallback(uint16_t data_len, uint8_t* p_data) {
    287   ALOGD("%s: enter; len=%u", __func__, data_len);
    288   gAndroidHalDataCallback(data_len, p_data);
    289 }
    290 
    291 int HaiClose(const bcm2079x_dev_t* device) {
    292   ALOGD("%s: enter", __func__);
    293   int retval = EACCES;
    294 
    295   SyncEventGuard guard(gCloseCompletedEvent);
    296   HAL_NfcClose();
    297   gCloseCompletedEvent.wait();
    298   retval = 0;
    299   ALOGD("%s: exit %d", __func__, retval);
    300   return retval;
    301 }
    302 
    303 int HaiCoreInitialized(const bcm2079x_dev_t* device,
    304                        uint8_t* coreInitResponseParams) {
    305   ALOGD("%s: enter", __func__);
    306   int retval = EACCES;
    307 
    308   SyncEventGuard guard(gPostInitCompletedEvent);
    309   HAL_NfcCoreInitialized(0, coreInitResponseParams);
    310   gPostInitCompletedEvent.wait();
    311   retval = 0;
    312   ALOGD("%s: exit %d", __func__, retval);
    313   return retval;
    314 }
    315 
    316 int HaiWrite(const bcm2079x_dev_t* dev, uint16_t dataLen, const uint8_t* data) {
    317   ALOGD("%s: enter; len=%u", __func__, dataLen);
    318   int retval = EACCES;
    319 
    320   HAL_NfcWrite(dataLen, const_cast<uint8_t*>(data));
    321   retval = 0;
    322   ALOGD("%s: exit %d", __func__, retval);
    323   return retval;
    324 }
    325 
    326 int HaiPreDiscover(const bcm2079x_dev_t* device) {
    327   ALOGD("%s: enter", __func__);
    328   int retval = EACCES;
    329 
    330   // This function is a clear indication that the stack is initializing
    331   // EE.  So we can reset the cold-boot flag here.
    332   isColdBoot = false;
    333   retval = HAL_NfcPreDiscover() ? 1 : 0;
    334   ALOGD("%s: exit %d", __func__, retval);
    335   return retval;
    336 }
    337 
    338 int HaiControlGranted(const bcm2079x_dev_t* device) {
    339   ALOGD("%s: enter", __func__);
    340   int retval = EACCES;
    341 
    342   HAL_NfcControlGranted();
    343   retval = 0;
    344   ALOGD("%s: exit %d", __func__, retval);
    345   return retval;
    346 }
    347 
    348 int HaiPowerCycle(const bcm2079x_dev_t* device) {
    349   ALOGD("%s: enter", __func__);
    350   int retval = EACCES;
    351 
    352   HAL_NfcPowerCycle();
    353   retval = 0;
    354   ALOGD("%s: exit %d", __func__, retval);
    355   return retval;
    356 }
    357 
    358 int HaiGetMaxNfcee(const bcm2079x_dev_t* device, uint8_t* maxNfcee) {
    359   ALOGD("%s: enter", __func__);
    360   int retval = EACCES;
    361 
    362   // This function is a clear indication that the stack is initializing
    363   // EE.  So we can reset the cold-boot flag here.
    364   isColdBoot = false;
    365 
    366   if (maxNfcee) {
    367     *maxNfcee = HAL_NfcGetMaxNfcee();
    368     ALOGD("%s: max_ee from HAL to use %d", __func__, *maxNfcee);
    369     retval = 0;
    370   }
    371   ALOGD("%s: exit %d", __func__, retval);
    372   return retval;
    373 }
    374