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
HaiInitializeLibrary(const bcm2079x_dev_t * device)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
HaiTerminateLibrary()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
HaiOpen(const bcm2079x_dev_t * device,nfc_stack_callback_t * halCallbackFunc,nfc_stack_data_callback_t * halDataCallbackFunc)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
BroadcomHalCallback(uint8_t event,tHAL_NFC_STATUS status)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
BroadcomHalDataCallback(uint16_t data_len,uint8_t * p_data)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
HaiClose(const bcm2079x_dev_t * device)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
HaiCoreInitialized(const bcm2079x_dev_t * device,uint8_t * coreInitResponseParams)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
HaiWrite(const bcm2079x_dev_t * dev,uint16_t dataLen,const uint8_t * data)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
HaiPreDiscover(const bcm2079x_dev_t * device)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
HaiControlGranted(const bcm2079x_dev_t * device)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
HaiPowerCycle(const bcm2079x_dev_t * device)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
HaiGetMaxNfcee(const bcm2079x_dev_t * device,uint8_t * maxNfcee)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