hardware/broadcom/libbt
Revision | a745e079f6427423cbae88437e63ce20177cfd8a (tree) |
---|---|
Zeit | 2012-09-25 03:47:13 |
Autor | Wink Saville <wink@goog...> |
Commiter | Wink Saville |
Move libbt-vendor from vendor/broadcom/libbt-vendor
Bug: 6837125
Change-Id: I9e9d5a95463d5cd61a6e7f3b2f0a57c0b2f47e16
@@ -0,0 +1,48 @@ | ||
1 | +$(warning "wink:device/common/libbt E") | |
2 | +LOCAL_PATH := $(call my-dir) | |
3 | + | |
4 | +ifneq ($(BOARD_HAVE_BLUETOOTH_BCM),) | |
5 | + | |
6 | +include $(CLEAR_VARS) | |
7 | + | |
8 | +BDROID_DIR := $(TOP_DIR)external/bluetooth/bluedroid | |
9 | + | |
10 | +LOCAL_SRC_FILES := \ | |
11 | + src/bt_vendor_brcm.c \ | |
12 | + src/hardware.c \ | |
13 | + src/userial_vendor.c \ | |
14 | + src/upio.c \ | |
15 | + src/conf.c | |
16 | + | |
17 | +LOCAL_C_INCLUDES += \ | |
18 | + $(LOCAL_PATH)/include \ | |
19 | + $(BDROID_DIR)/hci/include | |
20 | + | |
21 | +LOCAL_SHARED_LIBRARIES := \ | |
22 | + libcutils | |
23 | + | |
24 | +LOCAL_MODULE := libbt-vendor | |
25 | +LOCAL_MODULE_TAGS := optional | |
26 | +LOCAL_MODULE_CLASS := SHARED_LIBRARIES | |
27 | +LOCAL_MODULE_OWNER := broadcom | |
28 | +LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_SHARED_LIBRARIES) | |
29 | + | |
30 | +include $(LOCAL_PATH)/vnd_buildcfg.mk | |
31 | + | |
32 | +include $(BUILD_SHARED_LIBRARY) | |
33 | + | |
34 | +ifeq ($(TARGET_PRODUCT), full_maguro) | |
35 | + include $(LOCAL_PATH)/conf/samsung/maguro/Android.mk | |
36 | +endif | |
37 | +ifeq ($(TARGET_PRODUCT), full_crespo) | |
38 | + include $(LOCAL_PATH)/conf/samsung/crespo/Android.mk | |
39 | +endif | |
40 | +ifeq ($(TARGET_PRODUCT), full_crespo4g) | |
41 | + include $(LOCAL_PATH)/conf/samsung/crespo4g/Android.mk | |
42 | +endif | |
43 | +ifeq ($(TARGET_PRODUCT), full_wingray) | |
44 | + include $(LOCAL_PATH)/conf/moto/wingray/Android.mk | |
45 | +endif | |
46 | + | |
47 | +endif # BOARD_HAVE_BLUETOOTH_BCM | |
48 | +$(warning "wink:device/common/libbt X") |
@@ -0,0 +1,14 @@ | ||
1 | +LOCAL_PATH := $(call my-dir) | |
2 | + | |
3 | +include $(CLEAR_VARS) | |
4 | + | |
5 | +LOCAL_MODULE := bt_vendor.conf | |
6 | +LOCAL_MODULE_CLASS := ETC | |
7 | +LOCAL_MODULE_PATH := $(TARGET_OUT)/etc/bluetooth | |
8 | + | |
9 | +LOCAL_MODULE_TAGS := eng | |
10 | + | |
11 | +LOCAL_SRC_FILES := $(LOCAL_MODULE) | |
12 | + | |
13 | +include $(BUILD_PREBUILT) | |
14 | + |
@@ -0,0 +1,5 @@ | ||
1 | +# UART device port where Bluetooth controller is attached | |
2 | +UartPort = /dev/ttyHS2 | |
3 | + | |
4 | +# Firmware patch file location | |
5 | +FwPatchFilePath = /etc/firmware/ |
@@ -0,0 +1,14 @@ | ||
1 | +LOCAL_PATH := $(call my-dir) | |
2 | + | |
3 | +include $(CLEAR_VARS) | |
4 | + | |
5 | +LOCAL_MODULE := bt_vendor.conf | |
6 | +LOCAL_MODULE_CLASS := ETC | |
7 | +LOCAL_MODULE_PATH := $(TARGET_OUT)/etc/bluetooth | |
8 | + | |
9 | +LOCAL_MODULE_TAGS := eng | |
10 | + | |
11 | +LOCAL_SRC_FILES := $(LOCAL_MODULE) | |
12 | + | |
13 | +include $(BUILD_PREBUILT) | |
14 | + |
@@ -0,0 +1,5 @@ | ||
1 | +# UART device port where Bluetooth controller is attached | |
2 | +UartPort = /dev/ttyHS2 | |
3 | + | |
4 | +# Firmware patch file location | |
5 | +FwPatchFilePath = /etc/firmware/ |
@@ -0,0 +1,14 @@ | ||
1 | +LOCAL_PATH := $(call my-dir) | |
2 | + | |
3 | +include $(CLEAR_VARS) | |
4 | + | |
5 | +LOCAL_MODULE := bt_vendor.conf | |
6 | +LOCAL_MODULE_CLASS := ETC | |
7 | +LOCAL_MODULE_PATH := $(TARGET_OUT)/etc/bluetooth | |
8 | + | |
9 | +LOCAL_MODULE_TAGS := eng | |
10 | + | |
11 | +LOCAL_SRC_FILES := $(LOCAL_MODULE) | |
12 | + | |
13 | +include $(BUILD_PREBUILT) | |
14 | + |
@@ -0,0 +1,5 @@ | ||
1 | +# UART device port where Bluetooth controller is attached | |
2 | +UartPort = /dev/s3c2410_serial0 | |
3 | + | |
4 | +# Firmware patch file location | |
5 | +FwPatchFilePath = /vendor/firmware/ |
@@ -0,0 +1,14 @@ | ||
1 | +LOCAL_PATH := $(call my-dir) | |
2 | + | |
3 | +include $(CLEAR_VARS) | |
4 | + | |
5 | +LOCAL_MODULE := bt_vendor.conf | |
6 | +LOCAL_MODULE_CLASS := ETC | |
7 | +LOCAL_MODULE_PATH := $(TARGET_OUT)/etc/bluetooth | |
8 | + | |
9 | +LOCAL_MODULE_TAGS := eng | |
10 | + | |
11 | +LOCAL_SRC_FILES := $(LOCAL_MODULE) | |
12 | + | |
13 | +include $(BUILD_PREBUILT) | |
14 | + |
@@ -0,0 +1,5 @@ | ||
1 | +# UART device port where Bluetooth controller is attached | |
2 | +UartPort = /dev/s3c2410_serial0 | |
3 | + | |
4 | +# Firmware patch file location | |
5 | +FwPatchFilePath = /vendor/firmware/ |
@@ -0,0 +1,14 @@ | ||
1 | +LOCAL_PATH := $(call my-dir) | |
2 | + | |
3 | +include $(CLEAR_VARS) | |
4 | + | |
5 | +LOCAL_MODULE := bt_vendor.conf | |
6 | +LOCAL_MODULE_CLASS := ETC | |
7 | +LOCAL_MODULE_PATH := $(TARGET_OUT)/etc/bluetooth | |
8 | + | |
9 | +LOCAL_MODULE_TAGS := eng | |
10 | + | |
11 | +LOCAL_SRC_FILES := $(LOCAL_MODULE) | |
12 | + | |
13 | +include $(BUILD_PREBUILT) | |
14 | + |
@@ -0,0 +1,5 @@ | ||
1 | +# UART device port where Bluetooth controller is attached | |
2 | +UartPort = /dev/ttyO1 | |
3 | + | |
4 | +# Firmware patch file location | |
5 | +FwPatchFilePath = /vendor/firmware/ |
@@ -0,0 +1,334 @@ | ||
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.h | |
22 | + * | |
23 | + * Description: A wrapper header file of bt_vendor_lib.h | |
24 | + * | |
25 | + * Contains definitions specific for interfacing with Broadcom | |
26 | + * Bluetooth chipsets | |
27 | + * | |
28 | + ******************************************************************************/ | |
29 | + | |
30 | +#ifndef BT_VENDOR_BRCM_H | |
31 | +#define BT_VENDOR_BRCM_H | |
32 | + | |
33 | +#include "bt_vendor_lib.h" | |
34 | +#include "vnd_buildcfg.h" | |
35 | + | |
36 | +/****************************************************************************** | |
37 | +** Constants & Macros | |
38 | +******************************************************************************/ | |
39 | + | |
40 | +#ifndef FALSE | |
41 | +#define FALSE 0 | |
42 | +#endif | |
43 | + | |
44 | +#ifndef TRUE | |
45 | +#define TRUE (!FALSE) | |
46 | +#endif | |
47 | + | |
48 | +#ifndef VENDOR_LIB_RUNTIME_TUNING_ENABLED | |
49 | +#define VENDOR_LIB_RUNTIME_TUNING_ENABLED FALSE | |
50 | +#endif | |
51 | + | |
52 | +/* Run-time configuration file */ | |
53 | +#ifndef VENDOR_LIB_CONF_FILE | |
54 | +#define VENDOR_LIB_CONF_FILE "/etc/bluetooth/bt_vendor.conf" | |
55 | +#endif | |
56 | + | |
57 | +/* Device port name where Bluetooth controller attached */ | |
58 | +#ifndef BLUETOOTH_UART_DEVICE_PORT | |
59 | +#define BLUETOOTH_UART_DEVICE_PORT "/dev/ttyO1" /* maguro */ | |
60 | +#endif | |
61 | + | |
62 | +/* Location of firmware patch files */ | |
63 | +#ifndef FW_PATCHFILE_LOCATION | |
64 | +#define FW_PATCHFILE_LOCATION "/vendor/firmware/" /* maguro */ | |
65 | +#endif | |
66 | + | |
67 | +#ifndef UART_TARGET_BAUD_RATE | |
68 | +#define UART_TARGET_BAUD_RATE 3000000 | |
69 | +#endif | |
70 | + | |
71 | +/* The millisecond delay pauses on HCI transport after firmware patches | |
72 | + * were downloaded. This gives some time for firmware to restart with | |
73 | + * patches before host attempts to send down any HCI commands. | |
74 | + * | |
75 | + * Note: It has been discovered that BCM43241B0 needs at least 200ms | |
76 | + * settlement delay in here. Without the delay, a Hardware Error event | |
77 | + * from BCM43241B0 had been seen in HCI upstream path right after the | |
78 | + * host sent the HCI_VSC_SET_BDADDR commad to the controller at higher | |
79 | + * baud. | |
80 | + */ | |
81 | +#ifndef FW_PATCH_SETTLEMENT_DELAY_MS | |
82 | +#define FW_PATCH_SETTLEMENT_DELAY_MS 0 | |
83 | +#endif | |
84 | + | |
85 | +/* sleep mode | |
86 | + | |
87 | + 0: disable | |
88 | + 1: UART with Host wake/BT wake out of band signals | |
89 | +*/ | |
90 | +#ifndef LPM_SLEEP_MODE | |
91 | +#define LPM_SLEEP_MODE 1 | |
92 | +#endif | |
93 | + | |
94 | +/* Host Stack Idle Threshold in 300ms or 25ms | |
95 | + | |
96 | + In sleep mode 1, this is the number of firmware loops executed with no | |
97 | + activity before the Host wake line is deasserted. Activity includes HCI | |
98 | + traffic excluding certain sleep mode commands and the presence of SCO | |
99 | + connections if the "Allow Host Sleep During SCO" flag is not set to 1. | |
100 | + Each count of this parameter is roughly equivalent to 300ms or 25ms. | |
101 | +*/ | |
102 | +#ifndef LPM_IDLE_THRESHOLD | |
103 | +#define LPM_IDLE_THRESHOLD 1 | |
104 | +#endif | |
105 | + | |
106 | +/* Host Controller Idle Threshold in 300ms or 25ms | |
107 | + | |
108 | + This is the number of firmware loops executed with no activity before the | |
109 | + HC is considered idle. Depending on the mode, HC may then attempt to sleep. | |
110 | + Activity includes HCI traffic excluding certain sleep mode commands and | |
111 | + the presence of ACL/SCO connections. | |
112 | +*/ | |
113 | +#ifndef LPM_HC_IDLE_THRESHOLD | |
114 | +#define LPM_HC_IDLE_THRESHOLD 1 | |
115 | +#endif | |
116 | + | |
117 | +/* BT_WAKE Polarity - 0=Active Low, 1= Active High */ | |
118 | +#ifndef LPM_BT_WAKE_POLARITY | |
119 | +#define LPM_BT_WAKE_POLARITY 1 /* maguro */ | |
120 | +#endif | |
121 | + | |
122 | +/* HOST_WAKE Polarity - 0=Active Low, 1= Active High */ | |
123 | +#ifndef LPM_HOST_WAKE_POLARITY | |
124 | +#define LPM_HOST_WAKE_POLARITY 1 /* maguro */ | |
125 | +#endif | |
126 | + | |
127 | +/* LPM_ALLOW_HOST_SLEEP_DURING_SCO | |
128 | + | |
129 | + When this flag is set to 0, the host is not allowed to sleep while | |
130 | + an SCO is active. In sleep mode 1, the device will keep the host | |
131 | + wake line asserted while an SCO is active. | |
132 | + When this flag is set to 1, the host can sleep while an SCO is active. | |
133 | + This flag should only be set to 1 if SCO traffic is directed to the PCM | |
134 | + interface. | |
135 | +*/ | |
136 | +#ifndef LPM_ALLOW_HOST_SLEEP_DURING_SCO | |
137 | +#define LPM_ALLOW_HOST_SLEEP_DURING_SCO 1 | |
138 | +#endif | |
139 | + | |
140 | +/* LPM_COMBINE_SLEEP_MODE_AND_LPM | |
141 | + | |
142 | + In Mode 0, always set byte 7 to 0. In sleep mode 1, device always | |
143 | + requires permission to sleep between scans / periodic inquiries regardless | |
144 | + of the setting of this byte. In sleep mode 1, if byte is set, device must | |
145 | + have "permission" to sleep during the low power modes of sniff, hold, and | |
146 | + park. If byte is not set, device can sleep without permission during these | |
147 | + modes. Permission to sleep in Mode 1 is obtained if the BT_WAKE signal is | |
148 | + not asserted. | |
149 | +*/ | |
150 | +#ifndef LPM_COMBINE_SLEEP_MODE_AND_LPM | |
151 | +#define LPM_COMBINE_SLEEP_MODE_AND_LPM 1 | |
152 | +#endif | |
153 | + | |
154 | +/* LPM_ENABLE_UART_TXD_TRI_STATE | |
155 | + | |
156 | + When set to 0, the device will not tristate its UART TX line before going | |
157 | + to sleep. | |
158 | + When set to 1, the device will tristate its UART TX line before going to | |
159 | + sleep. | |
160 | +*/ | |
161 | +#ifndef LPM_ENABLE_UART_TXD_TRI_STATE | |
162 | +#define LPM_ENABLE_UART_TXD_TRI_STATE 0 | |
163 | +#endif | |
164 | + | |
165 | +/* LPM_PULSED_HOST_WAKE | |
166 | +*/ | |
167 | +#ifndef LPM_PULSED_HOST_WAKE | |
168 | +#define LPM_PULSED_HOST_WAKE 0 | |
169 | +#endif | |
170 | + | |
171 | +/* LPM_IDLE_TIMEOUT_MULTIPLE | |
172 | + | |
173 | + The multiple factor of host stack idle threshold in 300ms/25ms | |
174 | +*/ | |
175 | +#ifndef LPM_IDLE_TIMEOUT_MULTIPLE | |
176 | +#define LPM_IDLE_TIMEOUT_MULTIPLE 10 | |
177 | +#endif | |
178 | + | |
179 | +/* BT_WAKE_VIA_USERIAL_IOCTL | |
180 | + | |
181 | + Use userial ioctl function to control BT_WAKE signal | |
182 | +*/ | |
183 | +#ifndef BT_WAKE_VIA_USERIAL_IOCTL | |
184 | +#define BT_WAKE_VIA_USERIAL_IOCTL FALSE | |
185 | +#endif | |
186 | + | |
187 | + | |
188 | +/* SCO_CFG_INCLUDED | |
189 | + | |
190 | + Do SCO configuration by default. If the firmware patch had been embedded | |
191 | + with desired SCO configuration, set this FALSE to bypass configuration | |
192 | + from host software. | |
193 | +*/ | |
194 | +#ifndef SCO_CFG_INCLUDED | |
195 | +#define SCO_CFG_INCLUDED TRUE | |
196 | +#endif | |
197 | + | |
198 | +#ifndef SCO_USE_I2S_INTERFACE | |
199 | +#define SCO_USE_I2S_INTERFACE FALSE | |
200 | +#endif | |
201 | + | |
202 | +#if (SCO_USE_I2S_INTERFACE == TRUE) | |
203 | +#define SCO_I2SPCM_PARAM_SIZE 4 | |
204 | + | |
205 | +/* SCO_I2SPCM_IF_MODE - 0=Disable, 1=Enable */ | |
206 | +#ifndef SCO_I2SPCM_IF_MODE | |
207 | +#define SCO_I2SPCM_IF_MODE 1 | |
208 | +#endif | |
209 | + | |
210 | +/* SCO_I2SPCM_IF_ROLE - 0=Slave, 1=Master */ | |
211 | +#ifndef SCO_I2SPCM_IF_ROLE | |
212 | +#define SCO_I2SPCM_IF_ROLE 1 | |
213 | +#endif | |
214 | + | |
215 | +/* SCO_I2SPCM_IF_SAMPLE_RATE | |
216 | + | |
217 | + 0 : 8K | |
218 | + 1 : 16K | |
219 | + 2 : 4K | |
220 | +*/ | |
221 | +#ifndef SCO_I2SPCM_IF_SAMPLE_RATE | |
222 | +#define SCO_I2SPCM_IF_SAMPLE_RATE 0 | |
223 | +#endif | |
224 | + | |
225 | +/* SCO_I2SPCM_IF_CLOCK_RATE | |
226 | + | |
227 | + 0 : 128K | |
228 | + 1 : 256K | |
229 | + 2 : 512K | |
230 | + 3 : 1024K | |
231 | + 4 : 2048K | |
232 | +*/ | |
233 | +#ifndef SCO_I2SPCM_IF_CLOCK_RATE | |
234 | +#define SCO_I2SPCM_IF_CLOCK_RATE 1 | |
235 | +#endif | |
236 | +#endif // SCO_USE_I2S_INTERFACE | |
237 | + | |
238 | + | |
239 | +#define SCO_PCM_PARAM_SIZE 5 | |
240 | + | |
241 | +/* SCO_PCM_ROUTING | |
242 | + | |
243 | + 0 : PCM | |
244 | + 1 : Transport | |
245 | + 2 : Codec | |
246 | + 3 : I2S | |
247 | +*/ | |
248 | +#ifndef SCO_PCM_ROUTING | |
249 | +#define SCO_PCM_ROUTING 0 | |
250 | +#endif | |
251 | + | |
252 | +/* SCO_PCM_IF_CLOCK_RATE | |
253 | + | |
254 | + 0 : 128K | |
255 | + 1 : 256K | |
256 | + 2 : 512K | |
257 | + 3 : 1024K | |
258 | + 4 : 2048K | |
259 | +*/ | |
260 | +#ifndef SCO_PCM_IF_CLOCK_RATE | |
261 | +#define SCO_PCM_IF_CLOCK_RATE 4 | |
262 | +#endif | |
263 | + | |
264 | +/* SCO_PCM_IF_FRAME_TYPE - 0=Short, 1=Long */ | |
265 | +#ifndef SCO_PCM_IF_FRAME_TYPE | |
266 | +#define SCO_PCM_IF_FRAME_TYPE 0 | |
267 | +#endif | |
268 | + | |
269 | +/* SCO_PCM_IF_SYNC_MODE - 0=Slave, 1=Master */ | |
270 | +#ifndef SCO_PCM_IF_SYNC_MODE | |
271 | +#define SCO_PCM_IF_SYNC_MODE 0 | |
272 | +#endif | |
273 | + | |
274 | +/* SCO_PCM_IF_CLOCK_MODE - 0=Slave, 1=Master */ | |
275 | +#ifndef SCO_PCM_IF_CLOCK_MODE | |
276 | +#define SCO_PCM_IF_CLOCK_MODE 0 | |
277 | +#endif | |
278 | + | |
279 | +#define PCM_DATA_FORMAT_PARAM_SIZE 5 | |
280 | + | |
281 | +/* PCM_DATA_FMT_SHIFT_MODE | |
282 | + | |
283 | + 0 : MSB first | |
284 | + 1 : LSB first | |
285 | +*/ | |
286 | +#ifndef PCM_DATA_FMT_SHIFT_MODE | |
287 | +#define PCM_DATA_FMT_SHIFT_MODE 0 | |
288 | +#endif | |
289 | + | |
290 | +/* PCM_DATA_FMT_FILL_BITS | |
291 | + | |
292 | + Specifies the value with which to fill unused bits | |
293 | + if Fill_Method is set to programmable | |
294 | +*/ | |
295 | +#ifndef PCM_DATA_FMT_FILL_BITS | |
296 | +#define PCM_DATA_FMT_FILL_BITS 0 | |
297 | +#endif | |
298 | + | |
299 | +/* PCM_DATA_FMT_FILL_METHOD | |
300 | + | |
301 | + 0 : 0's | |
302 | + 1 : 1's | |
303 | + 2 : Signed | |
304 | + 3 : Programmable | |
305 | +*/ | |
306 | +#ifndef PCM_DATA_FMT_FILL_METHOD | |
307 | +#define PCM_DATA_FMT_FILL_METHOD 3 | |
308 | +#endif | |
309 | + | |
310 | +/* PCM_DATA_FMT_FILL_NUM | |
311 | + | |
312 | + Specifies the number of bits to be filled | |
313 | +*/ | |
314 | +#ifndef PCM_DATA_FMT_FILL_NUM | |
315 | +#define PCM_DATA_FMT_FILL_NUM 3 | |
316 | +#endif | |
317 | + | |
318 | +/* PCM_DATA_FMT_JUSTIFY_MODE | |
319 | + | |
320 | + 0 : Left justify (fill data shifted out last) | |
321 | + 1 : Right justify (fill data shifted out first) | |
322 | +*/ | |
323 | +#ifndef PCM_DATA_FMT_JUSTIFY_MODE | |
324 | +#define PCM_DATA_FMT_JUSTIFY_MODE 0 | |
325 | +#endif | |
326 | + | |
327 | +/****************************************************************************** | |
328 | +** Extern variables and functions | |
329 | +******************************************************************************/ | |
330 | + | |
331 | +extern bt_vendor_callbacks_t *bt_vendor_cbacks; | |
332 | + | |
333 | +#endif /* BT_VENDOR_BRCM_H */ | |
334 | + |
@@ -0,0 +1,106 @@ | ||
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: upio.h | |
22 | + * | |
23 | + * Description: Contains definitions used for I/O controls | |
24 | + * | |
25 | + ******************************************************************************/ | |
26 | + | |
27 | +#ifndef UPIO_H | |
28 | +#define UPIO_H | |
29 | + | |
30 | +/****************************************************************************** | |
31 | +** Constants & Macros | |
32 | +******************************************************************************/ | |
33 | + | |
34 | +#define UPIO_BT_POWER_OFF 0 | |
35 | +#define UPIO_BT_POWER_ON 1 | |
36 | + | |
37 | +/* UPIO signals */ | |
38 | +enum { | |
39 | + UPIO_BT_WAKE = 0, | |
40 | + UPIO_HOST_WAKE, | |
41 | + UPIO_MAX_COUNT | |
42 | +}; | |
43 | + | |
44 | +/* UPIO assertion/deassertion */ | |
45 | +enum { | |
46 | + UPIO_UNKNOWN = 0, | |
47 | + UPIO_DEASSERT, | |
48 | + UPIO_ASSERT | |
49 | +}; | |
50 | + | |
51 | +/****************************************************************************** | |
52 | +** Extern variables and functions | |
53 | +******************************************************************************/ | |
54 | + | |
55 | +/****************************************************************************** | |
56 | +** Functions | |
57 | +******************************************************************************/ | |
58 | + | |
59 | +/******************************************************************************* | |
60 | +** | |
61 | +** Function upio_init | |
62 | +** | |
63 | +** Description Initialization | |
64 | +** | |
65 | +** Returns None | |
66 | +** | |
67 | +*******************************************************************************/ | |
68 | +void upio_init(void); | |
69 | + | |
70 | +/******************************************************************************* | |
71 | +** | |
72 | +** Function upio_cleanup | |
73 | +** | |
74 | +** Description Clean up | |
75 | +** | |
76 | +** Returns None | |
77 | +** | |
78 | +*******************************************************************************/ | |
79 | +void upio_cleanup(void); | |
80 | + | |
81 | +/******************************************************************************* | |
82 | +** | |
83 | +** Function upio_set_bluetooth_power | |
84 | +** | |
85 | +** Description Interact with low layer driver to set Bluetooth power | |
86 | +** on/off. | |
87 | +** | |
88 | +** Returns 0 : SUCCESS or Not-Applicable | |
89 | +** <0 : ERROR | |
90 | +** | |
91 | +*******************************************************************************/ | |
92 | +int upio_set_bluetooth_power(int on); | |
93 | + | |
94 | +/******************************************************************************* | |
95 | +** | |
96 | +** Function upio_set | |
97 | +** | |
98 | +** Description Set i/o based on polarity | |
99 | +** | |
100 | +** Returns None | |
101 | +** | |
102 | +*******************************************************************************/ | |
103 | +void upio_set(uint8_t pio, uint8_t action, uint8_t polarity); | |
104 | + | |
105 | +#endif /* UPIO_H */ | |
106 | + |
@@ -0,0 +1,175 @@ | ||
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: userial_vendor.h | |
22 | + * | |
23 | + * Description: Contains vendor-specific definitions used in serial port | |
24 | + * controls | |
25 | + * | |
26 | + ******************************************************************************/ | |
27 | + | |
28 | +#ifndef USERIAL_VENDOR_H | |
29 | +#define USERIAL_VENDOR_H | |
30 | + | |
31 | +#include "bt_vendor_brcm.h" | |
32 | +#include "userial.h" | |
33 | + | |
34 | +/****************************************************************************** | |
35 | +** Constants & Macros | |
36 | +******************************************************************************/ | |
37 | + | |
38 | +/**** baud rates ****/ | |
39 | +#define USERIAL_BAUD_300 0 | |
40 | +#define USERIAL_BAUD_600 1 | |
41 | +#define USERIAL_BAUD_1200 2 | |
42 | +#define USERIAL_BAUD_2400 3 | |
43 | +#define USERIAL_BAUD_9600 4 | |
44 | +#define USERIAL_BAUD_19200 5 | |
45 | +#define USERIAL_BAUD_57600 6 | |
46 | +#define USERIAL_BAUD_115200 7 | |
47 | +#define USERIAL_BAUD_230400 8 | |
48 | +#define USERIAL_BAUD_460800 9 | |
49 | +#define USERIAL_BAUD_921600 10 | |
50 | +#define USERIAL_BAUD_1M 11 | |
51 | +#define USERIAL_BAUD_1_5M 12 | |
52 | +#define USERIAL_BAUD_2M 13 | |
53 | +#define USERIAL_BAUD_3M 14 | |
54 | +#define USERIAL_BAUD_4M 15 | |
55 | +#define USERIAL_BAUD_AUTO 16 | |
56 | + | |
57 | +/**** Data Format ****/ | |
58 | +/* Stop Bits */ | |
59 | +#define USERIAL_STOPBITS_1 1 | |
60 | +#define USERIAL_STOPBITS_1_5 (1<<1) | |
61 | +#define USERIAL_STOPBITS_2 (1<<2) | |
62 | + | |
63 | +/* Parity Bits */ | |
64 | +#define USERIAL_PARITY_NONE (1<<3) | |
65 | +#define USERIAL_PARITY_EVEN (1<<4) | |
66 | +#define USERIAL_PARITY_ODD (1<<5) | |
67 | + | |
68 | +/* Data Bits */ | |
69 | +#define USERIAL_DATABITS_5 (1<<6) | |
70 | +#define USERIAL_DATABITS_6 (1<<7) | |
71 | +#define USERIAL_DATABITS_7 (1<<8) | |
72 | +#define USERIAL_DATABITS_8 (1<<9) | |
73 | + | |
74 | + | |
75 | +#if (BT_WAKE_VIA_USERIAL_IOCTL==TRUE) | |
76 | +/* These are the ioctl values used for bt_wake ioctl via UART driver. you may | |
77 | + * need to redefine them on you platform! | |
78 | + * Logically they need to be unique and not colide with existing uart ioctl's. | |
79 | + */ | |
80 | +#ifndef USERIAL_IOCTL_BT_WAKE_ASSERT | |
81 | +#define USERIAL_IOCTL_BT_WAKE_ASSERT 0x8003 | |
82 | +#endif | |
83 | +#ifndef USERIAL_IOCTL_BT_WAKE_DEASSERT | |
84 | +#define USERIAL_IOCTL_BT_WAKE_DEASSERT 0x8004 | |
85 | +#endif | |
86 | +#ifndef USERIAL_IOCTL_BT_WAKE_GET_ST | |
87 | +#define USERIAL_IOCTL_BT_WAKE_GET_ST 0x8005 | |
88 | +#endif | |
89 | +#endif // (BT_WAKE_VIA_USERIAL_IOCTL==TRUE) | |
90 | + | |
91 | +/****************************************************************************** | |
92 | +** Type definitions | |
93 | +******************************************************************************/ | |
94 | + | |
95 | +/* Structure used to configure serial port during open */ | |
96 | +typedef struct | |
97 | +{ | |
98 | + uint16_t fmt; /* Data format */ | |
99 | + uint8_t baud; /* Baud rate */ | |
100 | +} tUSERIAL_CFG; | |
101 | + | |
102 | +typedef enum { | |
103 | +#if (BT_WAKE_VIA_USERIAL_IOCTL==TRUE) | |
104 | + USERIAL_OP_ASSERT_BT_WAKE, | |
105 | + USERIAL_OP_DEASSERT_BT_WAKE, | |
106 | + USERIAL_OP_GET_BT_WAKE_STATE, | |
107 | +#endif | |
108 | + USERIAL_OP_NOP, | |
109 | +} userial_vendor_ioctl_op_t; | |
110 | + | |
111 | +/****************************************************************************** | |
112 | +** Extern variables and functions | |
113 | +******************************************************************************/ | |
114 | + | |
115 | +/****************************************************************************** | |
116 | +** Functions | |
117 | +******************************************************************************/ | |
118 | + | |
119 | +/******************************************************************************* | |
120 | +** | |
121 | +** Function userial_vendor_init | |
122 | +** | |
123 | +** Description Initialize userial vendor-specific control block | |
124 | +** | |
125 | +** Returns None | |
126 | +** | |
127 | +*******************************************************************************/ | |
128 | +void userial_vendor_init(void); | |
129 | + | |
130 | +/******************************************************************************* | |
131 | +** | |
132 | +** Function userial_vendor_open | |
133 | +** | |
134 | +** Description Open the serial port with the given configuration | |
135 | +** | |
136 | +** Returns device fd | |
137 | +** | |
138 | +*******************************************************************************/ | |
139 | +int userial_vendor_open(tUSERIAL_CFG *p_cfg); | |
140 | + | |
141 | +/******************************************************************************* | |
142 | +** | |
143 | +** Function userial_vendor_close | |
144 | +** | |
145 | +** Description Conduct vendor-specific close work | |
146 | +** | |
147 | +** Returns None | |
148 | +** | |
149 | +*******************************************************************************/ | |
150 | +void userial_vendor_close(void); | |
151 | + | |
152 | +/******************************************************************************* | |
153 | +** | |
154 | +** Function userial_vendor_set_baud | |
155 | +** | |
156 | +** Description Set new baud rate | |
157 | +** | |
158 | +** Returns None | |
159 | +** | |
160 | +*******************************************************************************/ | |
161 | +void userial_vendor_set_baud(uint8_t userial_baud); | |
162 | + | |
163 | +/******************************************************************************* | |
164 | +** | |
165 | +** Function userial_vendor_ioctl | |
166 | +** | |
167 | +** Description ioctl inteface | |
168 | +** | |
169 | +** Returns None | |
170 | +** | |
171 | +*******************************************************************************/ | |
172 | +void userial_vendor_ioctl(userial_vendor_ioctl_op_t op, void *p_data); | |
173 | + | |
174 | +#endif /* USERIAL_VENDOR_H */ | |
175 | + |
@@ -0,0 +1,9 @@ | ||
1 | +BLUETOOTH_UART_DEVICE_PORT = "/dev/s3c2410_serial0" | |
2 | +FW_PATCHFILE_LOCATION = "/vendor/firmware/" | |
3 | +BT_WAKE_VIA_USERIAL_IOCTL = TRUE | |
4 | +LPM_IDLE_TIMEOUT_MULTIPLE = 5 | |
5 | +SCO_PCM_IF_CLOCK_RATE = 0 | |
6 | +BTVND_DBG = FALSE | |
7 | +BTHW_DBG = TRUE | |
8 | +VNDUSERIAL_DBG = FALSE | |
9 | +UPIO_DBG = FALSE |
@@ -0,0 +1,9 @@ | ||
1 | +BLUETOOTH_UART_DEVICE_PORT = "/dev/s3c2410_serial0" | |
2 | +FW_PATCHFILE_LOCATION = "/vendor/firmware/" | |
3 | +BT_WAKE_VIA_USERIAL_IOCTL = TRUE | |
4 | +LPM_IDLE_TIMEOUT_MULTIPLE = 5 | |
5 | +SCO_PCM_IF_CLOCK_RATE = 0 | |
6 | +BTVND_DBG = FALSE | |
7 | +BTHW_DBG = TRUE | |
8 | +VNDUSERIAL_DBG = FALSE | |
9 | +UPIO_DBG = FALSE |
@@ -0,0 +1,9 @@ | ||
1 | +BLUETOOTH_UART_DEVICE_PORT = "/dev/ttyO1" | |
2 | +FW_PATCHFILE_LOCATION = "/vendor/firmware/" | |
3 | +BT_WAKE_VIA_USERIAL_IOCTL = TRUE | |
4 | +LPM_IDLE_TIMEOUT_MULTIPLE = 5 | |
5 | +SCO_USE_I2S_INTERFACE = TRUE | |
6 | +BTVND_DBG = FALSE | |
7 | +BTHW_DBG = TRUE | |
8 | +VNDUSERIAL_DBG = FALSE | |
9 | +UPIO_DBG = FALSE |
@@ -0,0 +1,9 @@ | ||
1 | +BLUETOOTH_UART_DEVICE_PORT = "/dev/ttyO1" | |
2 | +FW_PATCHFILE_LOCATION = "/vendor/firmware/" | |
3 | +BT_WAKE_VIA_USERIAL_IOCTL = TRUE | |
4 | +LPM_IDLE_TIMEOUT_MULTIPLE = 5 | |
5 | +SCO_USE_I2S_INTERFACE = TRUE | |
6 | +BTVND_DBG = FALSE | |
7 | +BTHW_DBG = TRUE | |
8 | +VNDUSERIAL_DBG = FALSE | |
9 | +UPIO_DBG = FALSE |
@@ -0,0 +1,9 @@ | ||
1 | +BLUETOOTH_UART_DEVICE_PORT = "/dev/ttyHS2" | |
2 | +FW_PATCHFILE_LOCATION = "/etc/firmware/" | |
3 | +BT_WAKE_VIA_USERIAL_IOCTL = TRUE | |
4 | +LPM_IDLE_TIMEOUT_MULTIPLE = 5 | |
5 | +BTVND_DBG = FALSE | |
6 | +BTHW_DBG = TRUE | |
7 | +VNDUSERIAL_DBG = FALSE | |
8 | +UPIO_DBG = FALSE | |
9 | +SCO_PCM_IF_CLOCK_RATE = 2 |
@@ -0,0 +1,9 @@ | ||
1 | +BLUETOOTH_UART_DEVICE_PORT = "/dev/ttyO1" | |
2 | +FW_PATCHFILE_LOCATION = "/vendor/firmware/" | |
3 | +BT_WAKE_VIA_USERIAL_IOCTL = TRUE | |
4 | +LPM_IDLE_TIMEOUT_MULTIPLE = 5 | |
5 | +SCO_USE_I2S_INTERFACE = TRUE | |
6 | +BTVND_DBG = FALSE | |
7 | +BTHW_DBG = TRUE | |
8 | +VNDUSERIAL_DBG = FALSE | |
9 | +UPIO_DBG = FALSE |
@@ -0,0 +1,9 @@ | ||
1 | +BLUETOOTH_UART_DEVICE_PORT = "/dev/ttyO1" | |
2 | +FW_PATCHFILE_LOCATION = "/vendor/firmware/" | |
3 | +BT_WAKE_VIA_USERIAL_IOCTL = TRUE | |
4 | +LPM_IDLE_TIMEOUT_MULTIPLE = 5 | |
5 | +SCO_USE_I2S_INTERFACE = TRUE | |
6 | +BTVND_DBG = FALSE | |
7 | +BTHW_DBG = TRUE | |
8 | +VNDUSERIAL_DBG = FALSE | |
9 | +UPIO_DBG = FALSE |
@@ -0,0 +1,9 @@ | ||
1 | +BLUETOOTH_UART_DEVICE_PORT = "/dev/ttySAC0" | |
2 | +FW_PATCHFILE_LOCATION = "/vendor/firmware/" | |
3 | +UART_TARGET_BAUD_RATE = 921600 | |
4 | +BT_WAKE_VIA_USERIAL_IOCTL = TRUE | |
5 | +LPM_IDLE_TIMEOUT_MULTIPLE = 5 | |
6 | +BTVND_DBG = FALSE | |
7 | +BTHW_DBG = TRUE | |
8 | +VNDUSERIAL_DBG = FALSE | |
9 | +UPIO_DBG = FALSE |
@@ -0,0 +1,9 @@ | ||
1 | +BLUETOOTH_UART_DEVICE_PORT = "/dev/ttyO1" | |
2 | +FW_PATCHFILE_LOCATION = "/vendor/firmware/" | |
3 | +BT_WAKE_VIA_USERIAL_IOCTL = TRUE | |
4 | +LPM_IDLE_TIMEOUT_MULTIPLE = 5 | |
5 | +SCO_USE_I2S_INTERFACE = TRUE | |
6 | +BTVND_DBG = FALSE | |
7 | +BTHW_DBG = TRUE | |
8 | +VNDUSERIAL_DBG = FALSE | |
9 | +UPIO_DBG = FALSE |
@@ -0,0 +1,9 @@ | ||
1 | +BLUETOOTH_UART_DEVICE_PORT = "/dev/ttyHS2" | |
2 | +FW_PATCHFILE_LOCATION = "/etc/firmware/" | |
3 | +BT_WAKE_VIA_USERIAL_IOCTL = TRUE | |
4 | +LPM_IDLE_TIMEOUT_MULTIPLE = 5 | |
5 | +BTVND_DBG = FALSE | |
6 | +BTHW_DBG = TRUE | |
7 | +VNDUSERIAL_DBG = FALSE | |
8 | +UPIO_DBG = FALSE | |
9 | +SCO_PCM_IF_CLOCK_RATE = 2 |
@@ -0,0 +1,9 @@ | ||
1 | +BLUETOOTH_UART_DEVICE_PORT = "/dev/ttyO1" | |
2 | +FW_PATCHFILE_LOCATION = "/vendor/firmware/" | |
3 | +BT_WAKE_VIA_USERIAL_IOCTL = TRUE | |
4 | +LPM_IDLE_TIMEOUT_MULTIPLE = 5 | |
5 | +SCO_USE_I2S_INTERFACE = TRUE | |
6 | +BTVND_DBG = FALSE | |
7 | +BTHW_DBG = TRUE | |
8 | +VNDUSERIAL_DBG = FALSE | |
9 | +UPIO_DBG = FALSE |
@@ -0,0 +1,9 @@ | ||
1 | +BLUETOOTH_UART_DEVICE_PORT = "/dev/ttyO1" | |
2 | +FW_PATCHFILE_LOCATION = "/vendor/firmware/" | |
3 | +BT_WAKE_VIA_USERIAL_IOCTL = TRUE | |
4 | +LPM_IDLE_TIMEOUT_MULTIPLE = 5 | |
5 | +SCO_USE_I2S_INTERFACE = TRUE | |
6 | +BTVND_DBG = FALSE | |
7 | +BTHW_DBG = TRUE | |
8 | +VNDUSERIAL_DBG = FALSE | |
9 | +UPIO_DBG = FALSE |
@@ -0,0 +1,9 @@ | ||
1 | +BLUETOOTH_UART_DEVICE_PORT = "/dev/ttyHS2" | |
2 | +FW_PATCHFILE_LOCATION = "/etc/firmware/" | |
3 | +BT_WAKE_VIA_USERIAL_IOCTL = TRUE | |
4 | +LPM_IDLE_TIMEOUT_MULTIPLE = 5 | |
5 | +BTVND_DBG = FALSE | |
6 | +BTHW_DBG = TRUE | |
7 | +VNDUSERIAL_DBG = FALSE | |
8 | +UPIO_DBG = FALSE | |
9 | +SCO_PCM_IF_CLOCK_RATE = 2 |
@@ -0,0 +1,227 @@ | ||
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 "bt_vendor_brcm.h" | |
31 | +#include "upio.h" | |
32 | +#include "userial_vendor.h" | |
33 | + | |
34 | +#ifndef BTVND_DBG | |
35 | +#define BTVND_DBG FALSE | |
36 | +#endif | |
37 | + | |
38 | +#if (BTVND_DBG == TRUE) | |
39 | +#define BTVNDDBG(param, ...) {ALOGD(param, ## __VA_ARGS__);} | |
40 | +#else | |
41 | +#define BTVNDDBG(param, ...) {} | |
42 | +#endif | |
43 | + | |
44 | +/****************************************************************************** | |
45 | +** Externs | |
46 | +******************************************************************************/ | |
47 | + | |
48 | +void hw_config_start(void); | |
49 | +uint8_t hw_lpm_enable(uint8_t turn_on); | |
50 | +uint32_t hw_lpm_get_idle_timeout(void); | |
51 | +void hw_lpm_set_wake_state(uint8_t wake_assert); | |
52 | +#if (SCO_CFG_INCLUDED == TRUE) | |
53 | +void hw_sco_config(void); | |
54 | +#endif | |
55 | +void vnd_load_conf(const char *p_path); | |
56 | + | |
57 | +/****************************************************************************** | |
58 | +** Variables | |
59 | +******************************************************************************/ | |
60 | + | |
61 | +bt_vendor_callbacks_t *bt_vendor_cbacks = NULL; | |
62 | +uint8_t vnd_local_bd_addr[6]={0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; | |
63 | + | |
64 | +/****************************************************************************** | |
65 | +** Local type definitions | |
66 | +******************************************************************************/ | |
67 | + | |
68 | +/****************************************************************************** | |
69 | +** Static Variables | |
70 | +******************************************************************************/ | |
71 | + | |
72 | +static const tUSERIAL_CFG userial_init_cfg = | |
73 | +{ | |
74 | + (USERIAL_DATABITS_8 | USERIAL_PARITY_NONE | USERIAL_STOPBITS_1), | |
75 | + USERIAL_BAUD_115200 | |
76 | +}; | |
77 | + | |
78 | +/****************************************************************************** | |
79 | +** Functions | |
80 | +******************************************************************************/ | |
81 | + | |
82 | +/***************************************************************************** | |
83 | +** | |
84 | +** BLUETOOTH VENDOR INTERFACE LIBRARY FUNCTIONS | |
85 | +** | |
86 | +*****************************************************************************/ | |
87 | + | |
88 | +static int init(const bt_vendor_callbacks_t* p_cb, unsigned char *local_bdaddr) | |
89 | +{ | |
90 | + ALOGI("init"); | |
91 | + | |
92 | + if (p_cb == NULL) | |
93 | + { | |
94 | + ALOGE("init failed with no user callbacks!"); | |
95 | + return -1; | |
96 | + } | |
97 | + | |
98 | +#if (VENDOR_LIB_RUNTIME_TUNING_ENABLED == TRUE) | |
99 | + ALOGW("*****************************************************************"); | |
100 | + ALOGW("*****************************************************************"); | |
101 | + ALOGW("** Warning - BT Vendor Lib is loaded in debug tuning mode!"); | |
102 | + ALOGW("**"); | |
103 | + ALOGW("** If this is not intentional, rebuild libbt-vendor.so "); | |
104 | + ALOGW("** with VENDOR_LIB_RUNTIME_TUNING_ENABLED=FALSE and "); | |
105 | + ALOGW("** check if any run-time tuning parameters needed to be"); | |
106 | + ALOGW("** carried to the build-time configuration accordingly."); | |
107 | + ALOGW("*****************************************************************"); | |
108 | + ALOGW("*****************************************************************"); | |
109 | +#endif | |
110 | + | |
111 | + userial_vendor_init(); | |
112 | + upio_init(); | |
113 | + | |
114 | + vnd_load_conf(VENDOR_LIB_CONF_FILE); | |
115 | + | |
116 | + /* store reference to user callbacks */ | |
117 | + bt_vendor_cbacks = (bt_vendor_callbacks_t *) p_cb; | |
118 | + | |
119 | + /* This is handed over from the stack */ | |
120 | + memcpy(vnd_local_bd_addr, local_bdaddr, 6); | |
121 | + | |
122 | + return 0; | |
123 | +} | |
124 | + | |
125 | + | |
126 | +/** Requested operations */ | |
127 | +static int op(bt_vendor_opcode_t opcode, void *param) | |
128 | +{ | |
129 | + int retval = 0; | |
130 | + | |
131 | + BTVNDDBG("op for %d", opcode); | |
132 | + | |
133 | + switch(opcode) | |
134 | + { | |
135 | + case BT_VND_OP_POWER_CTRL: | |
136 | + { | |
137 | + int *state = (int *) param; | |
138 | + if (*state == BT_VND_PWR_OFF) | |
139 | + upio_set_bluetooth_power(UPIO_BT_POWER_OFF); | |
140 | + else if (*state == BT_VND_PWR_ON) | |
141 | + upio_set_bluetooth_power(UPIO_BT_POWER_ON); | |
142 | + } | |
143 | + break; | |
144 | + | |
145 | + case BT_VND_OP_FW_CFG: | |
146 | + { | |
147 | + hw_config_start(); | |
148 | + } | |
149 | + break; | |
150 | + | |
151 | + case BT_VND_OP_SCO_CFG: | |
152 | + { | |
153 | +#if (SCO_CFG_INCLUDED == TRUE) | |
154 | + hw_sco_config(); | |
155 | +#else | |
156 | + retval = -1; | |
157 | +#endif | |
158 | + } | |
159 | + break; | |
160 | + | |
161 | + case BT_VND_OP_USERIAL_OPEN: | |
162 | + { | |
163 | + int (*fd_array)[] = (int (*)[]) param; | |
164 | + int fd, idx; | |
165 | + fd = userial_vendor_open((tUSERIAL_CFG *) &userial_init_cfg); | |
166 | + if (fd != -1) | |
167 | + { | |
168 | + for (idx=0; idx < CH_MAX; idx++) | |
169 | + (*fd_array)[idx] = fd; | |
170 | + | |
171 | + retval = 1; | |
172 | + } | |
173 | + /* retval contains numbers of open fd of HCI channels */ | |
174 | + } | |
175 | + break; | |
176 | + | |
177 | + case BT_VND_OP_USERIAL_CLOSE: | |
178 | + { | |
179 | + userial_vendor_close(); | |
180 | + } | |
181 | + break; | |
182 | + | |
183 | + case BT_VND_OP_GET_LPM_IDLE_TIMEOUT: | |
184 | + { | |
185 | + uint32_t *timeout_ms = (uint32_t *) param; | |
186 | + *timeout_ms = hw_lpm_get_idle_timeout(); | |
187 | + } | |
188 | + break; | |
189 | + | |
190 | + case BT_VND_OP_LPM_SET_MODE: | |
191 | + { | |
192 | + uint8_t *mode = (uint8_t *) param; | |
193 | + retval = hw_lpm_enable(*mode); | |
194 | + } | |
195 | + break; | |
196 | + | |
197 | + case BT_VND_OP_LPM_WAKE_SET_STATE: | |
198 | + { | |
199 | + uint8_t *state = (uint8_t *) param; | |
200 | + uint8_t wake_assert = (state == BT_VND_LPM_WAKE_ASSERT) ? \ | |
201 | + TRUE : FALSE; | |
202 | + | |
203 | + hw_lpm_set_wake_state(wake_assert); | |
204 | + } | |
205 | + break; | |
206 | + } | |
207 | + | |
208 | + return retval; | |
209 | +} | |
210 | + | |
211 | +/** Closes the interface */ | |
212 | +static void cleanup( void ) | |
213 | +{ | |
214 | + BTVNDDBG("cleanup"); | |
215 | + | |
216 | + upio_cleanup(); | |
217 | + | |
218 | + bt_vendor_cbacks = NULL; | |
219 | +} | |
220 | + | |
221 | +// Entry point of DLib | |
222 | +const bt_vendor_interface_t BLUETOOTH_VENDOR_LIB_INTERFACE = { | |
223 | + sizeof(bt_vendor_interface_t), | |
224 | + init, | |
225 | + op, | |
226 | + cleanup | |
227 | +}; |
@@ -0,0 +1,147 @@ | ||
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: conf.c | |
22 | + * | |
23 | + * Description: Contains functions to conduct run-time module configuration | |
24 | + * based on entries present in the .conf file | |
25 | + * | |
26 | + ******************************************************************************/ | |
27 | + | |
28 | +#define LOG_TAG "bt_vnd_conf" | |
29 | + | |
30 | +#include <utils/Log.h> | |
31 | +#include <string.h> | |
32 | +#include "bt_vendor_brcm.h" | |
33 | + | |
34 | +/****************************************************************************** | |
35 | +** Externs | |
36 | +******************************************************************************/ | |
37 | +int userial_set_port(char *p_conf_name, char *p_conf_value, int param); | |
38 | +int hw_set_patch_file_path(char *p_conf_name, char *p_conf_value, int param); | |
39 | +int hw_set_patch_file_name(char *p_conf_name, char *p_conf_value, int param); | |
40 | +#if (VENDOR_LIB_RUNTIME_TUNING_ENABLED == TRUE) | |
41 | +int hw_set_patch_settlement_delay(char *p_conf_name, char *p_conf_value, int param); | |
42 | +#endif | |
43 | + | |
44 | + | |
45 | +/****************************************************************************** | |
46 | +** Local type definitions | |
47 | +******************************************************************************/ | |
48 | + | |
49 | +#define CONF_COMMENT '#' | |
50 | +#define CONF_DELIMITERS " =\n\r\t" | |
51 | +#define CONF_VALUES_DELIMITERS "=\n\r\t" | |
52 | +#define CONF_MAX_LINE_LEN 255 | |
53 | + | |
54 | +typedef int (conf_action_t)(char *p_conf_name, char *p_conf_value, int param); | |
55 | + | |
56 | +typedef struct { | |
57 | + const char *conf_entry; | |
58 | + conf_action_t *p_action; | |
59 | + int param; | |
60 | +} conf_entry_t; | |
61 | + | |
62 | +/****************************************************************************** | |
63 | +** Static variables | |
64 | +******************************************************************************/ | |
65 | + | |
66 | +/* | |
67 | + * Current supported entries and corresponding action functions | |
68 | + */ | |
69 | +static const conf_entry_t conf_table[] = { | |
70 | + {"UartPort", userial_set_port, 0}, | |
71 | + {"FwPatchFilePath", hw_set_patch_file_path, 0}, | |
72 | + {"FwPatchFileName", hw_set_patch_file_name, 0}, | |
73 | +#if (VENDOR_LIB_RUNTIME_TUNING_ENABLED == TRUE) | |
74 | + {"FwPatchSettlementDelay", hw_set_patch_settlement_delay, 0}, | |
75 | +#endif | |
76 | + {(const char *) NULL, NULL, 0} | |
77 | +}; | |
78 | + | |
79 | +/***************************************************************************** | |
80 | +** CONF INTERFACE FUNCTIONS | |
81 | +*****************************************************************************/ | |
82 | + | |
83 | +/******************************************************************************* | |
84 | +** | |
85 | +** Function vnd_load_conf | |
86 | +** | |
87 | +** Description Read conf entry from p_path file one by one and call | |
88 | +** the corresponding config function | |
89 | +** | |
90 | +** Returns None | |
91 | +** | |
92 | +*******************************************************************************/ | |
93 | +void vnd_load_conf(const char *p_path) | |
94 | +{ | |
95 | + FILE *p_file; | |
96 | + char *p_name; | |
97 | + char *p_value; | |
98 | + conf_entry_t *p_entry; | |
99 | + char line[CONF_MAX_LINE_LEN+1]; /* add 1 for \0 char */ | |
100 | + | |
101 | + ALOGI("Attempt to load conf from %s", p_path); | |
102 | + | |
103 | + if ((p_file = fopen(p_path, "r")) != NULL) | |
104 | + { | |
105 | + /* read line by line */ | |
106 | + while (fgets(line, CONF_MAX_LINE_LEN+1, p_file) != NULL) | |
107 | + { | |
108 | + if (line[0] == CONF_COMMENT) | |
109 | + continue; | |
110 | + | |
111 | + p_name = strtok(line, CONF_DELIMITERS); | |
112 | + | |
113 | + if (NULL == p_name) | |
114 | + { | |
115 | + continue; | |
116 | + } | |
117 | + | |
118 | + p_value = strtok(NULL, CONF_DELIMITERS); | |
119 | + | |
120 | + if (NULL == p_value) | |
121 | + { | |
122 | + ALOGW("vnd_load_conf: missing value for name: %s", p_name); | |
123 | + continue; | |
124 | + } | |
125 | + | |
126 | + p_entry = (conf_entry_t *)conf_table; | |
127 | + | |
128 | + while (p_entry->conf_entry != NULL) | |
129 | + { | |
130 | + if (strcmp(p_entry->conf_entry, (const char *)p_name) == 0) | |
131 | + { | |
132 | + p_entry->p_action(p_name, p_value, p_entry->param); | |
133 | + break; | |
134 | + } | |
135 | + | |
136 | + p_entry++; | |
137 | + } | |
138 | + } | |
139 | + | |
140 | + fclose(p_file); | |
141 | + } | |
142 | + else | |
143 | + { | |
144 | + ALOGI( "vnd_load_conf file >%s< not found", p_path); | |
145 | + } | |
146 | +} | |
147 | + |
@@ -0,0 +1,1155 @@ | ||
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: hardware.c | |
22 | + * | |
23 | + * Description: Contains controller-specific functions, like | |
24 | + * firmware patch download | |
25 | + * low power mode operations | |
26 | + * | |
27 | + ******************************************************************************/ | |
28 | + | |
29 | +#define LOG_TAG "bt_hwcfg" | |
30 | + | |
31 | +#include <utils/Log.h> | |
32 | +#include <sys/types.h> | |
33 | +#include <sys/stat.h> | |
34 | +#include <signal.h> | |
35 | +#include <time.h> | |
36 | +#include <errno.h> | |
37 | +#include <fcntl.h> | |
38 | +#include <dirent.h> | |
39 | +#include <ctype.h> | |
40 | +#include <cutils/properties.h> | |
41 | +#include <stdlib.h> | |
42 | +#include "bt_hci_bdroid.h" | |
43 | +#include "bt_vendor_brcm.h" | |
44 | +#include "userial.h" | |
45 | +#include "userial_vendor.h" | |
46 | +#include "upio.h" | |
47 | + | |
48 | +/****************************************************************************** | |
49 | +** Constants & Macros | |
50 | +******************************************************************************/ | |
51 | + | |
52 | +#ifndef BTHW_DBG | |
53 | +#define BTHW_DBG FALSE | |
54 | +#endif | |
55 | + | |
56 | +#if (BTHW_DBG == TRUE) | |
57 | +#define BTHWDBG(param, ...) {ALOGD(param, ## __VA_ARGS__);} | |
58 | +#else | |
59 | +#define BTHWDBG(param, ...) {} | |
60 | +#endif | |
61 | + | |
62 | +#define FW_PATCHFILE_EXTENSION ".hcd" | |
63 | +#define FW_PATCHFILE_EXTENSION_LEN 4 | |
64 | +#define FW_PATCHFILE_PATH_MAXLEN 248 /* Local_Name length of return of | |
65 | + HCI_Read_Local_Name */ | |
66 | + | |
67 | +#define HCI_CMD_MAX_LEN 258 | |
68 | + | |
69 | +#define HCI_RESET 0x0C03 | |
70 | +#define HCI_VSC_WRITE_UART_CLOCK_SETTING 0xFC45 | |
71 | +#define HCI_VSC_UPDATE_BAUDRATE 0xFC18 | |
72 | +#define HCI_READ_LOCAL_NAME 0x0C14 | |
73 | +#define HCI_VSC_DOWNLOAD_MINIDRV 0xFC2E | |
74 | +#define HCI_VSC_WRITE_BD_ADDR 0xFC01 | |
75 | +#define HCI_VSC_WRITE_SLEEP_MODE 0xFC27 | |
76 | +#define HCI_VSC_WRITE_SCO_PCM_INT_PARAM 0xFC1C | |
77 | +#define HCI_VSC_WRITE_PCM_DATA_FORMAT_PARAM 0xFC1E | |
78 | +#define HCI_VSC_WRITE_I2SPCM_INTERFACE_PARAM 0xFC6D | |
79 | +#define HCI_VSC_LAUNCH_RAM 0xFC4E | |
80 | + | |
81 | +#define HCI_EVT_CMD_CMPL_STATUS_RET_BYTE 5 | |
82 | +#define HCI_EVT_CMD_CMPL_LOCAL_NAME_STRING 6 | |
83 | +#define HCI_EVT_CMD_CMPL_OPCODE 3 | |
84 | +#define LPM_CMD_PARAM_SIZE 12 | |
85 | +#define UPDATE_BAUDRATE_CMD_PARAM_SIZE 6 | |
86 | +#define HCI_CMD_PREAMBLE_SIZE 3 | |
87 | +#define HCD_REC_PAYLOAD_LEN_BYTE 2 | |
88 | +#define BD_ADDR_LEN 6 | |
89 | +#define LOCAL_NAME_BUFFER_LEN 32 | |
90 | +#define LOCAL_BDADDR_PATH_BUFFER_LEN 256 | |
91 | + | |
92 | +#define STREAM_TO_UINT16(u16, p) {u16 = ((uint16_t)(*(p)) + (((uint16_t)(*((p) + 1))) << 8)); (p) += 2;} | |
93 | +#define UINT16_TO_STREAM(p, u16) {*(p)++ = (uint8_t)(u16); *(p)++ = (uint8_t)((u16) >> 8);} | |
94 | +#define UINT32_TO_STREAM(p, u32) {*(p)++ = (uint8_t)(u32); *(p)++ = (uint8_t)((u32) >> 8); *(p)++ = (uint8_t)((u32) >> 16); *(p)++ = (uint8_t)((u32) >> 24);} | |
95 | + | |
96 | +/****************************************************************************** | |
97 | +** Local type definitions | |
98 | +******************************************************************************/ | |
99 | + | |
100 | +/* Hardware Configuration State */ | |
101 | +enum { | |
102 | + HW_CFG_START = 1, | |
103 | + HW_CFG_SET_UART_CLOCK, | |
104 | + HW_CFG_SET_UART_BAUD_1, | |
105 | + HW_CFG_READ_LOCAL_NAME, | |
106 | + HW_CFG_DL_MINIDRIVER, | |
107 | + HW_CFG_DL_FW_PATCH, | |
108 | + HW_CFG_SET_UART_BAUD_2, | |
109 | + HW_CFG_SET_BD_ADDR | |
110 | +}; | |
111 | + | |
112 | +/* h/w config control block */ | |
113 | +typedef struct | |
114 | +{ | |
115 | + uint8_t state; /* Hardware configuration state */ | |
116 | + int fw_fd; /* FW patch file fd */ | |
117 | + uint8_t f_set_baud_2; /* Baud rate switch state */ | |
118 | + char local_chip_name[LOCAL_NAME_BUFFER_LEN]; | |
119 | +} bt_hw_cfg_cb_t; | |
120 | + | |
121 | +/* low power mode parameters */ | |
122 | +typedef struct | |
123 | +{ | |
124 | + uint8_t sleep_mode; /* 0(disable),1(UART),9(H5) */ | |
125 | + uint8_t host_stack_idle_threshold; /* Unit scale 300ms/25ms */ | |
126 | + uint8_t host_controller_idle_threshold; /* Unit scale 300ms/25ms */ | |
127 | + uint8_t bt_wake_polarity; /* 0=Active Low, 1= Active High */ | |
128 | + uint8_t host_wake_polarity; /* 0=Active Low, 1= Active High */ | |
129 | + uint8_t allow_host_sleep_during_sco; | |
130 | + uint8_t combine_sleep_mode_and_lpm; | |
131 | + uint8_t enable_uart_txd_tri_state; /* UART_TXD Tri-State */ | |
132 | + uint8_t sleep_guard_time; /* sleep guard time in 12.5ms */ | |
133 | + uint8_t wakeup_guard_time; /* wakeup guard time in 12.5ms */ | |
134 | + uint8_t txd_config; /* TXD is high in sleep state */ | |
135 | + uint8_t pulsed_host_wake; /* pulsed host wake if mode = 1 */ | |
136 | +} bt_lpm_param_t; | |
137 | + | |
138 | +/* Firmware re-launch settlement time */ | |
139 | +typedef struct { | |
140 | + const char *chipset_name; | |
141 | + const uint32_t delay_time; | |
142 | +} fw_settlement_entry_t; | |
143 | + | |
144 | + | |
145 | +/****************************************************************************** | |
146 | +** Externs | |
147 | +******************************************************************************/ | |
148 | + | |
149 | +void hw_config_cback(void *p_evt_buf); | |
150 | +extern uint8_t vnd_local_bd_addr[BD_ADDR_LEN]; | |
151 | + | |
152 | + | |
153 | +/****************************************************************************** | |
154 | +** Static variables | |
155 | +******************************************************************************/ | |
156 | + | |
157 | +static char fw_patchfile_path[256] = FW_PATCHFILE_LOCATION; | |
158 | +static char fw_patchfile_name[128] = { 0 }; | |
159 | +#if (VENDOR_LIB_RUNTIME_TUNING_ENABLED == TRUE) | |
160 | +static int fw_patch_settlement_delay = -1; | |
161 | +#endif | |
162 | + | |
163 | +static bt_hw_cfg_cb_t hw_cfg_cb; | |
164 | + | |
165 | +static bt_lpm_param_t lpm_param = | |
166 | +{ | |
167 | + LPM_SLEEP_MODE, | |
168 | + LPM_IDLE_THRESHOLD, | |
169 | + LPM_HC_IDLE_THRESHOLD, | |
170 | + LPM_BT_WAKE_POLARITY, | |
171 | + LPM_HOST_WAKE_POLARITY, | |
172 | + LPM_ALLOW_HOST_SLEEP_DURING_SCO, | |
173 | + LPM_COMBINE_SLEEP_MODE_AND_LPM, | |
174 | + LPM_ENABLE_UART_TXD_TRI_STATE, | |
175 | + 0, /* not applicable */ | |
176 | + 0, /* not applicable */ | |
177 | + 0, /* not applicable */ | |
178 | + LPM_PULSED_HOST_WAKE | |
179 | +}; | |
180 | + | |
181 | +#if (!defined(SCO_USE_I2S_INTERFACE) || (SCO_USE_I2S_INTERFACE == FALSE)) | |
182 | +static uint8_t bt_sco_param[SCO_PCM_PARAM_SIZE] = | |
183 | +{ | |
184 | + SCO_PCM_ROUTING, | |
185 | + SCO_PCM_IF_CLOCK_RATE, | |
186 | + SCO_PCM_IF_FRAME_TYPE, | |
187 | + SCO_PCM_IF_SYNC_MODE, | |
188 | + SCO_PCM_IF_CLOCK_MODE | |
189 | +}; | |
190 | + | |
191 | +static uint8_t bt_pcm_data_fmt_param[PCM_DATA_FORMAT_PARAM_SIZE] = | |
192 | +{ | |
193 | + PCM_DATA_FMT_SHIFT_MODE, | |
194 | + PCM_DATA_FMT_FILL_BITS, | |
195 | + PCM_DATA_FMT_FILL_METHOD, | |
196 | + PCM_DATA_FMT_FILL_NUM, | |
197 | + PCM_DATA_FMT_JUSTIFY_MODE | |
198 | +}; | |
199 | +#else | |
200 | +static uint8_t bt_sco_param[SCO_I2SPCM_PARAM_SIZE] = | |
201 | +{ | |
202 | + SCO_I2SPCM_IF_MODE, | |
203 | + SCO_I2SPCM_IF_ROLE, | |
204 | + SCO_I2SPCM_IF_SAMPLE_RATE, | |
205 | + SCO_I2SPCM_IF_CLOCK_RATE | |
206 | +}; | |
207 | +#endif | |
208 | + | |
209 | +/* | |
210 | + * The look-up table of recommended firmware settlement delay (milliseconds) on | |
211 | + * known chipsets. | |
212 | + */ | |
213 | +static const fw_settlement_entry_t fw_settlement_table[] = { | |
214 | + {"BCM43241", 200}, | |
215 | + {(const char *) NULL, 100} // Giving the generic fw settlement delay setting. | |
216 | +}; | |
217 | + | |
218 | +/****************************************************************************** | |
219 | +** Static functions | |
220 | +******************************************************************************/ | |
221 | + | |
222 | +/****************************************************************************** | |
223 | +** Controller Initialization Static Functions | |
224 | +******************************************************************************/ | |
225 | + | |
226 | +/******************************************************************************* | |
227 | +** | |
228 | +** Function look_up_fw_settlement_delay | |
229 | +** | |
230 | +** Description If FW_PATCH_SETTLEMENT_DELAY_MS has not been explicitly | |
231 | +** re-defined in the platform specific build-time configuration | |
232 | +** file, we will search into the look-up table for a | |
233 | +** recommended firmware settlement delay value. | |
234 | +** | |
235 | +** Although the settlement time might be also related to board | |
236 | +** configurations such as the crystal clocking speed. | |
237 | +** | |
238 | +** Returns Firmware settlement delay | |
239 | +** | |
240 | +*******************************************************************************/ | |
241 | +uint32_t look_up_fw_settlement_delay (void) | |
242 | +{ | |
243 | + uint32_t ret_value; | |
244 | + fw_settlement_entry_t *p_entry; | |
245 | + | |
246 | + if (FW_PATCH_SETTLEMENT_DELAY_MS > 0) | |
247 | + { | |
248 | + ret_value = FW_PATCH_SETTLEMENT_DELAY_MS; | |
249 | + } | |
250 | +#if (VENDOR_LIB_RUNTIME_TUNING_ENABLED == TRUE) | |
251 | + else if (fw_patch_settlement_delay >= 0) | |
252 | + { | |
253 | + ret_value = fw_patch_settlement_delay; | |
254 | + } | |
255 | +#endif | |
256 | + else | |
257 | + { | |
258 | + p_entry = (fw_settlement_entry_t *)fw_settlement_table; | |
259 | + | |
260 | + while (p_entry->chipset_name != NULL) | |
261 | + { | |
262 | + if (strstr(hw_cfg_cb.local_chip_name, p_entry->chipset_name)!=NULL) | |
263 | + { | |
264 | + break; | |
265 | + } | |
266 | + | |
267 | + p_entry++; | |
268 | + } | |
269 | + | |
270 | + ret_value = p_entry->delay_time; | |
271 | + } | |
272 | + | |
273 | + BTHWDBG( "Settlement delay -- %d ms", ret_value); | |
274 | + | |
275 | + return (ret_value); | |
276 | +} | |
277 | + | |
278 | +/******************************************************************************* | |
279 | +** | |
280 | +** Function ms_delay | |
281 | +** | |
282 | +** Description sleep unconditionally for timeout milliseconds | |
283 | +** | |
284 | +** Returns None | |
285 | +** | |
286 | +*******************************************************************************/ | |
287 | +void ms_delay (uint32_t timeout) | |
288 | +{ | |
289 | + struct timespec delay; | |
290 | + int err; | |
291 | + | |
292 | + if (timeout == 0) | |
293 | + return; | |
294 | + | |
295 | + delay.tv_sec = timeout / 1000; | |
296 | + delay.tv_nsec = 1000 * 1000 * (timeout%1000); | |
297 | + | |
298 | + /* [u]sleep can't be used because it uses SIGALRM */ | |
299 | + do { | |
300 | + err = nanosleep(&delay, &delay); | |
301 | + } while (err < 0 && errno ==EINTR); | |
302 | +} | |
303 | + | |
304 | +/******************************************************************************* | |
305 | +** | |
306 | +** Function line_speed_to_userial_baud | |
307 | +** | |
308 | +** Description helper function converts line speed number into USERIAL baud | |
309 | +** rate symbol | |
310 | +** | |
311 | +** Returns unit8_t (USERIAL baud symbol) | |
312 | +** | |
313 | +*******************************************************************************/ | |
314 | +uint8_t line_speed_to_userial_baud(uint32_t line_speed) | |
315 | +{ | |
316 | + uint8_t baud; | |
317 | + | |
318 | + if (line_speed == 4000000) | |
319 | + baud = USERIAL_BAUD_4M; | |
320 | + else if (line_speed == 3000000) | |
321 | + baud = USERIAL_BAUD_3M; | |
322 | + else if (line_speed == 2000000) | |
323 | + baud = USERIAL_BAUD_2M; | |
324 | + else if (line_speed == 1000000) | |
325 | + baud = USERIAL_BAUD_1M; | |
326 | + else if (line_speed == 921600) | |
327 | + baud = USERIAL_BAUD_921600; | |
328 | + else if (line_speed == 460800) | |
329 | + baud = USERIAL_BAUD_460800; | |
330 | + else if (line_speed == 230400) | |
331 | + baud = USERIAL_BAUD_230400; | |
332 | + else if (line_speed == 115200) | |
333 | + baud = USERIAL_BAUD_115200; | |
334 | + else if (line_speed == 57600) | |
335 | + baud = USERIAL_BAUD_57600; | |
336 | + else if (line_speed == 19200) | |
337 | + baud = USERIAL_BAUD_19200; | |
338 | + else if (line_speed == 9600) | |
339 | + baud = USERIAL_BAUD_9600; | |
340 | + else if (line_speed == 1200) | |
341 | + baud = USERIAL_BAUD_1200; | |
342 | + else if (line_speed == 600) | |
343 | + baud = USERIAL_BAUD_600; | |
344 | + else | |
345 | + { | |
346 | + ALOGE( "userial vendor: unsupported baud speed %d", line_speed); | |
347 | + baud = USERIAL_BAUD_115200; | |
348 | + } | |
349 | + | |
350 | + return baud; | |
351 | +} | |
352 | + | |
353 | + | |
354 | +/******************************************************************************* | |
355 | +** | |
356 | +** Function hw_strncmp | |
357 | +** | |
358 | +** Description Used to compare two strings in caseless | |
359 | +** | |
360 | +** Returns 0: match, otherwise: not match | |
361 | +** | |
362 | +*******************************************************************************/ | |
363 | +static int hw_strncmp (const char *p_str1, const char *p_str2, const int len) | |
364 | +{ | |
365 | + int i; | |
366 | + | |
367 | + if (!p_str1 || !p_str2) | |
368 | + return (1); | |
369 | + | |
370 | + for (i = 0; i < len; i++) | |
371 | + { | |
372 | + if (toupper(p_str1[i]) != toupper(p_str2[i])) | |
373 | + return (i+1); | |
374 | + } | |
375 | + | |
376 | + return 0; | |
377 | +} | |
378 | + | |
379 | +/******************************************************************************* | |
380 | +** | |
381 | +** Function hw_config_findpatch | |
382 | +** | |
383 | +** Description Search for a proper firmware patch file | |
384 | +** The selected firmware patch file name with full path | |
385 | +** will be stored in the input string parameter, i.e. | |
386 | +** p_chip_id_str, when returns. | |
387 | +** | |
388 | +** Returns TRUE when found the target patch file, otherwise FALSE | |
389 | +** | |
390 | +*******************************************************************************/ | |
391 | +static uint8_t hw_config_findpatch(char *p_chip_id_str) | |
392 | +{ | |
393 | + DIR *dirp; | |
394 | + struct dirent *dp; | |
395 | + int filenamelen; | |
396 | + uint8_t retval = FALSE; | |
397 | + | |
398 | + BTHWDBG("Target name = [%s]", p_chip_id_str); | |
399 | + | |
400 | + if (strlen(fw_patchfile_name)> 0) | |
401 | + { | |
402 | + /* If specific filepath and filename have been given in run-time | |
403 | + * configuration /etc/bluetooth/bt_vendor.conf file, we will use them | |
404 | + * to concatenate the filename to open rather than searching a file | |
405 | + * matching to chipset name in the fw_patchfile_path folder. | |
406 | + */ | |
407 | + sprintf(p_chip_id_str, "%s", fw_patchfile_path); | |
408 | + if (fw_patchfile_path[strlen(fw_patchfile_path)- 1] != '/') | |
409 | + { | |
410 | + strcat(p_chip_id_str, "/"); | |
411 | + } | |
412 | + strcat(p_chip_id_str, fw_patchfile_name); | |
413 | + | |
414 | + ALOGI("FW patchfile: %s", p_chip_id_str); | |
415 | + return TRUE; | |
416 | + } | |
417 | + | |
418 | + if ((dirp = opendir(fw_patchfile_path)) != NULL) | |
419 | + { | |
420 | + /* Fetch next filename in patchfile directory */ | |
421 | + while ((dp = readdir(dirp)) != NULL) | |
422 | + { | |
423 | + /* Check if filename starts with chip-id name */ | |
424 | + if ((hw_strncmp(dp->d_name, p_chip_id_str, strlen(p_chip_id_str)) \ | |
425 | + ) == 0) | |
426 | + { | |
427 | + /* Check if it has .hcd extenstion */ | |
428 | + filenamelen = strlen(dp->d_name); | |
429 | + if ((filenamelen >= FW_PATCHFILE_EXTENSION_LEN) && | |
430 | + ((hw_strncmp( | |
431 | + &dp->d_name[filenamelen-FW_PATCHFILE_EXTENSION_LEN], \ | |
432 | + FW_PATCHFILE_EXTENSION, \ | |
433 | + FW_PATCHFILE_EXTENSION_LEN) \ | |
434 | + ) == 0)) | |
435 | + { | |
436 | + ALOGI("Found patchfile: %s/%s", \ | |
437 | + fw_patchfile_path, dp->d_name); | |
438 | + | |
439 | + /* Make sure length does not exceed maximum */ | |
440 | + if ((filenamelen + strlen(fw_patchfile_path)) > \ | |
441 | + FW_PATCHFILE_PATH_MAXLEN) | |
442 | + { | |
443 | + ALOGE("Invalid patchfile name (too long)"); | |
444 | + } | |
445 | + else | |
446 | + { | |
447 | + memset(p_chip_id_str, 0, FW_PATCHFILE_PATH_MAXLEN); | |
448 | + /* Found patchfile. Store location and name */ | |
449 | + strcpy(p_chip_id_str, fw_patchfile_path); | |
450 | + if (fw_patchfile_path[ \ | |
451 | + strlen(fw_patchfile_path)- 1 \ | |
452 | + ] != '/') | |
453 | + { | |
454 | + strcat(p_chip_id_str, "/"); | |
455 | + } | |
456 | + strcat(p_chip_id_str, dp->d_name); | |
457 | + retval = TRUE; | |
458 | + } | |
459 | + break; | |
460 | + } | |
461 | + } | |
462 | + } | |
463 | + | |
464 | + closedir(dirp); | |
465 | + | |
466 | + if (retval == FALSE) | |
467 | + { | |
468 | + /* Try again chip name without revision info */ | |
469 | + | |
470 | + int len = strlen(p_chip_id_str); | |
471 | + char *p = p_chip_id_str + len - 1; | |
472 | + | |
473 | + /* Scan backward and look for the first alphabet | |
474 | + which is not M or m | |
475 | + */ | |
476 | + while (len > 3) // BCM**** | |
477 | + { | |
478 | + if ((isdigit(*p)==0) && (*p != 'M') && (*p != 'm')) | |
479 | + break; | |
480 | + | |
481 | + p--; | |
482 | + len--; | |
483 | + } | |
484 | + | |
485 | + if (len > 3) | |
486 | + { | |
487 | + *p = 0; | |
488 | + retval = hw_config_findpatch(p_chip_id_str); | |
489 | + } | |
490 | + } | |
491 | + } | |
492 | + else | |
493 | + { | |
494 | + ALOGE("Could not open %s", fw_patchfile_path); | |
495 | + } | |
496 | + | |
497 | + return (retval); | |
498 | +} | |
499 | + | |
500 | +/******************************************************************************* | |
501 | +** | |
502 | +** Function hw_config_set_bdaddr | |
503 | +** | |
504 | +** Description Program controller's Bluetooth Device Address | |
505 | +** | |
506 | +** Returns TRUE, if valid address is sent | |
507 | +** FALSE, otherwise | |
508 | +** | |
509 | +*******************************************************************************/ | |
510 | +static uint8_t hw_config_set_bdaddr(HC_BT_HDR *p_buf) | |
511 | +{ | |
512 | + uint8_t retval = FALSE; | |
513 | + uint8_t *p = (uint8_t *) (p_buf + 1); | |
514 | + | |
515 | + ALOGI("Setting local bd addr to %02X:%02X:%02X:%02X:%02X:%02X", | |
516 | + vnd_local_bd_addr[0], vnd_local_bd_addr[1], vnd_local_bd_addr[2], | |
517 | + vnd_local_bd_addr[3], vnd_local_bd_addr[4], vnd_local_bd_addr[5]); | |
518 | + | |
519 | + UINT16_TO_STREAM(p, HCI_VSC_WRITE_BD_ADDR); | |
520 | + *p++ = BD_ADDR_LEN; /* parameter length */ | |
521 | + *p++ = vnd_local_bd_addr[5]; | |
522 | + *p++ = vnd_local_bd_addr[4]; | |
523 | + *p++ = vnd_local_bd_addr[3]; | |
524 | + *p++ = vnd_local_bd_addr[2]; | |
525 | + *p++ = vnd_local_bd_addr[1]; | |
526 | + *p = vnd_local_bd_addr[0]; | |
527 | + | |
528 | + p_buf->len = HCI_CMD_PREAMBLE_SIZE + BD_ADDR_LEN; | |
529 | + hw_cfg_cb.state = HW_CFG_SET_BD_ADDR; | |
530 | + | |
531 | + retval = bt_vendor_cbacks->xmit_cb(HCI_VSC_WRITE_BD_ADDR, p_buf, \ | |
532 | + hw_config_cback); | |
533 | + | |
534 | + return (retval); | |
535 | +} | |
536 | + | |
537 | +/******************************************************************************* | |
538 | +** | |
539 | +** Function hw_config_cback | |
540 | +** | |
541 | +** Description Callback function for controller configuration | |
542 | +** | |
543 | +** Returns None | |
544 | +** | |
545 | +*******************************************************************************/ | |
546 | +void hw_config_cback(void *p_mem) | |
547 | +{ | |
548 | + HC_BT_HDR *p_evt_buf = (HC_BT_HDR *) p_mem; | |
549 | + char *p_name, *p_tmp; | |
550 | + uint8_t *p, status; | |
551 | + uint16_t opcode; | |
552 | + HC_BT_HDR *p_buf=NULL; | |
553 | + uint8_t is_proceeding = FALSE; | |
554 | + int i; | |
555 | + | |
556 | + status = *((uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_STATUS_RET_BYTE); | |
557 | + p = (uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_OPCODE; | |
558 | + STREAM_TO_UINT16(opcode,p); | |
559 | + | |
560 | + /* Ask a new buffer big enough to hold any HCI commands sent in here */ | |
561 | + if ((status == 0) && bt_vendor_cbacks) | |
562 | + p_buf = (HC_BT_HDR *) bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE + \ | |
563 | + HCI_CMD_MAX_LEN); | |
564 | + | |
565 | + if (p_buf != NULL) | |
566 | + { | |
567 | + p_buf->event = MSG_STACK_TO_HC_HCI_CMD; | |
568 | + p_buf->offset = 0; | |
569 | + p_buf->len = 0; | |
570 | + p_buf->layer_specific = 0; | |
571 | + | |
572 | + p = (uint8_t *) (p_buf + 1); | |
573 | + | |
574 | + switch (hw_cfg_cb.state) | |
575 | + { | |
576 | + case HW_CFG_SET_UART_BAUD_1: | |
577 | + /* update baud rate of host's UART port */ | |
578 | + ALOGI("bt vendor lib: set UART baud %i", UART_TARGET_BAUD_RATE); | |
579 | + userial_vendor_set_baud( \ | |
580 | + line_speed_to_userial_baud(UART_TARGET_BAUD_RATE) \ | |
581 | + ); | |
582 | + | |
583 | + /* read local name */ | |
584 | + UINT16_TO_STREAM(p, HCI_READ_LOCAL_NAME); | |
585 | + *p = 0; /* parameter length */ | |
586 | + | |
587 | + p_buf->len = HCI_CMD_PREAMBLE_SIZE; | |
588 | + hw_cfg_cb.state = HW_CFG_READ_LOCAL_NAME; | |
589 | + | |
590 | + is_proceeding = bt_vendor_cbacks->xmit_cb(HCI_READ_LOCAL_NAME, \ | |
591 | + p_buf, hw_config_cback); | |
592 | + break; | |
593 | + | |
594 | + case HW_CFG_READ_LOCAL_NAME: | |
595 | + p_tmp = p_name = (char *) (p_evt_buf + 1) + \ | |
596 | + HCI_EVT_CMD_CMPL_LOCAL_NAME_STRING; | |
597 | + | |
598 | + for (i=0; (i < LOCAL_NAME_BUFFER_LEN)||(*(p_name+i) != 0); i++) | |
599 | + *(p_name+i) = toupper(*(p_name+i)); | |
600 | + | |
601 | + if ((p_name = strstr(p_name, "BCM")) != NULL) | |
602 | + { | |
603 | + strncpy(hw_cfg_cb.local_chip_name, p_name, \ | |
604 | + LOCAL_NAME_BUFFER_LEN-1); | |
605 | + } | |
606 | + else | |
607 | + { | |
608 | + strncpy(hw_cfg_cb.local_chip_name, "UNKNOWN", \ | |
609 | + LOCAL_NAME_BUFFER_LEN-1); | |
610 | + p_name = p_tmp; | |
611 | + } | |
612 | + | |
613 | + hw_cfg_cb.local_chip_name[LOCAL_NAME_BUFFER_LEN-1] = 0; | |
614 | + | |
615 | + BTHWDBG("Chipset %s", hw_cfg_cb.local_chip_name); | |
616 | + | |
617 | + if ((status = hw_config_findpatch(p_name)) == TRUE) | |
618 | + { | |
619 | + if ((hw_cfg_cb.fw_fd = open(p_name, O_RDONLY)) == -1) | |
620 | + { | |
621 | + ALOGE("vendor lib preload failed to open [%s]", p_name); | |
622 | + } | |
623 | + else | |
624 | + { | |
625 | + /* vsc_download_minidriver */ | |
626 | + UINT16_TO_STREAM(p, HCI_VSC_DOWNLOAD_MINIDRV); | |
627 | + *p = 0; /* parameter length */ | |
628 | + | |
629 | + p_buf->len = HCI_CMD_PREAMBLE_SIZE; | |
630 | + hw_cfg_cb.state = HW_CFG_DL_MINIDRIVER; | |
631 | + | |
632 | + is_proceeding = bt_vendor_cbacks->xmit_cb( \ | |
633 | + HCI_VSC_DOWNLOAD_MINIDRV, p_buf, \ | |
634 | + hw_config_cback); | |
635 | + } | |
636 | + } | |
637 | + else | |
638 | + { | |
639 | + ALOGE( \ | |
640 | + "vendor lib preload failed to locate firmware patch file" \ | |
641 | + ); | |
642 | + } | |
643 | + | |
644 | + if (is_proceeding == FALSE) | |
645 | + { | |
646 | + is_proceeding = hw_config_set_bdaddr(p_buf); | |
647 | + } | |
648 | + break; | |
649 | + | |
650 | + case HW_CFG_DL_MINIDRIVER: | |
651 | + /* give time for placing firmware in download mode */ | |
652 | + ms_delay(50); | |
653 | + hw_cfg_cb.state = HW_CFG_DL_FW_PATCH; | |
654 | + /* fall through intentionally */ | |
655 | + case HW_CFG_DL_FW_PATCH: | |
656 | + p_buf->len = read(hw_cfg_cb.fw_fd, p, HCI_CMD_PREAMBLE_SIZE); | |
657 | + if (p_buf->len > 0) | |
658 | + { | |
659 | + if ((p_buf->len < HCI_CMD_PREAMBLE_SIZE) || \ | |
660 | + (opcode == HCI_VSC_LAUNCH_RAM)) | |
661 | + { | |
662 | + ALOGW("firmware patch file might be altered!"); | |
663 | + } | |
664 | + else | |
665 | + { | |
666 | + p_buf->len += read(hw_cfg_cb.fw_fd, \ | |
667 | + p+HCI_CMD_PREAMBLE_SIZE,\ | |
668 | + *(p+HCD_REC_PAYLOAD_LEN_BYTE)); | |
669 | + STREAM_TO_UINT16(opcode,p); | |
670 | + is_proceeding = bt_vendor_cbacks->xmit_cb(opcode, \ | |
671 | + p_buf, hw_config_cback); | |
672 | + break; | |
673 | + } | |
674 | + } | |
675 | + | |
676 | + close(hw_cfg_cb.fw_fd); | |
677 | + hw_cfg_cb.fw_fd = -1; | |
678 | + | |
679 | + /* Normally the firmware patch configuration file | |
680 | + * sets the new starting baud rate at 115200. | |
681 | + * So, we need update host's baud rate accordingly. | |
682 | + */ | |
683 | + ALOGI("bt vendor lib: set UART baud 115200"); | |
684 | + userial_vendor_set_baud(USERIAL_BAUD_115200); | |
685 | + | |
686 | + /* Next, we would like to boost baud rate up again | |
687 | + * to desired working speed. | |
688 | + */ | |
689 | + hw_cfg_cb.f_set_baud_2 = TRUE; | |
690 | + | |
691 | + /* Check if we need to pause a few hundred milliseconds | |
692 | + * before sending down any HCI command. | |
693 | + */ | |
694 | + ms_delay(look_up_fw_settlement_delay()); | |
695 | + | |
696 | + /* fall through intentionally */ | |
697 | + case HW_CFG_START: | |
698 | + if (UART_TARGET_BAUD_RATE > 3000000) | |
699 | + { | |
700 | + /* set UART clock to 48MHz */ | |
701 | + UINT16_TO_STREAM(p, HCI_VSC_WRITE_UART_CLOCK_SETTING); | |
702 | + *p++ = 1; /* parameter length */ | |
703 | + *p = 1; /* (1,"UART CLOCK 48 MHz")(2,"UART CLOCK 24 MHz") */ | |
704 | + | |
705 | + p_buf->len = HCI_CMD_PREAMBLE_SIZE + 1; | |
706 | + hw_cfg_cb.state = HW_CFG_SET_UART_CLOCK; | |
707 | + | |
708 | + is_proceeding = bt_vendor_cbacks->xmit_cb( \ | |
709 | + HCI_VSC_WRITE_UART_CLOCK_SETTING, \ | |
710 | + p_buf, hw_config_cback); | |
711 | + break; | |
712 | + } | |
713 | + /* fall through intentionally */ | |
714 | + case HW_CFG_SET_UART_CLOCK: | |
715 | + /* set controller's UART baud rate to 3M */ | |
716 | + UINT16_TO_STREAM(p, HCI_VSC_UPDATE_BAUDRATE); | |
717 | + *p++ = UPDATE_BAUDRATE_CMD_PARAM_SIZE; /* parameter length */ | |
718 | + *p++ = 0; /* encoded baud rate */ | |
719 | + *p++ = 0; /* use encoded form */ | |
720 | + UINT32_TO_STREAM(p, UART_TARGET_BAUD_RATE); | |
721 | + | |
722 | + p_buf->len = HCI_CMD_PREAMBLE_SIZE + \ | |
723 | + UPDATE_BAUDRATE_CMD_PARAM_SIZE; | |
724 | + hw_cfg_cb.state = (hw_cfg_cb.f_set_baud_2) ? \ | |
725 | + HW_CFG_SET_UART_BAUD_2 : HW_CFG_SET_UART_BAUD_1; | |
726 | + | |
727 | + is_proceeding = bt_vendor_cbacks->xmit_cb(HCI_VSC_UPDATE_BAUDRATE, \ | |
728 | + p_buf, hw_config_cback); | |
729 | + break; | |
730 | + | |
731 | + case HW_CFG_SET_UART_BAUD_2: | |
732 | + /* update baud rate of host's UART port */ | |
733 | + ALOGI("bt vendor lib: set UART baud %i", UART_TARGET_BAUD_RATE); | |
734 | + userial_vendor_set_baud( \ | |
735 | + line_speed_to_userial_baud(UART_TARGET_BAUD_RATE) \ | |
736 | + ); | |
737 | + | |
738 | + if ((is_proceeding = hw_config_set_bdaddr(p_buf)) == TRUE) | |
739 | + break; | |
740 | + | |
741 | + /* fall through intentionally */ | |
742 | + case HW_CFG_SET_BD_ADDR: | |
743 | + ALOGI("vendor lib fwcfg completed"); | |
744 | + bt_vendor_cbacks->dealloc(p_buf); | |
745 | + bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_SUCCESS); | |
746 | + | |
747 | + hw_cfg_cb.state = 0; | |
748 | + | |
749 | + if (hw_cfg_cb.fw_fd != -1) | |
750 | + { | |
751 | + close(hw_cfg_cb.fw_fd); | |
752 | + hw_cfg_cb.fw_fd = -1; | |
753 | + } | |
754 | + | |
755 | + is_proceeding = TRUE; | |
756 | + break; | |
757 | + } // switch(hw_cfg_cb.state) | |
758 | + } // if (p_buf != NULL) | |
759 | + | |
760 | + /* Free the RX event buffer */ | |
761 | + if (bt_vendor_cbacks) | |
762 | + bt_vendor_cbacks->dealloc(p_evt_buf); | |
763 | + | |
764 | + if (is_proceeding == FALSE) | |
765 | + { | |
766 | + ALOGE("vendor lib fwcfg aborted!!!"); | |
767 | + if (bt_vendor_cbacks) | |
768 | + { | |
769 | + if (p_buf != NULL) | |
770 | + bt_vendor_cbacks->dealloc(p_buf); | |
771 | + | |
772 | + bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_FAIL); | |
773 | + } | |
774 | + | |
775 | + if (hw_cfg_cb.fw_fd != -1) | |
776 | + { | |
777 | + close(hw_cfg_cb.fw_fd); | |
778 | + hw_cfg_cb.fw_fd = -1; | |
779 | + } | |
780 | + | |
781 | + hw_cfg_cb.state = 0; | |
782 | + } | |
783 | +} | |
784 | + | |
785 | +/****************************************************************************** | |
786 | +** LPM Static Functions | |
787 | +******************************************************************************/ | |
788 | + | |
789 | +/******************************************************************************* | |
790 | +** | |
791 | +** Function hw_lpm_ctrl_cback | |
792 | +** | |
793 | +** Description Callback function for lpm enable/disable rquest | |
794 | +** | |
795 | +** Returns None | |
796 | +** | |
797 | +*******************************************************************************/ | |
798 | +void hw_lpm_ctrl_cback(void *p_mem) | |
799 | +{ | |
800 | + HC_BT_HDR *p_evt_buf = (HC_BT_HDR *) p_mem; | |
801 | + bt_vendor_op_result_t status = BT_VND_OP_RESULT_FAIL; | |
802 | + | |
803 | + if (*((uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_STATUS_RET_BYTE) == 0) | |
804 | + { | |
805 | + status = BT_VND_OP_RESULT_SUCCESS; | |
806 | + } | |
807 | + | |
808 | + if (bt_vendor_cbacks) | |
809 | + { | |
810 | + bt_vendor_cbacks->lpm_cb(status); | |
811 | + bt_vendor_cbacks->dealloc(p_evt_buf); | |
812 | + } | |
813 | +} | |
814 | + | |
815 | + | |
816 | +#if (SCO_CFG_INCLUDED == TRUE) | |
817 | +/***************************************************************************** | |
818 | +** SCO Configuration Static Functions | |
819 | +*****************************************************************************/ | |
820 | + | |
821 | +/******************************************************************************* | |
822 | +** | |
823 | +** Function hw_sco_cfg_cback | |
824 | +** | |
825 | +** Description Callback function for SCO configuration rquest | |
826 | +** | |
827 | +** Returns None | |
828 | +** | |
829 | +*******************************************************************************/ | |
830 | +void hw_sco_cfg_cback(void *p_mem) | |
831 | +{ | |
832 | + HC_BT_HDR *p_evt_buf = (HC_BT_HDR *) p_mem; | |
833 | + uint8_t *p; | |
834 | + uint16_t opcode; | |
835 | + HC_BT_HDR *p_buf=NULL; | |
836 | + | |
837 | + p = (uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_OPCODE; | |
838 | + STREAM_TO_UINT16(opcode,p); | |
839 | + | |
840 | + /* Free the RX event buffer */ | |
841 | + if (bt_vendor_cbacks) | |
842 | + bt_vendor_cbacks->dealloc(p_evt_buf); | |
843 | + | |
844 | +#if (!defined(SCO_USE_I2S_INTERFACE) || (SCO_USE_I2S_INTERFACE == FALSE)) | |
845 | + if (opcode == HCI_VSC_WRITE_SCO_PCM_INT_PARAM) | |
846 | + { | |
847 | + uint8_t ret = FALSE; | |
848 | + | |
849 | + /* Ask a new buffer to hold WRITE_PCM_DATA_FORMAT_PARAM command */ | |
850 | + if (bt_vendor_cbacks) | |
851 | + p_buf = (HC_BT_HDR *) bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE + \ | |
852 | + HCI_CMD_PREAMBLE_SIZE + \ | |
853 | + PCM_DATA_FORMAT_PARAM_SIZE); | |
854 | + if (p_buf) | |
855 | + { | |
856 | + p_buf->event = MSG_STACK_TO_HC_HCI_CMD; | |
857 | + p_buf->offset = 0; | |
858 | + p_buf->layer_specific = 0; | |
859 | + p_buf->len = HCI_CMD_PREAMBLE_SIZE + PCM_DATA_FORMAT_PARAM_SIZE; | |
860 | + | |
861 | + p = (uint8_t *) (p_buf + 1); | |
862 | + UINT16_TO_STREAM(p, HCI_VSC_WRITE_PCM_DATA_FORMAT_PARAM); | |
863 | + *p++ = PCM_DATA_FORMAT_PARAM_SIZE; | |
864 | + memcpy(p, &bt_pcm_data_fmt_param, PCM_DATA_FORMAT_PARAM_SIZE); | |
865 | + | |
866 | + if ((ret = bt_vendor_cbacks->xmit_cb(HCI_VSC_WRITE_PCM_DATA_FORMAT_PARAM,\ | |
867 | + p_buf, hw_sco_cfg_cback)) == FALSE) | |
868 | + { | |
869 | + bt_vendor_cbacks->dealloc(p_buf); | |
870 | + } | |
871 | + else | |
872 | + return; | |
873 | + } | |
874 | + } | |
875 | +#endif // !SCO_USE_I2S_INTERFACE | |
876 | + | |
877 | +if (bt_vendor_cbacks) | |
878 | + bt_vendor_cbacks->scocfg_cb(BT_VND_OP_RESULT_SUCCESS); | |
879 | +} | |
880 | +#endif // SCO_CFG_INCLUDED | |
881 | + | |
882 | +/***************************************************************************** | |
883 | +** Hardware Configuration Interface Functions | |
884 | +*****************************************************************************/ | |
885 | + | |
886 | + | |
887 | +/******************************************************************************* | |
888 | +** | |
889 | +** Function hw_config_start | |
890 | +** | |
891 | +** Description Kick off controller initialization process | |
892 | +** | |
893 | +** Returns None | |
894 | +** | |
895 | +*******************************************************************************/ | |
896 | +void hw_config_start(void) | |
897 | +{ | |
898 | + HC_BT_HDR *p_buf = NULL; | |
899 | + uint8_t *p; | |
900 | + | |
901 | + hw_cfg_cb.state = 0; | |
902 | + hw_cfg_cb.fw_fd = -1; | |
903 | + hw_cfg_cb.f_set_baud_2 = FALSE; | |
904 | + | |
905 | + /* Start from sending HCI_RESET */ | |
906 | + | |
907 | + if (bt_vendor_cbacks) | |
908 | + { | |
909 | + p_buf = (HC_BT_HDR *) bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE + \ | |
910 | + HCI_CMD_PREAMBLE_SIZE); | |
911 | + } | |
912 | + | |
913 | + if (p_buf) | |
914 | + { | |
915 | + p_buf->event = MSG_STACK_TO_HC_HCI_CMD; | |
916 | + p_buf->offset = 0; | |
917 | + p_buf->layer_specific = 0; | |
918 | + p_buf->len = HCI_CMD_PREAMBLE_SIZE; | |
919 | + | |
920 | + p = (uint8_t *) (p_buf + 1); | |
921 | + UINT16_TO_STREAM(p, HCI_RESET); | |
922 | + *p = 0; /* parameter length */ | |
923 | + | |
924 | + hw_cfg_cb.state = HW_CFG_START; | |
925 | + | |
926 | + bt_vendor_cbacks->xmit_cb(HCI_RESET, p_buf, hw_config_cback); | |
927 | + } | |
928 | + else | |
929 | + { | |
930 | + if (bt_vendor_cbacks) | |
931 | + { | |
932 | + ALOGE("vendor lib fw conf aborted [no buffer]"); | |
933 | + bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_FAIL); | |
934 | + } | |
935 | + } | |
936 | +} | |
937 | + | |
938 | +/******************************************************************************* | |
939 | +** | |
940 | +** Function hw_lpm_enable | |
941 | +** | |
942 | +** Description Enalbe/Disable LPM | |
943 | +** | |
944 | +** Returns TRUE/FALSE | |
945 | +** | |
946 | +*******************************************************************************/ | |
947 | +uint8_t hw_lpm_enable(uint8_t turn_on) | |
948 | +{ | |
949 | + HC_BT_HDR *p_buf = NULL; | |
950 | + uint8_t *p; | |
951 | + uint8_t ret = FALSE; | |
952 | + | |
953 | + if (bt_vendor_cbacks) | |
954 | + p_buf = (HC_BT_HDR *) bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE + \ | |
955 | + HCI_CMD_PREAMBLE_SIZE + \ | |
956 | + LPM_CMD_PARAM_SIZE); | |
957 | + | |
958 | + if (p_buf) | |
959 | + { | |
960 | + p_buf->event = MSG_STACK_TO_HC_HCI_CMD; | |
961 | + p_buf->offset = 0; | |
962 | + p_buf->layer_specific = 0; | |
963 | + p_buf->len = HCI_CMD_PREAMBLE_SIZE + LPM_CMD_PARAM_SIZE; | |
964 | + | |
965 | + p = (uint8_t *) (p_buf + 1); | |
966 | + UINT16_TO_STREAM(p, HCI_VSC_WRITE_SLEEP_MODE); | |
967 | + *p++ = LPM_CMD_PARAM_SIZE; /* parameter length */ | |
968 | + | |
969 | + if (turn_on) | |
970 | + { | |
971 | + memcpy(p, &lpm_param, LPM_CMD_PARAM_SIZE); | |
972 | + } | |
973 | + else | |
974 | + { | |
975 | + memset(p, 0, LPM_CMD_PARAM_SIZE); | |
976 | + } | |
977 | + | |
978 | + if ((ret = bt_vendor_cbacks->xmit_cb(HCI_VSC_WRITE_SLEEP_MODE, p_buf, \ | |
979 | + hw_lpm_ctrl_cback)) == FALSE) | |
980 | + { | |
981 | + bt_vendor_cbacks->dealloc(p_buf); | |
982 | + } | |
983 | + } | |
984 | + | |
985 | + if ((ret == FALSE) && bt_vendor_cbacks) | |
986 | + bt_vendor_cbacks->lpm_cb(BT_VND_OP_RESULT_FAIL); | |
987 | + | |
988 | + return ret; | |
989 | +} | |
990 | + | |
991 | +/******************************************************************************* | |
992 | +** | |
993 | +** Function hw_lpm_get_idle_timeout | |
994 | +** | |
995 | +** Description Calculate idle time based on host stack idle threshold | |
996 | +** | |
997 | +** Returns idle timeout value | |
998 | +** | |
999 | +*******************************************************************************/ | |
1000 | +uint32_t hw_lpm_get_idle_timeout(void) | |
1001 | +{ | |
1002 | + uint32_t timeout_ms; | |
1003 | + | |
1004 | + /* set idle time to be LPM_IDLE_TIMEOUT_MULTIPLE times of | |
1005 | + * host stack idle threshold (in 300ms/25ms) | |
1006 | + */ | |
1007 | + timeout_ms = (uint32_t)lpm_param.host_stack_idle_threshold \ | |
1008 | + * LPM_IDLE_TIMEOUT_MULTIPLE; | |
1009 | + | |
1010 | + if (strstr(hw_cfg_cb.local_chip_name, "BCM4325") != NULL) | |
1011 | + timeout_ms *= 25; // 12.5 or 25 ? | |
1012 | + else | |
1013 | + timeout_ms *= 300; | |
1014 | + | |
1015 | + return timeout_ms; | |
1016 | +} | |
1017 | + | |
1018 | +/******************************************************************************* | |
1019 | +** | |
1020 | +** Function hw_lpm_set_wake_state | |
1021 | +** | |
1022 | +** Description Assert/Deassert BT_WAKE | |
1023 | +** | |
1024 | +** Returns None | |
1025 | +** | |
1026 | +*******************************************************************************/ | |
1027 | +void hw_lpm_set_wake_state(uint8_t wake_assert) | |
1028 | +{ | |
1029 | + uint8_t state = (wake_assert) ? UPIO_ASSERT : UPIO_DEASSERT; | |
1030 | + | |
1031 | + upio_set(UPIO_BT_WAKE, state, lpm_param.bt_wake_polarity); | |
1032 | +} | |
1033 | + | |
1034 | +#if (SCO_CFG_INCLUDED == TRUE) | |
1035 | +/******************************************************************************* | |
1036 | +** | |
1037 | +** Function hw_sco_config | |
1038 | +** | |
1039 | +** Description Configure SCO related hardware settings | |
1040 | +** | |
1041 | +** Returns None | |
1042 | +** | |
1043 | +*******************************************************************************/ | |
1044 | +void hw_sco_config(void) | |
1045 | +{ | |
1046 | + HC_BT_HDR *p_buf = NULL; | |
1047 | + uint8_t *p, ret; | |
1048 | + | |
1049 | +#if (!defined(SCO_USE_I2S_INTERFACE) || (SCO_USE_I2S_INTERFACE == FALSE)) | |
1050 | + uint16_t cmd_u16 = HCI_CMD_PREAMBLE_SIZE + SCO_PCM_PARAM_SIZE; | |
1051 | +#else | |
1052 | + uint16_t cmd_u16 = HCI_CMD_PREAMBLE_SIZE + SCO_I2SPCM_PARAM_SIZE; | |
1053 | +#endif | |
1054 | + | |
1055 | + if (bt_vendor_cbacks) | |
1056 | + p_buf = (HC_BT_HDR *) bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE+cmd_u16); | |
1057 | + | |
1058 | + if (p_buf) | |
1059 | + { | |
1060 | + p_buf->event = MSG_STACK_TO_HC_HCI_CMD; | |
1061 | + p_buf->offset = 0; | |
1062 | + p_buf->layer_specific = 0; | |
1063 | + p_buf->len = cmd_u16; | |
1064 | + | |
1065 | + p = (uint8_t *) (p_buf + 1); | |
1066 | +#if (!defined(SCO_USE_I2S_INTERFACE) || (SCO_USE_I2S_INTERFACE == FALSE)) | |
1067 | + UINT16_TO_STREAM(p, HCI_VSC_WRITE_SCO_PCM_INT_PARAM); | |
1068 | + *p++ = SCO_PCM_PARAM_SIZE; | |
1069 | + memcpy(p, &bt_sco_param, SCO_PCM_PARAM_SIZE); | |
1070 | + cmd_u16 = HCI_VSC_WRITE_SCO_PCM_INT_PARAM; | |
1071 | + ALOGI("SCO PCM configure {%d, %d, %d, %d, %d}", | |
1072 | + bt_sco_param[0], bt_sco_param[1], bt_sco_param[2], bt_sco_param[3], \ | |
1073 | + bt_sco_param[4]); | |
1074 | + | |
1075 | +#else | |
1076 | + UINT16_TO_STREAM(p, HCI_VSC_WRITE_I2SPCM_INTERFACE_PARAM); | |
1077 | + *p++ = SCO_I2SPCM_PARAM_SIZE; | |
1078 | + memcpy(p, &bt_sco_param, SCO_I2SPCM_PARAM_SIZE); | |
1079 | + cmd_u16 = HCI_VSC_WRITE_I2SPCM_INTERFACE_PARAM; | |
1080 | + ALOGI("SCO over I2SPCM interface {%d, %d, %d, %d}", | |
1081 | + bt_sco_param[0], bt_sco_param[1], bt_sco_param[2], bt_sco_param[3]); | |
1082 | +#endif | |
1083 | + | |
1084 | + if ((ret=bt_vendor_cbacks->xmit_cb(cmd_u16, p_buf, hw_sco_cfg_cback)) \ | |
1085 | + == FALSE) | |
1086 | + { | |
1087 | + bt_vendor_cbacks->dealloc(p_buf); | |
1088 | + } | |
1089 | + else | |
1090 | + return; | |
1091 | + } | |
1092 | + | |
1093 | + if (bt_vendor_cbacks) | |
1094 | + { | |
1095 | + ALOGE("vendor lib scocfg aborted"); | |
1096 | + bt_vendor_cbacks->scocfg_cb(BT_VND_OP_RESULT_FAIL); | |
1097 | + } | |
1098 | +} | |
1099 | +#endif // SCO_CFG_INCLUDED | |
1100 | + | |
1101 | +/******************************************************************************* | |
1102 | +** | |
1103 | +** Function hw_set_patch_file_path | |
1104 | +** | |
1105 | +** Description Set the location of firmware patch file | |
1106 | +** | |
1107 | +** Returns 0 : Success | |
1108 | +** Otherwise : Fail | |
1109 | +** | |
1110 | +*******************************************************************************/ | |
1111 | +int hw_set_patch_file_path(char *p_conf_name, char *p_conf_value, int param) | |
1112 | +{ | |
1113 | + | |
1114 | + strcpy(fw_patchfile_path, p_conf_value); | |
1115 | + | |
1116 | + return 0; | |
1117 | +} | |
1118 | + | |
1119 | +/******************************************************************************* | |
1120 | +** | |
1121 | +** Function hw_set_patch_file_name | |
1122 | +** | |
1123 | +** Description Give the specific firmware patch filename | |
1124 | +** | |
1125 | +** Returns 0 : Success | |
1126 | +** Otherwise : Fail | |
1127 | +** | |
1128 | +*******************************************************************************/ | |
1129 | +int hw_set_patch_file_name(char *p_conf_name, char *p_conf_value, int param) | |
1130 | +{ | |
1131 | + | |
1132 | + strcpy(fw_patchfile_name, p_conf_value); | |
1133 | + | |
1134 | + return 0; | |
1135 | +} | |
1136 | + | |
1137 | +#if (VENDOR_LIB_RUNTIME_TUNING_ENABLED == TRUE) | |
1138 | +/******************************************************************************* | |
1139 | +** | |
1140 | +** Function hw_set_patch_settlement_delay | |
1141 | +** | |
1142 | +** Description Give the specific firmware patch settlement time in milliseconds | |
1143 | +** | |
1144 | +** Returns 0 : Success | |
1145 | +** Otherwise : Fail | |
1146 | +** | |
1147 | +*******************************************************************************/ | |
1148 | +int hw_set_patch_settlement_delay(char *p_conf_name, char *p_conf_value, int param) | |
1149 | +{ | |
1150 | + fw_patch_settlement_delay = atoi(p_conf_value); | |
1151 | + | |
1152 | + return 0; | |
1153 | +} | |
1154 | +#endif //VENDOR_LIB_RUNTIME_TUNING_ENABLED | |
1155 | + |
@@ -0,0 +1,298 @@ | ||
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: upio.c | |
22 | + * | |
23 | + * Description: Contains I/O functions, like | |
24 | + * rfkill control | |
25 | + * BT_WAKE/HOST_WAKE control | |
26 | + * | |
27 | + ******************************************************************************/ | |
28 | + | |
29 | +#define LOG_TAG "bt_upio" | |
30 | + | |
31 | +#include <utils/Log.h> | |
32 | +#include <fcntl.h> | |
33 | +#include <errno.h> | |
34 | +#include <cutils/properties.h> | |
35 | +#include "bt_vendor_brcm.h" | |
36 | +#include "upio.h" | |
37 | +#include "userial_vendor.h" | |
38 | + | |
39 | +/****************************************************************************** | |
40 | +** Constants & Macros | |
41 | +******************************************************************************/ | |
42 | + | |
43 | +#ifndef UPIO_DBG | |
44 | +#define UPIO_DBG FALSE | |
45 | +#endif | |
46 | + | |
47 | +#if (UPIO_DBG == TRUE) | |
48 | +#define UPIODBG(param, ...) {ALOGD(param, ## __VA_ARGS__);} | |
49 | +#else | |
50 | +#define UPIODBG(param, ...) {} | |
51 | +#endif | |
52 | + | |
53 | +/****************************************************************************** | |
54 | +** Local type definitions | |
55 | +******************************************************************************/ | |
56 | + | |
57 | +/****************************************************************************** | |
58 | +** Static variables | |
59 | +******************************************************************************/ | |
60 | + | |
61 | +static uint8_t upio_state[UPIO_MAX_COUNT]; | |
62 | +static int rfkill_id = -1; | |
63 | +static int bt_emul_enable = 0; | |
64 | +static char *rfkill_state_path = NULL; | |
65 | + | |
66 | +/****************************************************************************** | |
67 | +** Static functions | |
68 | +******************************************************************************/ | |
69 | + | |
70 | +/* for friendly debugging outpout string */ | |
71 | +static char *lpm_state[] = { | |
72 | + "UNKNOWN", | |
73 | + "de-asserted", | |
74 | + "asserted" | |
75 | +}; | |
76 | + | |
77 | +/***************************************************************************** | |
78 | +** Bluetooth On/Off Static Functions | |
79 | +*****************************************************************************/ | |
80 | +static int is_emulator_context(void) | |
81 | +{ | |
82 | + char value[PROPERTY_VALUE_MAX]; | |
83 | + | |
84 | + property_get("ro.kernel.qemu", value, "0"); | |
85 | + UPIODBG("is_emulator_context : %s", value); | |
86 | + if (strcmp(value, "1") == 0) { | |
87 | + return 1; | |
88 | + } | |
89 | + return 0; | |
90 | +} | |
91 | + | |
92 | +static int is_rfkill_disabled(void) | |
93 | +{ | |
94 | + char value[PROPERTY_VALUE_MAX]; | |
95 | + | |
96 | + property_get("ro.rfkilldisabled", value, "0"); | |
97 | + UPIODBG("is_rfkill_disabled ? [%s]", value); | |
98 | + | |
99 | + if (strcmp(value, "1") == 0) { | |
100 | + return UPIO_BT_POWER_ON; | |
101 | + } | |
102 | + | |
103 | + return UPIO_BT_POWER_OFF; | |
104 | +} | |
105 | + | |
106 | +static int init_rfkill() | |
107 | +{ | |
108 | + char path[64]; | |
109 | + char buf[16]; | |
110 | + int fd, sz, id; | |
111 | + | |
112 | + if (is_rfkill_disabled()) | |
113 | + return -1; | |
114 | + | |
115 | + for (id = 0; ; id++) | |
116 | + { | |
117 | + snprintf(path, sizeof(path), "/sys/class/rfkill/rfkill%d/type", id); | |
118 | + fd = open(path, O_RDONLY); | |
119 | + if (fd < 0) | |
120 | + { | |
121 | + ALOGE("init_rfkill : open(%s) failed: %s (%d)\n", \ | |
122 | + path, strerror(errno), errno); | |
123 | + return -1; | |
124 | + } | |
125 | + | |
126 | + sz = read(fd, &buf, sizeof(buf)); | |
127 | + close(fd); | |
128 | + | |
129 | + if (sz >= 9 && memcmp(buf, "bluetooth", 9) == 0) | |
130 | + { | |
131 | + rfkill_id = id; | |
132 | + break; | |
133 | + } | |
134 | + } | |
135 | + | |
136 | + asprintf(&rfkill_state_path, "/sys/class/rfkill/rfkill%d/state", rfkill_id); | |
137 | + return 0; | |
138 | +} | |
139 | + | |
140 | +/***************************************************************************** | |
141 | +** LPM Static Functions | |
142 | +*****************************************************************************/ | |
143 | + | |
144 | +/***************************************************************************** | |
145 | +** UPIO Interface Functions | |
146 | +*****************************************************************************/ | |
147 | + | |
148 | +/******************************************************************************* | |
149 | +** | |
150 | +** Function upio_init | |
151 | +** | |
152 | +** Description Initialization | |
153 | +** | |
154 | +** Returns None | |
155 | +** | |
156 | +*******************************************************************************/ | |
157 | +void upio_init(void) | |
158 | +{ | |
159 | + memset(upio_state, UPIO_UNKNOWN, UPIO_MAX_COUNT); | |
160 | +} | |
161 | + | |
162 | +/******************************************************************************* | |
163 | +** | |
164 | +** Function upio_cleanup | |
165 | +** | |
166 | +** Description Clean up | |
167 | +** | |
168 | +** Returns None | |
169 | +** | |
170 | +*******************************************************************************/ | |
171 | +void upio_cleanup(void) | |
172 | +{ | |
173 | +} | |
174 | + | |
175 | +/******************************************************************************* | |
176 | +** | |
177 | +** Function upio_set_bluetooth_power | |
178 | +** | |
179 | +** Description Interact with low layer driver to set Bluetooth power | |
180 | +** on/off. | |
181 | +** | |
182 | +** Returns 0 : SUCCESS or Not-Applicable | |
183 | +** <0 : ERROR | |
184 | +** | |
185 | +*******************************************************************************/ | |
186 | +int upio_set_bluetooth_power(int on) | |
187 | +{ | |
188 | + int sz; | |
189 | + int fd = -1; | |
190 | + int ret = -1; | |
191 | + char buffer = '0'; | |
192 | + | |
193 | + switch(on) | |
194 | + { | |
195 | + case UPIO_BT_POWER_OFF: | |
196 | + buffer = '0'; | |
197 | + break; | |
198 | + | |
199 | + case UPIO_BT_POWER_ON: | |
200 | + buffer = '1'; | |
201 | + break; | |
202 | + } | |
203 | + | |
204 | + if (is_emulator_context()) | |
205 | + { | |
206 | + /* if new value is same as current, return -1 */ | |
207 | + if (bt_emul_enable == on) | |
208 | + return ret; | |
209 | + | |
210 | + UPIODBG("set_bluetooth_power [emul] %d", on); | |
211 | + | |
212 | + bt_emul_enable = on; | |
213 | + return 0; | |
214 | + } | |
215 | + | |
216 | + /* check if we have rfkill interface */ | |
217 | + if (is_rfkill_disabled()) | |
218 | + return 0; | |
219 | + | |
220 | + if (rfkill_id == -1) | |
221 | + { | |
222 | + if (init_rfkill()) | |
223 | + return ret; | |
224 | + } | |
225 | + | |
226 | + fd = open(rfkill_state_path, O_WRONLY); | |
227 | + | |
228 | + if (fd < 0) | |
229 | + { | |
230 | + ALOGE("set_bluetooth_power : open(%s) for write failed: %s (%d)", | |
231 | + rfkill_state_path, strerror(errno), errno); | |
232 | + return ret; | |
233 | + } | |
234 | + | |
235 | + sz = write(fd, &buffer, 1); | |
236 | + | |
237 | + if (sz < 0) { | |
238 | + ALOGE("set_bluetooth_power : write(%s) failed: %s (%d)", | |
239 | + rfkill_state_path, strerror(errno),errno); | |
240 | + } | |
241 | + else | |
242 | + ret = 0; | |
243 | + | |
244 | + if (fd >= 0) | |
245 | + close(fd); | |
246 | + | |
247 | + return ret; | |
248 | +} | |
249 | + | |
250 | + | |
251 | +/******************************************************************************* | |
252 | +** | |
253 | +** Function upio_set | |
254 | +** | |
255 | +** Description Set i/o based on polarity | |
256 | +** | |
257 | +** Returns None | |
258 | +** | |
259 | +*******************************************************************************/ | |
260 | +void upio_set(uint8_t pio, uint8_t action, uint8_t polarity) | |
261 | +{ | |
262 | + int rc; | |
263 | + | |
264 | + switch (pio) | |
265 | + { | |
266 | + case UPIO_BT_WAKE: | |
267 | + | |
268 | + if (upio_state[UPIO_BT_WAKE] == action) | |
269 | + { | |
270 | + UPIODBG("BT_WAKE is %s already", lpm_state[action]); | |
271 | + return; | |
272 | + } | |
273 | + | |
274 | + upio_state[UPIO_BT_WAKE] = action; | |
275 | + | |
276 | + /**************************************** | |
277 | + * !!! TODO !!! | |
278 | + * | |
279 | + * === Custom Porting Required === | |
280 | + * | |
281 | + * Platform dependent user-to-kernel | |
282 | + * interface is required to set output | |
283 | + * state of physical BT_WAKE pin. | |
284 | + ****************************************/ | |
285 | +#if (BT_WAKE_VIA_USERIAL_IOCTL == TRUE) | |
286 | + userial_vendor_ioctl( ( (action==UPIO_ASSERT) ? \ | |
287 | + USERIAL_OP_ASSERT_BT_WAKE : USERIAL_OP_DEASSERT_BT_WAKE),\ | |
288 | + NULL); | |
289 | +#endif | |
290 | + break; | |
291 | + | |
292 | + case UPIO_HOST_WAKE: | |
293 | + UPIODBG("upio_set: UPIO_HOST_WAKE"); | |
294 | + break; | |
295 | + } | |
296 | +} | |
297 | + | |
298 | + |
@@ -0,0 +1,361 @@ | ||
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: userial_vendor.c | |
22 | + * | |
23 | + * Description: Contains vendor-specific userial functions | |
24 | + * | |
25 | + ******************************************************************************/ | |
26 | + | |
27 | +#define LOG_TAG "bt_userial_vendor" | |
28 | + | |
29 | +#include <utils/Log.h> | |
30 | +#include <termios.h> | |
31 | +#include <fcntl.h> | |
32 | +#include <errno.h> | |
33 | +#include <stdio.h> | |
34 | +#include "bt_vendor_brcm.h" | |
35 | +#include "userial.h" | |
36 | +#include "userial_vendor.h" | |
37 | + | |
38 | +/****************************************************************************** | |
39 | +** Constants & Macros | |
40 | +******************************************************************************/ | |
41 | + | |
42 | +#ifndef VNDUSERIAL_DBG | |
43 | +#define VNDUSERIAL_DBG FALSE | |
44 | +#endif | |
45 | + | |
46 | +#if (VNDUSERIAL_DBG == TRUE) | |
47 | +#define VNDUSERIALDBG(param, ...) {ALOGD(param, ## __VA_ARGS__);} | |
48 | +#else | |
49 | +#define VNDUSERIALDBG(param, ...) {} | |
50 | +#endif | |
51 | + | |
52 | +#define VND_PORT_NAME_MAXLEN 256 | |
53 | + | |
54 | +/****************************************************************************** | |
55 | +** Local type definitions | |
56 | +******************************************************************************/ | |
57 | + | |
58 | +/* vendor serial control block */ | |
59 | +typedef struct | |
60 | +{ | |
61 | + int fd; /* fd to Bluetooth device */ | |
62 | + struct termios termios; /* serial terminal of BT port */ | |
63 | + char port_name[VND_PORT_NAME_MAXLEN]; | |
64 | +} vnd_userial_cb_t; | |
65 | + | |
66 | +/****************************************************************************** | |
67 | +** Static variables | |
68 | +******************************************************************************/ | |
69 | + | |
70 | +static vnd_userial_cb_t vnd_userial; | |
71 | + | |
72 | +/***************************************************************************** | |
73 | +** Helper Functions | |
74 | +*****************************************************************************/ | |
75 | + | |
76 | +/******************************************************************************* | |
77 | +** | |
78 | +** Function userial_to_tcio_baud | |
79 | +** | |
80 | +** Description helper function converts USERIAL baud rates into TCIO | |
81 | +** conforming baud rates | |
82 | +** | |
83 | +** Returns TRUE/FALSE | |
84 | +** | |
85 | +*******************************************************************************/ | |
86 | +uint8_t userial_to_tcio_baud(uint8_t cfg_baud, uint32_t *baud) | |
87 | +{ | |
88 | + if (cfg_baud == USERIAL_BAUD_115200) | |
89 | + *baud = B115200; | |
90 | + else if (cfg_baud == USERIAL_BAUD_4M) | |
91 | + *baud = B4000000; | |
92 | + else if (cfg_baud == USERIAL_BAUD_3M) | |
93 | + *baud = B3000000; | |
94 | + else if (cfg_baud == USERIAL_BAUD_2M) | |
95 | + *baud = B2000000; | |
96 | + else if (cfg_baud == USERIAL_BAUD_1M) | |
97 | + *baud = B1000000; | |
98 | + else if (cfg_baud == USERIAL_BAUD_921600) | |
99 | + *baud = B921600; | |
100 | + else if (cfg_baud == USERIAL_BAUD_460800) | |
101 | + *baud = B460800; | |
102 | + else if (cfg_baud == USERIAL_BAUD_230400) | |
103 | + *baud = B230400; | |
104 | + else if (cfg_baud == USERIAL_BAUD_57600) | |
105 | + *baud = B57600; | |
106 | + else if (cfg_baud == USERIAL_BAUD_19200) | |
107 | + *baud = B19200; | |
108 | + else if (cfg_baud == USERIAL_BAUD_9600) | |
109 | + *baud = B9600; | |
110 | + else if (cfg_baud == USERIAL_BAUD_1200) | |
111 | + *baud = B1200; | |
112 | + else if (cfg_baud == USERIAL_BAUD_600) | |
113 | + *baud = B600; | |
114 | + else | |
115 | + { | |
116 | + ALOGE( "userial vendor open: unsupported baud idx %i", cfg_baud); | |
117 | + *baud = B115200; | |
118 | + return FALSE; | |
119 | + } | |
120 | + | |
121 | + return TRUE; | |
122 | +} | |
123 | + | |
124 | +#if (BT_WAKE_VIA_USERIAL_IOCTL==TRUE) | |
125 | +/******************************************************************************* | |
126 | +** | |
127 | +** Function userial_ioctl_init_bt_wake | |
128 | +** | |
129 | +** Description helper function to set the open state of the bt_wake if ioctl | |
130 | +** is used. it should not hurt in the rfkill case but it might | |
131 | +** be better to compile it out. | |
132 | +** | |
133 | +** Returns none | |
134 | +** | |
135 | +*******************************************************************************/ | |
136 | +void userial_ioctl_init_bt_wake(int fd) | |
137 | +{ | |
138 | + uint32_t bt_wake_state; | |
139 | + | |
140 | + /* assert BT_WAKE through ioctl */ | |
141 | + ioctl(fd, USERIAL_IOCTL_BT_WAKE_ASSERT, NULL); | |
142 | + ioctl(fd, USERIAL_IOCTL_BT_WAKE_GET_ST, &bt_wake_state); | |
143 | + VNDUSERIALDBG("userial_ioctl_init_bt_wake read back BT_WAKE state=%i", \ | |
144 | + bt_wake_state); | |
145 | +} | |
146 | +#endif // (BT_WAKE_VIA_USERIAL_IOCTL==TRUE) | |
147 | + | |
148 | + | |
149 | +/***************************************************************************** | |
150 | +** Userial Vendor API Functions | |
151 | +*****************************************************************************/ | |
152 | + | |
153 | +/******************************************************************************* | |
154 | +** | |
155 | +** Function userial_vendor_init | |
156 | +** | |
157 | +** Description Initialize userial vendor-specific control block | |
158 | +** | |
159 | +** Returns None | |
160 | +** | |
161 | +*******************************************************************************/ | |
162 | +void userial_vendor_init(void) | |
163 | +{ | |
164 | + vnd_userial.fd = -1; | |
165 | + snprintf(vnd_userial.port_name, VND_PORT_NAME_MAXLEN, "%s", \ | |
166 | + BLUETOOTH_UART_DEVICE_PORT); | |
167 | +} | |
168 | + | |
169 | +/******************************************************************************* | |
170 | +** | |
171 | +** Function userial_vendor_open | |
172 | +** | |
173 | +** Description Open the serial port with the given configuration | |
174 | +** | |
175 | +** Returns device fd | |
176 | +** | |
177 | +*******************************************************************************/ | |
178 | +int userial_vendor_open(tUSERIAL_CFG *p_cfg) | |
179 | +{ | |
180 | + uint32_t baud; | |
181 | + uint8_t data_bits; | |
182 | + uint16_t parity; | |
183 | + uint8_t stop_bits; | |
184 | + | |
185 | + vnd_userial.fd = -1; | |
186 | + | |
187 | + if (!userial_to_tcio_baud(p_cfg->baud, &baud)) | |
188 | + { | |
189 | + return -1; | |
190 | + } | |
191 | + | |
192 | + if(p_cfg->fmt & USERIAL_DATABITS_8) | |
193 | + data_bits = CS8; | |
194 | + else if(p_cfg->fmt & USERIAL_DATABITS_7) | |
195 | + data_bits = CS7; | |
196 | + else if(p_cfg->fmt & USERIAL_DATABITS_6) | |
197 | + data_bits = CS6; | |
198 | + else if(p_cfg->fmt & USERIAL_DATABITS_5) | |
199 | + data_bits = CS5; | |
200 | + else | |
201 | + { | |
202 | + ALOGE("userial vendor open: unsupported data bits"); | |
203 | + return -1; | |
204 | + } | |
205 | + | |
206 | + if(p_cfg->fmt & USERIAL_PARITY_NONE) | |
207 | + parity = 0; | |
208 | + else if(p_cfg->fmt & USERIAL_PARITY_EVEN) | |
209 | + parity = PARENB; | |
210 | + else if(p_cfg->fmt & USERIAL_PARITY_ODD) | |
211 | + parity = (PARENB | PARODD); | |
212 | + else | |
213 | + { | |
214 | + ALOGE("userial vendor open: unsupported parity bit mode"); | |
215 | + return -1; | |
216 | + } | |
217 | + | |
218 | + if(p_cfg->fmt & USERIAL_STOPBITS_1) | |
219 | + stop_bits = 0; | |
220 | + else if(p_cfg->fmt & USERIAL_STOPBITS_2) | |
221 | + stop_bits = CSTOPB; | |
222 | + else | |
223 | + { | |
224 | + ALOGE("userial vendor open: unsupported stop bits"); | |
225 | + return -1; | |
226 | + } | |
227 | + | |
228 | + ALOGI("userial vendor open: opening %s", vnd_userial.port_name); | |
229 | + | |
230 | + if ((vnd_userial.fd = open(vnd_userial.port_name, O_RDWR)) == -1) | |
231 | + { | |
232 | + ALOGE("userial vendor open: unable to open %s", vnd_userial.port_name); | |
233 | + return -1; | |
234 | + } | |
235 | + | |
236 | + tcflush(vnd_userial.fd, TCIOFLUSH); | |
237 | + | |
238 | + tcgetattr(vnd_userial.fd, &vnd_userial.termios); | |
239 | + cfmakeraw(&vnd_userial.termios); | |
240 | + vnd_userial.termios.c_cflag |= (CRTSCTS | stop_bits); | |
241 | + tcsetattr(vnd_userial.fd, TCSANOW, &vnd_userial.termios); | |
242 | + tcflush(vnd_userial.fd, TCIOFLUSH); | |
243 | + | |
244 | + tcsetattr(vnd_userial.fd, TCSANOW, &vnd_userial.termios); | |
245 | + tcflush(vnd_userial.fd, TCIOFLUSH); | |
246 | + tcflush(vnd_userial.fd, TCIOFLUSH); | |
247 | + | |
248 | + /* set input/output baudrate */ | |
249 | + cfsetospeed(&vnd_userial.termios, baud); | |
250 | + cfsetispeed(&vnd_userial.termios, baud); | |
251 | + tcsetattr(vnd_userial.fd, TCSANOW, &vnd_userial.termios); | |
252 | + | |
253 | +#if (BT_WAKE_VIA_USERIAL_IOCTL==TRUE) | |
254 | + userial_ioctl_init_bt_wake(vnd_userial.fd); | |
255 | +#endif | |
256 | + | |
257 | + ALOGI("device fd = %d open", vnd_userial.fd); | |
258 | + | |
259 | + return vnd_userial.fd; | |
260 | +} | |
261 | + | |
262 | +/******************************************************************************* | |
263 | +** | |
264 | +** Function userial_vendor_close | |
265 | +** | |
266 | +** Description Conduct vendor-specific close work | |
267 | +** | |
268 | +** Returns None | |
269 | +** | |
270 | +*******************************************************************************/ | |
271 | +void userial_vendor_close(void) | |
272 | +{ | |
273 | + int result; | |
274 | + | |
275 | + if (vnd_userial.fd == -1) | |
276 | + return; | |
277 | + | |
278 | +#if (BT_WAKE_VIA_USERIAL_IOCTL==TRUE) | |
279 | + /* de-assert bt_wake BEFORE closing port */ | |
280 | + ioctl(vnd_userial.fd, USERIAL_IOCTL_BT_WAKE_DEASSERT, NULL); | |
281 | +#endif | |
282 | + | |
283 | + ALOGI("device fd = %d close", vnd_userial.fd); | |
284 | + | |
285 | + if ((result = close(vnd_userial.fd)) < 0) | |
286 | + ALOGE( "close(fd:%d) FAILED result:%d", vnd_userial.fd, result); | |
287 | + | |
288 | + vnd_userial.fd = -1; | |
289 | +} | |
290 | + | |
291 | +/******************************************************************************* | |
292 | +** | |
293 | +** Function userial_vendor_set_baud | |
294 | +** | |
295 | +** Description Set new baud rate | |
296 | +** | |
297 | +** Returns None | |
298 | +** | |
299 | +*******************************************************************************/ | |
300 | +void userial_vendor_set_baud(uint8_t userial_baud) | |
301 | +{ | |
302 | + uint32_t tcio_baud; | |
303 | + | |
304 | + userial_to_tcio_baud(userial_baud, &tcio_baud); | |
305 | + | |
306 | + cfsetospeed(&vnd_userial.termios, tcio_baud); | |
307 | + cfsetispeed(&vnd_userial.termios, tcio_baud); | |
308 | + tcsetattr(vnd_userial.fd, TCSANOW, &vnd_userial.termios); | |
309 | +} | |
310 | + | |
311 | +/******************************************************************************* | |
312 | +** | |
313 | +** Function userial_vendor_ioctl | |
314 | +** | |
315 | +** Description ioctl inteface | |
316 | +** | |
317 | +** Returns None | |
318 | +** | |
319 | +*******************************************************************************/ | |
320 | +void userial_vendor_ioctl(userial_vendor_ioctl_op_t op, void *p_data) | |
321 | +{ | |
322 | + switch(op) | |
323 | + { | |
324 | +#if (BT_WAKE_VIA_USERIAL_IOCTL==TRUE) | |
325 | + case USERIAL_OP_ASSERT_BT_WAKE: | |
326 | + VNDUSERIALDBG("## userial_vendor_ioctl: Asserting BT_Wake ##"); | |
327 | + ioctl(vnd_userial.fd, USERIAL_IOCTL_BT_WAKE_ASSERT, NULL); | |
328 | + break; | |
329 | + | |
330 | + case USERIAL_OP_DEASSERT_BT_WAKE: | |
331 | + VNDUSERIALDBG("## userial_vendor_ioctl: De-asserting BT_Wake ##"); | |
332 | + ioctl(vnd_userial.fd, USERIAL_IOCTL_BT_WAKE_DEASSERT, NULL); | |
333 | + break; | |
334 | + | |
335 | + case USERIAL_OP_GET_BT_WAKE_STATE: | |
336 | + ioctl(vnd_userial.fd, USERIAL_IOCTL_BT_WAKE_GET_ST, p_data); | |
337 | + break; | |
338 | +#endif // (BT_WAKE_VIA_USERIAL_IOCTL==TRUE) | |
339 | + | |
340 | + default: | |
341 | + break; | |
342 | + } | |
343 | +} | |
344 | + | |
345 | +/******************************************************************************* | |
346 | +** | |
347 | +** Function userial_set_port | |
348 | +** | |
349 | +** Description Configure UART port name | |
350 | +** | |
351 | +** Returns 0 : Success | |
352 | +** Otherwise : Fail | |
353 | +** | |
354 | +*******************************************************************************/ | |
355 | +int userial_set_port(char *p_conf_name, char *p_conf_value, int param) | |
356 | +{ | |
357 | + strcpy(vnd_userial.port_name, p_conf_value); | |
358 | + | |
359 | + return 0; | |
360 | +} | |
361 | + |
@@ -0,0 +1,16 @@ | ||
1 | +intermediates := $(local-intermediates-dir) | |
2 | + | |
3 | +SRC := $(call my-dir)/include/$(addprefix vnd_, $(addsuffix .txt,$(basename $(TARGET_DEVICE)))) | |
4 | +ifeq (,$(wildcard $(SRC))) | |
5 | +# configuration file does not exist. Use default one | |
6 | +SRC := $(call my-dir)/include/vnd_generic.txt | |
7 | +endif | |
8 | +GEN := $(intermediates)/vnd_buildcfg.h | |
9 | +TOOL := $(TOP_DIR)external/bluetooth/bluedroid/tools/gen-buildcfg.sh | |
10 | + | |
11 | +$(GEN): PRIVATE_PATH := $(call my-dir) | |
12 | +$(GEN): PRIVATE_CUSTOM_TOOL = $(TOOL) $< $@ | |
13 | +$(GEN): $(SRC) $(TOOL) | |
14 | + $(transform-generated-source) | |
15 | + | |
16 | +LOCAL_GENERATED_SOURCES += $(GEN) |