Merge tag 'android-7.1.0_r4' of https://android.googlesource.com/platform/hardware/qcom/bt into n7.1

Android 7.1.0 release 4
diff --git a/msm8996/libbt-vendor/Android.mk b/msm8996/libbt-vendor/Android.mk
index ee4c0b8..e923776 100644
--- a/msm8996/libbt-vendor/Android.mk
+++ b/msm8996/libbt-vendor/Android.mk
@@ -41,9 +41,14 @@
 LOCAL_CFLAGS += -DBT_SOC_TYPE_ROME
 endif
 
+ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT)))
+LOCAL_CFLAGS += -DPANIC_ON_SOC_CRASH
+endif
+
 LOCAL_C_INCLUDES += \
         $(LOCAL_PATH)/include \
-        $(BDROID_DIR)/hci/include \
+        external/bluetooth/bluedroid/hci/include \
+        system/bt/hci/include \
         $(TARGET_OUT_HEADERS)/bt/hci_qcomm_init
 
 ifeq ($(BOARD_HAS_QCA_BT_AR3002), true)
@@ -69,6 +74,16 @@
 LOCAL_MODULE_CLASS := SHARED_LIBRARIES
 LOCAL_MODULE_OWNER := qcom
 
+ifdef TARGET_2ND_ARCH
+LOCAL_MODULE_PATH_32 := $(TARGET_OUT_VENDOR)/lib
+LOCAL_MODULE_PATH_64 := $(TARGET_OUT_VENDOR)/lib64
+else
+LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_SHARED_LIBRARIES)
+endif
+
+ifneq ($(BOARD_ANT_WIRELESS_DEVICE),)
+LOCAL_CFLAGS += -DENABLE_ANT
+endif
 #LOCAL_CFLAGS += -DREAD_BT_ADDR_FROM_PROP
 
 #include $(LOCAL_PATH)/vnd_buildcfg.mk
diff --git a/msm8996/libbt-vendor/include/bt_vendor_qcom.h b/msm8996/libbt-vendor/include/bt_vendor_qcom.h
index cf7d9e9..6e5469e 100644
--- a/msm8996/libbt-vendor/include/bt_vendor_qcom.h
+++ b/msm8996/libbt-vendor/include/bt_vendor_qcom.h
@@ -20,9 +20,6 @@
 #include "bt_vendor_lib.h"
 //#include "vnd_buildcfg.h"
 
-#define STREAM_TO_UINT16(u16, p) {u16 = ((uint16_t)(*(p)) + (((uint16_t)(*((p) + 1))) << 8)); (p) += 2;}
-#define UINT16_TO_STREAM(p, u16) {*(p)++ = (uint8_t)(u16); *(p)++ = (uint8_t)((u16) >> 8);}
-#define UINT32_TO_STREAM(p, u32) {*(p)++ = (uint8_t)(u32); *(p)++ = (uint8_t)((u32) >> 8); *(p)++ = (uint8_t)((u32) >> 16); *(p)++ = (uint8_t)((u32) >> 24);}
 
 #ifndef FALSE
 #define FALSE  0
@@ -32,6 +29,10 @@
 #define TRUE   (!FALSE)
 #endif
 
+#define STREAM_TO_UINT16(u16, p) {u16 = ((uint16_t)(*(p)) + (((uint16_t)(*((p) + 1))) << 8)); (p) += 2;}
+#define UINT16_TO_STREAM(p, u16) {*(p)++ = (uint8_t)(u16); *(p)++ = (uint8_t)((u16) >> 8);}
+#define UINT32_TO_STREAM(p, u32) {*(p)++ = (uint8_t)(u32); *(p)++ = (uint8_t)((u32) >> 8); *(p)++ = (uint8_t)((u32) >> 16); *(p)++ = (uint8_t)((u32) >> 24);}
+
 typedef enum {
     BT_SOC_DEFAULT = 0,
     BT_SOC_SMD = BT_SOC_DEFAULT,
@@ -41,6 +42,10 @@
     BT_SOC_RESERVED
 }bt_soc_type;
 
+typedef enum {
+    BT_VND_OP_ANT_USERIAL_OPEN = 254,
+    BT_VND_OP_ANT_USERIAL_CLOSE
+}ant_serial;
 
 extern bt_vendor_callbacks_t *bt_vendor_cbacks;
 /* HW_NEED_END_WITH_HCI_RESET
diff --git a/msm8996/libbt-vendor/include/hw_rome.h b/msm8996/libbt-vendor/include/hw_rome.h
index 6f0aa8d..7d4a400 100644
--- a/msm8996/libbt-vendor/include/hw_rome.h
+++ b/msm8996/libbt-vendor/include/hw_rome.h
@@ -108,6 +108,7 @@
 #define HCI_VS_GET_ADDON_FEATURES_EVENT      (0x1B)
 #define EDL_BOARD_ID_RESPONSE                (0x23)
 #define HCI_VS_GET_BUILD_VER_EVT             (0x05)
+#define HCI_VS_STRAY_EVT                (0x17)
 
 /* Status Codes of HCI CMD execution*/
 #define HCI_CMD_SUCCESS                     (0x0)
diff --git a/msm8996/libbt-vendor/src/bt_vendor_qcom.c b/msm8996/libbt-vendor/src/bt_vendor_qcom.c
index fffdcb8..56a1552 100644
--- a/msm8996/libbt-vendor/src/bt_vendor_qcom.c
+++ b/msm8996/libbt-vendor/src/bt_vendor_qcom.c
@@ -41,10 +41,20 @@
 #include "bt_vendor_persist.h"
 #endif
 #include "hw_rome.h"
-
+#include "bt_vendor_lib.h"
 #define WAIT_TIMEOUT 200000
 #define BT_VND_OP_GET_LINESPEED 12
 
+#ifdef PANIC_ON_SOC_CRASH
+#define BT_VND_FILTER_START "wc_transport.start_root"
+#else
+#define BT_VND_FILTER_START "wc_transport.start_hci"
+#endif
+
+#define CMD_TIMEOUT  0x22
+
+static void wait_for_patch_download(bool is_ant_req);
+
 /******************************************************************************
 **  Externs
 ******************************************************************************/
@@ -55,7 +65,7 @@
 extern int check_embedded_mode(int fd);
 extern int rome_get_addon_feature_list(int fd);
 extern int rome_ver;
-extern int enable_controller_log(int fd);
+extern int enable_controller_log(int fd, unsigned char req);
 /******************************************************************************
 **  Variables
 ******************************************************************************/
@@ -70,6 +80,15 @@
 static char *rfkill_state = NULL;
 bool enable_extldo = FALSE;
 
+int userial_clock_operation(int fd, int cmd);
+int ath3k_init(int fd, int speed, int init_speed, char *bdaddr, struct termios *ti);
+int rome_soc_init(int fd, char *bdaddr);
+int userial_vendor_get_baud(void);
+int readTrpState();
+void lpm_set_ar3k(uint8_t pio, uint8_t action, uint8_t polarity);
+
+pthread_mutex_t m_lock = PTHREAD_MUTEX_INITIALIZER;
+
 static const tUSERIAL_CFG userial_init_cfg =
 {
     (USERIAL_DATABITS_8 | USERIAL_PARITY_NONE | USERIAL_STOPBITS_1),
@@ -223,6 +242,7 @@
 bool can_perform_action(char action) {
     bool can_perform = false;
     char ref_count[PROPERTY_VALUE_MAX];
+    char inProgress[PROPERTY_VALUE_MAX] = {'\0'};
     int value, ret;
 
     property_get("wc_transport.ref_count", ref_count, "0");
@@ -234,7 +254,8 @@
         ALOGV("%s: on : value is: %d", __func__, value);
         if(value == 1)
         {
-          if(is_soc_initialized() == true)
+          property_get("wc_transport.patch_dnld_inprog", inProgress, "null");
+          if((is_soc_initialized() == true) || (strcmp(inProgress,"null") != 0))
           {
             value++;
             ALOGV("%s: on : value is incremented to : %d", __func__, value);
@@ -244,15 +265,19 @@
         {
              value++;
         }
+
         if (value == 1)
            can_perform = true;
-        else if (value > 2) return false;
-    } else  {
+        else if (value > 2)
+           return false;
+    }
+    else {
         ALOGV("%s: off : value is: %d", __func__, value);
         value--;
         if (value == 0)
            can_perform = true;
-        else if (value < 0) return false;
+        else if (value < 0)
+           return false;
     }
 
     snprintf(ref_count, 3, "%d", value);
@@ -271,14 +296,14 @@
        char value[PROPERTY_VALUE_MAX] = {'\0'};
        ALOGV("%s: Entry ", __func__);
 
-       property_get("wc_transport.start_hci", value, "false");
+       property_get(BT_VND_FILTER_START, value, "false");
 
        if (strcmp(value, "false") == 0) {
-           ALOGV("%s: hci_filter has been stopped already", __func__);
-           return;
+           ALOGI("%s: hci_filter has been stopped already", __func__);
+//           return;
        }
 
-       property_set("wc_transport.start_hci", "false");
+       property_set(BT_VND_FILTER_START, "false");
        property_set("wc_transport.hci_filter_status", "0");
        ALOGV("%s: Exit ", __func__);
 }
@@ -288,17 +313,18 @@
        int i, init_success = 0;
        char value[PROPERTY_VALUE_MAX] = {'\0'};
 
-
-       property_get("wc_transport.start_hci", value, false);
+       property_get(BT_VND_FILTER_START, value, false);
 
        if (strcmp(value, "true") == 0) {
-           ALOGV("%s: hci_filter has been started already", __func__);
+           ALOGI("%s: hci_filter has been started already", __func__);
            return;
        }
 
        property_set("wc_transport.hci_filter_status", "0");
+       property_set(BT_VND_FILTER_START, "true");
 
-       property_set("wc_transport.start_hci", "true");
+       ALOGV("%s: %s set to true ", __func__, BT_VND_FILTER_START );
+
        //sched_yield();
        for(i=0; i<45; i++) {
           property_get("wc_transport.hci_filter_status", value, "0");
@@ -319,7 +345,7 @@
 {
     char rfkill_type[64], *enable_ldo_path = NULL;
     char type[16], enable_ldo[6];
-    int fd, size, i, ret, fd_ldo;
+    int fd = 0, size, i, ret, fd_ldo;
 
     char disable[PROPERTY_VALUE_MAX];
     char state;
@@ -423,14 +449,17 @@
     ALOGE("Write %c to rfkill\n", on);
 
     /* Write value to control rfkill */
-    if ((size = write(fd, &on, 1)) < 0) {
-        ALOGE("write(%s) failed: %s (%d)",rfkill_state, strerror(errno),errno);
+    if(fd >= 0) {
+        if ((size = write(fd, &on, 1)) < 0) {
+            ALOGE("write(%s) failed: %s (%d)",rfkill_state, strerror(errno),errno);
 #ifdef WIFI_BT_STATUS_SYNC
-        bt_semaphore_release(lock_fd);
-        bt_semaphore_destroy(lock_fd);
+            bt_semaphore_release(lock_fd);
+            bt_semaphore_destroy(lock_fd);
 #endif
-        return -1;
+            return -1;
+        }
     }
+
 #ifdef BT_SOC_TYPE_ROME
     if(on == '0'){
         ALOGE("Stopping HCI filter as part of CTRL:OFF");
@@ -623,6 +652,7 @@
     int nState = -1;
     bool is_ant_req = false;
     char wipower_status[PROPERTY_VALUE_MAX];
+    char emb_wp_mode[PROPERTY_VALUE_MAX];
     char bt_version[PROPERTY_VALUE_MAX];
     bool ignore_boot_prop = TRUE;
 #ifdef READ_BT_ADDR_FROM_PROP
@@ -632,10 +662,10 @@
     char* tok;
 #endif
     bool skip_init = true;
-
+    int  opcode_init = opcode;
     ALOGV("bt-vendor : op for %d", opcode);
 
-    switch(opcode)
+    switch(opcode_init)
     {
         case BT_VND_OP_POWER_CTRL:
             {
@@ -664,7 +694,15 @@
                     case BT_SOC_ROME:
                     case BT_SOC_AR3K:
                         /* BT Chipset Power Control through Device Tree Node */
-                        retval = bt_powerup(nState);
+                        if(!pthread_mutex_lock(&m_lock)) {
+                            if(nState == BT_VND_PWR_ON && property_get_bool("wc_transport.vnd_power", 0)) {
+                                bt_powerup(BT_VND_PWR_OFF);
+                            }
+                            retval = bt_powerup(nState);
+                            if(retval == 0)
+                                property_set("wc_transport.vnd_power", nState == BT_VND_PWR_ON ? "1" : "0");
+                            pthread_mutex_unlock(&m_lock);
+                        }
                     default:
                         break;
                 }
@@ -675,8 +713,19 @@
             {
                 // call hciattach to initalize the stack
                 if(bt_vendor_cbacks){
-                   ALOGI("Bluetooth Firmware and transport layer are initialized");
-                   bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_SUCCESS);
+                   if (btSocType ==  BT_SOC_ROME) {
+                       if (is_soc_initialized()) {
+                           ALOGI("Bluetooth FW and transport layer are initialized");
+                           bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_SUCCESS);
+                       } else {
+                           ALOGE("bt_vendor_cbacks is null or SoC not initialized");
+                           ALOGE("Error : hci, smd initialization Error");
+                           retval = -1;
+                       }
+                   } else {
+                       ALOGI("Bluetooth FW and transport layer are initialized");
+                       bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_SUCCESS);
+                   }
                 }
                 else{
                    ALOGE("bt_vendor_cbacks is null");
@@ -703,7 +752,7 @@
         case BT_VND_OP_USERIAL_OPEN:
             {
                 int (*fd_array)[] = (int (*)[]) param;
-                int fd = -1, fd_filter = -1;
+                int idx, fd = -1, fd_filter = -1;
                 ALOGI("bt-vendor : BT_VND_OP_USERIAL_OPEN");
                 switch(btSocType)
                 {
@@ -748,9 +797,14 @@
                         break;
                     case BT_SOC_ROME:
                         {
-                            int idx;
-                            property_get("persist.BT3_2.version", bt_version, false);
+                            wait_for_patch_download(is_ant_req);
+                            property_get("ro.bluetooth.emb_wp_mode", emb_wp_mode, false);
                             if (!is_soc_initialized()) {
+                                char* dlnd_inprog = is_ant_req ? "ant" : "bt";
+                                if (property_set("wc_transport.patch_dnld_inprog", dlnd_inprog) < 0) {
+                                    ALOGE("%s: Failed to set dnld_inprog %s", __FUNCTION__, dlnd_inprog);
+                                }
+
                                 fd = userial_vendor_open((tUSERIAL_CFG *) &userial_init_cfg);
                                 if (fd < 0) {
                                     ALOGE("userial_vendor_open returns err");
@@ -759,7 +813,7 @@
                                     /* Clock on */
                                     userial_clock_operation(fd, USERIAL_OP_CLK_ON);
                                     ALOGD("userial clock on");
-                                    if(strcmp(bt_version, "true") == 0) {
+                                    if(strcmp(emb_wp_mode, "true") == 0) {
                                         property_get("ro.bluetooth.wipower", wipower_status, false);
                                         if(strcmp(wipower_status, "true") == 0) {
                                             check_embedded_mode(fd);
@@ -812,7 +866,7 @@
                                        ALOGI("Failed to read BD address. Use the one from bluedroid stack/ftm");
                                     }
 #endif //BT_NV_SUPPORT
-                                    if(rome_soc_init(fd,vnd_local_bd_addr)<0) {
+                                    if(rome_soc_init(fd, (char*)vnd_local_bd_addr)<0) {
                                         retval = -1;
                                     } else {
                                         ALOGV("rome_soc_init is completed");
@@ -821,6 +875,9 @@
                                     }
                                 }
                             }
+                            if (property_set("wc_transport.patch_dnld_inprog", "null") < 0) {
+                                ALOGE("%s: Failed to set property", __FUNCTION__);
+                            }
 
                             property_set("wc_transport.clean_up","0");
                             if (retval != -1) {
@@ -840,22 +897,23 @@
                                  if (fd_filter != -1) {
                                      ALOGV("%s: received the socket fd: %d is_ant_req: %d\n",
                                                                  __func__, fd_filter, is_ant_req);
-                                     if((strcmp(bt_version, "true") == 0) && !is_ant_req) {
+                                     if((strcmp(emb_wp_mode, "true") == 0) && !is_ant_req) {
                                          if (rome_ver >= ROME_VER_3_0) {
                                              /*  get rome supported feature request */
                                              ALOGE("%s: %x08 %0x", __FUNCTION__,rome_ver, ROME_VER_3_0);
                                              rome_get_addon_feature_list(fd_filter);
                                          }
                                      }
-
                                      if (!skip_init) {
-                                         /* skip if already sent */
-                                         enable_controller_log(fd_filter);
+                                         /*Skip if already sent*/
+                                         enable_controller_log(fd_filter, is_ant_req);
                                          skip_init = true;
                                      }
 
-                                     for (idx=0; idx < CH_MAX; idx++)
+                                     for (idx=0; idx < CH_MAX; idx++) {
                                          (*fd_array)[idx] = fd_filter;
+                                     }
+
                                      retval = 1;
                                  }
                                  else {
@@ -865,6 +923,7 @@
 
                              if (fd >= 0) {
                                  userial_clock_operation(fd, USERIAL_OP_CLK_OFF);
+                                 /*Close the UART port*/
                                  close(fd);
                              }
                         }
@@ -880,11 +939,14 @@
         case BT_VND_OP_ANT_USERIAL_CLOSE:
             {
                 ALOGI("bt-vendor : BT_VND_OP_ANT_USERIAL_CLOSE");
-                property_set("wc_transport.clean_up","1");
-                if (ant_fd != -1) {
-                    ALOGE("closing ant_fd");
-                    close(ant_fd);
-                    ant_fd = -1;
+                if(!pthread_mutex_lock(&m_lock)) {
+                    property_set("wc_transport.clean_up","1");
+                    if (ant_fd != -1) {
+                        ALOGE("closing ant_fd");
+                        close(ant_fd);
+                        ant_fd = -1;
+                    }
+                    pthread_mutex_unlock(&m_lock);
                 }
             }
             break;
@@ -901,8 +963,11 @@
 
                      case BT_SOC_ROME:
                      case BT_SOC_AR3K:
-                        property_set("wc_transport.clean_up","1");
-                        userial_vendor_close();
+                        if(!pthread_mutex_lock(&m_lock)) {
+                            property_set("wc_transport.clean_up","1");
+                            userial_vendor_close();
+                            pthread_mutex_unlock(&m_lock);
+                        }
                         break;
                     default:
                         ALOGE("Unknown btSocType: 0x%x", btSocType);
@@ -912,10 +977,11 @@
             break;
 
         case BT_VND_OP_GET_LPM_IDLE_TIMEOUT:
-            if (btSocType ==  BT_SOC_AR3K) {
+            {
                 uint32_t *timeout_ms = (uint32_t *) param;
                 *timeout_ms = 1000;
             }
+
             break;
 
         case BT_VND_OP_LPM_SET_MODE:
@@ -932,8 +998,9 @@
                     bt_vendor_cbacks->lpm_cb(BT_VND_OP_RESULT_SUCCESS);
             }
             else {
+                // respond with failure as it's already handled by other mechanism
                 if (bt_vendor_cbacks)
-                    bt_vendor_cbacks->lpm_cb(BT_VND_OP_RESULT_SUCCESS); //dummy
+                    bt_vendor_cbacks->lpm_cb(BT_VND_OP_RESULT_FAIL);
             }
             break;
 
@@ -1034,10 +1101,14 @@
     return retval;
 }
 
-static void ssr_cleanup(void) {
+static void ssr_cleanup(int reason) {
     int pwr_state=BT_VND_PWR_OFF;
-
+    int ret;
+    unsigned char trig_ssr = 0xEE;
     ALOGI("ssr_cleanup");
+    if (property_set("wc_transport.patch_dnld_inprog", "null") < 0) {
+        ALOGE("%s: Failed to set property", __FUNCTION__);
+    }
 
     if ((btSocType = get_bt_soc_type()) < 0) {
         ALOGE("%s: Failed to detect BT SOC Type", __FUNCTION__);
@@ -1047,6 +1118,14 @@
     if (btSocType == BT_SOC_ROME) {
 #ifdef BT_SOC_TYPE_ROME
 #ifdef ENABLE_ANT
+        //Indicate to filter by sending
+        //special byte
+        if (reason == CMD_TIMEOUT) {
+            trig_ssr = 0xEE;
+            ret = write (vnd_userial.fd, &trig_ssr, 1);
+            ALOGI("Trig_ssr is being sent to BT socket, retval(%d) :errno:  %s", ret, strerror(errno));
+            return;
+        }
         /*Close both ANT channel*/
         op(BT_VND_OP_ANT_USERIAL_CLOSE, NULL);
 #endif
@@ -1055,15 +1134,15 @@
         op(BT_VND_OP_USERIAL_CLOSE, NULL);
         /*CTRL OFF twice to make sure hw
          * turns off*/
+#ifdef ENABLE_ANT
         op(BT_VND_OP_POWER_CTRL, &pwr_state);
+#endif
 
     }
-
 #ifdef BT_SOC_TYPE_ROME
     /*Generally switching of chip should be enough*/
     op(BT_VND_OP_POWER_CTRL, &pwr_state);
 #endif
-    bt_vendor_cbacks = NULL;
 }
 
 
@@ -1071,13 +1150,40 @@
 static void cleanup( void )
 {
     ALOGI("cleanup");
-    bt_vendor_cbacks = NULL;
+    if(!pthread_mutex_lock(&m_lock)) {
+        bt_vendor_cbacks = NULL;
+        pthread_mutex_unlock(&m_lock);
+    }
 
 #ifdef WIFI_BT_STATUS_SYNC
     isInit = 0;
 #endif /* WIFI_BT_STATUS_SYNC */
 }
 
+/* Check for one of the cients ANT/BT patch download is already in
+** progress if yes wait till complete
+*/
+void wait_for_patch_download(bool is_ant_req) {
+    ALOGV("%s:", __FUNCTION__);
+    char inProgress[PROPERTY_VALUE_MAX] = {'\0'};
+    while (1) {
+        property_get("wc_transport.patch_dnld_inprog", inProgress, "null");
+
+        if(is_ant_req && !strcmp(inProgress,"bt") ) {
+           //ANT request, wait for BT to finish
+           usleep(50000);
+        }
+        else if(!is_ant_req && !strcmp(inProgress,"ant") ) {
+           //BT request, wait for ANT to finish
+           usleep(50000);
+        }
+        else {
+           ALOGI("%s: patch download completed", __FUNCTION__);
+           break;
+        }
+    }
+}
+
 // Entry point of DLib
 const bt_vendor_interface_t BLUETOOTH_VENDOR_LIB_INTERFACE = {
     sizeof(bt_vendor_interface_t),
diff --git a/msm8996/libbt-vendor/src/hardware.c b/msm8996/libbt-vendor/src/hardware.c
index 5fadec7..a1ebd35 100644
--- a/msm8996/libbt-vendor/src/hardware.c
+++ b/msm8996/libbt-vendor/src/hardware.c
@@ -40,25 +40,40 @@
 #include <string.h>
 #include "bt_hci_bdroid.h"
 #include "bt_vendor_qcom.h"
-
+#include <string.h>
 #define MAX_CNT_RETRY 100
 
 int hw_config(int nState)
 {
-    ALOGI("Starting hciattach daemon");
     char *szState[] = {"true", "false"};
     char *szReqSt = NULL;
+    char szBtSocStatus[PROPERTY_VALUE_MAX] = {'\0', };
 
     if(nState == BT_VND_PWR_OFF)
         szReqSt = szState[1];
     else
         szReqSt = szState[0];
 
-    ALOGI("try to set %s", szReqSt);
-
-    if (property_set("bluetooth.hciattach", szReqSt) < 0){
-        ALOGE("Property Setting fail");
-	return -1;
+    if((property_get("bluetooth.status", szBtSocStatus, "") <= 0))
+    {
+       if(nState == BT_VND_PWR_ON ) {
+          ALOGW("Hw_config: First Time BT on after boot.Starting hciattach daemon BTStatus=%s",szBtSocStatus);
+          if (property_set("bluetooth.hciattach", szReqSt) < 0)
+          {
+              ALOGE("Hw_config: Property Setting fail");
+              return -1;
+          }
+       }
+    } else if( !(strncmp(szBtSocStatus, "on", strlen("on")))) {
+          //BTSOC is already on
+          ALOGW("Hw_config: nState = %d", nState);
+    } else {
+          ALOGW("Hw_config: trigerring hciattach");
+          if (property_set("bluetooth.hciattach", szReqSt) < 0)
+          {
+              ALOGE("Hw_config: Property Setting fail");
+              return -1;
+          }
     }
 
     return 0;
@@ -68,12 +83,12 @@
 {
     char szBtStatus[PROPERTY_VALUE_MAX] = {0, };
     if(property_get("bluetooth.status", szBtStatus, "") < 0){
-        ALOGE("Fail to get bluetooth satus");
+        ALOGE("Fail to get bluetooth status");
         return FALSE;
     }
 
     if(!strncmp(szBtStatus, "on", strlen("on"))){
-        ALOGI("bluetooth satus is on");
+        ALOGI("bluetooth status is on");
         return TRUE;
     }
     return FALSE;
@@ -85,13 +100,12 @@
     char szStatus[10] = {0,};
 
     for(i=MAX_CNT_RETRY; i>0; i--){
-       usleep(50*1000);
        //TODO :: checking routine
        if(readTrpState()==TRUE){
            break;
        }
+       usleep(50*1000);
     }
-
     return (i==0)? FALSE:TRUE;
 }
 
diff --git a/msm8996/libbt-vendor/src/hci_smd.c b/msm8996/libbt-vendor/src/hci_smd.c
index bdb54cd..3ddbcc2 100644
--- a/msm8996/libbt-vendor/src/hci_smd.c
+++ b/msm8996/libbt-vendor/src/hci_smd.c
@@ -33,6 +33,8 @@
 #include <cutils/properties.h>
 #include "bt_vendor_qcom.h"
 #include "hci_smd.h"
+#include <string.h>
+#include <cutils/properties.h>
 
 /*****************************************************************************
 **   Macros & Constants
@@ -52,6 +54,7 @@
 /*****************************************************************************
 **   Functions
 *****************************************************************************/
+
 int bt_hci_init_transport_id (int chId )
 {
   struct termios   term;
diff --git a/msm8996/libbt-vendor/src/hci_uart.c b/msm8996/libbt-vendor/src/hci_uart.c
index 58235f6..e4ce994 100644
--- a/msm8996/libbt-vendor/src/hci_uart.c
+++ b/msm8996/libbt-vendor/src/hci_uart.c
@@ -34,7 +34,7 @@
 #include <string.h>
 #include "bt_vendor_qcom.h"
 #include "hci_uart.h"
-
+#include <string.h>
 
 /******************************************************************************
 **  Constants & Macros
@@ -50,6 +50,8 @@
 #define VNDUSERIALDBG(param, ...) {}
 #endif
 
+#define RESERVED(p)  if(p) ALOGI( "%s: reserved param", __FUNCTION__);
+
 /******************************************************************************
 **  Global variables
 ******************************************************************************/
@@ -358,6 +360,7 @@
     cfsetospeed(&vnd_userial.termios, tcio_baud);
     cfsetispeed(&vnd_userial.termios, tcio_baud);
     tcsetattr(vnd_userial.fd, TCSADRAIN, &vnd_userial.termios); /* don't change speed until last write done */
+//    tcflush(vnd_userial.fd, TCIOFLUSH);
 }
 
 /*******************************************************************************
@@ -391,7 +394,7 @@
 *******************************************************************************/
 int userial_vendor_ioctl(userial_vendor_ioctl_op_t op, int *p_data)
 {
-    int err;
+    int err = -1;
 
     switch(op)
     {
@@ -442,6 +445,8 @@
 *******************************************************************************/
 int userial_set_port(char *p_conf_name, char *p_conf_value, int param)
 {
+    RESERVED(p_conf_name);
+    RESERVED(param);
     strlcpy(vnd_userial.port_name, p_conf_value, VND_PORT_NAME_MAXLEN);
 
     return 0;
diff --git a/msm8996/libbt-vendor/src/hw_ar3k.c b/msm8996/libbt-vendor/src/hw_ar3k.c
index 9ca5b3c..681cd09 100644
--- a/msm8996/libbt-vendor/src/hw_ar3k.c
+++ b/msm8996/libbt-vendor/src/hw_ar3k.c
@@ -48,6 +48,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <termios.h>
+#include <string.h>
 
 #include "bt_hci_bdroid.h"
 #include "hci_uart.h"
@@ -96,6 +97,8 @@
 }
 #endif
 
+#define RESERVED(p)  if(p) ALOGI( "%s: reserved param", __FUNCTION__);
+
 /*****************************************************************************
 **   Functions
 *****************************************************************************/
@@ -874,6 +877,8 @@
     uint8_t *event;
     uint8_t *loc_ptr = &cmd[7];
 
+    RESERVED(len);
+
     if (!patch_loc)
         return -1;
 
@@ -1387,6 +1392,8 @@
 
     ALOGI("lpm mode: %d  action: %d", pio, action);
 
+    RESERVED(polarity);
+
     switch (pio)
     {
         case UPIO_LPM_MODE:
diff --git a/msm8996/libbt-vendor/src/hw_rome.c b/msm8996/libbt-vendor/src/hw_rome.c
index 715df4b..6a19d77 100644
--- a/msm8996/libbt-vendor/src/hw_rome.c
+++ b/msm8996/libbt-vendor/src/hw_rome.c
@@ -48,6 +48,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <termios.h>
+#include <string.h>
 #include <stdbool.h>
 
 #include "bt_hci_bdroid.h"
@@ -56,11 +57,21 @@
 #include "hw_rome.h"
 
 #define BT_VERSION_FILEPATH "/data/misc/bluedroid/bt_fw_version.txt"
+#define BOARD_ID_LEN 0x5
+#define MSB_NIBBLE_MASK 0xF0
+#define LSB_NIBBLE_MASK 0x0F
 
 #ifdef __cplusplus
 }
 #endif
 
+#define RESERVED(p)  if(p) ALOGI( "%s: reserved param", __FUNCTION__);
+
+int read_vs_hci_event(int fd, unsigned char* buf, int size);
+int get_boardid_req(int fd);
+unsigned char convert2ascii(unsigned char temp);
+
+
 /******************************************************************************
 **  Variables
 ******************************************************************************/
@@ -79,6 +90,9 @@
 unsigned short fw_su_offset =0;
 extern char enable_extldo;
 unsigned char wait_vsc_evt = TRUE;
+bool patch_dnld_pending = FALSE;
+int dnld_fd = -1;
+unsigned char board_id[BOARD_ID_LEN];
 
 /******************************************************************************
 **  Extern variables
@@ -232,6 +246,20 @@
                     ALOGI("Failed to dump  FW SU build info. Errno:%d", errno);
                 }
             break;
+            case EDL_BOARD_ID_RESPONSE:
+                ALOGI("%s: board id %x %x!!", __FUNCTION__, rsp[6], rsp[7]);
+                if (rsp[6] <= 0x00) {
+                    board_id[0] = convert2ascii ((rsp[7] & MSB_NIBBLE_MASK) >> 4);
+                    board_id[1] = convert2ascii (rsp[7] & LSB_NIBBLE_MASK);
+                    board_id[2] = '\0';
+                } else {
+                    board_id[0] = convert2ascii ((rsp[6] & MSB_NIBBLE_MASK) >> 4);
+                    board_id[1] = convert2ascii (rsp[6] & LSB_NIBBLE_MASK);
+                    board_id[2] = convert2ascii ((rsp[7] & MSB_NIBBLE_MASK) >> 4);
+                    board_id[3] = convert2ascii (rsp[7] & LSB_NIBBLE_MASK);
+                    board_id[4] = '\0';
+                }
+            break;
         }
         break;
 
@@ -249,9 +277,14 @@
             }
             break;
        case EDL_WIP_QUERY_CHARGING_STATUS_EVT:
-            /*TODO: rsp code 00 mean no charging
-            this is going to change in FW soon*/
-            if (rsp[4] != EMBEDDED_MODE_CHECK)
+            /* Query charging command has below return values
+            0 - in embedded mode not charging
+            1 - in embedded mode and charging
+            2 - hadofff completed and in normal mode
+            3 - no wipower supported on mtp. so irrepective of charging
+            handoff command has to be sent if return values are 0 or 1.
+            These change include logic to enable generic BT turn on sequence.*/
+            if (rsp[4] < EMBEDDED_MODE_CHECK)
             {
                ALOGI("%s: WiPower Charging in Embedded Mode!!!", __FUNCTION__);
                wipower_handoff_ready = rsp[4];
@@ -273,6 +306,21 @@
                property_set("persist.bluetooth.a4wp", "true");
             }
             break;
+        case HCI_VS_STRAY_EVT:
+            /* WAR to handle stray Power Apply EVT during patch download */
+            ALOGD("%s: Stray HCI VS EVENT", __FUNCTION__);
+            if (patch_dnld_pending && dnld_fd != -1)
+            {
+                unsigned char rsp[HCI_MAX_EVENT_SIZE];
+                memset(rsp, 0x00, HCI_MAX_EVENT_SIZE);
+                read_vs_hci_event(dnld_fd, rsp, HCI_MAX_EVENT_SIZE);
+            }
+            else
+            {
+                ALOGE("%s: Not a valid status!!!", __FUNCTION__);
+                err = -1;
+            }
+            break;
         default:
             ALOGE("%s: Not a valid status!!!", __FUNCTION__);
             err = -1;
@@ -953,7 +1001,7 @@
 int rome_tlv_dnld_req(int fd, int tlv_size)
 {
     int  total_segment, remain_size, i, err = -1;
-    unsigned char wait_cc_evt;
+    unsigned char wait_cc_evt = TRUE;
 
     total_segment = tlv_size/MAX_SIZE_PER_TLV_SEGMENT;
     remain_size = (tlv_size < MAX_SIZE_PER_TLV_SEGMENT)?\
@@ -1014,8 +1062,10 @@
              }
         }
 
+        patch_dnld_pending = TRUE;
         if((err = rome_tlv_dnld_segment(fd, i, MAX_SIZE_PER_TLV_SEGMENT, wait_cc_evt )) < 0)
             goto error;
+        patch_dnld_pending = FALSE;
     }
 
     if ((rome_ver >= ROME_VER_1_1) && (rome_ver < ROME_VER_3_2) && (gTlv_type == TLV_TYPE_PATCH)) {
@@ -1038,15 +1088,20 @@
         }
     }
 
+    patch_dnld_pending = TRUE;
     if(remain_size) err =rome_tlv_dnld_segment(fd, i, remain_size, wait_cc_evt);
-
+    patch_dnld_pending = FALSE;
 error:
+    if(patch_dnld_pending) patch_dnld_pending = FALSE;
     return err;
 }
 
 int rome_download_tlv_file(int fd)
 {
     int tlv_size, err = -1;
+    char nvm_file_path_bid[32] = { 0,};
+
+    memcpy(nvm_file_path_bid, nvm_file_path, strlen(nvm_file_path) - 2);
 
     /* Rampatch TLV file Downloading */
     pdata_buffer = NULL;
@@ -1060,9 +1115,20 @@
         free (pdata_buffer);
         pdata_buffer = NULL;
     }
-    /* NVM TLV file Downloading */
-    if((tlv_size = rome_get_tlv_file(nvm_file_path)) < 0)
-        goto error;
+    if (get_boardid_req(fd) < 0) {
+        ALOGE("%s: failed to get board id(0x%x)", __FUNCTION__, err);
+        goto default_download;
+    }
+
+    strlcat(nvm_file_path_bid, board_id, sizeof(nvm_file_path_bid));
+
+    if((tlv_size = rome_get_tlv_file(nvm_file_path_bid)) < 0) {
+        ALOGI("%s: %s: file doesn't exist, falling back to default file", __FUNCTION__, nvm_file_path_bid);
+default_download:
+        /* NVM TLV file Downloading */
+        if((tlv_size = rome_get_tlv_file(nvm_file_path)) < 0)
+            goto error;
+    }
 
     if((err =rome_tlv_dnld_req(fd, tlv_size)) <0 )
         goto error;
@@ -1614,6 +1680,36 @@
     return err;
 }
 
+int get_boardid_req(int fd)
+{
+    int size, err = 0;
+    unsigned char cmd[HCI_MAX_CMD_SIZE];
+    unsigned char rsp[HCI_MAX_EVENT_SIZE];
+    bool cmd_supported = TRUE;
+
+    /* Frame the HCI CMD to be sent to the Controller */
+    frame_hci_cmd_pkt(cmd, EDL_GET_BOARD_ID, 0,
+    -1, EDL_PATCH_CMD_LEN);
+    /* Total length of the packet to be sent to the Controller */
+    size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + EDL_PATCH_CMD_LEN);
+
+    ALOGI("%s: Sending EDL_GET_BOARD_ID", __FUNCTION__);
+    err = hci_send_vs_cmd(fd, (unsigned char *)cmd, rsp, size);
+    if ( err != size) {
+        ALOGE("Failed to send EDL_GET_BOARD_ID command!");
+        cmd_supported = FALSE;
+    }
+
+    err = read_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE);
+    if (err < 0) {
+        ALOGE("%s: Failed to get feature request", __FUNCTION__);
+        goto error;
+    }
+error:
+    return (cmd_supported == TRUE? err: -1);
+}
+
+
 int addon_feature_req(int fd)
 {
     int size, err = 0;
@@ -1716,7 +1812,7 @@
 }
 
 
-void enable_controller_log (int fd)
+void enable_controller_log (int fd, unsigned char wait_for_evt)
 {
    int ret = 0;
    /* VS command to enable controller logging to the HOST. By default it is disabled */
@@ -1729,11 +1825,23 @@
    // value at cmd[5]: 1 - to enable, 0 - to disable
    ret = (strcmp(value, "true") == 0) ? cmd[5] = 0x01: 0;
    ALOGI("%s: %d", __func__, ret);
+   /* Ignore vsc evt if wait_for_evt is true */
+   if (wait_for_evt) wait_vsc_evt = FALSE;
 
    ret = hci_send_vs_cmd(fd, (unsigned char *)cmd, rsp, 6);
    if (ret != 6) {
-     ALOGE("%s: command failed", __func__);
+       ALOGE("%s: command failed", __func__);
    }
+   /*Ignore hci_event if wait_for_evt is true*/
+   if (wait_for_evt)
+       goto end;
+   ret = read_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE);
+   if (ret < 0) {
+       ALOGE("%s: Failed to get CC for enable SoC log", __FUNCTION__);
+   }
+end:
+   wait_vsc_evt = TRUE;
+   return;
 }
 
 
@@ -1763,8 +1871,9 @@
 int rome_soc_init(int fd, char *bdaddr)
 {
     int err = -1, size = 0;
-
+    dnld_fd = fd;
     ALOGI(" %s ", __FUNCTION__);
+    RESERVED(bdaddr);
 
     /* If wipower charging is going on in embedded mode then start hand off req */
     if (wipower_flag == WIPOWER_IN_EMBEDDED_MODE && wipower_handoff_ready != NON_WIPOWER_MODE)
@@ -1900,5 +2009,16 @@
     }
 
 error:
+    dnld_fd = -1;
     return err;
 }
+
+unsigned char convert2ascii(unsigned char temp)
+{
+  unsigned char n = temp;
+  if ( n  >= 0 && n <= 9)
+     n = n + 0x30;
+  else
+     n = n + 0x57;
+  return n;
+}