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