1 /*
2 * Copyright 2012 The Android Open Source Project
3 * Copyright (c) 2013, The Linux Foundation. All rights reserved.
4 * Not a Contribution.
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19 /******************************************************************************
20 *
21 * Filename: bt_vendor_qcom.c
22 *
23 * Description: vendor specific library implementation
24 *
25 ******************************************************************************/
26
27 #define LOG_TAG "bt_vendor"
28 #define BLUETOOTH_MAC_ADDR_BOOT_PROPERTY "ro.boot.btmacaddr"
29
30 #include <utils/Log.h>
31 #include <cutils/properties.h>
32 #include <fcntl.h>
33 #include <termios.h>
34 #include "bt_vendor_qcom.h"
35 #include "hci_uart.h"
36 #include "hci_smd.h"
37 #include <sys/socket.h>
38 #include <cutils/sockets.h>
39 #include <linux/un.h>
40 #ifdef BT_NV_SUPPORT
41 #include "bt_vendor_persist.h"
42 #endif
43 #include "hw_rome.h"
44
45 #define WAIT_TIMEOUT 200000
46 #define BT_VND_OP_GET_LINESPEED 12
47
48 /******************************************************************************
49 ** Externs
50 ******************************************************************************/
51 extern int hw_config(int nState);
52
53 extern int is_hw_ready();
54 extern int rome_soc_init(int fd, char *bdaddr);
55 extern int check_embedded_mode(int fd);
56 extern int rome_get_addon_feature_list(int fd);
57 extern int rome_ver;
58 extern int enable_controller_log(int fd);
59 /******************************************************************************
60 ** Variables
61 ******************************************************************************/
62 int pFd[2] = {0,};
63 #ifdef BT_SOC_TYPE_ROME
64 int ant_fd;
65 #endif
66 bt_vendor_callbacks_t *bt_vendor_cbacks = NULL;
67 uint8_t vnd_local_bd_addr[6]={0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
68 static int btSocType = BT_SOC_DEFAULT;
69 static int rfkill_id = -1;
70 static char *rfkill_state = NULL;
71 bool enable_extldo = FALSE;
72
73 static const tUSERIAL_CFG userial_init_cfg =
74 {
75 (USERIAL_DATABITS_8 | USERIAL_PARITY_NONE | USERIAL_STOPBITS_1),
76 USERIAL_BAUD_115200
77 };
78
79 #if (HW_NEED_END_WITH_HCI_RESET == TRUE)
80 void hw_epilog_process(void);
81 #endif
82
83 #ifdef WIFI_BT_STATUS_SYNC
84 #include <string.h>
85 #include <errno.h>
86 #include <dlfcn.h>
87 #include "cutils/properties.h"
88
89 static const char WIFI_PROP_NAME[] = "wlan.driver.status";
90 static const char SERVICE_PROP_NAME[] = "bluetooth.hsic_ctrl";
91 static const char BT_STATUS_NAME[] = "bluetooth.enabled";
92 static const char WIFI_SERVICE_PROP[] = "wlan.hsic_ctrl";
93
94 #define WIFI_BT_STATUS_LOCK "/data/connectivity/wifi_bt_lock"
95 int isInit=0;
96 #endif /* WIFI_BT_STATUS_SYNC */
97 bool is_soc_initialized(void);
98
99 /******************************************************************************
100 ** Local type definitions
101 ******************************************************************************/
102
103 /******************************************************************************
104 ** TODO: Cleanup to use header file. Declare externally used functions.
105 ******************************************************************************/
106 int readTrpState();
107 int ath3k_init(int fd, int speed, int init_speed, char *bdaddr, struct termios *ti);
108 int userial_clock_operation(int fd, int cmd);
109 int rome_soc_init(int fd, char *bdaddr);
110 void lpm_set_ar3k(uint8_t pio, uint8_t action, uint8_t polarity);
111 int userial_vendor_get_baud(void);
112
113
114 /******************************************************************************
115 ** Functions
116 ******************************************************************************/
117 #ifdef WIFI_BT_STATUS_SYNC
bt_semaphore_create(void)118 int bt_semaphore_create(void)
119 {
120 int fd;
121
122 fd = open(WIFI_BT_STATUS_LOCK, O_RDONLY);
123
124 if (fd < 0)
125 ALOGE("can't create file\n");
126
127 return fd;
128 }
129
bt_semaphore_get(int fd)130 int bt_semaphore_get(int fd)
131 {
132 int ret;
133
134 if (fd < 0)
135 return -1;
136
137 ret = flock(fd, LOCK_EX);
138 if (ret != 0) {
139 ALOGE("can't hold lock: %s\n", strerror(errno));
140 return -1;
141 }
142
143 return ret;
144 }
145
bt_semaphore_release(int fd)146 int bt_semaphore_release(int fd)
147 {
148 int ret;
149
150 if (fd < 0)
151 return -1;
152
153 ret = flock(fd, LOCK_UN);
154 if (ret != 0) {
155 ALOGE("can't release lock: %s\n", strerror(errno));
156 return -1;
157 }
158
159 return ret;
160 }
161
bt_semaphore_destroy(int fd)162 int bt_semaphore_destroy(int fd)
163 {
164 if (fd < 0)
165 return -1;
166
167 return close (fd);
168 }
169
bt_wait_for_service_done(void)170 int bt_wait_for_service_done(void)
171 {
172 char service_status[PROPERTY_VALUE_MAX];
173 int count = 30;
174
175 ALOGE("%s: check\n", __func__);
176
177 /* wait for service done */
178 while (count-- > 0) {
179 property_get(WIFI_SERVICE_PROP, service_status, NULL);
180
181 if (strcmp(service_status, "") != 0) {
182 usleep(200000);
183 } else {
184 break;
185 }
186 }
187
188 return 0;
189 }
190
191 #endif /* WIFI_BT_STATUS_SYNC */
192
193 /** Get Bluetooth SoC type from system setting */
get_bt_soc_type()194 static int get_bt_soc_type()
195 {
196 int ret = 0;
197 char bt_soc_type[PROPERTY_VALUE_MAX];
198
199 ALOGI("bt-vendor : get_bt_soc_type");
200
201 ret = property_get("qcom.bluetooth.soc", bt_soc_type, NULL);
202 if (ret != 0) {
203 ALOGI("qcom.bluetooth.soc set to %s\n", bt_soc_type);
204 if (!strncasecmp(bt_soc_type, "rome", sizeof("rome"))) {
205 return BT_SOC_ROME;
206 }
207 else if (!strncasecmp(bt_soc_type, "ath3k", sizeof("ath3k"))) {
208 return BT_SOC_AR3K;
209 }
210 else {
211 ALOGI("qcom.bluetooth.soc not set, so using default.\n");
212 return BT_SOC_DEFAULT;
213 }
214 }
215 else {
216 ALOGE("%s: Failed to get soc type", __FUNCTION__);
217 ret = BT_SOC_DEFAULT;
218 }
219
220 return ret;
221 }
222
can_perform_action(char action)223 bool can_perform_action(char action) {
224 bool can_perform = false;
225 char ref_count[PROPERTY_VALUE_MAX];
226 int value, ret;
227
228 property_get("wc_transport.ref_count", ref_count, "0");
229
230 value = atoi(ref_count);
231 ALOGV("%s: ref_count: %s\n",__func__, ref_count);
232
233 if(action == '1') {
234 ALOGV("%s: on : value is: %d", __func__, value);
235 if(value == 1)
236 {
237 if(is_soc_initialized() == true)
238 {
239 value++;
240 ALOGV("%s: on : value is incremented to : %d", __func__, value);
241 }
242 }
243 else
244 {
245 value++;
246 }
247 if (value == 1)
248 can_perform = true;
249 else if (value > 2) return false;
250 } else {
251 ALOGV("%s: off : value is: %d", __func__, value);
252 value--;
253 if (value == 0)
254 can_perform = true;
255 else if (value < 0) return false;
256 }
257
258 snprintf(ref_count, 3, "%d", value);
259 ALOGV("%s: updated ref_count is: %s", __func__, ref_count);
260
261 ret = property_set("wc_transport.ref_count", ref_count);
262 if (ret < 0) {
263 ALOGE("%s: Error while updating property: %d\n", __func__, ret);
264 return false;
265 }
266 ALOGV("%s returning %d", __func__, can_perform);
267 return can_perform;
268 }
269
stop_hci_filter()270 void stop_hci_filter() {
271 char value[PROPERTY_VALUE_MAX] = {'\0'};
272 ALOGV("%s: Entry ", __func__);
273
274 property_get("wc_transport.start_hci", value, "false");
275
276 if (strcmp(value, "false") == 0) {
277 ALOGV("%s: hci_filter has been stopped already", __func__);
278 return;
279 }
280
281 property_set("wc_transport.start_hci", "false");
282 property_set("wc_transport.hci_filter_status", "0");
283 ALOGV("%s: Exit ", __func__);
284 }
285
start_hci_filter()286 void start_hci_filter() {
287 ALOGV("%s: Entry ", __func__);
288 int i, init_success = 0;
289 char value[PROPERTY_VALUE_MAX] = {'\0'};
290
291
292 property_get("wc_transport.start_hci", value, false);
293
294 if (strcmp(value, "true") == 0) {
295 ALOGV("%s: hci_filter has been started already", __func__);
296 return;
297 }
298
299 property_set("wc_transport.hci_filter_status", "0");
300
301 property_set("wc_transport.start_hci", "true");
302 //sched_yield();
303 for(i=0; i<45; i++) {
304 property_get("wc_transport.hci_filter_status", value, "0");
305 if (strcmp(value, "1") == 0) {
306 init_success = 1;
307 break;
308 } else {
309 usleep(WAIT_TIMEOUT);
310 }
311 }
312 ALOGV("start_hcifilter status:%d after %f seconds \n", init_success, 0.2*i);
313
314 ALOGV("%s: Exit ", __func__);
315 }
316
317 /** Bluetooth Controller power up or shutdown */
bt_powerup(int en)318 static int bt_powerup(int en )
319 {
320 char rfkill_type[64], *enable_ldo_path = NULL;
321 char type[16], enable_ldo[6];
322 int fd, size, i, ret, fd_ldo;
323
324 char disable[PROPERTY_VALUE_MAX];
325 char state;
326 char on = (en)?'1':'0';
327
328 #ifdef WIFI_BT_STATUS_SYNC
329 char wifi_status[PROPERTY_VALUE_MAX];
330 int lock_fd;
331 #endif /*WIFI_BT_STATUS_SYNC*/
332
333 ALOGI("bt_powerup: %c", on);
334
335 /* Check if rfkill has been disabled */
336 ret = property_get("ro.rfkilldisabled", disable, "0");
337 if (!ret ){
338 ALOGE("Couldn't get ro.rfkilldisabled (%d)", ret);
339 return -1;
340 }
341 /* In case rfkill disabled, then no control power*/
342 if (strcmp(disable, "1") == 0) {
343 ALOGI("ro.rfkilldisabled : %s", disable);
344 return -1;
345 }
346
347 #ifdef WIFI_BT_STATUS_SYNC
348 lock_fd = bt_semaphore_create();
349 bt_semaphore_get(lock_fd);
350 bt_wait_for_service_done();
351 #endif
352
353 /* Assign rfkill_id and find bluetooth rfkill state path*/
354 for(i=0;(rfkill_id == -1) && (rfkill_state == NULL);i++)
355 {
356 snprintf(rfkill_type, sizeof(rfkill_type), "/sys/class/rfkill/rfkill%d/type", i);
357 if ((fd = open(rfkill_type, O_RDONLY)) < 0)
358 {
359 ALOGE("open(%s) failed: %s (%d)\n", rfkill_type, strerror(errno), errno);
360
361 #ifdef WIFI_BT_STATUS_SYNC
362 bt_semaphore_release(lock_fd);
363 bt_semaphore_destroy(lock_fd);
364 #endif
365 return -1;
366 }
367
368 size = read(fd, &type, sizeof(type));
369 close(fd);
370
371 if ((size >= 9) && !memcmp(type, "bluetooth", 9))
372 {
373 asprintf(&rfkill_state, "/sys/class/rfkill/rfkill%d/state", rfkill_id = i);
374 break;
375 }
376 }
377
378 /* Get rfkill State to control */
379 if (rfkill_state != NULL)
380 {
381 if ((fd = open(rfkill_state, O_RDWR)) < 0)
382 {
383 ALOGE("open(%s) for write failed: %s (%d)",rfkill_state, strerror(errno), errno);
384 #ifdef WIFI_BT_STATUS_SYNC
385 bt_semaphore_release(lock_fd);
386 bt_semaphore_destroy(lock_fd);
387 #endif
388
389 return -1;
390 }
391 }
392 #ifdef BT_SOC_TYPE_ROME
393 if(can_perform_action(on) == false) {
394 ALOGE("%s:can't perform action as it is being used by other clients", __func__);
395 #ifdef WIFI_BT_STATUS_SYNC
396 bt_semaphore_release(lock_fd);
397 bt_semaphore_destroy(lock_fd);
398 #endif
399 goto done;
400 }
401 #endif
402 ret = asprintf(&enable_ldo_path, "/sys/class/rfkill/rfkill%d/device/extldo", rfkill_id);
403 if( (ret < 0 ) || (enable_ldo_path == NULL) )
404 {
405 ALOGE("Memory Allocation failure");
406 return -1;
407 }
408 if ((fd_ldo = open(enable_ldo_path, O_RDWR)) < 0) {
409 ALOGE("open(%s) failed: %s (%d)", enable_ldo_path, strerror(errno), errno);
410 return -1;
411 }
412 size = read(fd_ldo, &enable_ldo, sizeof(enable_ldo));
413 close(fd_ldo);
414 if (size <= 0) {
415 ALOGE("read(%s) failed: %s (%d)", enable_ldo_path, strerror(errno), errno);
416 return -1;
417 }
418 if (!memcmp(enable_ldo, "true", 4)) {
419 ALOGI("External LDO has been configured");
420 enable_extldo = TRUE;
421 }
422
423 ALOGE("Write %c to rfkill\n", on);
424
425 /* Write value to control rfkill */
426 if ((size = write(fd, &on, 1)) < 0) {
427 ALOGE("write(%s) failed: %s (%d)",rfkill_state, strerror(errno),errno);
428 #ifdef WIFI_BT_STATUS_SYNC
429 bt_semaphore_release(lock_fd);
430 bt_semaphore_destroy(lock_fd);
431 #endif
432 return -1;
433 }
434 #ifdef BT_SOC_TYPE_ROME
435 if(on == '0'){
436 ALOGE("Stopping HCI filter as part of CTRL:OFF");
437 stop_hci_filter();
438 property_set("wc_transport.soc_initialized", "0");
439 }
440 #endif
441 #ifdef WIFI_BT_STATUS_SYNC
442 /* query wifi status */
443 property_get(WIFI_PROP_NAME, wifi_status, "");
444
445 ALOGE("bt get wifi status: %s, isInit: %d\n", wifi_status, isInit);
446
447 /* If wlan driver is not loaded, and bt is changed from off => on */
448 if (strncmp(wifi_status, "unloaded", strlen("unloaded")) == 0 || strlen(wifi_status) == 0) {
449 if (on == '1') {
450 ALOGI("%s: BT_VND_PWR_ON\n", __func__);
451 if(property_set(SERVICE_PROP_NAME, "load_wlan") < 0) {
452 ALOGE("%s Property setting failed", SERVICE_PROP_NAME);
453 close(fd);
454 bt_semaphore_release(lock_fd);
455 bt_semaphore_destroy(lock_fd);
456 return -1;
457 }
458 }
459 else if (isInit == 0 && on == '0') {
460 ALOGI("%s: BT_VND_PWR_OFF\n", __func__);
461 if(property_set(SERVICE_PROP_NAME, "unbind_hsic") < 0) {
462 ALOGE("%s Property setting failed", SERVICE_PROP_NAME);
463 close(fd);
464 bt_semaphore_release(lock_fd);
465 bt_semaphore_destroy(lock_fd);
466 return -1;
467 }
468 }
469 }
470
471 if (isInit == 0 && on == '0')
472 property_set(BT_STATUS_NAME, "false");
473 else if (on == '1')
474 property_set(BT_STATUS_NAME, "true");
475
476 bt_semaphore_release(lock_fd);
477 bt_semaphore_destroy(lock_fd);
478 #endif /* WIFI_BT_STATUS_SYNC */
479
480 done:
481 if (fd >= 0)
482 close(fd);
483
484 return 0;
485 }
486
487 /*****************************************************************************
488 **
489 ** BLUETOOTH VENDOR INTERFACE LIBRARY FUNCTIONS
490 **
491 *****************************************************************************/
492
init(const bt_vendor_callbacks_t * p_cb,unsigned char * local_bdaddr)493 static int init(const bt_vendor_callbacks_t* p_cb, unsigned char *local_bdaddr)
494 {
495 int i;
496
497 ALOGI("bt-vendor : init");
498
499 if (p_cb == NULL)
500 {
501 ALOGE("init failed with no user callbacks!");
502 return -1;
503 }
504
505 if ((btSocType = get_bt_soc_type()) < 0) {
506 ALOGE("%s: Failed to detect BT SOC Type", __FUNCTION__);
507 return -1;
508 }
509
510 switch(btSocType)
511 {
512 case BT_SOC_ROME:
513 case BT_SOC_AR3K:
514 ALOGI("bt-vendor : Initializing UART transport layer");
515 userial_vendor_init();
516 break;
517 case BT_SOC_DEFAULT:
518 break;
519 default:
520 ALOGE("Unknown btSocType: 0x%x", btSocType);
521 break;
522 }
523
524 /* store reference to user callbacks */
525 bt_vendor_cbacks = (bt_vendor_callbacks_t *) p_cb;
526
527 /* Copy BD Address as little-endian byte order */
528 if(local_bdaddr)
529 for(i=0;i<6;i++)
530 vnd_local_bd_addr[i] = *(local_bdaddr + (5-i));
531
532 ALOGI("%s: Local BD Address : %.2x:%.2x:%.2x:%.2x:%.2x:%.2x", __FUNCTION__,
533 vnd_local_bd_addr[0],
534 vnd_local_bd_addr[1],
535 vnd_local_bd_addr[2],
536 vnd_local_bd_addr[3],
537 vnd_local_bd_addr[4],
538 vnd_local_bd_addr[5]);
539
540 #ifdef WIFI_BT_STATUS_SYNC
541 isInit = 1;
542 #endif /* WIFI_BT_STATUS_SYNC */
543
544 return 0;
545 }
546
547 #ifdef READ_BT_ADDR_FROM_PROP
validate_tok(char * bdaddr_tok)548 static bool validate_tok(char* bdaddr_tok) {
549 int i = 0;
550 bool ret;
551
552 if (strlen(bdaddr_tok) != 2) {
553 ret = FALSE;
554 ALOGE("Invalid token length");
555 } else {
556 ret = TRUE;
557 for (i=0; i<2; i++) {
558 if ((bdaddr_tok[i] >= '0' && bdaddr_tok[i] <= '9') ||
559 (bdaddr_tok[i] >= 'A' && bdaddr_tok[i] <= 'F') ||
560 (bdaddr_tok[i] >= 'a' && bdaddr_tok[i] <= 'f')) {
561 ret = TRUE;
562 ALOGV("%s: tok %s @ %d is good", __func__, bdaddr_tok, i);
563 } else {
564 ret = FALSE;
565 ALOGE("invalid character in tok: %s at ind: %d", bdaddr_tok, i);
566 break;
567 }
568 }
569 }
570 return ret;
571 }
572 #endif /*READ_BT_ADDR_FROM_PROP*/
573
connect_to_local_socket(char * name)574 int connect_to_local_socket(char* name) {
575 socklen_t len; int sk = -1;
576
577 ALOGE("%s: ACCEPT ", __func__);
578 sk = socket(AF_LOCAL, SOCK_STREAM, 0);
579 if (sk < 0) {
580 ALOGE("Socket creation failure");
581 return -1;
582 }
583
584 if(socket_local_client_connect(sk, name,
585 ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM) < 0)
586 {
587 ALOGE("failed to connect (%s)", strerror(errno));
588 close(sk);
589 sk = -1;
590 } else {
591 ALOGE("%s: Connection succeeded\n", __func__);
592 }
593 return sk;
594 }
595
is_soc_initialized()596 bool is_soc_initialized() {
597 bool init = false;
598 char init_value[PROPERTY_VALUE_MAX];
599 int ret;
600
601 ALOGI("bt-vendor : is_soc_initialized");
602
603 ret = property_get("wc_transport.soc_initialized", init_value, NULL);
604 if (ret != 0) {
605 ALOGI("wc_transport.soc_initialized set to %s\n", init_value);
606 if (!strncasecmp(init_value, "1", sizeof("1"))) {
607 init = true;
608 }
609 }
610 else {
611 ALOGE("%s: Failed to get wc_transport.soc_initialized", __FUNCTION__);
612 }
613
614 return init;
615 }
616
617
618 /** Requested operations */
op(bt_vendor_opcode_t opcode,void * param)619 static int op(bt_vendor_opcode_t opcode, void *param)
620 {
621 int retval = 0;
622 int nCnt = 0;
623 int nState = -1;
624 bool is_ant_req = false;
625 char wipower_status[PROPERTY_VALUE_MAX];
626 char bt_version[PROPERTY_VALUE_MAX];
627 bool ignore_boot_prop = TRUE;
628 #ifdef READ_BT_ADDR_FROM_PROP
629 int i = 0;
630 static char bd_addr[PROPERTY_VALUE_MAX];
631 uint8_t local_bd_addr_from_prop[6];
632 char* tok;
633 #endif
634 bool skip_init = true;
635
636 ALOGV("bt-vendor : op for %d", opcode);
637
638 switch(opcode)
639 {
640 case BT_VND_OP_POWER_CTRL:
641 {
642 nState = *(int *) param;
643 ALOGI("bt-vendor : BT_VND_OP_POWER_CTRL: %s",
644 (nState == BT_VND_PWR_ON)? "On" : "Off" );
645
646 switch(btSocType)
647 {
648 case BT_SOC_DEFAULT:
649 if (readTrpState())
650 {
651 ALOGI("bt-vendor : resetting BT status");
652 hw_config(BT_VND_PWR_OFF);
653 }
654 retval = hw_config(nState);
655 if(nState == BT_VND_PWR_ON
656 && retval == 0
657 && is_hw_ready() == TRUE){
658 retval = 0;
659 }
660 else {
661 retval = -1;
662 }
663 break;
664 case BT_SOC_ROME:
665 case BT_SOC_AR3K:
666 /* BT Chipset Power Control through Device Tree Node */
667 if(nState == BT_VND_PWR_ON && property_get_bool("wc_transport.vnd_power", 0)) {
668 bt_powerup(BT_VND_PWR_OFF);
669 }
670 retval = bt_powerup(nState);
671 if(retval == 0)
672 property_set("wc_transport.vnd_power", nState == BT_VND_PWR_ON ? "1" : "0");
673 default:
674 break;
675 }
676 }
677 break;
678
679 case BT_VND_OP_FW_CFG:
680 {
681 // call hciattach to initalize the stack
682 if(bt_vendor_cbacks){
683 ALOGI("Bluetooth Firmware and transport layer are initialized");
684 bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_SUCCESS);
685 }
686 else{
687 ALOGE("bt_vendor_cbacks is null");
688 ALOGE("Error : hci, smd initialization Error");
689 retval = -1;
690 }
691 }
692 break;
693
694 case BT_VND_OP_SCO_CFG:
695 {
696 if (bt_vendor_cbacks)
697 bt_vendor_cbacks->scocfg_cb(BT_VND_OP_RESULT_SUCCESS); //dummy
698 }
699 break;
700 #ifdef BT_SOC_TYPE_ROME
701 #ifdef ENABLE_ANT
702 case BT_VND_OP_ANT_USERIAL_OPEN:
703 ALOGI("bt-vendor : BT_VND_OP_ANT_USERIAL_OPEN");
704 is_ant_req = true;
705 //fall through
706 #endif
707 #endif
708 case BT_VND_OP_USERIAL_OPEN:
709 {
710 int (*fd_array)[] = (int (*)[]) param;
711 int fd = -1, fd_filter = -1;
712 ALOGI("bt-vendor : BT_VND_OP_USERIAL_OPEN");
713 switch(btSocType)
714 {
715 case BT_SOC_DEFAULT:
716 {
717 if(bt_hci_init_transport(pFd) != -1){
718 int (*fd_array)[] = (int (*) []) param;
719
720 (*fd_array)[CH_CMD] = pFd[0];
721 (*fd_array)[CH_EVT] = pFd[0];
722 (*fd_array)[CH_ACL_OUT] = pFd[1];
723 (*fd_array)[CH_ACL_IN] = pFd[1];
724 }
725 else {
726 retval = -1;
727 break;
728 }
729 retval = 2;
730 }
731 break;
732 case BT_SOC_AR3K:
733 {
734 int idx;
735 fd = userial_vendor_open((tUSERIAL_CFG *) &userial_init_cfg);
736 if (fd != -1) {
737 for (idx=0; idx < CH_MAX; idx++)
738 (*fd_array)[idx] = fd;
739 retval = 1;
740 }
741 else {
742 retval = -1;
743 break;
744 }
745
746 /* Vendor Specific Process should happened during userial_open process
747 After userial_open, rx read thread is running immediately,
748 so it will affect VS event read process.
749 */
750 if(ath3k_init(fd,3000000,115200,NULL,&vnd_userial.termios)<0)
751 retval = -1;
752 }
753 break;
754 case BT_SOC_ROME:
755 {
756 int idx;
757 property_get("persist.BT3_2.version", bt_version, false);
758 if (!is_soc_initialized()) {
759 fd = userial_vendor_open((tUSERIAL_CFG *) &userial_init_cfg);
760 if (fd < 0) {
761 ALOGE("userial_vendor_open returns err");
762 retval = -1;
763 } else {
764 /* Clock on */
765 userial_clock_operation(fd, USERIAL_OP_CLK_ON);
766 ALOGD("userial clock on");
767 if(strcmp(bt_version, "true") == 0) {
768 property_get("ro.bluetooth.wipower", wipower_status, false);
769 if(strcmp(wipower_status, "true") == 0) {
770 check_embedded_mode(fd);
771 } else {
772 ALOGI("Wipower not enabled");
773 }
774 }
775 ALOGV("rome_soc_init is started");
776 property_set("wc_transport.soc_initialized", "0");
777 #ifdef READ_BT_ADDR_FROM_PROP
778 /*Give priority to read BD address from boot property*/
779 ignore_boot_prop = FALSE;
780 if (property_get(BLUETOOTH_MAC_ADDR_BOOT_PROPERTY, bd_addr, NULL)) {
781 ALOGV("BD address read from Boot property: %s\n", bd_addr);
782 tok = strtok(bd_addr, ":");
783 while (tok != NULL) {
784 ALOGV("bd add [%d]: %d ", i, strtol(tok, NULL, 16));
785 if (i>=6) {
786 ALOGE("bd property of invalid length");
787 ignore_boot_prop = TRUE;
788 break;
789 }
790 if (!validate_tok(tok)) {
791 ALOGE("Invalid token in BD address");
792 ignore_boot_prop = TRUE;
793 break;
794 }
795 local_bd_addr_from_prop[5-i] = strtol(tok, NULL, 16);
796 tok = strtok(NULL, ":");
797 i++;
798 }
799 if (i == 6 && !ignore_boot_prop) {
800 ALOGV("Valid BD address read from prop");
801 memcpy(vnd_local_bd_addr, local_bd_addr_from_prop, sizeof(vnd_local_bd_addr));
802 ignore_boot_prop = FALSE;
803 } else {
804 ALOGE("There are not enough tokens in BD addr");
805 ignore_boot_prop = TRUE;
806 }
807 } else {
808 ALOGE("BD address boot property not set");
809 ignore_boot_prop = TRUE;
810 }
811 #endif //READ_BT_ADDR_FROM_PROP
812 #ifdef BT_NV_SUPPORT
813 /* Always read BD address from NV file */
814 if(ignore_boot_prop && !bt_vendor_nv_read(1, vnd_local_bd_addr))
815 {
816 /* Since the BD address is configured in boot time We should not be here */
817 ALOGI("Failed to read BD address. Use the one from bluedroid stack/ftm");
818 }
819 #endif //BT_NV_SUPPORT
820 if(rome_soc_init(fd,vnd_local_bd_addr)<0) {
821 retval = -1;
822 } else {
823 ALOGV("rome_soc_init is completed");
824 property_set("wc_transport.soc_initialized", "1");
825 skip_init = false;
826 }
827 }
828 }
829
830 property_set("wc_transport.clean_up","0");
831 if (retval != -1) {
832 #ifdef BT_SOC_TYPE_ROME
833 start_hci_filter();
834 if (is_ant_req) {
835 ALOGV("connect to ant channel");
836 ant_fd = fd_filter = connect_to_local_socket("ant_sock");
837 }
838 else
839 #endif
840 {
841 ALOGV("connect to bt channel");
842 vnd_userial.fd = fd_filter = connect_to_local_socket("bt_sock");
843 }
844
845 if (fd_filter != -1) {
846 ALOGV("%s: received the socket fd: %d is_ant_req: %d\n",
847 __func__, fd_filter, is_ant_req);
848 if((strcmp(bt_version, "true") == 0) && !is_ant_req) {
849 if (rome_ver >= ROME_VER_3_0) {
850 /* get rome supported feature request */
851 ALOGE("%s: %x08 %0x", __FUNCTION__,rome_ver, ROME_VER_3_0);
852 rome_get_addon_feature_list(fd_filter);
853 }
854 }
855
856 if (!skip_init) {
857 /* skip if already sent */
858 enable_controller_log(fd_filter);
859 skip_init = true;
860 }
861
862 for (idx=0; idx < CH_MAX; idx++)
863 (*fd_array)[idx] = fd_filter;
864 retval = 1;
865 }
866 else {
867 retval = -1;
868 }
869 }
870
871 if (fd >= 0) {
872 userial_clock_operation(fd, USERIAL_OP_CLK_OFF);
873 close(fd);
874 }
875 }
876 break;
877 default:
878 ALOGE("Unknown btSocType: 0x%x", btSocType);
879 break;
880 }
881 }
882 break;
883 #ifdef BT_SOC_TYPE_ROME
884 #ifdef ENABLE_ANT
885 case BT_VND_OP_ANT_USERIAL_CLOSE:
886 {
887 ALOGI("bt-vendor : BT_VND_OP_ANT_USERIAL_CLOSE");
888 property_set("wc_transport.clean_up","1");
889 if (ant_fd != -1) {
890 ALOGE("closing ant_fd");
891 close(ant_fd);
892 ant_fd = -1;
893 }
894 }
895 break;
896 #endif
897 #endif
898 case BT_VND_OP_USERIAL_CLOSE:
899 {
900 ALOGI("bt-vendor : BT_VND_OP_USERIAL_CLOSE btSocType: %d", btSocType);
901 switch(btSocType)
902 {
903 case BT_SOC_DEFAULT:
904 bt_hci_deinit_transport(pFd);
905 break;
906
907 case BT_SOC_ROME:
908 case BT_SOC_AR3K:
909 property_set("wc_transport.clean_up","1");
910 userial_vendor_close();
911 break;
912 default:
913 ALOGE("Unknown btSocType: 0x%x", btSocType);
914 break;
915 }
916 }
917 break;
918
919 case BT_VND_OP_GET_LPM_IDLE_TIMEOUT:
920 {
921 uint32_t *timeout_ms = (uint32_t *) param;
922 *timeout_ms = 1000;
923 }
924 break;
925
926 case BT_VND_OP_LPM_SET_MODE:
927 if(btSocType == BT_SOC_AR3K) {
928 uint8_t *mode = (uint8_t *) param;
929
930 if (*mode) {
931 lpm_set_ar3k(UPIO_LPM_MODE, UPIO_ASSERT, 0);
932 }
933 else {
934 lpm_set_ar3k(UPIO_LPM_MODE, UPIO_DEASSERT, 0);
935 }
936 if (bt_vendor_cbacks )
937 bt_vendor_cbacks->lpm_cb(BT_VND_OP_RESULT_SUCCESS);
938 }
939 else {
940 if (bt_vendor_cbacks)
941 bt_vendor_cbacks->lpm_cb(BT_VND_OP_RESULT_SUCCESS); //dummy
942 }
943 break;
944
945 case BT_VND_OP_LPM_WAKE_SET_STATE:
946 {
947 switch(btSocType)
948 {
949 case BT_SOC_ROME:
950 {
951 uint8_t *state = (uint8_t *) param;
952 uint8_t wake_assert = (*state == BT_VND_LPM_WAKE_ASSERT) ? \
953 BT_VND_LPM_WAKE_ASSERT : BT_VND_LPM_WAKE_DEASSERT;
954
955 if (wake_assert == 0)
956 ALOGV("ASSERT: Waking up BT-Device");
957 else if (wake_assert == 1)
958 ALOGV("DEASSERT: Allowing BT-Device to Sleep");
959
960 #ifdef QCOM_BT_SIBS_ENABLE
961 if(bt_vendor_cbacks){
962 ALOGI("Invoking HCI H4 callback function");
963 bt_vendor_cbacks->lpm_set_state_cb(wake_assert);
964 }
965 #endif
966 }
967 break;
968 case BT_SOC_AR3K:
969 {
970 uint8_t *state = (uint8_t *) param;
971 uint8_t wake_assert = (*state == BT_VND_LPM_WAKE_ASSERT) ? \
972 UPIO_ASSERT : UPIO_DEASSERT;
973 lpm_set_ar3k(UPIO_BT_WAKE, wake_assert, 0);
974 }
975 case BT_SOC_DEFAULT:
976 break;
977 default:
978 ALOGE("Unknown btSocType: 0x%x", btSocType);
979 break;
980 }
981 }
982 break;
983 case BT_VND_OP_EPILOG:
984 {
985 #if (HW_NEED_END_WITH_HCI_RESET == FALSE)
986 if (bt_vendor_cbacks)
987 {
988 bt_vendor_cbacks->epilog_cb(BT_VND_OP_RESULT_SUCCESS);
989 }
990 #else
991 switch(btSocType)
992 {
993 case BT_SOC_ROME:
994 {
995 char value[PROPERTY_VALUE_MAX] = {'\0'};
996 property_get("wc_transport.hci_filter_status", value, "0");
997 if(is_soc_initialized()&& (strcmp(value,"1") == 0))
998 {
999 hw_epilog_process();
1000 }
1001 else
1002 {
1003 if (bt_vendor_cbacks)
1004 {
1005 ALOGE("vendor lib epilog process aborted");
1006 bt_vendor_cbacks->epilog_cb(BT_VND_OP_RESULT_SUCCESS);
1007 }
1008 }
1009 }
1010 break;
1011 default:
1012 hw_epilog_process();
1013 break;
1014 }
1015 #endif
1016 }
1017 break;
1018 case BT_VND_OP_GET_LINESPEED:
1019 {
1020 retval = -1;
1021 switch(btSocType)
1022 {
1023 case BT_SOC_ROME:
1024 if(!is_soc_initialized()) {
1025 ALOGE("BT_VND_OP_GET_LINESPEED: error"
1026 " - transport driver not initialized!");
1027 }else {
1028 retval = 3000000;
1029 }
1030 break;
1031 default:
1032 retval = userial_vendor_get_baud();
1033 break;
1034 }
1035 break;
1036 }
1037 }
1038
1039 return retval;
1040 }
1041
ssr_cleanup(void)1042 static void ssr_cleanup(void) {
1043 int pwr_state=BT_VND_PWR_OFF;
1044
1045 ALOGI("ssr_cleanup");
1046
1047 if ((btSocType = get_bt_soc_type()) < 0) {
1048 ALOGE("%s: Failed to detect BT SOC Type", __FUNCTION__);
1049 return;
1050 }
1051
1052 if (btSocType == BT_SOC_ROME) {
1053 #ifdef BT_SOC_TYPE_ROME
1054 #ifdef ENABLE_ANT
1055 /*Close both ANT channel*/
1056 op(BT_VND_OP_ANT_USERIAL_CLOSE, NULL);
1057 #endif
1058 #endif
1059 /*Close both ANT channel*/
1060 op(BT_VND_OP_USERIAL_CLOSE, NULL);
1061 /*CTRL OFF twice to make sure hw
1062 * turns off*/
1063 op(BT_VND_OP_POWER_CTRL, &pwr_state);
1064
1065 }
1066
1067 #ifdef BT_SOC_TYPE_ROME
1068 /*Generally switching of chip should be enough*/
1069 op(BT_VND_OP_POWER_CTRL, &pwr_state);
1070 #endif
1071 bt_vendor_cbacks = NULL;
1072 }
1073
1074
1075 /** Closes the interface */
cleanup(void)1076 static void cleanup( void )
1077 {
1078 ALOGI("cleanup");
1079 bt_vendor_cbacks = NULL;
1080
1081 #ifdef WIFI_BT_STATUS_SYNC
1082 isInit = 0;
1083 #endif /* WIFI_BT_STATUS_SYNC */
1084 }
1085
1086 // Entry point of DLib
1087 const bt_vendor_interface_t BLUETOOTH_VENDOR_LIB_INTERFACE = {
1088 sizeof(bt_vendor_interface_t),
1089 init,
1090 op,
1091 cleanup,
1092 ssr_cleanup
1093 };
1094