1/******************************************************************************
2 *
3 *  Copyright (C) 1999-2012 Broadcom Corporation
4 *
5 *  Licensed under the Apache License, Version 2.0 (the "License");
6 *  you may not use this file except in compliance with the License.
7 *  You may obtain a copy of the License at:
8 *
9 *  http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 *
17 ******************************************************************************/
18#include "OverrideLog.h"
19#include "config.h"
20#include "nfc_hal_int.h"
21#include "userial.h"
22extern "C"
23{
24    #include "nfc_hal_post_reset.h"
25}
26#include <malloc.h>
27#include <string>
28#include <cutils/properties.h>
29#include "spdhelper.h"
30#include "StartupConfig.h"
31
32#define LOG_TAG "NfcNciHal"
33
34#define FW_PRE_PATCH                        "FW_PRE_PATCH"
35#define FW_PATCH                            "FW_PATCH"
36#define MAX_RF_DATA_CREDITS                 "MAX_RF_DATA_CREDITS"
37
38#define MAX_BUFFER      (512)
39static char sPrePatchFn[MAX_BUFFER+1];
40static char sPatchFn[MAX_BUFFER+1];
41static void * sPrmBuf = NULL;
42static void * sI2cFixPrmBuf = NULL;
43
44#define CONFIG_MAX_LEN 256
45static UINT8 sConfig [CONFIG_MAX_LEN];
46static StartupConfig sStartupConfig;
47static StartupConfig sLptdConfig;
48static StartupConfig sPreDiscoveryConfig;
49static StartupConfig sXtalCustomParam;
50extern UINT8 *p_nfc_hal_dm_start_up_cfg; //defined in the HAL
51static UINT8 nfa_dm_start_up_vsc_cfg[CONFIG_MAX_LEN];
52extern UINT8 *p_nfc_hal_dm_start_up_vsc_cfg; //defined in the HAL
53extern UINT8 *p_nfc_hal_dm_lptd_cfg; //defined in the HAL
54static UINT8 sDontSendLptd[] = { 0 };
55extern UINT8 *p_nfc_hal_pre_discover_cfg; //defined in the HAL
56extern UINT8 *p_nfc_hal_dm_xtal_params_cfg; //defined in HAL
57
58extern tSNOOZE_MODE_CONFIG gSnoozeModeCfg;
59extern tNFC_HAL_CFG *p_nfc_hal_cfg;
60static void mayDisableSecureElement (StartupConfig& config);
61
62/* Default patchfile (in NCD format) */
63#ifndef NFA_APP_DEFAULT_PATCHFILE_NAME
64#define NFA_APP_DEFAULT_PATCHFILE_NAME      "\0"
65#endif
66
67/* Default patchfile (in NCD format) */
68#ifndef NFA_APP_DEFAULT_I2C_PATCHFILE_NAME
69#define NFA_APP_DEFAULT_I2C_PATCHFILE_NAME  "\0"
70#endif
71
72tNFC_POST_RESET_CB nfc_post_reset_cb =
73{
74    /* Default Patch & Pre-Patch */
75    NFA_APP_DEFAULT_PATCHFILE_NAME,
76    NULL,
77    NFA_APP_DEFAULT_I2C_PATCHFILE_NAME,
78    NULL,
79
80    /* Default UART baud rate */
81    NFC_HAL_DEFAULT_BAUD,
82
83    /* Default tNFC_HAL_DEV_INIT_CFG (flags, num_xtal_cfg, {brcm_hw_id, xtal-freq, xtal-index} ) */
84    {
85        2, /* number of valid entries */
86        {
87            {0x43341000, 37400, NFC_HAL_XTAL_INDEX_37400},      // All revisions of 43341 use 37,400
88            {0x20795000, 26000, NFC_HAL_XTAL_INDEX_26000},
89            {0, 0, 0},
90            {0, 0, 0},
91            {0, 0, 0},
92        }
93    },
94
95    /* Default low power mode settings */
96    NFC_HAL_LP_SNOOZE_MODE_NONE,    /* Snooze Mode          */
97    NFC_HAL_LP_IDLE_THRESHOLD_HOST, /* Idle Threshold Host  */
98    NFC_HAL_LP_IDLE_THRESHOLD_HC,   /* Idle Threshold HC    */
99    NFC_HAL_LP_ACTIVE_LOW,          /* NFC_WAKE Active Mode */
100    NFC_HAL_LP_ACTIVE_HIGH,         /* DH_WAKE Active Mode  */
101
102    NFA_APP_MAX_NUM_REINIT,         /* max retry to get NVM type */
103    0,                              /* current retry count */
104    TRUE,                           /* debug mode for downloading patchram */
105    FALSE                           /* skip downloading patchram after reinit because of patch download failure */
106};
107
108
109/*******************************************************************************
110**
111** Function         getFileLength
112**
113** Description      return the size of a file
114**
115** Returns          file size in number of bytes
116**
117*******************************************************************************/
118static long getFileLength(FILE* fp)
119{
120    long sz;
121    fseek(fp, 0L, SEEK_END);
122    sz = ftell(fp);
123    fseek(fp, 0L, SEEK_SET);
124
125    return (sz > 0) ? sz : 0;
126}
127
128/*******************************************************************************
129**
130** Function         isFileExist
131**
132** Description      Check if file name exists (android does not support fexists)
133**
134** Returns          TRUE if file exists
135**
136*******************************************************************************/
137static BOOLEAN isFileExist(const char *pFilename)
138{
139    FILE *pf;
140
141    if ((pf = fopen(pFilename, "r")) != NULL)
142    {
143        fclose(pf);
144        return TRUE;
145    }
146    return FALSE;
147}
148
149/*******************************************************************************
150**
151** Function         findPatchramFile
152**
153** Description      Find the patchram file name specified in the .conf
154**
155** Returns          pointer to the file name
156**
157*******************************************************************************/
158static const char* findPatchramFile(const char * pConfigName, char * pBuffer, int bufferLen)
159{
160    ALOGD("%s: config=%s", __FUNCTION__, pConfigName);
161
162    if (pConfigName == NULL)
163    {
164        ALOGD("%s No patchfile defined\n", __FUNCTION__);
165        return NULL;
166    }
167
168    if (GetStrValue(pConfigName, &pBuffer[0], bufferLen))
169    {
170        ALOGD("%s found patchfile %s\n", __FUNCTION__, pBuffer);
171        return (pBuffer[0] == '\0') ? NULL : pBuffer;
172    }
173
174    ALOGD("%s Cannot find patchfile '%s'\n", __FUNCTION__, pConfigName);
175    return NULL;
176}
177
178/*******************************************************************************
179**
180** Function:    continueAfterSetSnoozeMode
181**
182** Description: Called after Snooze Mode is enabled.
183**
184** Returns:     none
185**
186*******************************************************************************/
187static void continueAfterSetSnoozeMode(tHAL_NFC_STATUS status)
188{
189    ALOGD("%s: status=%u", __FUNCTION__, status);
190    //let stack download firmware during next initialization
191    nfc_post_reset_cb.spd_skip_on_power_cycle = FALSE;
192    if (status == NCI_STATUS_OK)
193        HAL_NfcPreInitDone (HAL_NFC_STATUS_OK);
194    else
195        HAL_NfcPreInitDone (HAL_NFC_STATUS_FAILED);
196}
197
198/*******************************************************************************
199**
200** Function:    postDownloadPatchram
201**
202** Description: Called after patch download
203**
204** Returns:     none
205**
206*******************************************************************************/
207static void postDownloadPatchram(tHAL_NFC_STATUS status)
208{
209    ALOGD("%s: status=%i", __FUNCTION__, status);
210    GetStrValue (NAME_SNOOZE_MODE_CFG, (char*)&gSnoozeModeCfg, sizeof(gSnoozeModeCfg));
211    if (status != HAL_NFC_STATUS_OK)
212    {
213        ALOGE("%s: Patch download failed", __FUNCTION__);
214        if (status == HAL_NFC_STATUS_REFUSED)
215        {
216            SpdHelper::setPatchAsBad();
217        }
218        else
219            SpdHelper::incErrorCount();
220
221        /* If in SPD Debug mode, fail immediately and obviously */
222        if (SpdHelper::isSpdDebug())
223            HAL_NfcPreInitDone (HAL_NFC_STATUS_FAILED);
224        else
225        {
226            /* otherwise, power cycle the chip and let the stack startup normally */
227            ALOGD("%s: re-init; don't download firmware", __FUNCTION__);
228            //stop stack from downloading firmware during next initialization
229            nfc_post_reset_cb.spd_skip_on_power_cycle = TRUE;
230            USERIAL_PowerupDevice(0);
231            HAL_NfcReInit ();
232        }
233    }
234    /* Set snooze mode here */
235    else if (gSnoozeModeCfg.snooze_mode != NFC_HAL_LP_SNOOZE_MODE_NONE)
236    {
237        status = HAL_NfcSetSnoozeMode(gSnoozeModeCfg.snooze_mode,
238                                       gSnoozeModeCfg.idle_threshold_dh,
239                                       gSnoozeModeCfg.idle_threshold_nfcc,
240                                       gSnoozeModeCfg.nfc_wake_active_mode,
241                                       gSnoozeModeCfg.dh_wake_active_mode,
242                                       continueAfterSetSnoozeMode);
243        if (status != NCI_STATUS_OK)
244        {
245            ALOGE("%s: Setting snooze mode failed, status=%i", __FUNCTION__, status);
246            HAL_NfcPreInitDone(HAL_NFC_STATUS_FAILED);
247        }
248    }
249    else
250    {
251        ALOGD("%s: Not using Snooze Mode", __FUNCTION__);
252        HAL_NfcPreInitDone(HAL_NFC_STATUS_OK);
253    }
254}
255
256
257/*******************************************************************************
258**
259** Function:    prmCallback
260**
261** Description: Patchram callback (for static patchram mode)
262**
263** Returns:     none
264**
265*******************************************************************************/
266void prmCallback(UINT8 event)
267{
268    ALOGD("%s: event=0x%x", __FUNCTION__, event);
269    switch (event)
270    {
271    case NFC_HAL_PRM_CONTINUE_EVT:
272        /* This event does not occur if static patchram buf is used */
273        break;
274
275    case NFC_HAL_PRM_COMPLETE_EVT:
276        postDownloadPatchram(HAL_NFC_STATUS_OK);
277        break;
278
279    case NFC_HAL_PRM_ABORT_EVT:
280        postDownloadPatchram(HAL_NFC_STATUS_FAILED);
281        break;
282
283    case NFC_HAL_PRM_ABORT_INVALID_PATCH_EVT:
284        ALOGD("%s: invalid patch...skipping patch download", __FUNCTION__);
285        postDownloadPatchram(HAL_NFC_STATUS_REFUSED);
286        break;
287
288    case NFC_HAL_PRM_ABORT_BAD_SIGNATURE_EVT:
289        ALOGD("%s: patch authentication failed", __FUNCTION__);
290        postDownloadPatchram(HAL_NFC_STATUS_REFUSED);
291        break;
292
293    case NFC_HAL_PRM_ABORT_NO_NVM_EVT:
294        ALOGD("%s: No NVM detected", __FUNCTION__);
295        HAL_NfcPreInitDone(HAL_NFC_STATUS_FAILED);
296        break;
297
298    default:
299        ALOGD("%s: not handled event=0x%x", __FUNCTION__, event);
300        break;
301    }
302}
303
304
305/*******************************************************************************
306**
307** Function         getNfaValues
308**
309** Description      Get configuration values needed by NFA layer
310**
311** Returns:         None
312**
313*******************************************************************************/
314static void getNfaValues (UINT32 chipid)
315{
316    unsigned long num = 0;
317    int actualLen = 0;
318
319    sStartupConfig.initialize ();
320    sLptdConfig.initialize ();
321    sPreDiscoveryConfig.initialize();
322
323    actualLen = GetStrValue (NAME_NFA_DM_START_UP_CFG, (char*)sConfig, sizeof(sConfig));
324    if (actualLen)
325        sStartupConfig.append (sConfig, actualLen);
326
327    // Set antenna tuning configuration if configured.
328    actualLen = GetStrValue(NAME_PREINIT_DSP_CFG, (char*)sConfig, sizeof(sConfig));
329    if (actualLen)
330        sStartupConfig.append (sConfig, actualLen);
331
332    if ( GetStrValue ( NAME_NFA_DM_START_UP_VSC_CFG, (char*)nfa_dm_start_up_vsc_cfg, sizeof (nfa_dm_start_up_vsc_cfg) ) )
333    {
334        p_nfc_hal_dm_start_up_vsc_cfg = &nfa_dm_start_up_vsc_cfg[0];
335        ALOGD ( "START_UP_VSC_CFG[0] = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
336                                                                            nfa_dm_start_up_vsc_cfg[0],
337                                                                            nfa_dm_start_up_vsc_cfg[1],
338                                                                            nfa_dm_start_up_vsc_cfg[2],
339                                                                            nfa_dm_start_up_vsc_cfg[3],
340                                                                            nfa_dm_start_up_vsc_cfg[4],
341                                                                            nfa_dm_start_up_vsc_cfg[5],
342                                                                            nfa_dm_start_up_vsc_cfg[6],
343                                                                            nfa_dm_start_up_vsc_cfg[7] );
344    }
345
346    actualLen = GetStrValue(NAME_LPTD_CFG, (char*)sConfig, sizeof(sConfig));
347    if (actualLen)
348    {
349        sLptdConfig.append (sConfig, actualLen);
350        p_nfc_hal_dm_lptd_cfg = const_cast<UINT8*> (sLptdConfig.getInternalBuffer ());
351    }
352    else
353    {
354        // Default to not sending any LPTD setting.
355        p_nfc_hal_dm_lptd_cfg = sDontSendLptd;
356    }
357
358    mayDisableSecureElement (sStartupConfig);
359    p_nfc_hal_dm_start_up_cfg = const_cast<UINT8*> (sStartupConfig.getInternalBuffer ());
360
361    actualLen = GetStrValue(NAME_NFA_DM_PRE_DISCOVERY_CFG, (char*)sConfig, sizeof(sConfig));
362    if (actualLen)
363    {
364        sPreDiscoveryConfig.append (sConfig, actualLen);
365        mayDisableSecureElement (sPreDiscoveryConfig);
366        p_nfc_hal_pre_discover_cfg = const_cast<UINT8*> (sPreDiscoveryConfig.getInternalBuffer ());
367    }
368
369    //configure how many secure elements are available for each type of chip
370    if (p_nfc_hal_cfg->nfc_hal_hci_uicc_support > 0)
371    {
372        if ((chipid & BRCM_NFC_GEN_MASK) == BRCM_NFC_20791_GEN)
373        {
374            nfc_hal_cb.max_ee = BRCM_NFC_20791_GEN_MAX_EE;
375            p_nfc_hal_cfg->nfc_hal_hci_uicc_support = HAL_NFC_HCI_UICC0_HOST | HAL_NFC_HCI_UICC1_HOST;
376        }
377        else if ((chipid & BRCM_NFC_GEN_MASK) == BRCM_NFC_43341_GEN)
378        {
379            nfc_hal_cb.max_ee = BRCM_NFC_43341_GEN_MAX_EE;
380            p_nfc_hal_cfg->nfc_hal_hci_uicc_support = HAL_NFC_HCI_UICC0_HOST | HAL_NFC_HCI_UICC1_HOST;
381        }
382        else if ((chipid & BRCM_NFC_GEN_MASK) == BRCM_NFC_20795_GEN)
383        {
384            nfc_hal_cb.max_ee = BRCM_NFC_20795_GEN_MAX_EE;
385            p_nfc_hal_cfg->nfc_hal_hci_uicc_support = HAL_NFC_HCI_UICC0_HOST | HAL_NFC_HCI_UICC1_HOST | HAL_NFC_HCI_UICC2_HOST;
386        }
387
388        //let .conf variable determine how many EE's to discover
389        if (GetNumValue(NAME_NFA_MAX_EE_SUPPORTED, &num, sizeof(num)))
390            nfc_hal_cb.max_ee = num;
391    }
392}
393
394/*******************************************************************************
395**
396** Function         StartPatchDownload
397**
398** Description      Reads configuration settings, and begins the download
399**                  process if patch files are configured.
400**
401** Returns:         None
402**
403*******************************************************************************/
404static void StartPatchDownload(UINT32 chipid)
405{
406    ALOGD ("%s: chipid=%lx",__FUNCTION__, chipid);
407
408    char chipID[30];
409    sprintf(chipID, "%lx", chipid);
410    ALOGD ("%s: chidId=%s", __FUNCTION__, chipID);
411
412    readOptionalConfig(chipID);     // Read optional chip specific settings
413    readOptionalConfig("fime");     // Read optional FIME specific settings
414    getNfaValues(chipid);                 // Get NFA configuration values into variables
415
416    findPatchramFile(FW_PATCH, sPatchFn, sizeof(sPatchFn));
417    findPatchramFile(FW_PRE_PATCH, sPrePatchFn, sizeof(sPatchFn));
418
419    {
420        FILE *fd;
421        /* If an I2C fix patch file was specified, then tell the stack about it */
422        if (sPrePatchFn[0] != '\0')
423        {
424            if ((fd = fopen(sPrePatchFn, "rb")) != NULL)
425            {
426                UINT32 lenPrmBuffer = getFileLength(fd);
427
428                if ((sI2cFixPrmBuf = malloc(lenPrmBuffer)) != NULL)
429                {
430                    size_t actualLen = fread(sI2cFixPrmBuf, 1, lenPrmBuffer, fd);
431                    if (actualLen == lenPrmBuffer)
432                    {
433                        ALOGD("%s Setting I2C fix to %s (size: %lu)", __FUNCTION__, sPrePatchFn, lenPrmBuffer);
434                        HAL_NfcPrmSetI2cPatch((UINT8*)sI2cFixPrmBuf, (UINT16)lenPrmBuffer, 0);
435                    }
436                    else
437                        ALOGE("%s fail reading i2c fix; actual len=%u; expected len=%lu", __FUNCTION__, actualLen, lenPrmBuffer);
438                }
439                else
440                {
441                    ALOGE("%s Unable to get buffer to i2c fix (%lu bytes)", __FUNCTION__, lenPrmBuffer);
442                }
443
444                fclose(fd);
445            }
446            else
447            {
448                ALOGE("%s Unable to open i2c fix patchfile %s", __FUNCTION__, sPrePatchFn);
449            }
450        }
451    }
452
453    {
454        FILE *fd;
455
456        /* If a patch file was specified, then download it now */
457        if (sPatchFn[0] != '\0')
458        {
459            UINT32 bDownloadStarted = false;
460
461            /* open patchfile, read it into a buffer */
462            if ((fd = fopen(sPatchFn, "rb")) != NULL)
463            {
464                UINT32 lenPrmBuffer = getFileLength(fd);
465                ALOGD("%s Downloading patchfile %s (size: %lu) format=%u", __FUNCTION__, sPatchFn, lenPrmBuffer, NFC_HAL_PRM_FORMAT_NCD);
466                if ((sPrmBuf = malloc(lenPrmBuffer)) != NULL)
467                {
468                    size_t actualLen = fread(sPrmBuf, 1, lenPrmBuffer, fd);
469                    if (actualLen == lenPrmBuffer)
470                    {
471                        if (!SpdHelper::isPatchBad((UINT8*)sPrmBuf, lenPrmBuffer))
472                        {
473                            /* Download patch using static memeory mode */
474                            HAL_NfcPrmDownloadStart(NFC_HAL_PRM_FORMAT_NCD, 0, (UINT8*)sPrmBuf, lenPrmBuffer, 0, prmCallback);
475                            bDownloadStarted = true;
476                        }
477                    }
478                    else
479                        ALOGE("%s fail reading patchram", __FUNCTION__);
480                }
481                else
482                    ALOGE("%s Unable to buffer to hold patchram (%lu bytes)", __FUNCTION__, lenPrmBuffer);
483
484                fclose(fd);
485            }
486            else
487                ALOGE("%s Unable to open patchfile %s", __FUNCTION__, sPatchFn);
488
489            /* If the download never got started */
490            if (!bDownloadStarted)
491            {
492                /* If debug mode, fail in an obvious way, otherwise try to start stack */
493                postDownloadPatchram(SpdHelper::isSpdDebug() ? HAL_NFC_STATUS_FAILED :
494                        HAL_NFC_STATUS_OK);
495            }
496        }
497        else
498        {
499            ALOGE("%s: No patchfile specified or disabled. Proceeding to post-download procedure...", __FUNCTION__);
500            postDownloadPatchram(HAL_NFC_STATUS_OK);
501        }
502    }
503
504    ALOGD ("%s: exit", __FUNCTION__);
505}
506
507/*******************************************************************************
508**
509** Function:    nfc_hal_post_reset_init
510**
511** Description: Called by the NFC HAL after controller has been reset.
512**              Begin to download firmware patch files.
513**
514** Returns:     none
515**
516*******************************************************************************/
517void nfc_hal_post_reset_init (UINT32 brcm_hw_id, UINT8 nvm_type)
518{
519    ALOGD("%s: brcm_hw_id=0x%lx, nvm_type=%d", __FUNCTION__, brcm_hw_id, nvm_type);
520    tHAL_NFC_STATUS stat = HAL_NFC_STATUS_FAILED;
521    UINT8 max_credits = 1, allow_no_nvm=0;
522
523    p_nfc_hal_cfg->nfc_hal_prm_nvm_required = TRUE; //don't download firmware if controller cannot detect EERPOM
524
525    if (nvm_type == NCI_SPD_NVM_TYPE_NONE)
526    {
527        GetNumValue(NAME_ALLOW_NO_NVM, &allow_no_nvm, sizeof(allow_no_nvm));
528        if (allow_no_nvm == 0)
529        {
530        ALOGD("%s: No NVM detected, FAIL the init stage to force a retry", __FUNCTION__);
531        USERIAL_PowerupDevice (0);
532        stat = HAL_NfcReInit ();
533            return;
534        }
535
536        p_nfc_hal_cfg->nfc_hal_prm_nvm_required = FALSE; //allow download firmware if controller cannot detect EERPOM
537    }
538
539        /* Start downloading the patch files */
540        StartPatchDownload(brcm_hw_id);
541
542        if (GetNumValue(MAX_RF_DATA_CREDITS, &max_credits, sizeof(max_credits)) && (max_credits > 0))
543        {
544            ALOGD("%s : max_credits=%d", __FUNCTION__, max_credits);
545            HAL_NfcSetMaxRfDataCredits(max_credits);
546        }
547    }
548
549
550/*******************************************************************************
551**
552** Function:        mayDisableSecureElement
553**
554** Description:     Optionally adjust a TLV to disable secure element.  This feature
555**                  is enabled by setting the system property
556**                  nfc.disable_secure_element to a bit mask represented by a hex
557**                  octet: C0 = do not detect any secure element.
558**                         40 = do not detect secure element in slot 0.
559**                         80 = do not detect secure element in slot 1.
560**
561**                  config: a sequence of TLV's.
562**
563*******************************************************************************/
564void mayDisableSecureElement (StartupConfig& config)
565{
566    unsigned int bitmask = 0;
567    char valueStr [PROPERTY_VALUE_MAX] = {0};
568    int len = property_get ("nfc.disable_secure_element", valueStr, "");
569    if (len > 0)
570    {
571        sscanf (valueStr, "%x", &bitmask); //read system property as a hex octet
572        ALOGD ("%s: disable 0x%02X", __FUNCTION__, (UINT8) bitmask);
573        config.disableSecureElement ((UINT8) (bitmask & 0xC0));
574    }
575}
576
577
578/*******************************************************************************
579**
580** Function:    configureCrystalFrequency
581**
582** Description: Configure controller's crystal frequency by reading values from
583**              .conf file.  If .conf file does not define any value, then use
584**              default values defined in struct nfc_post_reset_cb.
585**
586** Returns:     none
587**
588*******************************************************************************/
589void configureCrystalFrequency ()
590{
591    unsigned long num = 0;
592    UINT32 hwId = 0;
593    UINT16 xtalFreq = 0;
594    UINT8 xtalIndex = 0;
595    int actualLen = 0;
596
597    if (GetNumValue (NAME_XTAL_HARDWARE_ID, &num, sizeof(num)))
598        hwId = num;
599
600    if (GetNumValue (NAME_XTAL_FREQUENCY, &num, sizeof(num)))
601        xtalFreq = (UINT16) num;
602
603    if (GetNumValue (NAME_XTAL_FREQ_INDEX, &num, sizeof(num)))
604        xtalIndex = (UINT8) num;
605
606    actualLen = GetStrValue (NAME_XTAL_PARAMS_CFG, (char*)sConfig, sizeof(sConfig));
607    if (actualLen && (xtalIndex == NFC_HAL_XTAL_INDEX_SPECIAL)) //whether to use custom crystal frequency
608    {
609        sXtalCustomParam.append (sConfig, actualLen);
610        p_nfc_hal_dm_xtal_params_cfg = const_cast<UINT8*> (sXtalCustomParam.getInternalBuffer ());
611    }
612
613    if ((hwId == 0) && (xtalFreq == 0) && (xtalIndex == 0))
614        return;
615
616    ALOGD ("%s: hwId=0x%lX; freq=%u; index=%u", __FUNCTION__, hwId, xtalFreq, xtalIndex);
617    nfc_post_reset_cb.dev_init_config.xtal_cfg[0].brcm_hw_id = (hwId & BRCM_NFC_GEN_MASK);
618    nfc_post_reset_cb.dev_init_config.xtal_cfg[0].xtal_freq  = xtalFreq;
619    nfc_post_reset_cb.dev_init_config.xtal_cfg[0].xtal_index = xtalIndex;
620    nfc_post_reset_cb.dev_init_config.num_xtal_cfg = 1;
621}
622