Home | History | Annotate | Download | only in hal
      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