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******************************************************************************/ 51extern int hw_config(int nState); 52 53extern int is_hw_ready(); 54extern int rome_soc_init(int fd, char *bdaddr); 55extern int check_embedded_mode(int fd); 56extern int rome_get_addon_feature_list(int fd); 57extern int rome_ver; 58extern int enable_controller_log(int fd); 59/****************************************************************************** 60** Variables 61******************************************************************************/ 62int pFd[2] = {0,}; 63#ifdef BT_SOC_TYPE_ROME 64int ant_fd; 65#endif 66bt_vendor_callbacks_t *bt_vendor_cbacks = NULL; 67uint8_t vnd_local_bd_addr[6]={0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 68static int btSocType = BT_SOC_DEFAULT; 69static int rfkill_id = -1; 70static char *rfkill_state = NULL; 71bool enable_extldo = FALSE; 72 73static 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) 80void 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 89static const char WIFI_PROP_NAME[] = "wlan.driver.status"; 90static const char SERVICE_PROP_NAME[] = "bluetooth.hsic_ctrl"; 91static const char BT_STATUS_NAME[] = "bluetooth.enabled"; 92static const char WIFI_SERVICE_PROP[] = "wlan.hsic_ctrl"; 93 94#define WIFI_BT_STATUS_LOCK "/data/connectivity/wifi_bt_lock" 95int isInit=0; 96#endif /* WIFI_BT_STATUS_SYNC */ 97bool 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******************************************************************************/ 106int readTrpState(); 107int ath3k_init(int fd, int speed, int init_speed, char *bdaddr, struct termios *ti); 108int userial_clock_operation(int fd, int cmd); 109int rome_soc_init(int fd, char *bdaddr); 110void lpm_set_ar3k(uint8_t pio, uint8_t action, uint8_t polarity); 111int userial_vendor_get_baud(void); 112 113 114/****************************************************************************** 115** Functions 116******************************************************************************/ 117#ifdef WIFI_BT_STATUS_SYNC 118int 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 130int 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 146int 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 162int bt_semaphore_destroy(int fd) 163{ 164 if (fd < 0) 165 return -1; 166 167 return close (fd); 168} 169 170int 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 */ 194static 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 223bool 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 270void 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 286void 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 */ 318static 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 480done: 481 if (fd >= 0) 482 close(fd); 483 484 return 0; 485} 486 487/***************************************************************************** 488** 489** BLUETOOTH VENDOR INTERFACE LIBRARY FUNCTIONS 490** 491*****************************************************************************/ 492 493static 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 548static 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 574int 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 596bool 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 */ 619static 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 retval = bt_powerup(nState); 668 default: 669 break; 670 } 671 } 672 break; 673 674 case BT_VND_OP_FW_CFG: 675 { 676 // call hciattach to initalize the stack 677 if(bt_vendor_cbacks){ 678 ALOGI("Bluetooth Firmware and transport layer are initialized"); 679 bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_SUCCESS); 680 } 681 else{ 682 ALOGE("bt_vendor_cbacks is null"); 683 ALOGE("Error : hci, smd initialization Error"); 684 retval = -1; 685 } 686 } 687 break; 688 689 case BT_VND_OP_SCO_CFG: 690 { 691 if (bt_vendor_cbacks) 692 bt_vendor_cbacks->scocfg_cb(BT_VND_OP_RESULT_SUCCESS); //dummy 693 } 694 break; 695#ifdef BT_SOC_TYPE_ROME 696#ifdef ENABLE_ANT 697 case BT_VND_OP_ANT_USERIAL_OPEN: 698 ALOGI("bt-vendor : BT_VND_OP_ANT_USERIAL_OPEN"); 699 is_ant_req = true; 700 //fall through 701#endif 702#endif 703 case BT_VND_OP_USERIAL_OPEN: 704 { 705 int (*fd_array)[] = (int (*)[]) param; 706 int fd = -1, fd_filter = -1; 707 ALOGI("bt-vendor : BT_VND_OP_USERIAL_OPEN"); 708 switch(btSocType) 709 { 710 case BT_SOC_DEFAULT: 711 { 712 if(bt_hci_init_transport(pFd) != -1){ 713 int (*fd_array)[] = (int (*) []) param; 714 715 (*fd_array)[CH_CMD] = pFd[0]; 716 (*fd_array)[CH_EVT] = pFd[0]; 717 (*fd_array)[CH_ACL_OUT] = pFd[1]; 718 (*fd_array)[CH_ACL_IN] = pFd[1]; 719 } 720 else { 721 retval = -1; 722 break; 723 } 724 retval = 2; 725 } 726 break; 727 case BT_SOC_AR3K: 728 { 729 int idx; 730 fd = userial_vendor_open((tUSERIAL_CFG *) &userial_init_cfg); 731 if (fd != -1) { 732 for (idx=0; idx < CH_MAX; idx++) 733 (*fd_array)[idx] = fd; 734 retval = 1; 735 } 736 else { 737 retval = -1; 738 break; 739 } 740 741 /* Vendor Specific Process should happened during userial_open process 742 After userial_open, rx read thread is running immediately, 743 so it will affect VS event read process. 744 */ 745 if(ath3k_init(fd,3000000,115200,NULL,&vnd_userial.termios)<0) 746 retval = -1; 747 } 748 break; 749 case BT_SOC_ROME: 750 { 751 int idx; 752 property_get("persist.BT3_2.version", bt_version, false); 753 if (!is_soc_initialized()) { 754 fd = userial_vendor_open((tUSERIAL_CFG *) &userial_init_cfg); 755 if (fd < 0) { 756 ALOGE("userial_vendor_open returns err"); 757 retval = -1; 758 } else { 759 /* Clock on */ 760 userial_clock_operation(fd, USERIAL_OP_CLK_ON); 761 ALOGD("userial clock on"); 762 if(strcmp(bt_version, "true") == 0) { 763 property_get("ro.bluetooth.wipower", wipower_status, false); 764 if(strcmp(wipower_status, "true") == 0) { 765 check_embedded_mode(fd); 766 } else { 767 ALOGI("Wipower not enabled"); 768 } 769 } 770 ALOGV("rome_soc_init is started"); 771 property_set("wc_transport.soc_initialized", "0"); 772#ifdef READ_BT_ADDR_FROM_PROP 773 /*Give priority to read BD address from boot property*/ 774 ignore_boot_prop = FALSE; 775 if (property_get(BLUETOOTH_MAC_ADDR_BOOT_PROPERTY, bd_addr, NULL)) { 776 ALOGV("BD address read from Boot property: %s\n", bd_addr); 777 tok = strtok(bd_addr, ":"); 778 while (tok != NULL) { 779 ALOGV("bd add [%d]: %d ", i, strtol(tok, NULL, 16)); 780 if (i>=6) { 781 ALOGE("bd property of invalid length"); 782 ignore_boot_prop = TRUE; 783 break; 784 } 785 if (!validate_tok(tok)) { 786 ALOGE("Invalid token in BD address"); 787 ignore_boot_prop = TRUE; 788 break; 789 } 790 local_bd_addr_from_prop[5-i] = strtol(tok, NULL, 16); 791 tok = strtok(NULL, ":"); 792 i++; 793 } 794 if (i == 6 && !ignore_boot_prop) { 795 ALOGV("Valid BD address read from prop"); 796 memcpy(vnd_local_bd_addr, local_bd_addr_from_prop, sizeof(vnd_local_bd_addr)); 797 ignore_boot_prop = FALSE; 798 } else { 799 ALOGE("There are not enough tokens in BD addr"); 800 ignore_boot_prop = TRUE; 801 } 802 } else { 803 ALOGE("BD address boot property not set"); 804 ignore_boot_prop = TRUE; 805 } 806#endif //READ_BT_ADDR_FROM_PROP 807#ifdef BT_NV_SUPPORT 808 /* Always read BD address from NV file */ 809 if(ignore_boot_prop && !bt_vendor_nv_read(1, vnd_local_bd_addr)) 810 { 811 /* Since the BD address is configured in boot time We should not be here */ 812 ALOGI("Failed to read BD address. Use the one from bluedroid stack/ftm"); 813 } 814#endif //BT_NV_SUPPORT 815 if(rome_soc_init(fd,vnd_local_bd_addr)<0) { 816 retval = -1; 817 } else { 818 ALOGV("rome_soc_init is completed"); 819 property_set("wc_transport.soc_initialized", "1"); 820 skip_init = false; 821 } 822 } 823 } 824 825 property_set("wc_transport.clean_up","0"); 826 if (retval != -1) { 827#ifdef BT_SOC_TYPE_ROME 828 start_hci_filter(); 829 if (is_ant_req) { 830 ALOGV("connect to ant channel"); 831 ant_fd = fd_filter = connect_to_local_socket("ant_sock"); 832 } 833 else 834#endif 835 { 836 ALOGV("connect to bt channel"); 837 vnd_userial.fd = fd_filter = connect_to_local_socket("bt_sock"); 838 } 839 840 if (fd_filter != -1) { 841 ALOGV("%s: received the socket fd: %d is_ant_req: %d\n", 842 __func__, fd_filter, is_ant_req); 843 if((strcmp(bt_version, "true") == 0) && !is_ant_req) { 844 if (rome_ver >= ROME_VER_3_0) { 845 /* get rome supported feature request */ 846 ALOGE("%s: %x08 %0x", __FUNCTION__,rome_ver, ROME_VER_3_0); 847 rome_get_addon_feature_list(fd_filter); 848 } 849 } 850 851 if (!skip_init) { 852 /* skip if already sent */ 853 enable_controller_log(fd_filter); 854 skip_init = true; 855 } 856 857 for (idx=0; idx < CH_MAX; idx++) 858 (*fd_array)[idx] = fd_filter; 859 retval = 1; 860 } 861 else { 862 retval = -1; 863 } 864 } 865 866 if (fd >= 0) { 867 userial_clock_operation(fd, USERIAL_OP_CLK_OFF); 868 close(fd); 869 } 870 } 871 break; 872 default: 873 ALOGE("Unknown btSocType: 0x%x", btSocType); 874 break; 875 } 876 } 877 break; 878#ifdef BT_SOC_TYPE_ROME 879#ifdef ENABLE_ANT 880 case BT_VND_OP_ANT_USERIAL_CLOSE: 881 { 882 ALOGI("bt-vendor : BT_VND_OP_ANT_USERIAL_CLOSE"); 883 property_set("wc_transport.clean_up","1"); 884 if (ant_fd != -1) { 885 ALOGE("closing ant_fd"); 886 close(ant_fd); 887 ant_fd = -1; 888 } 889 } 890 break; 891#endif 892#endif 893 case BT_VND_OP_USERIAL_CLOSE: 894 { 895 ALOGI("bt-vendor : BT_VND_OP_USERIAL_CLOSE btSocType: %d", btSocType); 896 switch(btSocType) 897 { 898 case BT_SOC_DEFAULT: 899 bt_hci_deinit_transport(pFd); 900 break; 901 902 case BT_SOC_ROME: 903 case BT_SOC_AR3K: 904 property_set("wc_transport.clean_up","1"); 905 userial_vendor_close(); 906 break; 907 default: 908 ALOGE("Unknown btSocType: 0x%x", btSocType); 909 break; 910 } 911 } 912 break; 913 914 case BT_VND_OP_GET_LPM_IDLE_TIMEOUT: 915 if (btSocType == BT_SOC_AR3K) { 916 uint32_t *timeout_ms = (uint32_t *) param; 917 *timeout_ms = 1000; 918 } 919 break; 920 921 case BT_VND_OP_LPM_SET_MODE: 922 if(btSocType == BT_SOC_AR3K) { 923 uint8_t *mode = (uint8_t *) param; 924 925 if (*mode) { 926 lpm_set_ar3k(UPIO_LPM_MODE, UPIO_ASSERT, 0); 927 } 928 else { 929 lpm_set_ar3k(UPIO_LPM_MODE, UPIO_DEASSERT, 0); 930 } 931 if (bt_vendor_cbacks ) 932 bt_vendor_cbacks->lpm_cb(BT_VND_OP_RESULT_SUCCESS); 933 } 934 else { 935 if (bt_vendor_cbacks) 936 bt_vendor_cbacks->lpm_cb(BT_VND_OP_RESULT_SUCCESS); //dummy 937 } 938 break; 939 940 case BT_VND_OP_LPM_WAKE_SET_STATE: 941 { 942 switch(btSocType) 943 { 944 case BT_SOC_ROME: 945 { 946 uint8_t *state = (uint8_t *) param; 947 uint8_t wake_assert = (*state == BT_VND_LPM_WAKE_ASSERT) ? \ 948 BT_VND_LPM_WAKE_ASSERT : BT_VND_LPM_WAKE_DEASSERT; 949 950 if (wake_assert == 0) 951 ALOGV("ASSERT: Waking up BT-Device"); 952 else if (wake_assert == 1) 953 ALOGV("DEASSERT: Allowing BT-Device to Sleep"); 954 955#ifdef QCOM_BT_SIBS_ENABLE 956 if(bt_vendor_cbacks){ 957 ALOGI("Invoking HCI H4 callback function"); 958 bt_vendor_cbacks->lpm_set_state_cb(wake_assert); 959 } 960#endif 961 } 962 break; 963 case BT_SOC_AR3K: 964 { 965 uint8_t *state = (uint8_t *) param; 966 uint8_t wake_assert = (*state == BT_VND_LPM_WAKE_ASSERT) ? \ 967 UPIO_ASSERT : UPIO_DEASSERT; 968 lpm_set_ar3k(UPIO_BT_WAKE, wake_assert, 0); 969 } 970 case BT_SOC_DEFAULT: 971 break; 972 default: 973 ALOGE("Unknown btSocType: 0x%x", btSocType); 974 break; 975 } 976 } 977 break; 978 case BT_VND_OP_EPILOG: 979 { 980#if (HW_NEED_END_WITH_HCI_RESET == FALSE) 981 if (bt_vendor_cbacks) 982 { 983 bt_vendor_cbacks->epilog_cb(BT_VND_OP_RESULT_SUCCESS); 984 } 985#else 986 switch(btSocType) 987 { 988 case BT_SOC_ROME: 989 { 990 char value[PROPERTY_VALUE_MAX] = {'\0'}; 991 property_get("wc_transport.hci_filter_status", value, "0"); 992 if(is_soc_initialized()&& (strcmp(value,"1") == 0)) 993 { 994 hw_epilog_process(); 995 } 996 else 997 { 998 if (bt_vendor_cbacks) 999 { 1000 ALOGE("vendor lib epilog process aborted"); 1001 bt_vendor_cbacks->epilog_cb(BT_VND_OP_RESULT_SUCCESS); 1002 } 1003 } 1004 } 1005 break; 1006 default: 1007 hw_epilog_process(); 1008 break; 1009 } 1010#endif 1011 } 1012 break; 1013 case BT_VND_OP_GET_LINESPEED: 1014 { 1015 retval = -1; 1016 switch(btSocType) 1017 { 1018 case BT_SOC_ROME: 1019 if(!is_soc_initialized()) { 1020 ALOGE("BT_VND_OP_GET_LINESPEED: error" 1021 " - transport driver not initialized!"); 1022 }else { 1023 retval = 3000000; 1024 } 1025 break; 1026 default: 1027 retval = userial_vendor_get_baud(); 1028 break; 1029 } 1030 break; 1031 } 1032 } 1033 1034 return retval; 1035} 1036 1037static void ssr_cleanup(void) { 1038 int pwr_state=BT_VND_PWR_OFF; 1039 1040 ALOGI("ssr_cleanup"); 1041 1042 if ((btSocType = get_bt_soc_type()) < 0) { 1043 ALOGE("%s: Failed to detect BT SOC Type", __FUNCTION__); 1044 return; 1045 } 1046 1047 if (btSocType == BT_SOC_ROME) { 1048#ifdef BT_SOC_TYPE_ROME 1049#ifdef ENABLE_ANT 1050 /*Close both ANT channel*/ 1051 op(BT_VND_OP_ANT_USERIAL_CLOSE, NULL); 1052#endif 1053#endif 1054 /*Close both ANT channel*/ 1055 op(BT_VND_OP_USERIAL_CLOSE, NULL); 1056 /*CTRL OFF twice to make sure hw 1057 * turns off*/ 1058 op(BT_VND_OP_POWER_CTRL, &pwr_state); 1059 1060 } 1061 1062#ifdef BT_SOC_TYPE_ROME 1063 /*Generally switching of chip should be enough*/ 1064 op(BT_VND_OP_POWER_CTRL, &pwr_state); 1065#endif 1066 bt_vendor_cbacks = NULL; 1067} 1068 1069 1070/** Closes the interface */ 1071static void cleanup( void ) 1072{ 1073 ALOGI("cleanup"); 1074 bt_vendor_cbacks = NULL; 1075 1076#ifdef WIFI_BT_STATUS_SYNC 1077 isInit = 0; 1078#endif /* WIFI_BT_STATUS_SYNC */ 1079} 1080 1081// Entry point of DLib 1082const bt_vendor_interface_t BLUETOOTH_VENDOR_LIB_INTERFACE = { 1083 sizeof(bt_vendor_interface_t), 1084 init, 1085 op, 1086 cleanup, 1087 ssr_cleanup 1088}; 1089