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"
38extern void delete_hal_non_volatile_store(bool forceDelete);
39extern void verify_hal_non_volatile_store();
40extern void resetConfig();
41extern "C" {
42#include "userial.h"
43}
44
45extern void configureCrystalFrequency();
46
47///////////////////////////////////////
48// private declaration, definition
49
50static nfc_stack_callback_t* gAndroidHalCallback = NULL;
51static nfc_stack_data_callback_t* gAndroidHalDataCallback = NULL;
52static SyncEvent gOpenCompletedEvent;
53static SyncEvent gPostInitCompletedEvent;
54static SyncEvent gCloseCompletedEvent;
55
56uint32_t ScrProtocolTraceFlag = SCR_PROTO_TRACE_ALL;  // 0x017F00;
57
58static void BroadcomHalCallback(uint8_t event, tHAL_NFC_STATUS status);
59static void BroadcomHalDataCallback(uint16_t data_len, uint8_t* p_data);
60
61static bool isColdBoot = true;
62
63extern tNFC_HAL_CFG* p_nfc_hal_cfg;
64extern const uint8_t nfca_version_string[];
65extern const uint8_t nfa_version_string[];
66
67tNFC_HAL_DM_PRE_SET_MEM nfc_hal_pre_set_mem_20795a1[] = {
68    {0x0016403c, 0x00000008},
69    {0x0016403c, 0x00000000},
70    {0x0014008c, 0x00000001},
71    {0, 0}};
72
73extern tNFC_HAL_DM_PRE_SET_MEM* p_nfc_hal_dm_pre_set_mem;
74
75///////////////////////////////////////
76
77int 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
210int 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
224int 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
241void 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
286void 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
291int 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
303int 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
316int 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
326int 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
338int 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
348int 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
358int 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