Merge "Bluetooth: Add VS command for disabling internal LDO"
diff --git a/libbt-vendor/src/bt_vendor_qcom.c b/libbt-vendor/src/bt_vendor_qcom.c
index 12fe16d..05a518c 100644
--- a/libbt-vendor/src/bt_vendor_qcom.c
+++ b/libbt-vendor/src/bt_vendor_qcom.c
@@ -57,7 +57,7 @@
 static int btSocType = BT_SOC_DEFAULT;
 static int rfkill_id = -1;
 static char *rfkill_state = NULL;
-
+bool enable_extldo = FALSE;
 
 static const tUSERIAL_CFG userial_init_cfg =
 {
@@ -297,9 +297,9 @@
 /** Bluetooth Controller power up or shutdown */
 static int bt_powerup(int en )
 {
-    char rfkill_type[64];
-    char type[16];
-    int fd, size, i, ret;
+    char rfkill_type[64], *enable_ldo_path = NULL;
+    char type[16], enable_ldo[6];
+    int fd, size, i, ret, fd_ldo;
 
     char disable[PROPERTY_VALUE_MAX];
     char state;
@@ -379,6 +379,22 @@
         goto done;
     }
 
+    asprintf(&enable_ldo_path, "/sys/devices/bt_qca6174.0/extldo");
+    if ((fd_ldo = open(enable_ldo_path, O_RDWR)) < 0) {
+        ALOGE("open(%s) failed: %s (%d)", enable_ldo_path, strerror(errno), errno);
+        return -1;
+    }
+    size = read(fd_ldo, &enable_ldo, sizeof(enable_ldo));
+    close(fd_ldo);
+    if (size <= 0) {
+        ALOGE("read(%s) failed: %s (%d)", enable_ldo_path, strerror(errno), errno);
+        return -1;
+    }
+    if (!memcmp(enable_ldo, "true", 4)) {
+        ALOGI("External LDO has been configured");
+	enable_extldo = TRUE;
+    }
+
     ALOGE("Write %c to rfkill\n", on);
 
     /* Write value to control rfkill */
diff --git a/libbt-vendor/src/hw_rome.c b/libbt-vendor/src/hw_rome.c
index 22b512e..ef7d3dc 100644
--- a/libbt-vendor/src/hw_rome.c
+++ b/libbt-vendor/src/hw_rome.c
@@ -68,6 +68,7 @@
 unsigned char gTlv_type;
 char *rampatch_file_path;
 char *nvm_file_path;
+extern char enable_extldo;
 
 /******************************************************************************
 **  Extern variables
@@ -1301,6 +1302,46 @@
 
 }
 
+
+int rome_hci_reset(int fd)
+{
+    int size, err = 0;
+    unsigned char cmd[HCI_MAX_CMD_SIZE];
+    unsigned char rsp[HCI_MAX_EVENT_SIZE];
+    hci_command_hdr *cmd_hdr;
+    int flags;
+
+    ALOGI("%s: HCI RESET ", __FUNCTION__);
+
+    memset(cmd, 0x0, HCI_MAX_CMD_SIZE);
+
+    cmd_hdr = (void *) (cmd + 1);
+    cmd[0]  = HCI_COMMAND_PKT;
+    cmd_hdr->opcode = HCI_RESET;
+    cmd_hdr->plen   = 0;
+
+    /* Total length of the packet to be sent to the Controller */
+    size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE);
+    err = write(fd, cmd, size);
+    if (err != size) {
+        ALOGE("%s: Send failed with ret value: %d", __FUNCTION__, err);
+        err = -1;
+        goto error;
+    }
+
+    /* Wait for command complete event */
+    err = read_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE);
+    if ( err < 0) {
+        ALOGE("%s: Failed to set patch info on Controller", __FUNCTION__);
+        goto error;
+    }
+
+error:
+    return err;
+
+}
+
+
 static void enable_controller_log (int fd)
 {
    int ret = 0;
@@ -1322,6 +1363,30 @@
    }
 }
 
+
+static int disable_internal_ldo(int fd)
+{
+    int ret = 0;
+    if (enable_extldo) {
+        unsigned char cmd[5] = {0x01, 0x0C, 0xFC, 0x01, 0x32};
+        unsigned char rsp[HCI_MAX_EVENT_SIZE];
+
+        ALOGI(" %s ", __FUNCTION__);
+        ret = write(fd, cmd, 5);
+        if (ret != 5) {
+            ALOGE("%s: Send failed with ret value: %d", __FUNCTION__, ret);
+            ret = -1;
+        } else {
+            /* Wait for command complete event */
+            ret = read_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE);
+            if ( ret < 0) {
+                ALOGE("%s: Failed to get response from controller", __FUNCTION__);
+            }
+        }
+    }
+    return ret;
+}
+
 int rome_soc_init(int fd, char *bdaddr)
 {
     int err = -1, size = 0;
@@ -1425,15 +1490,11 @@
              */
             enable_controller_log(fd);
 
-            /* Perform HCI reset here*/
-            err = rome_hci_reset_req(fd);
-            if ( err <0 ) {
-                ALOGE("HCI Reset Failed !!");
-                goto error;
-            }
+            /* Disable internal LDO to use external LDO instead*/
+            err = disable_internal_ldo(fd);
 
-            ALOGI("HCI Reset is done\n");
-
+            /* Send HCI Reset */
+            err = rome_hci_reset(fd);
             break;
         case ROME_VER_UNKNOWN:
         default: