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