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 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 1042static 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 */ 1076static 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 1087const 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