1 /******************************************************************************
2 *
3 * Copyright (C) 2009-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
19 /******************************************************************************
20 *
21 * Filename: bt_vendor_brcm.c
22 *
23 * Description: Broadcom vendor specific library implementation
24 *
25 ******************************************************************************/
26
27 #define LOG_TAG "bt_vendor"
28
29 #include <utils/Log.h>
30 #include <string.h>
31 #include "upio.h"
32 #include "userial_vendor.h"
33 #include "bt_vendor_brcm.h"
34
35 #ifndef BTVND_DBG
36 #define BTVND_DBG FALSE
37 #endif
38
39 #if (BTVND_DBG == TRUE)
40 #define BTVNDDBG(param, ...) \
41 { \
42 HILOGD(param, ##__VA_ARGS__); \
43 }
44 #else
45 #define BTVNDDBG(param, ...) \
46 { \
47 HILOGD(param, ##__VA_ARGS__); \
48 }
49 #endif
50
51 /******************************************************************************
52 ** Externs
53 ******************************************************************************/
54
55 void hw_config_start(void);
56 uint8_t hw_lpm_enable(uint8_t turn_on);
57 uint32_t hw_lpm_get_idle_timeout(void);
58 void hw_lpm_set_wake_state(uint8_t wake_assert);
59 #if (SCO_CFG_INCLUDED == TRUE)
60 void hw_sco_config(void);
61 #endif
62 void vnd_load_conf(const char *p_path);
63 #if (HW_END_WITH_HCI_RESET == TRUE)
64 void hw_epilog_process(void);
65 #endif
66
67 /******************************************************************************
68 ** Variables
69 ******************************************************************************/
70
71 bt_vendor_callbacks_t *bt_vendor_cbacks = NULL;
72 uint8_t vnd_local_bd_addr[BD_ADDR_LEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
73
74 /******************************************************************************
75 ** Local type definitions
76 ******************************************************************************/
77
78 /******************************************************************************
79 ** Static Variables
80 ******************************************************************************/
81
82 static const tUSERIAL_CFG userial_init_cfg = {
83 (USERIAL_DATABITS_8 | USERIAL_PARITY_NONE | USERIAL_STOPBITS_1),
84 USERIAL_BAUD_115200};
85
86 /******************************************************************************
87 ** Functions
88 ******************************************************************************/
89
90 /*****************************************************************************
91 **
92 ** BLUETOOTH VENDOR INTERFACE LIBRARY FUNCTIONS
93 **
94 *****************************************************************************/
95 /** LPM disable/enable request */
96 typedef enum {
97 BT_VND_LPM_DISABLE,
98 BT_VND_LPM_ENABLE,
99 } bt_vendor_lpm_mode_t;
100
init(const bt_vendor_callbacks_t * p_cb,unsigned char * local_bdaddr)101 static int init(const bt_vendor_callbacks_t *p_cb, unsigned char *local_bdaddr)
102 {
103 HILOGI("init, bdaddr:%02x%02x:%02x%02x:%02x%02x", local_bdaddr[0],
104 local_bdaddr[1], local_bdaddr[2], local_bdaddr[3], local_bdaddr[4],
105 local_bdaddr[5]);
106
107 if (p_cb == NULL) {
108 HILOGE("init failed with no user callbacks!");
109 return -1;
110 }
111
112 #if (VENDOR_LIB_RUNTIME_TUNING_ENABLED == TRUE)
113 HILOGW("*****************************************************************");
114 HILOGW("*****************************************************************");
115 HILOGW("** Warning - BT Vendor Lib is loaded in debug tuning mode!");
116 HILOGW("**");
117 HILOGW("** If this is not intentional, rebuild libbt-vendor.so ");
118 HILOGW("** with VENDOR_LIB_RUNTIME_TUNING_ENABLED=FALSE and ");
119 HILOGW("** check if any run-time tuning parameters needed to be");
120 HILOGW("** carried to the build-time configuration accordingly.");
121 HILOGW("*****************************************************************");
122 HILOGW("*****************************************************************");
123 #endif
124
125 userial_vendor_init();
126 upio_init();
127
128 vnd_load_conf(VENDOR_LIB_CONF_FILE);
129
130 /* store reference to user callbacks */
131 bt_vendor_cbacks = (bt_vendor_callbacks_t *)p_cb;
132
133 #if (BRCM_A2DP_OFFLOAD == TRUE)
134 brcm_vnd_a2dp_init(bt_vendor_cbacks);
135 #endif
136
137 /* This is handed over from the stack */
138 return memcpy_s(vnd_local_bd_addr, BD_ADDR_LEN, local_bdaddr, BD_ADDR_LEN);
139 }
140
141 /** Requested operations */
op(bt_opcode_t opcode,void * param)142 static int op(bt_opcode_t opcode, void *param)
143 {
144 int retval = 0;
145 HILOGI("op for %d", opcode);
146
147 switch (opcode) {
148 case BT_OP_POWER_ON: // BT_VND_OP_POWER_CTRL
149 upio_set_bluetooth_power(UPIO_BT_POWER_OFF);
150 upio_set_bluetooth_power(UPIO_BT_POWER_ON);
151 break;
152
153 case BT_OP_POWER_OFF: // BT_VND_OP_POWER_CTRL
154 upio_set_bluetooth_power(UPIO_BT_POWER_OFF);
155 hw_lpm_set_wake_state(false);
156 break;
157
158 case BT_OP_HCI_CHANNEL_OPEN: { // BT_VND_OP_USERIAL_OPEN
159 int(*fd_array)[] = (int(*)[])param;
160 int fd, idx;
161 fd = userial_vendor_open((tUSERIAL_CFG *)&userial_init_cfg);
162 if (fd != -1) {
163 for (idx = 0; idx < HCI_MAX_CHANNEL; idx++) {
164 (*fd_array)[idx] = fd;
165 }
166
167 retval = 1;
168 }
169 /* retval contains numbers of open fd of HCI channels */
170 break;
171 }
172 case BT_OP_HCI_CHANNEL_CLOSE: // BT_VND_OP_USERIAL_CLOSE
173 userial_vendor_close();
174 break;
175
176 case BT_OP_INIT: // BT_VND_OP_FW_CFG
177 hw_config_start();
178 break;
179
180 case BT_OP_GET_LPM_TIMER: { // BT_VND_OP_GET_LPM_IDLE_TIMEOUT
181 uint32_t *timeout_ms = (uint32_t *)param;
182 *timeout_ms = hw_lpm_get_idle_timeout();
183 break;
184 }
185
186 case BT_OP_LPM_ENABLE:
187 retval = hw_lpm_enable(BT_VND_LPM_ENABLE);
188 break;
189
190 case BT_OP_LPM_DISABLE:
191 retval = hw_lpm_enable(BT_VND_LPM_DISABLE);
192 break;
193
194 case BT_OP_WAKEUP_LOCK:
195 hw_lpm_set_wake_state(TRUE);
196 break;
197 case BT_OP_WAKEUP_UNLOCK:
198 hw_lpm_set_wake_state(FALSE);
199 break;
200 case BT_OP_EVENT_CALLBACK:
201 hw_process_event((HC_BT_HDR *)param);
202 break;
203 }
204
205 return retval;
206 }
207
208 /** Closes the interface */
cleanup(void)209 static void cleanup(void)
210 {
211 BTVNDDBG("cleanup");
212 upio_cleanup();
213 bt_vendor_cbacks = NULL;
214 }
215
216 // Entry point of DLib
217 const bt_vendor_interface_t BLUETOOTH_VENDOR_LIB_INTERFACE = {
218 sizeof(bt_vendor_interface_t), init, op, cleanup};
219