blob: 31c8927efee3e491c37bfc22ae2c4e639f217569
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 "bt_vendor_brcm.h" |
32 | #include "upio.h" |
33 | #include "userial_vendor.h" |
34 | |
35 | #ifndef BTVND_DBG |
36 | #define BTVND_DBG FALSE |
37 | #endif |
38 | |
39 | #if (BTVND_DBG == TRUE) |
40 | #define BTVNDDBG(param, ...) {ALOGD(param, ## __VA_ARGS__);} |
41 | #else |
42 | #define BTVNDDBG(param, ...) {} |
43 | #endif |
44 | |
45 | /****************************************************************************** |
46 | ** Externs |
47 | ******************************************************************************/ |
48 | |
49 | void hw_config_start(void); |
50 | uint8_t hw_lpm_enable(uint8_t turn_on); |
51 | uint32_t hw_lpm_get_idle_timeout(void); |
52 | void hw_lpm_set_wake_state(uint8_t wake_assert); |
53 | #if (SCO_CFG_INCLUDED == TRUE) |
54 | void hw_sco_config(void); |
55 | #endif |
56 | void vnd_load_conf(const char *p_path); |
57 | #if (HW_END_WITH_HCI_RESET == TRUE) |
58 | void hw_epilog_process(void); |
59 | #endif |
60 | |
61 | /****************************************************************************** |
62 | ** Variables |
63 | ******************************************************************************/ |
64 | |
65 | bt_vendor_callbacks_t *bt_vendor_cbacks = NULL; |
66 | uint8_t vnd_local_bd_addr[6]={0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; |
67 | |
68 | /****************************************************************************** |
69 | ** Local type definitions |
70 | ******************************************************************************/ |
71 | |
72 | /****************************************************************************** |
73 | ** Static Variables |
74 | ******************************************************************************/ |
75 | |
76 | static const tUSERIAL_CFG userial_init_cfg = |
77 | { |
78 | (USERIAL_DATABITS_8 | USERIAL_PARITY_NONE | USERIAL_STOPBITS_1), |
79 | USERIAL_BAUD_115200 |
80 | }; |
81 | |
82 | /****************************************************************************** |
83 | ** Functions |
84 | ******************************************************************************/ |
85 | |
86 | /***************************************************************************** |
87 | ** |
88 | ** BLUETOOTH VENDOR INTERFACE LIBRARY FUNCTIONS |
89 | ** |
90 | *****************************************************************************/ |
91 | |
92 | static int init(const bt_vendor_callbacks_t* p_cb, unsigned char *local_bdaddr) |
93 | { |
94 | ALOGI("init"); |
95 | |
96 | if (p_cb == NULL) |
97 | { |
98 | ALOGE("init failed with no user callbacks!"); |
99 | return -1; |
100 | } |
101 | |
102 | #if (VENDOR_LIB_RUNTIME_TUNING_ENABLED == TRUE) |
103 | ALOGW("*****************************************************************"); |
104 | ALOGW("*****************************************************************"); |
105 | ALOGW("** Warning - BT Vendor Lib is loaded in debug tuning mode!"); |
106 | ALOGW("**"); |
107 | ALOGW("** If this is not intentional, rebuild libbt-vendor.so "); |
108 | ALOGW("** with VENDOR_LIB_RUNTIME_TUNING_ENABLED=FALSE and "); |
109 | ALOGW("** check if any run-time tuning parameters needed to be"); |
110 | ALOGW("** carried to the build-time configuration accordingly."); |
111 | ALOGW("*****************************************************************"); |
112 | ALOGW("*****************************************************************"); |
113 | #endif |
114 | |
115 | userial_vendor_init(); |
116 | upio_init(); |
117 | |
118 | vnd_load_conf(VENDOR_LIB_CONF_FILE); |
119 | |
120 | /* store reference to user callbacks */ |
121 | bt_vendor_cbacks = (bt_vendor_callbacks_t *) p_cb; |
122 | |
123 | /* This is handed over from the stack */ |
124 | memcpy(vnd_local_bd_addr, local_bdaddr, 6); |
125 | |
126 | return 0; |
127 | } |
128 | |
129 | |
130 | /** Requested operations */ |
131 | static int op(bt_vendor_opcode_t opcode, void *param) |
132 | { |
133 | int retval = 0; |
134 | |
135 | BTVNDDBG("op for %d", opcode); |
136 | |
137 | switch(opcode) |
138 | { |
139 | case BT_VND_OP_POWER_CTRL: |
140 | { |
141 | int *state = (int *) param; |
142 | if (*state == BT_VND_PWR_OFF) |
143 | upio_set_bluetooth_power(UPIO_BT_POWER_OFF); |
144 | else if (*state == BT_VND_PWR_ON) |
145 | upio_set_bluetooth_power(UPIO_BT_POWER_ON); |
146 | } |
147 | break; |
148 | |
149 | case BT_VND_OP_FW_CFG: |
150 | { |
151 | hw_config_start(); |
152 | } |
153 | break; |
154 | |
155 | case BT_VND_OP_SCO_CFG: |
156 | { |
157 | #if (SCO_CFG_INCLUDED == TRUE) |
158 | hw_sco_config(); |
159 | #else |
160 | retval = -1; |
161 | #endif |
162 | } |
163 | break; |
164 | |
165 | case BT_VND_OP_USERIAL_OPEN: |
166 | { |
167 | int (*fd_array)[] = (int (*)[]) param; |
168 | int fd, idx; |
169 | fd = userial_vendor_open((tUSERIAL_CFG *) &userial_init_cfg); |
170 | if (fd != -1) |
171 | { |
172 | for (idx=0; idx < CH_MAX; idx++) |
173 | (*fd_array)[idx] = fd; |
174 | |
175 | retval = 1; |
176 | } |
177 | /* retval contains numbers of open fd of HCI channels */ |
178 | } |
179 | break; |
180 | |
181 | case BT_VND_OP_USERIAL_CLOSE: |
182 | { |
183 | userial_vendor_close(); |
184 | } |
185 | break; |
186 | |
187 | case BT_VND_OP_GET_LPM_IDLE_TIMEOUT: |
188 | { |
189 | uint32_t *timeout_ms = (uint32_t *) param; |
190 | *timeout_ms = hw_lpm_get_idle_timeout(); |
191 | } |
192 | break; |
193 | |
194 | case BT_VND_OP_LPM_SET_MODE: |
195 | { |
196 | usleep(100000); |
197 | uint8_t *mode = (uint8_t *) param; |
198 | retval = hw_lpm_enable(*mode); |
199 | } |
200 | break; |
201 | |
202 | case BT_VND_OP_LPM_WAKE_SET_STATE: |
203 | { |
204 | uint8_t *state = (uint8_t *) param; |
205 | uint8_t wake_assert = (*state == BT_VND_LPM_WAKE_ASSERT) ? \ |
206 | TRUE : FALSE; |
207 | |
208 | hw_lpm_set_wake_state(wake_assert); |
209 | } |
210 | break; |
211 | |
212 | case BT_VND_OP_SET_AUDIO_STATE: |
213 | { |
214 | retval = hw_set_audio_state((bt_vendor_op_audio_state_t *)param); |
215 | } |
216 | break; |
217 | |
218 | case BT_VND_OP_EPILOG: |
219 | { |
220 | #if (HW_END_WITH_HCI_RESET == FALSE) |
221 | if (bt_vendor_cbacks) |
222 | { |
223 | bt_vendor_cbacks->epilog_cb(BT_VND_OP_RESULT_SUCCESS); |
224 | } |
225 | #else |
226 | hw_epilog_process(); |
227 | #endif |
228 | } |
229 | break; |
230 | } |
231 | |
232 | return retval; |
233 | } |
234 | |
235 | /** Closes the interface */ |
236 | static void cleanup( void ) |
237 | { |
238 | BTVNDDBG("cleanup"); |
239 | |
240 | upio_cleanup(); |
241 | |
242 | bt_vendor_cbacks = NULL; |
243 | } |
244 | |
245 | // Entry point of DLib |
246 | const bt_vendor_interface_t BLUETOOTH_VENDOR_LIB_INTERFACE = { |
247 | sizeof(bt_vendor_interface_t), |
248 | init, |
249 | op, |
250 | cleanup |
251 | }; |
252 |