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 /******************************************************************************
88 ** Functions
89 ******************************************************************************/
90
91 /*****************************************************************************
92 **
93 ** BLUETOOTH VENDOR INTERFACE LIBRARY FUNCTIONS
94 **
95 *****************************************************************************/
96 /** LPM disable/enable request */
97 typedef enum {
98 BT_VND_LPM_DISABLE,
99 BT_VND_LPM_ENABLE,
100 } bt_vendor_lpm_mode_t;
101
init(const bt_vendor_callbacks_t * p_cb,unsigned char * local_bdaddr)102 static int init(const bt_vendor_callbacks_t *p_cb, unsigned char *local_bdaddr)
103 {
104 HILOGI("init, bdaddr:%02x%02x:%02x%02x:%02x%02x", local_bdaddr[0], local_bdaddr[1], local_bdaddr[2],
105 local_bdaddr[3], local_bdaddr[4], 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
146 switch (opcode) {
147 case BT_OP_POWER_ON: // BT_VND_OP_POWER_CTRL
148 upio_set_bluetooth_power(UPIO_BT_POWER_OFF);
149 upio_set_bluetooth_power(UPIO_BT_POWER_ON);
150 break;
151
152 case BT_OP_POWER_OFF: // BT_VND_OP_POWER_CTRL
153 upio_set_bluetooth_power(UPIO_BT_POWER_OFF);
154 hw_lpm_set_wake_state(false);
155 break;
156
157 case BT_OP_HCI_CHANNEL_OPEN: { // BT_VND_OP_USERIAL_OPEN
158 int(*fd_array)[] = (int(*)[])param;
159 int fd, idx;
160 fd = userial_vendor_open((tUSERIAL_CFG *)&userial_init_cfg);
161 if (fd != -1) {
162 for (idx = 0; idx < HCI_MAX_CHANNEL; idx++)
163 (*fd_array)[idx] = fd;
164
165 retval = 1;
166 }
167 /* retval contains numbers of open fd of HCI channels */
168 break;
169 }
170 case BT_OP_HCI_CHANNEL_CLOSE: // BT_VND_OP_USERIAL_CLOSE
171 userial_vendor_close();
172 break;
173
174 case BT_OP_INIT: // BT_VND_OP_FW_CFG
175 hw_config_start();
176 break;
177
178 case BT_OP_GET_LPM_TIMER: { // BT_VND_OP_GET_LPM_IDLE_TIMEOUT
179 uint32_t *timeout_ms = (uint32_t *)param;
180 *timeout_ms = hw_lpm_get_idle_timeout();
181 break;
182 }
183
184 case BT_OP_LPM_ENABLE:
185 retval = hw_lpm_enable(BT_VND_LPM_ENABLE);
186 break;
187
188 case BT_OP_LPM_DISABLE:
189 retval = hw_lpm_enable(BT_VND_LPM_DISABLE);
190 break;
191
192 case BT_OP_WAKEUP_LOCK:
193 hw_lpm_set_wake_state(TRUE);
194 break;
195 case BT_OP_WAKEUP_UNLOCK:
196 hw_lpm_set_wake_state(FALSE);
197 break;
198 case BT_OP_EVENT_CALLBACK:
199 hw_process_event((HC_BT_HDR *)param);
200 break;
201 }
202
203 return retval;
204 }
205
206 /** Closes the interface */
cleanup(void)207 static void cleanup(void)
208 {
209 BTVNDDBG("cleanup");
210 upio_cleanup();
211 bt_vendor_cbacks = NULL;
212 }
213
214 // Entry point of DLib
215 const bt_vendor_interface_t BLUETOOTH_VENDOR_LIB_INTERFACE = {
216 sizeof(bt_vendor_interface_t),
217 init,
218 op,
219 cleanup};
220