summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKiran Kelageri <kirankelageri@codeaurora.org>2015-07-09 15:14:29 -0700
committerLinux Build Service Account <lnxbuild@localhost>2015-10-06 03:21:39 -0600
commitf3e4f1207f39d62da23867bf2a6b457a15b1d678 (patch)
tree131abbe26f1e49c8248b01157e49a10797b5f101
parent0289c987ab29fc924c6672a242b2d104bc1f4e6e (diff)
downloadandroid_system_bt-f3e4f1207f39d62da23867bf2a6b457a15b1d678.tar.gz
android_system_bt-f3e4f1207f39d62da23867bf2a6b457a15b1d678.tar.bz2
android_system_bt-f3e4f1207f39d62da23867bf2a6b457a15b1d678.zip
Bluetooth-Wipower: Enable WiPower feature.
Enabling WiPower feature on lastest PL, this feature enables wireless charging capablity on the target. Change-Id: I133a00b17efa5a89a764230864b9c2db252aea26
-rw-r--r--Android.mk4
-rw-r--r--btif/src/bluetooth.c11
-rw-r--r--main/Android.mk9
-rw-r--r--stack/btm/btm_ble_multi_adv.c29
-rw-r--r--wipowerif/include/wipower_const.h56
-rw-r--r--wipowerif/src/wipower.c522
6 files changed, 630 insertions, 1 deletions
diff --git a/Android.mk b/Android.mk
index c5d3d1678..3ddffce66 100644
--- a/Android.mk
+++ b/Android.mk
@@ -17,6 +17,10 @@ ifneq ($(TARGET_BUILD_VARIANT),user)
bdroid_CFLAGS += -DBLUEDROID_DEBUG
endif
+ifeq ($(BOARD_USES_WIPOWER), true)
+bdroid_CFLAGS += -DWIPOWER_SUPPORTED
+endif
+
bdroid_CFLAGS += \
-Wall \
-Wno-unused-parameter \
diff --git a/btif/src/bluetooth.c b/btif/src/bluetooth.c
index 79af4f304..f93a4f829 100644
--- a/btif/src/bluetooth.c
+++ b/btif/src/bluetooth.c
@@ -44,6 +44,9 @@
#include <hardware/bt_gatt.h>
#include <hardware/bt_rc.h>
#include <hardware/bt_sdp.h>
+#ifdef WIPOWER_SUPPORTED
+#include <hardware/wipower.h>
+#endif
#define LOG_NDDEBUG 0
#define LOG_TAG "bt_bluedroid"
@@ -106,6 +109,9 @@ extern btgatt_interface_t *btif_gatt_get_interface();
/* avrc target */
extern btrc_interface_t *btif_rc_get_interface();
/* avrc controller */
+#ifdef WIPOWER_SUPPORTED
+extern wipower_interface_t *get_wipower_interface();
+#endif
extern btrc_interface_t *btif_rc_ctrl_get_interface();
/*SDP search client*/
extern btsdp_interface_t *btif_sdp_get_interface();
@@ -368,6 +374,11 @@ static const void* get_profile_interface (const char *profile_id)
if (is_profile(profile_id, BT_PROFILE_AV_RC_ID))
return btif_rc_get_interface();
+#ifdef WIPOWER_SUPPORTED
+ if (is_profile(profile_id, WIPOWER_PROFILE_ID))
+ return get_wipower_interface();
+#endif
+
if (is_profile(profile_id, BT_PROFILE_AV_RC_CTRL_ID))
return btif_rc_ctrl_get_interface();
diff --git a/main/Android.mk b/main/Android.mk
index 43f5605dd..55497a0d8 100644
--- a/main/Android.mk
+++ b/main/Android.mk
@@ -57,6 +57,11 @@ LOCAL_SRC_FILES += \
../btif/src/btif_util.c \
../btif/src/stack_manager.c
+ifeq ($(BOARD_USES_WIPOWER), true)
+ LOCAL_SRC_FILES += \
+ ../wipowerif/src/wipower.c
+endif
+
# callouts
LOCAL_SRC_FILES+= \
../btif/co/bta_ag_co.c \
@@ -114,6 +119,10 @@ LOCAL_C_INCLUDES+= . \
external/tinyxml2 \
external/zlib
+ifeq ($(BOARD_USES_WIPOWER), true)
+ LOCAL_C_INCLUDES+= $(LOCAL_PATH)/../wipowerif/include
+endif
+
LOCAL_CFLAGS += -DBUILDCFG $(bdroid_CFLAGS) -Wno-error=maybe-uninitialized -Wno-error=uninitialized -Wno-error=unused-parameter
LOCAL_CONLYFLAGS := -std=c99
diff --git a/stack/btm/btm_ble_multi_adv.c b/stack/btm/btm_ble_multi_adv.c
index 21f18ca04..a54ca6a26 100644
--- a/stack/btm/btm_ble_multi_adv.c
+++ b/stack/btm/btm_ble_multi_adv.c
@@ -42,12 +42,22 @@
#define BTM_BLE_MULTI_ADV_CB_EVT_MASK 0xF0
#define BTM_BLE_MULTI_ADV_SUBCODE_MASK 0x0F
+#ifdef WIPOWER_SUPPORTED
+#define WIPOWER_16_UUID_LSB 0xFE
+#define WIPOWER_16_UUID_MSB 0xFF
+static bool is_wipower_adv = false;
+#endif
+
/************************************************************************************
** Static variables
************************************************************************************/
tBTM_BLE_MULTI_ADV_CB btm_multi_adv_cb;
tBTM_BLE_MULTI_ADV_INST_IDX_Q btm_multi_adv_idx_q;
+#ifdef WIPOWER_SUPPORTED
+UINT8 wipower_inst_id = BTM_BLE_MULTI_ADV_DEFAULT_STD;
+#endif
+
/************************************************************************************
** Externs
************************************************************************************/
@@ -690,6 +700,13 @@ tBTM_STATUS BTM_BleCfgAdvInstData (UINT8 inst_id, BOOLEAN is_scan_rsp,
btm_ble_build_adv_data(&data_mask, &pp, p_data);
*p_len = (UINT8)(pp - param - 2);
UINT8_TO_STREAM(pp_temp, inst_id);
+#ifdef WIPOWER_SUPPORTED
+ if (param[7] == WIPOWER_16_UUID_LSB && param[8] == WIPOWER_16_UUID_MSB)
+ {
+ is_wipower_adv = true;
+ wipower_inst_id = inst_id;
+ }
+#endif
if ((rt = BTM_VendorSpecificCommand (HCI_BLE_MULTI_ADV_OCF,
(UINT8)BTM_BLE_MULTI_ADV_WRITE_DATA_LEN,
@@ -783,7 +800,13 @@ void btm_ble_multi_adv_vse_cback(UINT8 len, UINT8 *p)
adv_inst != BTM_BLE_MULTI_ADV_DEFAULT_STD)
{
BTM_TRACE_EVENT("btm_ble_multi_adv_reenable called");
- btm_ble_multi_adv_reenable(adv_inst);
+#ifdef WIPOWER_SUPPORTED
+ if (!(is_wipower_adv && (adv_inst == wipower_inst_id))) {
+ btm_ble_multi_adv_reenable(adv_inst);
+ }
+#else
+ btm_ble_multi_adv_reenable(adv_inst);
+#endif
}
/* re-enable connectibility */
else if (adv_inst == BTM_BLE_MULTI_ADV_DEFAULT_STD)
@@ -855,6 +878,10 @@ void btm_ble_multi_adv_init()
*******************************************************************************/
void btm_ble_multi_adv_cleanup(void)
{
+#ifdef WIPOWER_SUPPORTED
+ is_wipower_adv = false;
+ wipower_inst_id = BTM_BLE_MULTI_ADV_DEFAULT_STD;
+#endif
if (btm_multi_adv_cb.p_adv_inst)
GKI_freebuf(btm_multi_adv_cb.p_adv_inst);
diff --git a/wipowerif/include/wipower_const.h b/wipowerif/include/wipower_const.h
new file mode 100644
index 000000000..359ba7e1b
--- /dev/null
+++ b/wipowerif/include/wipower_const.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of The Linux Foundation nor
+ * the names of its contributors may be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _WIPOWER_CONSTANTS_H_
+#define _WIPOWER_CONSTANTS_H_
+
+#define WP_HCI_VS_CMD 0xFC1F
+
+#define WP_HCI_CMD_SET_CURRENT_LIMIT 0x16
+#define WP_HCI_CMD_SET_CHARGE_OUTPUT 0x17
+#define WP_HCI_CMD_ENABLE_ALERT 0x18
+#define WP_HCI_CMD_ENABLE_DATA 0x19
+#define WP_HCI_CMD_GET_CURRENT_LIMIT 0x1A
+#define WP_HCI_CMD_GET_CHARGE_OUTPUT 0x1B
+#define WP_HCI_CMD_ENABLE_POWER 0x1C
+
+#define WP_HCI_EVENT_ALERT 0x15
+#define WP_HCI_EVENT_DATA 0x16
+#define WP_HCI_EVENT_POWER_ON 0x17
+
+/*
+ * enable: 0x00 disabled, 0x01 enabled: enable/disable detection command
+ * on: 0x00 power down [event on PRU placed on to PTU]
+ * 0x01 power up [event on PRU taken out of PTU]
+ * time_flag: if true then host advertises on 600ms and if false its for 30ms
+ * i.e. for PTU to short beacon on long beacon detection on charge complete or
+ * charge required.
+ */
+int enable_power_apply(bool enable, bool on, bool time_flag);
+
+#endif /*_WIPOWER_CONSTANTS_H_*/
diff --git a/wipowerif/src/wipower.c b/wipowerif/src/wipower.c
new file mode 100644
index 000000000..c410c2e20
--- /dev/null
+++ b/wipowerif/src/wipower.c
@@ -0,0 +1,522 @@
+/*
+ * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of The Linux Foundation nor
+ * the names of its contributors may be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <utils/Log.h>
+#include <pthread.h>
+
+#include <hardware/wipower.h>
+#include <hardware/bluetooth.h>
+
+#include "bta_api.h"
+#include "btm_api.h"
+#include "btif_common.h"
+#include "wipower_const.h"
+
+pthread_mutex_t signal_mutex;
+pthread_cond_t signal_cv;
+
+/* #define LOG_NDDEBUG 0 */
+
+#define WIP_LOG_TAG "wipower"
+#define DBG false
+#define HCI_EVENT_WAIT_TIMEOUT 2
+
+#define WIPOWER_ADV_30MS_MSB 0x00
+#define WIPOWER_ADV_30MS_LSB 0x1E
+#define WIPOWER_ADV_600MS_LSB 0x58
+#define WIPOWER_ADV_600MS_MSB 0x02
+
+/*1 seconds timeout*/
+#define WIPOWER_DATA_IDLE_TIMEOUT (600)
+
+wipower_callbacks_t *wipower_hal_cbacks = NULL;
+wipower_dyn_data_t wipower_dyn_data;
+
+unsigned char gStatus;
+wipower_state_t gState;
+unsigned char gCurrentLimit;
+timer_t wp_data_timer;
+/* adv_inst is captured during MultiAdvertiser and
+** need to track same for wipower instance */
+extern UINT8 wipower_inst_id;
+
+char power_removal_event[] = {0x17, 0x00};
+void dispatch_wp_events (UINT16 len, char* p_param);
+
+static void wp_data_timeout() {
+ if (DBG)
+ ALOGI("%s",__FUNCTION__);
+ int len = 2;
+
+ /*Imitate the power removal event as part of the
+ * timeout so that App layer disconnect GATT*/
+ /*Event is part of payload, Length used as Event*/
+ btif_transfer_context(dispatch_wp_events, (UINT16)len,
+ (char*)power_removal_event, len, NULL);
+ if (wipower_hal_cbacks) {
+ ALOGE("kiran: dispatch_wp_events :Sending associate event to jni");
+ wipower_hal_cbacks->callback_thread_event(DISASSOCIATE_JVM);
+ }
+
+}
+
+static void wipower_data_timer_stop()
+{
+ int status;
+ struct itimerspec ts;
+
+ ts.it_value.tv_sec = 0;
+ ts.it_value.tv_nsec = 0;
+ ts.it_interval.tv_sec = 0;
+ ts.it_interval.tv_nsec = 0;
+ if (wp_data_timer != 0)
+ status = timer_settime(wp_data_timer, 0, &ts, 0);
+ if(status == -1)
+ ALOGE("%s:Failed to stop wp data timer",__FUNCTION__);
+ else if(status == 0)
+ ALOGI("%s: wp data timer Stopped",__FUNCTION__);
+}
+
+static void wipower_data_timer_start()
+{
+ int status;
+ struct itimerspec ts;
+ uint32_t timeout_ms;
+
+ timeout_ms = WIPOWER_DATA_IDLE_TIMEOUT;
+ ts.it_value.tv_sec = timeout_ms/1000;
+ ts.it_value.tv_nsec = 1000000*(timeout_ms%1000);
+ ts.it_interval.tv_sec = 0;
+ ts.it_interval.tv_nsec = 0;
+
+ if (wp_data_timer != 0)
+ status = timer_settime(wp_data_timer, 0, &ts, 0);
+ if (status == -1)
+ ALOGE("%s:Failed to set wack timer",__FUNCTION__);
+ if (DBG)
+ ALOGI("%s:set timer passed: %d",__FUNCTION__, status);
+}
+
+void dispatch_enable_event (UINT16 event, char* p_param) {
+ wipower_state_t state = OFF;
+
+ unsigned char stat = *p_param;
+ if (DBG)
+ ALOGI("%s: %x", __func__, stat);
+
+ if (stat == 0x00) state = ON;
+ else state = OFF;
+
+ if (wipower_hal_cbacks) {
+ wipower_hal_cbacks->wipower_state_changed_cb(state);
+ } else {
+ ALOGE("wipower_hal_cbacks not registered");
+ }
+}
+
+
+void enable_cb(tBTM_VSC_CMPL *p1) {
+ unsigned char status = 0xFF;
+
+ if (p1->param_len) {
+ status = p1->p_param_buf[p1->param_len-2];
+
+ if (DBG)
+ ALOGI("%s: %x", __func__, status);
+
+ }
+
+ btif_transfer_context(dispatch_enable_event, 0/*Event is not used*/,
+ (char*)&status, sizeof(status), NULL);
+}
+
+void set_current_limit_cb(tBTM_VSC_CMPL *p1) {
+ gStatus = 0xFF;
+ unsigned char status = 0x00;
+
+ if (p1->param_len) {
+ status = p1->p_param_buf[p1->param_len-2];
+
+ if (DBG)
+ ALOGI("%s: %x", __func__, status);
+
+ if (status == 0) {
+ gStatus = 0x00;
+ }
+ }
+}
+
+void get_current_limit_cb(tBTM_VSC_CMPL *p1) {
+ gStatus = 0xFF;
+ unsigned char status = 0x00;
+
+ if (p1->param_len) {
+ status = p1->p_param_buf[p1->param_len-2];
+
+ if (status == 0) {
+ gStatus = 0x00;
+ gCurrentLimit = p1->p_param_buf[p1->param_len-2];
+ }
+ }
+ if (DBG)
+ ALOGI("%s->%x", __func__, gCurrentLimit);
+}
+
+void get_state_cb(tBTM_VSC_CMPL *p1) {
+ gStatus = 0xFF;
+ unsigned char status = 0x00;
+
+ if (p1->param_len) {
+ status = p1->p_param_buf[p1->param_len-3];
+ if(DBG)
+ ALOGI("%s: %x", __func__, status);
+
+ if (status == 0) {
+ gStatus = 0x00;
+ gState = p1->p_param_buf[p1->param_len-1];
+ }
+ }
+}
+
+void enable_alert_cb(tBTM_VSC_CMPL *p1) {
+ gStatus = 0xFF;
+ unsigned char status = 0x00;
+
+ if (p1->param_len) {
+ status = p1->p_param_buf[p1->param_len-2];
+ if (DBG)
+ ALOGI("%s: %x", __func__, status);
+
+ if (status == 0) {
+ gStatus = 0x00;
+ }
+ }
+}
+
+void enable_data_cb(tBTM_VSC_CMPL *p1) {
+ gStatus = 0xFF;
+ unsigned char status = 0x00;
+
+ if (p1->param_len) {
+ status = p1->p_param_buf[p1->param_len-2];
+ if (DBG)
+ ALOGI("%s: %x", __func__, status);
+
+ if (status == 0) {
+ gStatus = 0x00;
+ }
+ }
+}
+
+void enable_power_cb(tBTM_VSC_CMPL *p1) {
+ gStatus = 0xFF;
+ unsigned char status = 0x00;
+
+ if (p1->param_len) {
+ status = p1->p_param_buf[p1->param_len-2];
+
+ if (DBG)
+ ALOGI("%s: %x", __func__, status);
+
+ if (status == 0) {
+ gStatus = 0x00;
+ }
+ }
+}
+
+void dispatch_wp_events (UINT16 len, char* p_param) {
+ if (DBG)
+ ALOGI("%s->", __func__);
+
+ unsigned char event = p_param[0];
+ switch(event) {
+ case WP_HCI_EVENT_ALERT: {
+ if (len != 2) {
+ ALOGE("WP_HCI_EVENT_ALERT:Error! Length"); return;
+ } else {
+ unsigned char alert = p_param[1];
+ if (wipower_hal_cbacks) {
+ wipower_hal_cbacks->wipower_alert(alert);
+ if (DBG)
+ ALOGI("alert event forwarded to app layer");
+ } else {
+ ALOGE("wipower_hal_cbacks not registered");
+ }
+ }
+ } break;
+ case WP_HCI_EVENT_DATA: {
+ if (len != 21) {
+ ALOGE("WP_HCI_EVENT_DATA: Error! Length"); return;
+ } else {
+ memcpy(&wipower_dyn_data, &p_param[1], 20);
+ if (wipower_hal_cbacks) {
+ wipower_hal_cbacks->wipower_data(&wipower_dyn_data);
+ if (DBG)
+ ALOGI("wp data event forwarded to app layer");
+ } else {
+ ALOGE("wipower_hal_cbacks not registered");
+ }
+ wipower_data_timer_stop();
+ wipower_data_timer_start();
+ }
+
+ } break;
+ case WP_HCI_EVENT_POWER_ON: {
+ if (len != 2) {
+ ALOGE("WP_HCI_EVENT_POWER_ON: Error! Length"); return;
+ } else {
+ if (wipower_hal_cbacks) {
+ ALOGE("kiran: dispatch_wp_events :Sending associate event to jni");
+ wipower_hal_cbacks->callback_thread_event(ASSOCIATE_JVM);
+ }
+ unsigned char alert = p_param[1];
+ if (wipower_hal_cbacks) {
+ wipower_hal_cbacks->wipower_power_event(alert);
+ if (DBG)
+ ALOGI("wp power-on event forwarded to app layer");
+ } else {
+ ALOGE("wipower_hal_cbacks not registered");
+ }
+
+ }
+
+ } break;
+ }
+
+}
+
+void wp_events(UINT8 len, UINT8 *p) {
+ if (DBG)
+ ALOGI("%s-> %d", __func__, len);
+
+ /*Event is part of payload, Length used as Event*/
+ btif_transfer_context(dispatch_wp_events, (UINT16)len,
+ (char*)p, len, NULL);
+}
+
+/** Enable Wireless charging/Start Wireless charging */
+int enable(bool enable)
+{
+ UINT8 en[2];
+ if (DBG)
+ ALOGI("enable: %d", enable);
+
+ en[0] = WP_HCI_CMD_SET_CHARGE_OUTPUT;
+
+ if (enable) {
+ en[1] = 1;
+ } else {
+ en[1]= 0;
+ }
+
+ BTM_VendorSpecificCommand(WP_HCI_VS_CMD, 2, en, enable_cb);
+
+ return 0;
+}
+
+
+int set_current_limit(short value)
+{
+ UINT8 curr_limit[2];
+ int status = -1;
+
+ curr_limit[0] = WP_HCI_CMD_SET_CURRENT_LIMIT;
+ curr_limit[1] = value;
+
+ gStatus = 0xFF;
+ BTM_VendorSpecificCommand(WP_HCI_VS_CMD, 2, curr_limit, set_current_limit_cb);
+
+ if (gStatus == 0) {
+ status = 0;
+ }
+ status = 0;
+ if (DBG)
+ ALOGI("set_current_limit: Status %x", status);
+ return status;
+}
+
+unsigned char get_current_limit(void)
+{
+ unsigned char val = 0;
+ UINT8 get_limit = 0;
+ get_limit = WP_HCI_CMD_GET_CURRENT_LIMIT;
+ gStatus = 0xFF;
+ BTM_VendorSpecificCommand(WP_HCI_VS_CMD, 1, &get_limit, get_current_limit_cb);
+
+ val = gCurrentLimit;
+
+ if (DBG)
+ ALOGI("get_current_limit: value %x", val);
+ return val;
+}
+
+wipower_state_t get_state(void)
+{
+ wipower_state_t state = OFF;
+ UINT8 get_state = 0;
+ get_state = WP_HCI_CMD_GET_CHARGE_OUTPUT;
+ gStatus = 0xFF;
+ BTM_VendorSpecificCommand(WP_HCI_VS_CMD, 1, &get_state, get_state_cb);
+
+ if (gStatus == 0x00) {
+ state = gState;
+ }
+ if (DBG)
+ ALOGI("%s: %x", __func__, state);
+ return state;
+}
+
+int enable_alerts(bool enable)
+{
+ UINT8 en[2];
+ int status = -1;
+
+ en[0] = WP_HCI_CMD_ENABLE_ALERT;
+ if (enable) {
+ en[1] = 1;
+ } else {
+ en[1] = 0;
+ }
+
+ BTM_VendorSpecificCommand(WP_HCI_VS_CMD, 2, en, enable_alert_cb);
+
+
+ status = gStatus;
+ if (DBG)
+ ALOGI("%s: Status %x", __func__, status);
+ return status;
+}
+
+int enable_data_notify(bool enable)
+{
+ UINT8 en[2];
+ int status = -1;
+ struct sigevent se;
+ int ret;
+
+ en[0] = WP_HCI_CMD_ENABLE_DATA;
+ if (enable) {
+ en[1] = 1;
+ } else {
+ en[1] = 0;
+ }
+
+ BTM_VendorSpecificCommand(WP_HCI_VS_CMD, 2, en, enable_data_cb);
+
+ status = gStatus;
+ if (DBG)
+ ALOGI("enable_data_notify: Status %x", status);
+
+ if (enable) {
+ se.sigev_notify_function = wp_data_timeout;
+ se.sigev_notify = SIGEV_THREAD;
+ se.sigev_value.sival_ptr = &wp_data_timer;
+ se.sigev_notify_attributes = NULL;
+
+ ret = timer_create(CLOCK_MONOTONIC, &se, &wp_data_timer);
+ if (ret < 0) {
+ ALOGE("%s: Error while creating timer", __func__);
+ return -1;
+ }
+ wipower_data_timer_start();
+ }
+ else {
+ if (wp_data_timer != 0)
+ timer_delete(wp_data_timer);
+ }
+
+ return status;
+}
+
+int enable_power_apply(bool enable, bool on, bool time_flag)
+{
+ UINT8 en[6];
+ if (DBG)
+ ALOGI("%s:%d", __func__, enable);
+
+ en[0] = WP_HCI_CMD_ENABLE_POWER;
+ if (enable) {
+ en[1] = 1;
+ } else {
+ en[1] = 0;
+ }
+
+ /* 30ms beacon is used to advertise if charge is required
+ * else uses 600ms beacon to advertise on charge completeion */
+
+ en[2] = on;
+ if (time_flag == true) {
+ en[3] = WIPOWER_ADV_600MS_LSB;
+ en[4] = WIPOWER_ADV_600MS_MSB;
+ } else {
+ en[3] = WIPOWER_ADV_30MS_LSB;
+ en[4] = WIPOWER_ADV_30MS_MSB;
+ }
+ en[5] = wipower_inst_id;
+ BTM_VendorSpecificCommand(WP_HCI_VS_CMD, 6, en, enable_power_cb);
+ return 0;
+}
+
+int init(wipower_callbacks_t *wp_callbacks) {
+ bool enable = true;
+ int ret = 0;
+
+ wipower_hal_cbacks = wp_callbacks;
+ ALOGV("BTM_RegisterForVSEvents: enetering init");
+
+ tBTM_STATUS res = BTM_RegisterForVSEvents(wp_events, enable);
+ if (res != BTM_SUCCESS) {
+ ALOGE("Failure of BTM_RegisterForVSEvents %d", res);
+ ret = -1;
+ }
+
+ return ret;
+}
+
+static const wipower_interface_t wipowerInterface = {
+ sizeof(wipowerInterface),
+ /* Initialize wipower module*/
+ init,
+ /** Enable wireless charging */
+ enable,
+ set_current_limit,
+ get_current_limit,
+ get_state,
+ enable_alerts,
+ enable_data_notify,
+ enable_power_apply
+};
+
+const wipower_interface_t* get_wipower_interface ()
+{
+ ALOGI("get wp interface>>");
+ return &wipowerInterface;
+}