• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 *******************************************************************************/
nfc_hal_dm_set_config(UINT8 tlv_size,UINT8 * p_param_tlvs,tNFC_HAL_NCI_CBACK * p_cback)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 *******************************************************************************/
nfc_hal_dm_set_fw_fsm(BOOLEAN enable,tNFC_HAL_NCI_CBACK * p_cback)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 *******************************************************************************/
nfc_hal_dm_config_nfcc_cback(tNFC_HAL_NCI_EVT event,UINT16 data_len,UINT8 * p_data)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 *******************************************************************************/
nfc_hal_dm_send_startup_vsc(void)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 *******************************************************************************/
nfc_hal_dm_config_nfcc(void)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 *******************************************************************************/
nfc_hal_dm_get_xtal_index(UINT32 brcm_hw_id,UINT16 * p_xtal_freq)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 *******************************************************************************/
nfc_hal_dm_set_xtal_freq_index(void)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 *******************************************************************************/
nfc_hal_dm_set_power_level_zero(void)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 *******************************************************************************/
nfc_hal_dm_send_get_build_info_cmd(void)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 *******************************************************************************/
nfc_hal_dm_adjust_hw_id(UINT32 hw_id)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 *******************************************************************************/
nfc_hal_dm_check_xtal(void)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 *******************************************************************************/
nfc_hal_dm_pre_set_mem_cback(tNFC_HAL_BTVSC_CPLT * pData)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 *******************************************************************************/
nfc_hal_dm_check_pre_set_mem(void)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 *******************************************************************************/
nfc_hal_dm_got_vs_rsp(void)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 *******************************************************************************/
nfc_hal_dm_proc_msg_during_init(NFC_HDR * p_msg)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 *******************************************************************************/
nfc_hal_dm_proc_msg_during_exit(NFC_HDR * p_msg)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 *******************************************************************************/
nfc_hal_dm_send_nci_cmd(const UINT8 * p_data,UINT16 len,tNFC_HAL_NCI_CBACK * p_cback)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 *******************************************************************************/
nfc_hal_dm_send_pend_cmd(void)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 *******************************************************************************/
nfc_hal_dm_send_bt_cmd(const UINT8 * p_data,UINT16 len,tNFC_HAL_BTVSC_CPLT_CBACK * p_cback)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 *******************************************************************************/
nfc_hal_dm_set_nfc_wake(UINT8 cmd)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 *******************************************************************************/
nfc_hal_dm_power_mode_execute(tNFC_HAL_LP_EVT event)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 *******************************************************************************/
nci_brcm_lp_timeout_cback(void * p_tle)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 *******************************************************************************/
nfc_hal_dm_pre_init_nfcc(void)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 *******************************************************************************/
nfc_hal_dm_shutting_down_nfcc(void)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 *******************************************************************************/
nfc_hal_dm_init(void)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 *******************************************************************************/
HAL_NfcPreInitDone(tHAL_NFC_STATUS status)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 *******************************************************************************/
HAL_NfcReInit(void)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 *******************************************************************************/
nfc_hal_dm_set_snooze_mode_cback(tNFC_HAL_BTVSC_CPLT * pData)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 *******************************************************************************/
HAL_NfcSetSnoozeMode(UINT8 snooze_mode,UINT8 idle_threshold_dh,UINT8 idle_threshold_nfcc,UINT8 nfc_wake_active_mode,UINT8 dh_wake_active_mode,tHAL_NFC_STATUS_CBACK * p_snooze_cback)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