blob: 05a5bcb422a9d223c70ab78f146b04cb36a06823
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 | uint8_t *mode = (uint8_t *) param; |
197 | retval = hw_lpm_enable(*mode); |
198 | } |
199 | break; |
200 | |
201 | case BT_VND_OP_LPM_WAKE_SET_STATE: |
202 | { |
203 | uint8_t *state = (uint8_t *) param; |
204 | uint8_t wake_assert = (*state == BT_VND_LPM_WAKE_ASSERT) ? \ |
205 | TRUE : FALSE; |
206 | |
207 | hw_lpm_set_wake_state(wake_assert); |
208 | } |
209 | break; |
210 | |
211 | case BT_VND_OP_SET_AUDIO_STATE: |
212 | { |
213 | retval = hw_set_audio_state((bt_vendor_op_audio_state_t *)param); |
214 | } |
215 | break; |
216 | |
217 | case BT_VND_OP_EPILOG: |
218 | { |
219 | #if (HW_END_WITH_HCI_RESET == FALSE) |
220 | if (bt_vendor_cbacks) |
221 | { |
222 | bt_vendor_cbacks->epilog_cb(BT_VND_OP_RESULT_SUCCESS); |
223 | } |
224 | #else |
225 | hw_epilog_process(); |
226 | #endif |
227 | } |
228 | break; |
229 | } |
230 | |
231 | return retval; |
232 | } |
233 | |
234 | /** Closes the interface */ |
235 | static void cleanup( void ) |
236 | { |
237 | BTVNDDBG("cleanup"); |
238 | |
239 | upio_cleanup(); |
240 | |
241 | bt_vendor_cbacks = NULL; |
242 | } |
243 | |
244 | // Entry point of DLib |
245 | const bt_vendor_interface_t BLUETOOTH_VENDOR_LIB_INTERFACE = { |
246 | sizeof(bt_vendor_interface_t), |
247 | init, |
248 | op, |
249 | cleanup |
250 | }; |
251 |