summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYK Jeffrey Chao <jechao@broadcom.com>2013-05-07 17:29:31 -0700
committerMatthew Xie <mattx@google.com>2013-05-09 12:20:28 -0700
commitf219785e8a4e011abe5488d22f3d72b6698ce45a (patch)
treef8752c528220e46d622c48e0540b5e3bb6da3f8d
parenta41dd34e0e4ae09527a8d5d3c5975805124ccc32 (diff)
downloadlibbt-jb-mr2.0-release.tar.gz
A pair of asynchronous call-in and call-back API are added into the Host Controller Vendor Lib interface (bt_vendor_lib.h). The caller calls this new call-in function to inform the vendor module to perform vendor-specific shutdown process (e.g. send HCI_RESET to BT Controller) before the caller calls for interface cleanup() function. The vendor module is responsible for calling call-back function to notify the caller completion of vendor-specific shutdown process. Sample codes of sending a HCI_RESET command in the vendor-specific shutdown process. bug 7390787 Change-Id: I817c0a7dd57e750d38884746edeb3436cfc9cfd8
-rw-r--r--include/bt_vendor_brcm.h10
-rw-r--r--src/bt_vendor_brcm.c16
-rw-r--r--src/hardware.c86
3 files changed, 112 insertions, 0 deletions
diff --git a/include/bt_vendor_brcm.h b/include/bt_vendor_brcm.h
index 858b71b..8f336bd 100644
--- a/include/bt_vendor_brcm.h
+++ b/include/bt_vendor_brcm.h
@@ -349,6 +349,16 @@
#define PCM_DATA_FMT_JUSTIFY_MODE 0
#endif
+/* HW_END_WITH_HCI_RESET
+
+ Sample code implementation of sending a HCI_RESET command during the epilog
+ process. It calls back to the callers after command complete of HCI_RESET
+ is received.
+*/
+#ifndef HW_END_WITH_HCI_RESET
+#define HW_END_WITH_HCI_RESET TRUE
+#endif
+
/******************************************************************************
** Extern variables and functions
******************************************************************************/
diff --git a/src/bt_vendor_brcm.c b/src/bt_vendor_brcm.c
index 9bd8922..ef6236f 100644
--- a/src/bt_vendor_brcm.c
+++ b/src/bt_vendor_brcm.c
@@ -53,6 +53,9 @@ void hw_lpm_set_wake_state(uint8_t wake_assert);
void hw_sco_config(void);
#endif
void vnd_load_conf(const char *p_path);
+#if (HW_END_WITH_HCI_RESET == TRUE)
+void hw_epilog_process(void);
+#endif
/******************************************************************************
** Variables
@@ -203,6 +206,19 @@ static int op(bt_vendor_opcode_t opcode, void *param)
hw_lpm_set_wake_state(wake_assert);
}
break;
+
+ case BT_VND_OP_EPILOG:
+ {
+#if (HW_END_WITH_HCI_RESET == FALSE)
+ if (bt_vendor_cbacks)
+ {
+ bt_vendor_cbacks->epilog_cb(BT_VND_OP_RESULT_SUCCESS);
+ }
+#else
+ hw_epilog_process();
+#endif
+ }
+ break;
}
return retval;
diff --git a/src/hardware.c b/src/hardware.c
index 45008ef..c8bf746 100644
--- a/src/hardware.c
+++ b/src/hardware.c
@@ -1231,3 +1231,89 @@ int hw_set_patch_settlement_delay(char *p_conf_name, char *p_conf_value, int par
}
#endif //VENDOR_LIB_RUNTIME_TUNING_ENABLED
+/*****************************************************************************
+** Sample Codes Section
+*****************************************************************************/
+
+#if (HW_END_WITH_HCI_RESET == TRUE)
+/*******************************************************************************
+**
+** Function hw_epilog_cback
+**
+** Description Callback function for Command Complete Events from HCI
+** commands sent in epilog process.
+**
+** Returns None
+**
+*******************************************************************************/
+void hw_epilog_cback(void *p_mem)
+{
+ HC_BT_HDR *p_evt_buf = (HC_BT_HDR *) p_mem;
+ uint8_t *p, status;
+ uint16_t opcode;
+
+ status = *((uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_STATUS_RET_BYTE);
+ p = (uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_OPCODE;
+ STREAM_TO_UINT16(opcode,p);
+
+ BTHWDBG("%s Opcode:0x%04X Status: %d", __FUNCTION__, opcode, status);
+
+ if (bt_vendor_cbacks)
+ {
+ /* Must free the RX event buffer */
+ bt_vendor_cbacks->dealloc(p_evt_buf);
+
+ /* Once epilog process is done, must call epilog_cb callback
+ to notify caller */
+ bt_vendor_cbacks->epilog_cb(BT_VND_OP_RESULT_SUCCESS);
+ }
+}
+
+/*******************************************************************************
+**
+** Function hw_epilog_process
+**
+** Description Sample implementation of epilog process
+**
+** Returns None
+**
+*******************************************************************************/
+void hw_epilog_process(void)
+{
+ HC_BT_HDR *p_buf = NULL;
+ uint8_t *p;
+
+ BTHWDBG("hw_epilog_process");
+
+ /* Sending a HCI_RESET */
+ if (bt_vendor_cbacks)
+ {
+ /* Must allocate command buffer via HC's alloc API */
+ p_buf = (HC_BT_HDR *) bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE + \
+ HCI_CMD_PREAMBLE_SIZE);
+ }
+
+ if (p_buf)
+ {
+ p_buf->event = MSG_STACK_TO_HC_HCI_CMD;
+ p_buf->offset = 0;
+ p_buf->layer_specific = 0;
+ p_buf->len = HCI_CMD_PREAMBLE_SIZE;
+
+ p = (uint8_t *) (p_buf + 1);
+ UINT16_TO_STREAM(p, HCI_RESET);
+ *p = 0; /* parameter length */
+
+ /* Send command via HC's xmit_cb API */
+ bt_vendor_cbacks->xmit_cb(HCI_RESET, p_buf, hw_epilog_cback);
+ }
+ else
+ {
+ if (bt_vendor_cbacks)
+ {
+ ALOGE("vendor lib epilog process aborted [no buffer]");
+ bt_vendor_cbacks->epilog_cb(BT_VND_OP_RESULT_FAIL);
+ }
+ }
+}
+#endif // (HW_END_WITH_HCI_RESET == TRUE)