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
40static 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
49static 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
63const 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
71const 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*****************************************************************************/
82extern UINT8 *p_nfc_hal_dm_lptd_cfg;
83extern UINT8 *p_nfc_hal_dm_pll_325_cfg;
84extern UINT8 *p_nfc_hal_dm_start_up_cfg;
85extern UINT8 *p_nfc_hal_dm_start_up_vsc_cfg;
86extern tNFC_HAL_CFG *p_nfc_hal_cfg;
87extern 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*******************************************************************************/
102tHAL_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*******************************************************************************/
179void 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*******************************************************************************/
198void 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*******************************************************************************/
219void 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*******************************************************************************/
262void 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*******************************************************************************/
369tNFC_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*******************************************************************************/
399void 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*******************************************************************************/
441void 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*******************************************************************************/
466void 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*******************************************************************************/
483static 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*******************************************************************************/
501static 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*******************************************************************************/
531static 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*******************************************************************************/
557BOOLEAN 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*******************************************************************************/
597tNFC_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*******************************************************************************/
616void 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*******************************************************************************/
830void 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*******************************************************************************/
891void 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*******************************************************************************/
941void 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*******************************************************************************/
993void 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*******************************************************************************/
1049void 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*******************************************************************************/
1080BOOLEAN 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*******************************************************************************/
1126static 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*******************************************************************************/
1143void 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*******************************************************************************/
1174void 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*******************************************************************************/
1213void 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*******************************************************************************/
1241void 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*******************************************************************************/
1266tHAL_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*******************************************************************************/
1296static 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*******************************************************************************/
1358tHAL_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