1 /****************************************************************************** 2 * 3 * Copyright (C) 2012-2014 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 * 22 * Vendor-specific handler for DM events 23 * 24 ******************************************************************************/ 25 #include <string.h> 26 #include "nfc_hal_int.h" 27 #include "nfc_hal_post_reset.h" 28 #include "userial.h" 29 #include "upio.h" 30 31 /***************************************************************************** 32 ** Constants and types 33 *****************************************************************************/ 34 35 #define NFC_HAL_I93_RW_CFG_LEN (5) 36 #define NFC_HAL_I93_RW_CFG_PARAM_LEN (3) 37 #define NFC_HAL_I93_AFI (0) 38 #define NFC_HAL_I93_ENABLE_SMART_POLL (1) 39 40 static UINT8 nfc_hal_dm_i93_rw_cfg[NFC_HAL_I93_RW_CFG_LEN] = 41 { 42 NCI_PARAM_ID_I93_DATARATE, 43 NFC_HAL_I93_RW_CFG_PARAM_LEN, 44 NFC_HAL_I93_FLAG_DATA_RATE, /* Bit0:Sub carrier, Bit1:Data rate, Bit4:Enable/Disable AFI */ 45 NFC_HAL_I93_AFI, /* AFI if Bit 4 is set in the flag byte */ 46 NFC_HAL_I93_ENABLE_SMART_POLL /* Bit0:Enable/Disable smart poll */ 47 }; 48 49 static UINT8 nfc_hal_dm_set_fw_fsm_cmd[NCI_MSG_HDR_SIZE + 1] = 50 { 51 NCI_MTS_CMD|NCI_GID_PROP, 52 NCI_MSG_SET_FWFSM, 53 0x01, 54 0x00, 55 }; 56 #define NCI_SET_FWFSM_OFFSET_ENABLE 3 57 58 #define NCI_PROP_PARAM_SIZE_XTAL_INDEX 3 /* length of parameters in XTAL_INDEX CMD */ 59 #ifndef NCI_PROP_PARAM_MAX_SIZE_XTAL_INDEX 60 #define NCI_PROP_PARAM_MAX_SIZE_XTAL_INDEX 20 61 #endif 62 63 const UINT8 nfc_hal_dm_get_build_info_cmd[NCI_MSG_HDR_SIZE] = 64 { 65 NCI_MTS_CMD|NCI_GID_PROP, 66 NCI_MSG_GET_BUILD_INFO, 67 0x00 68 }; 69 #define NCI_BUILD_INFO_OFFSET_HWID 25 /* HW ID offset in build info RSP */ 70 71 const UINT8 nfc_hal_dm_get_patch_version_cmd [NCI_MSG_HDR_SIZE] = 72 { 73 NCI_MTS_CMD|NCI_GID_PROP, 74 NCI_MSG_GET_PATCH_VERSION, 75 0x00 76 }; 77 #define NCI_PATCH_INFO_VERSION_LEN 16 /* Length of patch version string in PATCH_INFO */ 78 79 /***************************************************************************** 80 ** Extern function prototypes 81 *****************************************************************************/ 82 extern UINT8 *p_nfc_hal_dm_lptd_cfg; 83 extern UINT8 *p_nfc_hal_dm_pll_325_cfg; 84 extern UINT8 *p_nfc_hal_dm_start_up_cfg; 85 extern UINT8 *p_nfc_hal_dm_start_up_vsc_cfg; 86 extern tNFC_HAL_CFG *p_nfc_hal_cfg; 87 extern tNFC_HAL_DM_PRE_SET_MEM *p_nfc_hal_dm_pre_set_mem; 88 89 /***************************************************************************** 90 ** Local function prototypes 91 *****************************************************************************/ 92 93 /******************************************************************************* 94 ** 95 ** Function nfc_hal_dm_set_config 96 ** 97 ** Description Send NCI config items to NFCC 98 ** 99 ** Returns tHAL_NFC_STATUS 100 ** 101 *******************************************************************************/ 102 tHAL_NFC_STATUS nfc_hal_dm_set_config (UINT8 tlv_size, 103 UINT8 *p_param_tlvs, 104 tNFC_HAL_NCI_CBACK *p_cback) 105 { 106 UINT8 *p_buff, *p; 107 UINT8 num_param = 0, param_len, rem_len, *p_tlv; 108 UINT16 cmd_len = NCI_MSG_HDR_SIZE + tlv_size + 1; 109 tHAL_NFC_STATUS status = HAL_NFC_STATUS_FAILED; 110 111 if ((tlv_size == 0)||(p_param_tlvs == NULL)) 112 { 113 return status; 114 } 115 116 if ((p_buff = (UINT8 *) GKI_getbuf ((UINT16)(NCI_MSG_HDR_SIZE + tlv_size))) != NULL) 117 { 118 p = p_buff; 119 120 NCI_MSG_BLD_HDR0 (p, NCI_MT_CMD, NCI_GID_CORE); 121 NCI_MSG_BLD_HDR1 (p, NCI_MSG_CORE_SET_CONFIG); 122 UINT8_TO_STREAM (p, (UINT8) (tlv_size + 1)); 123 124 rem_len = tlv_size; 125 p_tlv = p_param_tlvs; 126 while (rem_len > 1) 127 { 128 num_param++; /* number of params */ 129 130 p_tlv ++; /* param type */ 131 param_len = *p_tlv++; /* param length */ 132 133 rem_len -= 2; /* param type and length */ 134 if (rem_len >= param_len) 135 { 136 rem_len -= param_len; 137 p_tlv += param_len; /* next param_type */ 138 139 if (rem_len == 0) 140 { 141 status = HAL_NFC_STATUS_OK; 142 break; 143 } 144 } 145 else 146 { 147 /* error found */ 148 break; 149 } 150 } 151 152 if (status == HAL_NFC_STATUS_OK) 153 { 154 UINT8_TO_STREAM (p, num_param); 155 ARRAY_TO_STREAM (p, p_param_tlvs, tlv_size); 156 157 nfc_hal_dm_send_nci_cmd (p_buff, cmd_len, p_cback); 158 } 159 else 160 { 161 HAL_TRACE_ERROR0 ("nfc_hal_dm_set_config ():Bad TLV"); 162 } 163 164 GKI_freebuf (p_buff); 165 } 166 167 return status; 168 } 169 170 /******************************************************************************* 171 ** 172 ** Function nfc_hal_dm_set_fw_fsm 173 ** 174 ** Description Enable or disable FW FSM 175 ** 176 ** Returns void 177 ** 178 *******************************************************************************/ 179 void nfc_hal_dm_set_fw_fsm (BOOLEAN enable, tNFC_HAL_NCI_CBACK *p_cback) 180 { 181 if (enable) 182 nfc_hal_dm_set_fw_fsm_cmd[NCI_SET_FWFSM_OFFSET_ENABLE] = 0x01; /* Enable, default is disabled */ 183 else 184 nfc_hal_dm_set_fw_fsm_cmd[NCI_SET_FWFSM_OFFSET_ENABLE] = 0x00; /* Disable */ 185 186 nfc_hal_dm_send_nci_cmd (nfc_hal_dm_set_fw_fsm_cmd, NCI_MSG_HDR_SIZE + 1, p_cback); 187 } 188 189 /******************************************************************************* 190 ** 191 ** Function nfc_hal_dm_config_nfcc_cback 192 ** 193 ** Description Callback for NCI vendor specific command complete 194 ** 195 ** Returns void 196 ** 197 *******************************************************************************/ 198 void nfc_hal_dm_config_nfcc_cback (tNFC_HAL_NCI_EVT event, UINT16 data_len, UINT8 *p_data) 199 { 200 if (nfc_hal_cb.dev_cb.next_dm_config == NFC_HAL_DM_CONFIG_NONE) 201 { 202 nfc_hal_hci_enable (); 203 } 204 else 205 { 206 nfc_hal_dm_config_nfcc (); 207 } 208 } 209 210 /******************************************************************************* 211 ** 212 ** Function nfc_hal_dm_send_startup_vsc 213 ** 214 ** Description Send VS command before NFA start-up 215 ** 216 ** Returns None 217 ** 218 *******************************************************************************/ 219 void nfc_hal_dm_send_startup_vsc (void) 220 { 221 UINT8 *p, *p_end; 222 UINT16 len; 223 224 HAL_TRACE_DEBUG0 ("nfc_hal_dm_send_startup_vsc ()"); 225 226 /* VSC must have NCI header at least */ 227 if (nfc_hal_cb.dev_cb.next_startup_vsc + NCI_MSG_HDR_SIZE - 1 <= *p_nfc_hal_dm_start_up_vsc_cfg) 228 { 229 p = p_nfc_hal_dm_start_up_vsc_cfg + nfc_hal_cb.dev_cb.next_startup_vsc; 230 len = *(p + 2); 231 p_end = p + NCI_MSG_HDR_SIZE - 1 + len; 232 233 if (p_end <= p_nfc_hal_dm_start_up_vsc_cfg + *p_nfc_hal_dm_start_up_vsc_cfg) 234 { 235 /* move to next VSC */ 236 nfc_hal_cb.dev_cb.next_startup_vsc += NCI_MSG_HDR_SIZE + len; 237 238 /* if this is last VSC */ 239 if (p_end == p_nfc_hal_dm_start_up_vsc_cfg + *p_nfc_hal_dm_start_up_vsc_cfg) 240 nfc_hal_cb.dev_cb.next_dm_config = NFC_HAL_DM_CONFIG_NONE; 241 242 nfc_hal_dm_send_nci_cmd (p, (UINT16)(NCI_MSG_HDR_SIZE + len), nfc_hal_dm_config_nfcc_cback); 243 return; 244 } 245 } 246 247 HAL_TRACE_ERROR0 ("nfc_hal_dm_send_startup_vsc (): Bad start-up VSC"); 248 249 NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_IDLE); 250 nfc_hal_cb.p_stack_cback (HAL_NFC_POST_INIT_CPLT_EVT, HAL_NFC_STATUS_FAILED); 251 } 252 253 /******************************************************************************* 254 ** 255 ** Function nfc_hal_dm_config_nfcc 256 ** 257 ** Description Send VS config before NFA start-up 258 ** 259 ** Returns void 260 ** 261 *******************************************************************************/ 262 void nfc_hal_dm_config_nfcc (void) 263 { 264 HAL_TRACE_DEBUG1 ("nfc_hal_dm_config_nfcc (): next_dm_config = %d", nfc_hal_cb.dev_cb.next_dm_config); 265 266 if ((p_nfc_hal_dm_lptd_cfg[0]) && (nfc_hal_cb.dev_cb.next_dm_config <= NFC_HAL_DM_CONFIG_LPTD)) 267 { 268 nfc_hal_cb.dev_cb.next_dm_config = NFC_HAL_DM_CONFIG_PLL_325; 269 270 if (nfc_hal_dm_set_config (p_nfc_hal_dm_lptd_cfg[0], 271 &p_nfc_hal_dm_lptd_cfg[1], 272 nfc_hal_dm_config_nfcc_cback) == HAL_NFC_STATUS_OK) 273 { 274 return; 275 } 276 else 277 { 278 NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_IDLE); 279 nfc_hal_cb.p_stack_cback (HAL_NFC_POST_INIT_CPLT_EVT, HAL_NFC_STATUS_FAILED); 280 return; 281 } 282 } 283 284 if ((p_nfc_hal_dm_pll_325_cfg) && (nfc_hal_cb.dev_cb.next_dm_config <= NFC_HAL_DM_CONFIG_PLL_325)) 285 { 286 nfc_hal_cb.dev_cb.next_dm_config = NFC_HAL_DM_CONFIG_START_UP; 287 288 if (nfc_hal_dm_set_config (NFC_HAL_PLL_325_SETCONFIG_PARAM_LEN, 289 p_nfc_hal_dm_pll_325_cfg, 290 nfc_hal_dm_config_nfcc_cback) == HAL_NFC_STATUS_OK) 291 { 292 return; 293 } 294 else 295 { 296 NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_IDLE); 297 nfc_hal_cb.p_stack_cback (HAL_NFC_POST_INIT_CPLT_EVT, HAL_NFC_STATUS_FAILED); 298 return; 299 } 300 } 301 302 if ((p_nfc_hal_dm_start_up_cfg[0]) && (nfc_hal_cb.dev_cb.next_dm_config <= NFC_HAL_DM_CONFIG_START_UP)) 303 { 304 nfc_hal_cb.dev_cb.next_dm_config = NFC_HAL_DM_CONFIG_I93_DATA_RATE; 305 if (nfc_hal_dm_set_config (p_nfc_hal_dm_start_up_cfg[0], 306 &p_nfc_hal_dm_start_up_cfg[1], 307 nfc_hal_dm_config_nfcc_cback) == HAL_NFC_STATUS_OK) 308 { 309 return; 310 } 311 else 312 { 313 NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_IDLE); 314 nfc_hal_cb.p_stack_cback (HAL_NFC_POST_INIT_CPLT_EVT, HAL_NFC_STATUS_FAILED); 315 return; 316 } 317 } 318 319 #if (NFC_HAL_I93_FLAG_DATA_RATE == NFC_HAL_I93_FLAG_DATA_RATE_HIGH) 320 if (nfc_hal_cb.dev_cb.next_dm_config <= NFC_HAL_DM_CONFIG_I93_DATA_RATE) 321 { 322 nfc_hal_cb.dev_cb.next_dm_config = NFC_HAL_DM_CONFIG_FW_FSM; 323 if (nfc_hal_dm_set_config (NFC_HAL_I93_RW_CFG_LEN, 324 nfc_hal_dm_i93_rw_cfg, 325 nfc_hal_dm_config_nfcc_cback) == HAL_NFC_STATUS_OK) 326 { 327 return; 328 } 329 else 330 { 331 NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_IDLE); 332 nfc_hal_cb.p_stack_cback (HAL_NFC_POST_INIT_CPLT_EVT, HAL_NFC_STATUS_FAILED); 333 return; 334 } 335 } 336 #endif 337 338 /* FW FSM is disabled as default in NFCC */ 339 if (nfc_hal_cb.dev_cb.next_dm_config <= NFC_HAL_DM_CONFIG_FW_FSM) 340 { 341 nfc_hal_cb.dev_cb.next_dm_config = NFC_HAL_DM_CONFIG_START_UP_VSC; 342 nfc_hal_dm_set_fw_fsm (NFC_HAL_DM_MULTI_TECH_RESP, nfc_hal_dm_config_nfcc_cback); 343 return; 344 } 345 346 if (nfc_hal_cb.dev_cb.next_dm_config <= NFC_HAL_DM_CONFIG_START_UP_VSC) 347 { 348 if (p_nfc_hal_dm_start_up_vsc_cfg && *p_nfc_hal_dm_start_up_vsc_cfg) 349 { 350 nfc_hal_dm_send_startup_vsc (); 351 return; 352 } 353 } 354 355 /* nothing to config */ 356 nfc_hal_cb.dev_cb.next_dm_config = NFC_HAL_DM_CONFIG_NONE; 357 nfc_hal_dm_config_nfcc_cback (0, 0, NULL); 358 } 359 360 /******************************************************************************* 361 ** 362 ** Function: nfc_hal_dm_get_xtal_index 363 ** 364 ** Description: Return Xtal index and frequency 365 ** 366 ** Returns: tNFC_HAL_XTAL_INDEX 367 ** 368 *******************************************************************************/ 369 tNFC_HAL_XTAL_INDEX nfc_hal_dm_get_xtal_index (UINT32 brcm_hw_id, UINT16 *p_xtal_freq) 370 { 371 UINT8 xx; 372 373 HAL_TRACE_DEBUG1("nfc_hal_dm_get_xtal_index() brcm_hw_id:0x%x", brcm_hw_id); 374 375 for (xx = 0; xx < nfc_post_reset_cb.dev_init_config.num_xtal_cfg; xx++) 376 { 377 if ((brcm_hw_id & BRCM_NFC_GEN_MASK) 378 == nfc_post_reset_cb.dev_init_config.xtal_cfg[xx].brcm_hw_id) 379 { 380 *p_xtal_freq = nfc_post_reset_cb.dev_init_config.xtal_cfg[xx].xtal_freq; 381 return (nfc_post_reset_cb.dev_init_config.xtal_cfg[xx].xtal_index); 382 } 383 } 384 385 /* if not found */ 386 *p_xtal_freq = 0; 387 return (NFC_HAL_XTAL_INDEX_MAX); 388 } 389 390 /******************************************************************************* 391 ** 392 ** Function nfc_hal_dm_set_xtal_freq_index 393 ** 394 ** Description Set crystal frequency index 395 ** 396 ** Returns void 397 ** 398 *******************************************************************************/ 399 void nfc_hal_dm_set_xtal_freq_index (void) 400 { 401 UINT8 nci_brcm_xtal_index_cmd[NCI_MSG_HDR_SIZE + NCI_PROP_PARAM_MAX_SIZE_XTAL_INDEX]; 402 UINT8 *p; 403 tNFC_HAL_XTAL_INDEX xtal_index; 404 UINT16 xtal_freq; 405 UINT8 cmd_len = NCI_PROP_PARAM_SIZE_XTAL_INDEX; 406 extern UINT8 *p_nfc_hal_dm_xtal_params_cfg; 407 408 HAL_TRACE_DEBUG1 ("nfc_hal_dm_set_xtal_freq_index (): brcm_hw_id = 0x%x", nfc_hal_cb.dev_cb.brcm_hw_id); 409 410 xtal_index = nfc_hal_dm_get_xtal_index (nfc_hal_cb.dev_cb.brcm_hw_id, &xtal_freq); 411 if ((xtal_index == NFC_HAL_XTAL_INDEX_SPECIAL) && (p_nfc_hal_dm_xtal_params_cfg)) 412 { 413 cmd_len += p_nfc_hal_dm_xtal_params_cfg[0]; /* [0] is the length of extra params */ 414 } 415 416 p = nci_brcm_xtal_index_cmd; 417 UINT8_TO_STREAM (p, (NCI_MTS_CMD|NCI_GID_PROP)); 418 UINT8_TO_STREAM (p, NCI_MSG_GET_XTAL_INDEX_FROM_DH); 419 UINT8_TO_STREAM (p, cmd_len); 420 UINT8_TO_STREAM (p, xtal_index); 421 UINT16_TO_STREAM (p, xtal_freq); 422 if (cmd_len > NCI_PROP_PARAM_SIZE_XTAL_INDEX) 423 { 424 memcpy (p, &p_nfc_hal_dm_xtal_params_cfg[1], p_nfc_hal_dm_xtal_params_cfg[0]); 425 } 426 427 NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_W4_XTAL_SET); 428 429 nfc_hal_dm_send_nci_cmd (nci_brcm_xtal_index_cmd, NCI_MSG_HDR_SIZE + cmd_len, NULL); 430 } 431 432 /******************************************************************************* 433 ** 434 ** Function nfc_hal_dm_set_power_level_zero 435 ** 436 ** Description set power level to 0 437 ** 438 ** Returns None 439 ** 440 *******************************************************************************/ 441 void nfc_hal_dm_set_power_level_zero (void) 442 { 443 UINT8 nci_brcm_set_pwr_level_cmd[NCI_MSG_HDR_SIZE + NCI_PARAM_LEN_POWER_LEVEL]; 444 UINT8 *p; 445 UINT8 cmd_len = NCI_PARAM_LEN_POWER_LEVEL; 446 447 p = nci_brcm_set_pwr_level_cmd; 448 UINT8_TO_STREAM (p, (NCI_MTS_CMD|NCI_GID_PROP)); 449 UINT8_TO_STREAM (p, NCI_MSG_POWER_LEVEL); 450 UINT8_TO_STREAM (p, NCI_PARAM_LEN_POWER_LEVEL); 451 memset (p, 0, NCI_PARAM_LEN_POWER_LEVEL); 452 453 nfc_hal_dm_send_nci_cmd (nci_brcm_set_pwr_level_cmd, NCI_MSG_HDR_SIZE + cmd_len, 454 nfc_hal_main_exit_op_done); 455 } 456 457 /******************************************************************************* 458 ** 459 ** Function nfc_hal_dm_send_get_build_info_cmd 460 ** 461 ** Description Send NCI_MSG_GET_BUILD_INFO CMD 462 ** 463 ** Returns void 464 ** 465 *******************************************************************************/ 466 void nfc_hal_dm_send_get_build_info_cmd (void) 467 { 468 NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_W4_BUILD_INFO); 469 470 /* get build information to find out HW */ 471 nfc_hal_dm_send_nci_cmd (nfc_hal_dm_get_build_info_cmd, NCI_MSG_HDR_SIZE, NULL); 472 } 473 /******************************************************************************* 474 ** 475 ** Function: nfc_hal_dm_adjust_hw_id 476 ** 477 ** Description: The hw_id of certain chips are shifted by 8 bits. 478 ** Adjust the hw_id before processing. 479 ** 480 ** Returns: Nothing 481 ** 482 *******************************************************************************/ 483 static UINT32 nfc_hal_dm_adjust_hw_id (UINT32 hw_id) 484 { 485 if ((hw_id & 0xF0000000) == 0) 486 hw_id <<= 4; /* shift hw_id by 4 bits to align w the format of most chips */ 487 return hw_id; 488 } 489 490 491 /******************************************************************************* 492 ** 493 ** Function nfc_hal_dm_check_xtal 494 ** 495 ** Description check if need to send xtal command. 496 ** If not, proceed to next step get_patch_version. 497 ** 498 ** Returns void 499 ** 500 *******************************************************************************/ 501 static void nfc_hal_dm_check_xtal (void) 502 { 503 UINT16 xtal_freq; 504 tNFC_HAL_XTAL_INDEX xtal_index; 505 506 /* if NFCC needs to set Xtal frequency before getting patch version */ 507 xtal_index = nfc_hal_dm_get_xtal_index (nfc_hal_cb.dev_cb.brcm_hw_id, &xtal_freq); 508 if ((xtal_index < NFC_HAL_XTAL_INDEX_MAX) || (xtal_index == NFC_HAL_XTAL_INDEX_SPECIAL)) 509 { 510 { 511 /* set Xtal index before getting patch version */ 512 nfc_hal_dm_set_xtal_freq_index (); 513 return; 514 } 515 } 516 517 NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_W4_PATCH_INFO); 518 519 nfc_hal_dm_send_nci_cmd (nfc_hal_dm_get_patch_version_cmd, NCI_MSG_HDR_SIZE, NULL); 520 } 521 522 /******************************************************************************* 523 ** 524 ** Function nfc_hal_dm_pre_set_mem_cback 525 ** 526 ** Description This is pre-set mem complete callback. 527 ** 528 ** Returns void 529 ** 530 *******************************************************************************/ 531 static void nfc_hal_dm_pre_set_mem_cback (tNFC_HAL_BTVSC_CPLT *pData) 532 { 533 UINT8 status = pData->p_param_buf[0]; 534 535 HAL_TRACE_DEBUG1 ("nfc_hal_dm_pre_set_mem_cback: %d", status); 536 /* if it is completed */ 537 if (status == HCI_SUCCESS) 538 { 539 if (!nfc_hal_dm_check_pre_set_mem()) 540 { 541 return; 542 } 543 } 544 nfc_hal_dm_check_xtal(); 545 } 546 547 548 /******************************************************************************* 549 ** 550 ** Function nfc_hal_dm_check_pre_set_mem 551 ** 552 ** Description Check if need to send the command. 553 ** 554 ** Returns TRUE if done. 555 ** 556 *******************************************************************************/ 557 BOOLEAN nfc_hal_dm_check_pre_set_mem (void) 558 { 559 UINT8 cmd[NFC_HAL_BT_HCI_CMD_HDR_SIZE + HCI_BRCM_PRE_SET_MEM_LENGTH]; 560 UINT8 *p; 561 UINT32 addr = 0; 562 563 if (p_nfc_hal_dm_pre_set_mem) 564 addr = p_nfc_hal_dm_pre_set_mem[nfc_hal_cb.pre_set_mem_idx].addr; 565 HAL_TRACE_DEBUG2 ("nfc_hal_dm_check_pre_set_mem: %d/0x%x", nfc_hal_cb.pre_set_mem_idx, addr); 566 if (addr == 0) 567 { 568 return TRUE; 569 } 570 p = cmd; 571 572 /* Add the command */ 573 UINT16_TO_STREAM (p, HCI_BRCM_PRE_SET_MEM); 574 UINT8_TO_STREAM (p, HCI_BRCM_PRE_SET_MEM_LENGTH); 575 576 UINT8_TO_STREAM (p, HCI_BRCM_PRE_SET_MEM_TYPE); 577 UINT32_TO_STREAM (p, addr); 578 UINT8_TO_STREAM (p, 0); 579 UINT32_TO_STREAM (p, p_nfc_hal_dm_pre_set_mem[nfc_hal_cb.pre_set_mem_idx].data); 580 nfc_hal_cb.pre_set_mem_idx++; 581 582 nfc_hal_dm_send_bt_cmd (cmd, 583 NFC_HAL_BT_HCI_CMD_HDR_SIZE + HCI_BRCM_PRE_SET_MEM_LENGTH, 584 nfc_hal_dm_pre_set_mem_cback); 585 return FALSE; 586 } 587 588 /******************************************************************************* 589 ** 590 ** Function nfc_hal_dm_got_vs_rsp 591 ** 592 ** Description Received VS RSP. Clean up control block to allow next NCI cmd 593 ** 594 ** Returns void 595 ** 596 *******************************************************************************/ 597 tNFC_HAL_NCI_CBACK * nfc_hal_dm_got_vs_rsp (void) 598 { 599 tNFC_HAL_NCI_CBACK *p_cback = NULL; 600 nfc_hal_cb.ncit_cb.nci_wait_rsp = NFC_HAL_WAIT_RSP_NONE; 601 p_cback = (tNFC_HAL_NCI_CBACK *)nfc_hal_cb.ncit_cb.p_vsc_cback; 602 nfc_hal_cb.ncit_cb.p_vsc_cback = NULL; 603 nfc_hal_main_stop_quick_timer (&nfc_hal_cb.ncit_cb.nci_wait_rsp_timer); 604 return p_cback; 605 } 606 607 /******************************************************************************* 608 ** 609 ** Function nfc_hal_dm_proc_msg_during_init 610 ** 611 ** Description Process NCI message while initializing NFCC 612 ** 613 ** Returns void 614 ** 615 *******************************************************************************/ 616 void nfc_hal_dm_proc_msg_during_init (NFC_HDR *p_msg) 617 { 618 UINT8 *p; 619 UINT8 reset_reason, reset_type; 620 UINT8 mt, pbf, gid, op_code; 621 UINT8 *p_old, old_gid, old_oid, old_mt; 622 UINT8 u8; 623 tNFC_HAL_NCI_CBACK *p_cback = NULL; 624 UINT8 chipverlen; 625 UINT8 chipverstr[NCI_SPD_HEADER_CHIPVER_LEN]; 626 UINT32 hw_id = 0; 627 628 HAL_TRACE_DEBUG1 ("nfc_hal_dm_proc_msg_during_init(): init state:%d", nfc_hal_cb.dev_cb.initializing_state); 629 630 p = (UINT8 *) (p_msg + 1) + p_msg->offset; 631 632 NCI_MSG_PRS_HDR0 (p, mt, pbf, gid); 633 NCI_MSG_PRS_HDR1 (p, op_code); 634 635 /* check if waiting for this response */ 636 if ( (nfc_hal_cb.ncit_cb.nci_wait_rsp == NFC_HAL_WAIT_RSP_CMD) 637 ||(nfc_hal_cb.ncit_cb.nci_wait_rsp == NFC_HAL_WAIT_RSP_VSC) ) 638 { 639 if (mt == NCI_MT_RSP) 640 { 641 p_old = nfc_hal_cb.ncit_cb.last_hdr; 642 NCI_MSG_PRS_HDR0 (p_old, old_mt, pbf, old_gid); 643 old_oid = ((*p_old) & NCI_OID_MASK); 644 /* make sure this is the RSP we are waiting for before updating the command window */ 645 if ((old_gid == gid) && (old_oid == op_code)) 646 { 647 nfc_hal_cb.ncit_cb.nci_wait_rsp = NFC_HAL_WAIT_RSP_NONE; 648 p_cback = (tNFC_HAL_NCI_CBACK *)nfc_hal_cb.ncit_cb.p_vsc_cback; 649 nfc_hal_cb.ncit_cb.p_vsc_cback = NULL; 650 nfc_hal_main_stop_quick_timer (&nfc_hal_cb.ncit_cb.nci_wait_rsp_timer); 651 } 652 } 653 } 654 655 if (gid == NCI_GID_CORE) 656 { 657 if (op_code == NCI_MSG_CORE_RESET) 658 { 659 if (mt == NCI_MT_NTF) 660 { 661 if ( (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_NFCC_ENABLE) 662 ||(nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_POST_XTAL_SET) ) 663 { 664 /* 665 ** Core reset ntf in the following cases; 666 ** 1) after power up (raising REG_PU) 667 ** 2) after setting xtal index 668 ** Start pre-initializing NFCC 669 */ 670 nfc_hal_main_stop_quick_timer (&nfc_hal_cb.timer); 671 nfc_hal_dm_pre_init_nfcc (); 672 } 673 else 674 { 675 /* Core reset ntf after post-patch download, Call reset notification callback */ 676 p++; /* Skip over param len */ 677 STREAM_TO_UINT8 (reset_reason, p); 678 STREAM_TO_UINT8 (reset_type, p); 679 nfc_hal_prm_spd_reset_ntf (reset_reason, reset_type); 680 } 681 } 682 } 683 else if (p_cback) 684 { 685 (*p_cback) ((tNFC_HAL_NCI_EVT) (op_code), 686 p_msg->len, 687 (UINT8 *) (p_msg + 1) + p_msg->offset); 688 } 689 } 690 else if (gid == NCI_GID_PROP) /* this is for download patch */ 691 { 692 if (mt == NCI_MT_NTF) 693 op_code |= NCI_NTF_BIT; 694 else 695 op_code |= NCI_RSP_BIT; 696 697 if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_XTAL_SET) 698 { 699 if (op_code == (NCI_RSP_BIT|NCI_MSG_GET_XTAL_INDEX_FROM_DH)) 700 { 701 /* start timer in case that NFCC doesn't send RESET NTF after loading patch from NVM */ 702 NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_POST_XTAL_SET); 703 704 nfc_hal_main_start_quick_timer (&nfc_hal_cb.timer, NFC_HAL_TTYPE_NFCC_ENABLE, 705 ((p_nfc_hal_cfg->nfc_hal_post_xtal_timeout)*QUICK_TIMER_TICKS_PER_SEC)/1000); 706 } 707 } 708 else if ( (op_code == NFC_VS_GET_BUILD_INFO_EVT) 709 &&(nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_BUILD_INFO) ) 710 { 711 p += NCI_BUILD_INFO_OFFSET_HWID; 712 713 STREAM_TO_UINT32 (hw_id, p); 714 nfc_hal_cb.dev_cb.brcm_hw_id = nfc_hal_dm_adjust_hw_id (hw_id); 715 HAL_TRACE_DEBUG2 ("brcm_hw_id: 0x%x -> 0x%x", hw_id, nfc_hal_cb.dev_cb.brcm_hw_id); 716 717 STREAM_TO_UINT8 (chipverlen, p); 718 memset (chipverstr, 0, NCI_SPD_HEADER_CHIPVER_LEN); 719 720 STREAM_TO_ARRAY (chipverstr, p, chipverlen); 721 722 /* If chip is not 20791 and 43341, set flag to send the "Disable" VSC */ 723 if ( ((nfc_hal_cb.dev_cb.brcm_hw_id & BRCM_NFC_GEN_MASK) != BRCM_NFC_20791_GEN) 724 && ((nfc_hal_cb.dev_cb.brcm_hw_id & BRCM_NFC_GEN_MASK) != BRCM_NFC_43341_GEN) ) 725 { 726 nfc_hal_cb.hal_flags |= NFC_HAL_FLAGS_NEED_DISABLE_VSC; 727 } 728 729 nfc_hal_hci_handle_build_info (chipverlen, chipverstr); 730 nfc_hal_cb.pre_set_mem_idx = 0; 731 if (!nfc_hal_dm_check_pre_set_mem()) 732 { 733 /* pre-set mem started */ 734 return; 735 } 736 nfc_hal_dm_check_xtal(); 737 } 738 else if ( (op_code == NFC_VS_GET_PATCH_VERSION_EVT) 739 &&(nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_PATCH_INFO) ) 740 { 741 /* Store NVM info to control block */ 742 743 /* Skip over rsp len */ 744 p++; 745 746 /* Get project id */ 747 STREAM_TO_UINT16 (nfc_hal_cb.nvm_cb.project_id, p); 748 749 /* RFU */ 750 p++; 751 752 /* Get chip version string */ 753 STREAM_TO_UINT8 (u8, p); 754 if (u8 > NFC_HAL_PRM_MAX_CHIP_VER_LEN) 755 u8 = NFC_HAL_PRM_MAX_CHIP_VER_LEN; 756 memcpy (nfc_hal_cb.nvm_cb.chip_ver, p, u8); 757 p += NCI_PATCH_INFO_VERSION_LEN; 758 759 /* Get major/minor version */ 760 STREAM_TO_UINT16 (nfc_hal_cb.nvm_cb.ver_major, p); 761 STREAM_TO_UINT16 (nfc_hal_cb.nvm_cb.ver_minor, p); 762 763 /* Skip over max_size and patch_max_size */ 764 p += 4; 765 766 /* Get current lpm patch size */ 767 STREAM_TO_UINT16 (nfc_hal_cb.nvm_cb.lpm_size, p); 768 STREAM_TO_UINT16 (nfc_hal_cb.nvm_cb.fpm_size, p); 769 770 /* clear all flags which may be set during previous initialization */ 771 nfc_hal_cb.nvm_cb.flags = 0; 772 773 /* Set patch present flag */ 774 if ((nfc_hal_cb.nvm_cb.fpm_size) || (nfc_hal_cb.nvm_cb.lpm_size)) 775 nfc_hal_cb.nvm_cb.flags |= NFC_HAL_NVM_FLAGS_PATCH_PRESENT; 776 777 /* LPMPatchCodeHasBadCRC (if not bad crc, then indicate LPM patch is present in nvm) */ 778 STREAM_TO_UINT8 (u8, p); 779 if (u8) 780 { 781 /* LPM patch in NVM fails CRC check */ 782 nfc_hal_cb.nvm_cb.flags |= NFC_HAL_NVM_FLAGS_LPM_BAD; 783 } 784 785 786 /* FPMPatchCodeHasBadCRC (if not bad crc, then indicate LPM patch is present in nvm) */ 787 STREAM_TO_UINT8 (u8, p); 788 if (u8) 789 { 790 /* FPM patch in NVM fails CRC check */ 791 nfc_hal_cb.nvm_cb.flags |= NFC_HAL_NVM_FLAGS_FPM_BAD; 792 } 793 794 /* Check if downloading patch to RAM only (no NVM) */ 795 STREAM_TO_UINT8 (nfc_hal_cb.nvm_cb.nvm_type, p); 796 if (nfc_hal_cb.nvm_cb.nvm_type == NCI_SPD_NVM_TYPE_NONE) 797 { 798 nfc_hal_cb.nvm_cb.flags |= NFC_HAL_NVM_FLAGS_NO_NVM; 799 } 800 801 /* let platform update baudrate or download patch */ 802 NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_W4_APP_COMPLETE); 803 nfc_hal_post_reset_init (nfc_hal_cb.dev_cb.brcm_hw_id, nfc_hal_cb.nvm_cb.nvm_type); 804 } 805 else if (p_cback) 806 { 807 (*p_cback) ((tNFC_HAL_NCI_EVT) (op_code), 808 p_msg->len, 809 (UINT8 *) (p_msg + 1) + p_msg->offset); 810 } 811 else if (op_code == NFC_VS_SEC_PATCH_AUTH_EVT) 812 { 813 HAL_TRACE_DEBUG0 ("signature!!"); 814 nfc_hal_prm_nci_command_complete_cback ((tNFC_HAL_NCI_EVT) (op_code), 815 p_msg->len, 816 (UINT8 *) (p_msg + 1) + p_msg->offset); 817 } 818 } 819 } 820 821 /******************************************************************************* 822 ** 823 ** Function nfc_hal_dm_proc_msg_during_exit 824 ** 825 ** Description Process NCI message while shutting down NFCC 826 ** 827 ** Returns void 828 ** 829 *******************************************************************************/ 830 void nfc_hal_dm_proc_msg_during_exit (NFC_HDR *p_msg) 831 { 832 UINT8 *p; 833 UINT8 mt, pbf, gid, op_code; 834 UINT8 *p_old, old_gid, old_oid, old_mt; 835 UINT8 u8; 836 tNFC_HAL_NCI_CBACK *p_cback = NULL; 837 838 HAL_TRACE_DEBUG1 ("nfc_hal_dm_proc_msg_during_exit(): state:%d", nfc_hal_cb.dev_cb.initializing_state); 839 840 p = (UINT8 *) (p_msg + 1) + p_msg->offset; 841 842 NCI_MSG_PRS_HDR0 (p, mt, pbf, gid); 843 NCI_MSG_PRS_HDR1 (p, op_code); 844 u8 = *p; 845 846 /* check if waiting for this response */ 847 if ( (nfc_hal_cb.ncit_cb.nci_wait_rsp == NFC_HAL_WAIT_RSP_CMD) 848 ||(nfc_hal_cb.ncit_cb.nci_wait_rsp == NFC_HAL_WAIT_RSP_VSC) ) 849 { 850 if (mt == NCI_MT_RSP) 851 { 852 p_old = nfc_hal_cb.ncit_cb.last_hdr; 853 NCI_MSG_PRS_HDR0 (p_old, old_mt, pbf, old_gid); 854 old_oid = ((*p_old) & NCI_OID_MASK); 855 /* make sure this is the RSP we are waiting for before updating the command window */ 856 if ((old_gid == gid) && (old_oid == op_code)) 857 { 858 p_cback = nfc_hal_dm_got_vs_rsp (); 859 if (p_cback) 860 { 861 if (gid == NCI_GID_PROP) 862 { 863 if (mt == NCI_MT_NTF) 864 op_code |= NCI_NTF_BIT; 865 else 866 op_code |= NCI_RSP_BIT; 867 868 if (op_code == NFC_VS_POWER_LEVEL_RSP) 869 { 870 (*p_cback) ((tNFC_HAL_NCI_EVT) (op_code), 871 p_msg->len, 872 (UINT8 *) (p_msg + 1) + p_msg->offset); 873 } 874 } 875 } 876 } 877 } 878 } 879 880 } 881 882 /******************************************************************************* 883 ** 884 ** Function nfc_hal_dm_send_nci_cmd 885 ** 886 ** Description Send NCI command to NFCC while initializing BRCM NFCC 887 ** 888 ** Returns void 889 ** 890 *******************************************************************************/ 891 void nfc_hal_dm_send_nci_cmd (const UINT8 *p_data, UINT16 len, tNFC_HAL_NCI_CBACK *p_cback) 892 { 893 NFC_HDR *p_buf; 894 UINT8 *ps; 895 896 HAL_TRACE_DEBUG1 ("nfc_hal_dm_send_nci_cmd (): nci_wait_rsp = 0x%x", nfc_hal_cb.ncit_cb.nci_wait_rsp); 897 898 if (nfc_hal_cb.ncit_cb.nci_wait_rsp != NFC_HAL_WAIT_RSP_NONE) 899 { 900 HAL_TRACE_ERROR0 ("nfc_hal_dm_send_nci_cmd(): no command window"); 901 return; 902 } 903 904 if ((p_buf = (NFC_HDR *)GKI_getpoolbuf (NFC_HAL_NCI_POOL_ID)) != NULL) 905 { 906 nfc_hal_cb.ncit_cb.nci_wait_rsp = NFC_HAL_WAIT_RSP_VSC; 907 908 p_buf->offset = NFC_HAL_NCI_MSG_OFFSET_SIZE; 909 p_buf->event = NFC_HAL_EVT_TO_NFC_NCI; 910 p_buf->len = len; 911 912 memcpy ((UINT8*) (p_buf + 1) + p_buf->offset, p_data, len); 913 914 /* Keep a copy of the command and send to NCI transport */ 915 916 /* save the message header to double check the response */ 917 ps = (UINT8 *)(p_buf + 1) + p_buf->offset; 918 memcpy(nfc_hal_cb.ncit_cb.last_hdr, ps, NFC_HAL_SAVED_HDR_SIZE); 919 memcpy(nfc_hal_cb.ncit_cb.last_cmd, ps + NCI_MSG_HDR_SIZE, NFC_HAL_SAVED_CMD_SIZE); 920 921 /* save the callback for NCI VSCs */ 922 nfc_hal_cb.ncit_cb.p_vsc_cback = (void *)p_cback; 923 924 nfc_hal_nci_send_cmd (p_buf); 925 926 /* start NFC command-timeout timer */ 927 nfc_hal_main_start_quick_timer (&nfc_hal_cb.ncit_cb.nci_wait_rsp_timer, (UINT16)(NFC_HAL_TTYPE_NCI_WAIT_RSP), 928 ((UINT32) NFC_HAL_CMD_TOUT) * QUICK_TIMER_TICKS_PER_SEC / 1000); 929 } 930 } 931 932 /******************************************************************************* 933 ** 934 ** Function nfc_hal_dm_send_pend_cmd 935 ** 936 ** Description Send a command to NFCC 937 ** 938 ** Returns void 939 ** 940 *******************************************************************************/ 941 void nfc_hal_dm_send_pend_cmd (void) 942 { 943 NFC_HDR *p_buf = nfc_hal_cb.ncit_cb.p_pend_cmd; 944 UINT8 *p; 945 946 if (p_buf == NULL) 947 return; 948 949 /* check low power mode state */ 950 if (!nfc_hal_dm_power_mode_execute (NFC_HAL_LP_TX_DATA_EVT)) 951 { 952 return; 953 } 954 955 if (nfc_hal_cb.ncit_cb.nci_wait_rsp == NFC_HAL_WAIT_RSP_PROP) 956 { 957 #if (NFC_HAL_TRACE_PROTOCOL == TRUE) 958 DispHciCmd (p_buf); 959 #endif 960 961 /* save the message header to double check the response */ 962 p = (UINT8 *)(p_buf + 1) + p_buf->offset; 963 memcpy(nfc_hal_cb.ncit_cb.last_hdr, p, NFC_HAL_SAVED_HDR_SIZE); 964 965 /* add packet type for BT message */ 966 p_buf->offset--; 967 p_buf->len++; 968 969 p = (UINT8 *) (p_buf + 1) + p_buf->offset; 970 *p = HCIT_TYPE_COMMAND; 971 972 USERIAL_Write (USERIAL_NFC_PORT, p, p_buf->len); 973 974 GKI_freebuf (p_buf); 975 nfc_hal_cb.ncit_cb.p_pend_cmd = NULL; 976 977 /* start NFC command-timeout timer */ 978 nfc_hal_main_start_quick_timer (&nfc_hal_cb.ncit_cb.nci_wait_rsp_timer, (UINT16)(NFC_HAL_TTYPE_NCI_WAIT_RSP), 979 ((UINT32) NFC_HAL_CMD_TOUT) * QUICK_TIMER_TICKS_PER_SEC / 1000); 980 981 } 982 } 983 984 /******************************************************************************* 985 ** 986 ** Function nfc_hal_dm_send_bt_cmd 987 ** 988 ** Description Send BT message to NFCC while initializing BRCM NFCC 989 ** 990 ** Returns void 991 ** 992 *******************************************************************************/ 993 void nfc_hal_dm_send_bt_cmd (const UINT8 *p_data, UINT16 len, tNFC_HAL_BTVSC_CPLT_CBACK *p_cback) 994 { 995 NFC_HDR *p_buf; 996 char buff[300]; 997 char tmp[4]; 998 buff[0] = 0; 999 int i; 1000 1001 HAL_TRACE_DEBUG1 ("nfc_hal_dm_send_bt_cmd (): nci_wait_rsp = 0x%x", nfc_hal_cb.ncit_cb.nci_wait_rsp); 1002 1003 for (i = 0; i < len; i++) 1004 { 1005 sprintf (tmp, "%02x ", p_data[i]); 1006 strcat(buff, tmp); 1007 } 1008 HAL_TRACE_DEBUG2 ("nfc_hal_dm_send_bt_cmd (): HCI Write (%d bytes): %s", len, buff); 1009 1010 if (nfc_hal_cb.ncit_cb.nci_wait_rsp != NFC_HAL_WAIT_RSP_NONE) 1011 { 1012 HAL_TRACE_ERROR0 ("nfc_hal_dm_send_bt_cmd(): no command window"); 1013 return; 1014 } 1015 1016 if ((p_buf = (NFC_HDR *) GKI_getpoolbuf (NFC_HAL_NCI_POOL_ID)) != NULL) 1017 { 1018 nfc_hal_cb.ncit_cb.nci_wait_rsp = NFC_HAL_WAIT_RSP_PROP; 1019 1020 p_buf->offset = NFC_HAL_NCI_MSG_OFFSET_SIZE; 1021 p_buf->len = len; 1022 1023 memcpy ((UINT8*) (p_buf + 1) + p_buf->offset, p_data, len); 1024 1025 /* save the callback for NCI VSCs) */ 1026 nfc_hal_cb.ncit_cb.p_vsc_cback = (void *)p_cback; 1027 1028 nfc_hal_cb.ncit_cb.p_pend_cmd = p_buf; 1029 if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_IDLE) 1030 { 1031 NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_W4_CONTROL_DONE); 1032 nfc_hal_cb.p_stack_cback (HAL_NFC_REQUEST_CONTROL_EVT, HAL_NFC_STATUS_OK); 1033 return; 1034 } 1035 1036 nfc_hal_dm_send_pend_cmd(); 1037 } 1038 } 1039 1040 /******************************************************************************* 1041 ** 1042 ** Function nfc_hal_dm_set_nfc_wake 1043 ** 1044 ** Description Set NFC_WAKE line 1045 ** 1046 ** Returns void 1047 ** 1048 *******************************************************************************/ 1049 void nfc_hal_dm_set_nfc_wake (UINT8 cmd) 1050 { 1051 HAL_TRACE_DEBUG1 ("nfc_hal_dm_set_nfc_wake () %s", 1052 (cmd == NFC_HAL_ASSERT_NFC_WAKE ? "ASSERT" : "DEASSERT")); 1053 1054 /* 1055 ** nfc_wake_active_mode cmd result of voltage on NFC_WAKE 1056 ** 1057 ** NFC_HAL_LP_ACTIVE_LOW (0) NFC_HAL_ASSERT_NFC_WAKE (0) pull down NFC_WAKE (GND) 1058 ** NFC_HAL_LP_ACTIVE_LOW (0) NFC_HAL_DEASSERT_NFC_WAKE (1) pull up NFC_WAKE (VCC) 1059 ** NFC_HAL_LP_ACTIVE_HIGH (1) NFC_HAL_ASSERT_NFC_WAKE (0) pull up NFC_WAKE (VCC) 1060 ** NFC_HAL_LP_ACTIVE_HIGH (1) NFC_HAL_DEASSERT_NFC_WAKE (1) pull down NFC_WAKE (GND) 1061 */ 1062 1063 if (cmd == nfc_hal_cb.dev_cb.nfc_wake_active_mode) 1064 UPIO_Set (UPIO_GENERAL, NFC_HAL_LP_NFC_WAKE_GPIO, UPIO_OFF); /* pull down NFC_WAKE */ 1065 else 1066 UPIO_Set (UPIO_GENERAL, NFC_HAL_LP_NFC_WAKE_GPIO, UPIO_ON); /* pull up NFC_WAKE */ 1067 } 1068 1069 /******************************************************************************* 1070 ** 1071 ** Function nfc_hal_dm_power_mode_execute 1072 ** 1073 ** Description If snooze mode is enabled in full power mode, 1074 ** Assert NFC_WAKE before sending data 1075 ** Deassert NFC_WAKE when idle timer expires 1076 ** 1077 ** Returns TRUE if DH can send data to NFCC 1078 ** 1079 *******************************************************************************/ 1080 BOOLEAN nfc_hal_dm_power_mode_execute (tNFC_HAL_LP_EVT event) 1081 { 1082 BOOLEAN send_to_nfcc = FALSE; 1083 1084 HAL_TRACE_DEBUG1 ("nfc_hal_dm_power_mode_execute () event = %d", event); 1085 1086 if (nfc_hal_cb.dev_cb.power_mode == NFC_HAL_POWER_MODE_FULL) 1087 { 1088 if (nfc_hal_cb.dev_cb.snooze_mode != NFC_HAL_LP_SNOOZE_MODE_NONE) 1089 { 1090 /* if any transport activity */ 1091 if ( (event == NFC_HAL_LP_TX_DATA_EVT) 1092 ||(event == NFC_HAL_LP_RX_DATA_EVT) ) 1093 { 1094 /* if idle timer is not running */ 1095 if (nfc_hal_cb.dev_cb.lp_timer.in_use == FALSE) 1096 { 1097 nfc_hal_dm_set_nfc_wake (NFC_HAL_ASSERT_NFC_WAKE); 1098 } 1099 1100 /* start or extend idle timer */ 1101 nfc_hal_main_start_quick_timer (&nfc_hal_cb.dev_cb.lp_timer, 0x00, 1102 ((UINT32) NFC_HAL_LP_IDLE_TIMEOUT) * QUICK_TIMER_TICKS_PER_SEC / 1000); 1103 } 1104 else if (event == NFC_HAL_LP_TIMEOUT_EVT) 1105 { 1106 /* let NFCC go to snooze mode */ 1107 nfc_hal_dm_set_nfc_wake (NFC_HAL_DEASSERT_NFC_WAKE); 1108 } 1109 } 1110 1111 send_to_nfcc = TRUE; 1112 } 1113 1114 return (send_to_nfcc); 1115 } 1116 1117 /******************************************************************************* 1118 ** 1119 ** Function nci_brcm_lp_timeout_cback 1120 ** 1121 ** Description callback function for low power timeout 1122 ** 1123 ** Returns void 1124 ** 1125 *******************************************************************************/ 1126 static void nci_brcm_lp_timeout_cback (void *p_tle) 1127 { 1128 HAL_TRACE_DEBUG0 ("nci_brcm_lp_timeout_cback ()"); 1129 1130 nfc_hal_dm_power_mode_execute (NFC_HAL_LP_TIMEOUT_EVT); 1131 } 1132 1133 /******************************************************************************* 1134 ** 1135 ** Function nfc_hal_dm_pre_init_nfcc 1136 ** 1137 ** Description This function initializes Broadcom specific control blocks for 1138 ** NCI transport 1139 ** 1140 ** Returns void 1141 ** 1142 *******************************************************************************/ 1143 void nfc_hal_dm_pre_init_nfcc (void) 1144 { 1145 HAL_TRACE_DEBUG0 ("nfc_hal_dm_pre_init_nfcc ()"); 1146 1147 /* if it was waiting for core reset notification after raising REG_PU */ 1148 if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_NFCC_ENABLE) 1149 { 1150 nfc_hal_dm_send_get_build_info_cmd (); 1151 } 1152 /* if it was waiting for core reset notification after setting Xtal */ 1153 else if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_POST_XTAL_SET) 1154 { 1155 { 1156 /* Core reset ntf after xtal setting indicating NFCC loaded patch from NVM */ 1157 NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_W4_PATCH_INFO); 1158 1159 nfc_hal_dm_send_nci_cmd (nfc_hal_dm_get_patch_version_cmd, NCI_MSG_HDR_SIZE, NULL); 1160 } 1161 } 1162 } 1163 1164 /******************************************************************************* 1165 ** 1166 ** Function nfc_hal_dm_shutting_down_nfcc 1167 ** 1168 ** Description This function initializes Broadcom specific control blocks for 1169 ** NCI transport 1170 ** 1171 ** Returns void 1172 ** 1173 *******************************************************************************/ 1174 void nfc_hal_dm_shutting_down_nfcc (void) 1175 { 1176 HAL_TRACE_DEBUG0 ("nfc_hal_dm_shutting_down_nfcc ()"); 1177 1178 nfc_hal_cb.dev_cb.initializing_state = NFC_HAL_INIT_STATE_CLOSING; 1179 1180 /* reset low power mode variables */ 1181 if ( (nfc_hal_cb.dev_cb.power_mode == NFC_HAL_POWER_MODE_FULL) 1182 &&(nfc_hal_cb.dev_cb.snooze_mode != NFC_HAL_LP_SNOOZE_MODE_NONE) ) 1183 { 1184 nfc_hal_dm_set_nfc_wake (NFC_HAL_ASSERT_NFC_WAKE); 1185 } 1186 1187 nfc_hal_cb.ncit_cb.nci_wait_rsp = NFC_HAL_WAIT_RSP_NONE; 1188 1189 nfc_hal_cb.dev_cb.power_mode = NFC_HAL_POWER_MODE_FULL; 1190 nfc_hal_cb.dev_cb.snooze_mode = NFC_HAL_LP_SNOOZE_MODE_NONE; 1191 1192 /* Stop all timers */ 1193 nfc_hal_main_stop_quick_timer (&nfc_hal_cb.ncit_cb.nci_wait_rsp_timer); 1194 nfc_hal_main_stop_quick_timer (&nfc_hal_cb.dev_cb.lp_timer); 1195 nfc_hal_main_stop_quick_timer (&nfc_hal_cb.prm.timer); 1196 #if (defined(NFC_HAL_HCI_INCLUDED) && (NFC_HAL_HCI_INCLUDED == TRUE)) 1197 nfc_hal_cb.hci_cb.hcp_conn_id = 0; 1198 nfc_hal_main_stop_quick_timer (&nfc_hal_cb.hci_cb.hci_timer); 1199 #endif 1200 nfc_hal_main_stop_quick_timer (&nfc_hal_cb.timer); 1201 } 1202 1203 /******************************************************************************* 1204 ** 1205 ** Function nfc_hal_dm_init 1206 ** 1207 ** Description This function initializes Broadcom specific control blocks for 1208 ** NCI transport 1209 ** 1210 ** Returns void 1211 ** 1212 *******************************************************************************/ 1213 void nfc_hal_dm_init (void) 1214 { 1215 HAL_TRACE_DEBUG0 ("nfc_hal_dm_init ()"); 1216 1217 nfc_hal_cb.dev_cb.lp_timer.p_cback = nci_brcm_lp_timeout_cback; 1218 1219 nfc_hal_cb.ncit_cb.nci_wait_rsp_timer.p_cback = nfc_hal_nci_cmd_timeout_cback; 1220 1221 #if (defined(NFC_HAL_HCI_INCLUDED) && (NFC_HAL_HCI_INCLUDED == TRUE)) 1222 nfc_hal_cb.hci_cb.hci_timer.p_cback = nfc_hal_hci_timeout_cback; 1223 #endif 1224 1225 nfc_hal_cb.pre_discover_done = FALSE; 1226 1227 nfc_post_reset_cb.spd_nvm_detection_cur_count = 0; 1228 nfc_post_reset_cb.spd_skip_on_power_cycle = FALSE; 1229 1230 } 1231 1232 /******************************************************************************* 1233 ** 1234 ** Function HAL_NfcDevInitDone 1235 ** 1236 ** Description Notify that pre-initialization of NFCC is complete 1237 ** 1238 ** Returns void 1239 ** 1240 *******************************************************************************/ 1241 void HAL_NfcPreInitDone (tHAL_NFC_STATUS status) 1242 { 1243 HAL_TRACE_DEBUG1 ("HAL_NfcPreInitDone () status=%d", status); 1244 1245 if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_APP_COMPLETE) 1246 { 1247 NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_IDLE); 1248 1249 nfc_hal_main_pre_init_done (status); 1250 } 1251 } 1252 1253 /******************************************************************************* 1254 ** 1255 ** Function HAL_NfcReInit 1256 ** 1257 ** Description This function is called to restart initialization after REG_PU 1258 ** toggled because of failure to detect NVM type or download patchram. 1259 ** 1260 ** Note This function should be called only during the HAL init process 1261 ** 1262 ** Returns HAL_NFC_STATUS_OK if successfully initiated 1263 ** HAL_NFC_STATUS_FAILED otherwise 1264 ** 1265 *******************************************************************************/ 1266 tHAL_NFC_STATUS HAL_NfcReInit (void) 1267 { 1268 tHAL_NFC_STATUS status = HAL_NFC_STATUS_FAILED; 1269 1270 HAL_TRACE_DEBUG1 ("HAL_NfcReInit () init st=0x%x", nfc_hal_cb.dev_cb.initializing_state); 1271 if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_APP_COMPLETE) 1272 { 1273 { 1274 /* Wait for NFCC to enable - Core reset notification */ 1275 NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_W4_NFCC_ENABLE); 1276 1277 /* NFCC Enable timeout */ 1278 nfc_hal_main_start_quick_timer (&nfc_hal_cb.timer, NFC_HAL_TTYPE_NFCC_ENABLE, 1279 ((p_nfc_hal_cfg->nfc_hal_nfcc_enable_timeout)*QUICK_TIMER_TICKS_PER_SEC)/1000); 1280 } 1281 1282 status = HAL_NFC_STATUS_OK; 1283 } 1284 return status; 1285 } 1286 1287 /******************************************************************************* 1288 ** 1289 ** Function nfc_hal_dm_set_snooze_mode_cback 1290 ** 1291 ** Description This is snooze update complete callback. 1292 ** 1293 ** Returns void 1294 ** 1295 *******************************************************************************/ 1296 static void nfc_hal_dm_set_snooze_mode_cback (tNFC_HAL_BTVSC_CPLT *pData) 1297 { 1298 UINT8 status = pData->p_param_buf[0]; 1299 tHAL_NFC_STATUS hal_status; 1300 tHAL_NFC_STATUS_CBACK *p_cback; 1301 1302 /* if it is completed */ 1303 if (status == HCI_SUCCESS) 1304 { 1305 /* update snooze mode */ 1306 nfc_hal_cb.dev_cb.snooze_mode = nfc_hal_cb.dev_cb.new_snooze_mode; 1307 1308 nfc_hal_dm_set_nfc_wake (NFC_HAL_ASSERT_NFC_WAKE); 1309 1310 if ( nfc_hal_cb.dev_cb.snooze_mode != NFC_HAL_LP_SNOOZE_MODE_NONE) 1311 { 1312 /* start idle timer */ 1313 nfc_hal_main_start_quick_timer (&nfc_hal_cb.dev_cb.lp_timer, 0x00, 1314 ((UINT32) NFC_HAL_LP_IDLE_TIMEOUT) * QUICK_TIMER_TICKS_PER_SEC / 1000); 1315 } 1316 else 1317 { 1318 nfc_hal_main_stop_quick_timer (&nfc_hal_cb.dev_cb.lp_timer); 1319 } 1320 hal_status = HAL_NFC_STATUS_OK; 1321 } 1322 else 1323 { 1324 hal_status = HAL_NFC_STATUS_FAILED; 1325 } 1326 1327 if (nfc_hal_cb.dev_cb.p_prop_cback) 1328 { 1329 p_cback = nfc_hal_cb.dev_cb.p_prop_cback; 1330 nfc_hal_cb.dev_cb.p_prop_cback = NULL; 1331 (*p_cback) (hal_status); 1332 } 1333 } 1334 1335 /******************************************************************************* 1336 ** 1337 ** Function HAL_NfcSetSnoozeMode 1338 ** 1339 ** Description Set snooze mode 1340 ** snooze_mode 1341 ** NFC_HAL_LP_SNOOZE_MODE_NONE - Snooze mode disabled 1342 ** NFC_HAL_LP_SNOOZE_MODE_UART - Snooze mode for UART 1343 ** NFC_HAL_LP_SNOOZE_MODE_SPI_I2C - Snooze mode for SPI/I2C 1344 ** 1345 ** idle_threshold_dh/idle_threshold_nfcc 1346 ** Idle Threshold Host in 100ms unit 1347 ** 1348 ** nfc_wake_active_mode/dh_wake_active_mode 1349 ** NFC_HAL_LP_ACTIVE_LOW - high to low voltage is asserting 1350 ** NFC_HAL_LP_ACTIVE_HIGH - low to high voltage is asserting 1351 ** 1352 ** p_snooze_cback 1353 ** Notify status of operation 1354 ** 1355 ** Returns tHAL_NFC_STATUS 1356 ** 1357 *******************************************************************************/ 1358 tHAL_NFC_STATUS HAL_NfcSetSnoozeMode (UINT8 snooze_mode, 1359 UINT8 idle_threshold_dh, 1360 UINT8 idle_threshold_nfcc, 1361 UINT8 nfc_wake_active_mode, 1362 UINT8 dh_wake_active_mode, 1363 tHAL_NFC_STATUS_CBACK *p_snooze_cback) 1364 { 1365 UINT8 cmd[NFC_HAL_BT_HCI_CMD_HDR_SIZE + HCI_BRCM_WRITE_SLEEP_MODE_LENGTH]; 1366 UINT8 *p; 1367 1368 HAL_TRACE_API1 ("HAL_NfcSetSnoozeMode (): snooze_mode = %d", snooze_mode); 1369 1370 nfc_hal_cb.dev_cb.new_snooze_mode = snooze_mode; 1371 nfc_hal_cb.dev_cb.nfc_wake_active_mode = nfc_wake_active_mode; 1372 nfc_hal_cb.dev_cb.p_prop_cback = p_snooze_cback; 1373 1374 p = cmd; 1375 1376 /* Add the HCI command */ 1377 UINT16_TO_STREAM (p, HCI_BRCM_WRITE_SLEEP_MODE); 1378 UINT8_TO_STREAM (p, HCI_BRCM_WRITE_SLEEP_MODE_LENGTH); 1379 1380 memset (p, 0x00, HCI_BRCM_WRITE_SLEEP_MODE_LENGTH); 1381 1382 UINT8_TO_STREAM (p, snooze_mode); /* Sleep Mode */ 1383 1384 UINT8_TO_STREAM (p, idle_threshold_dh); /* Idle Threshold Host */ 1385 UINT8_TO_STREAM (p, idle_threshold_nfcc); /* Idle Threshold HC */ 1386 UINT8_TO_STREAM (p, nfc_wake_active_mode); /* BT Wake Active Mode */ 1387 UINT8_TO_STREAM (p, dh_wake_active_mode); /* Host Wake Active Mode */ 1388 1389 nfc_hal_dm_send_bt_cmd (cmd, 1390 NFC_HAL_BT_HCI_CMD_HDR_SIZE + HCI_BRCM_WRITE_SLEEP_MODE_LENGTH, 1391 nfc_hal_dm_set_snooze_mode_cback); 1392 return (NCI_STATUS_OK); 1393 } 1394 1395 1396 1397 1398 1399 1400 1401 1402