1 /****************************************************************************** 2 * 3 * Copyright (C) 2009-2012 Broadcom Corporation 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at: 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 ******************************************************************************/ 18 19 /****************************************************************************** 20 * 21 * Filename: hardware.c 22 * 23 * Description: Contains controller-specific functions, like 24 * firmware patch download 25 * low power mode operations 26 * 27 ******************************************************************************/ 28 29 #define LOG_TAG "bt_hwcfg" 30 31 #include <utils/Log.h> 32 #include <sys/types.h> 33 #include <stdbool.h> 34 #include <sys/stat.h> 35 #include <signal.h> 36 #include <time.h> 37 #include <errno.h> 38 #include <fcntl.h> 39 #include <dirent.h> 40 #include <ctype.h> 41 #include <cutils/properties.h> 42 #include <stdlib.h> 43 #include <string.h> 44 #include <stdio.h> 45 #include <unistd.h> 46 #include "bt_hci_bdroid.h" 47 #include "bt_vendor_brcm.h" 48 #include "esco_parameters.h" 49 #include "userial.h" 50 #include "userial_vendor.h" 51 #include "upio.h" 52 53 /****************************************************************************** 54 ** Constants & Macros 55 ******************************************************************************/ 56 57 #ifndef BTHW_DBG 58 #define BTHW_DBG FALSE 59 #endif 60 61 #if (BTHW_DBG == TRUE) 62 #define BTHWDBG(param, ...) {ALOGD(param, ## __VA_ARGS__);} 63 #else 64 #define BTHWDBG(param, ...) {} 65 #endif 66 67 #define FW_PATCHFILE_EXTENSION ".hcd" 68 #define FW_PATCHFILE_EXTENSION_LEN 4 69 #define FW_PATCHFILE_PATH_MAXLEN 248 /* Local_Name length of return of 70 HCI_Read_Local_Name */ 71 72 #define HCI_CMD_MAX_LEN 258 73 74 #define HCI_RESET 0x0C03 75 #define HCI_VSC_WRITE_UART_CLOCK_SETTING 0xFC45 76 #define HCI_VSC_UPDATE_BAUDRATE 0xFC18 77 #define HCI_READ_LOCAL_NAME 0x0C14 78 #define HCI_VSC_DOWNLOAD_MINIDRV 0xFC2E 79 #define HCI_VSC_WRITE_BD_ADDR 0xFC01 80 #define HCI_VSC_WRITE_SLEEP_MODE 0xFC27 81 #define HCI_VSC_WRITE_SCO_PCM_INT_PARAM 0xFC1C 82 #define HCI_VSC_WRITE_PCM_DATA_FORMAT_PARAM 0xFC1E 83 #define HCI_VSC_WRITE_I2SPCM_INTERFACE_PARAM 0xFC6D 84 #define HCI_VSC_ENABLE_WBS 0xFC7E 85 #define HCI_VSC_LAUNCH_RAM 0xFC4E 86 #define HCI_READ_LOCAL_BDADDR 0x1009 87 88 #define HCI_EVT_CMD_CMPL_STATUS_RET_BYTE 5 89 #define HCI_EVT_CMD_CMPL_LOCAL_NAME_STRING 6 90 #define HCI_EVT_CMD_CMPL_LOCAL_BDADDR_ARRAY 6 91 #define HCI_EVT_CMD_CMPL_OPCODE 3 92 #define LPM_CMD_PARAM_SIZE 12 93 #define UPDATE_BAUDRATE_CMD_PARAM_SIZE 6 94 #define HCI_CMD_PREAMBLE_SIZE 3 95 #define HCD_REC_PAYLOAD_LEN_BYTE 2 96 #define BD_ADDR_LEN 6 97 #define LOCAL_NAME_BUFFER_LEN 32 98 #define LOCAL_BDADDR_PATH_BUFFER_LEN 256 99 100 #define STREAM_TO_UINT16(u16, p) {u16 = ((uint16_t)(*(p)) + (((uint16_t)(*((p) + 1))) << 8)); (p) += 2;} 101 #define UINT8_TO_STREAM(p, u8) {*(p)++ = (uint8_t)(u8);} 102 #define UINT16_TO_STREAM(p, u16) {*(p)++ = (uint8_t)(u16); *(p)++ = (uint8_t)((u16) >> 8);} 103 #define UINT32_TO_STREAM(p, u32) {*(p)++ = (uint8_t)(u32); *(p)++ = (uint8_t)((u32) >> 8); *(p)++ = (uint8_t)((u32) >> 16); *(p)++ = (uint8_t)((u32) >> 24);} 104 105 #define SCO_INTERFACE_PCM 0 106 #define SCO_INTERFACE_I2S 1 107 108 /* one byte is for enable/disable 109 next 2 bytes are for codec type */ 110 #define SCO_CODEC_PARAM_SIZE 3 111 112 /****************************************************************************** 113 ** Local type definitions 114 ******************************************************************************/ 115 116 /* Hardware Configuration State */ 117 enum { 118 HW_CFG_START = 1, 119 HW_CFG_SET_UART_CLOCK, 120 HW_CFG_SET_UART_BAUD_1, 121 HW_CFG_READ_LOCAL_NAME, 122 HW_CFG_DL_MINIDRIVER, 123 HW_CFG_DL_FW_PATCH, 124 HW_CFG_SET_UART_BAUD_2, 125 HW_CFG_SET_BD_ADDR 126 #if (USE_CONTROLLER_BDADDR == TRUE) 127 , HW_CFG_READ_BD_ADDR 128 #endif 129 }; 130 131 /* h/w config control block */ 132 typedef struct 133 { 134 uint8_t state; /* Hardware configuration state */ 135 int fw_fd; /* FW patch file fd */ 136 uint8_t f_set_baud_2; /* Baud rate switch state */ 137 char local_chip_name[LOCAL_NAME_BUFFER_LEN]; 138 } bt_hw_cfg_cb_t; 139 140 /* low power mode parameters */ 141 typedef struct 142 { 143 uint8_t sleep_mode; /* 0(disable),1(UART),9(H5) */ 144 uint8_t host_stack_idle_threshold; /* Unit scale 300ms/25ms */ 145 uint8_t host_controller_idle_threshold; /* Unit scale 300ms/25ms */ 146 uint8_t bt_wake_polarity; /* 0=Active Low, 1= Active High */ 147 uint8_t host_wake_polarity; /* 0=Active Low, 1= Active High */ 148 uint8_t allow_host_sleep_during_sco; 149 uint8_t combine_sleep_mode_and_lpm; 150 uint8_t enable_uart_txd_tri_state; /* UART_TXD Tri-State */ 151 uint8_t sleep_guard_time; /* sleep guard time in 12.5ms */ 152 uint8_t wakeup_guard_time; /* wakeup guard time in 12.5ms */ 153 uint8_t txd_config; /* TXD is high in sleep state */ 154 uint8_t pulsed_host_wake; /* pulsed host wake if mode = 1 */ 155 } bt_lpm_param_t; 156 157 /* Firmware re-launch settlement time */ 158 typedef struct { 159 const char *chipset_name; 160 const uint32_t delay_time; 161 } fw_settlement_entry_t; 162 163 164 /****************************************************************************** 165 ** Externs 166 ******************************************************************************/ 167 168 void hw_config_cback(void *p_evt_buf); 169 extern uint8_t vnd_local_bd_addr[BD_ADDR_LEN]; 170 171 172 /****************************************************************************** 173 ** Static variables 174 ******************************************************************************/ 175 176 static char fw_patchfile_path[256] = FW_PATCHFILE_LOCATION; 177 static char fw_patchfile_name[128] = { 0 }; 178 #if (VENDOR_LIB_RUNTIME_TUNING_ENABLED == TRUE) 179 static int fw_patch_settlement_delay = -1; 180 #endif 181 182 static int wbs_sample_rate = SCO_WBS_SAMPLE_RATE; 183 static bt_hw_cfg_cb_t hw_cfg_cb; 184 185 static bt_lpm_param_t lpm_param = 186 { 187 LPM_SLEEP_MODE, 188 LPM_IDLE_THRESHOLD, 189 LPM_HC_IDLE_THRESHOLD, 190 LPM_BT_WAKE_POLARITY, 191 LPM_HOST_WAKE_POLARITY, 192 LPM_ALLOW_HOST_SLEEP_DURING_SCO, 193 LPM_COMBINE_SLEEP_MODE_AND_LPM, 194 LPM_ENABLE_UART_TXD_TRI_STATE, 195 0, /* not applicable */ 196 0, /* not applicable */ 197 0, /* not applicable */ 198 LPM_PULSED_HOST_WAKE 199 }; 200 201 /* need to update the bt_sco_i2spcm_param as well 202 bt_sco_i2spcm_param will be used for WBS setting 203 update the bt_sco_param and bt_sco_i2spcm_param */ 204 static uint8_t bt_sco_param[SCO_PCM_PARAM_SIZE] = 205 { 206 SCO_PCM_ROUTING, 207 SCO_PCM_IF_CLOCK_RATE, 208 SCO_PCM_IF_FRAME_TYPE, 209 SCO_PCM_IF_SYNC_MODE, 210 SCO_PCM_IF_CLOCK_MODE 211 }; 212 213 static uint8_t bt_pcm_data_fmt_param[PCM_DATA_FORMAT_PARAM_SIZE] = 214 { 215 PCM_DATA_FMT_SHIFT_MODE, 216 PCM_DATA_FMT_FILL_BITS, 217 PCM_DATA_FMT_FILL_METHOD, 218 PCM_DATA_FMT_FILL_NUM, 219 PCM_DATA_FMT_JUSTIFY_MODE 220 }; 221 222 static uint8_t bt_sco_i2spcm_param[SCO_I2SPCM_PARAM_SIZE] = 223 { 224 SCO_I2SPCM_IF_MODE, 225 SCO_I2SPCM_IF_ROLE, 226 SCO_I2SPCM_IF_SAMPLE_RATE, 227 SCO_I2SPCM_IF_CLOCK_RATE 228 }; 229 230 /* 231 * The look-up table of recommended firmware settlement delay (milliseconds) on 232 * known chipsets. 233 */ 234 static const fw_settlement_entry_t fw_settlement_table[] = { 235 {"BCM43241", 200}, 236 {"BCM43341", 100}, 237 {(const char *) NULL, 100} // Giving the generic fw settlement delay setting. 238 }; 239 240 241 /* 242 * NOTICE: 243 * If the platform plans to run I2S interface bus over I2S/PCM port of the 244 * BT Controller with the Host AP, explicitly set "SCO_USE_I2S_INTERFACE = TRUE" 245 * in the correspodning include/vnd_<target>.txt file. 246 * Otherwise, leave SCO_USE_I2S_INTERFACE undefined in the vnd_<target>.txt file. 247 * And, PCM interface will be set as the default bus format running over I2S/PCM 248 * port. 249 */ 250 #if (defined(SCO_USE_I2S_INTERFACE) && SCO_USE_I2S_INTERFACE == TRUE) 251 static uint8_t sco_bus_interface = SCO_INTERFACE_I2S; 252 #else 253 static uint8_t sco_bus_interface = SCO_INTERFACE_PCM; 254 #endif 255 256 #define INVALID_SCO_CLOCK_RATE 0xFF 257 static uint8_t sco_bus_clock_rate = INVALID_SCO_CLOCK_RATE; 258 static uint8_t sco_bus_wbs_clock_rate = INVALID_SCO_CLOCK_RATE; 259 260 /****************************************************************************** 261 ** Static functions 262 ******************************************************************************/ 263 static void hw_sco_i2spcm_config(uint16_t codec); 264 static void hw_sco_i2spcm_config_from_command(void *p_mem, uint16_t codec); 265 266 /****************************************************************************** 267 ** Controller Initialization Static Functions 268 ******************************************************************************/ 269 270 /******************************************************************************* 271 ** 272 ** Function look_up_fw_settlement_delay 273 ** 274 ** Description If FW_PATCH_SETTLEMENT_DELAY_MS has not been explicitly 275 ** re-defined in the platform specific build-time configuration 276 ** file, we will search into the look-up table for a 277 ** recommended firmware settlement delay value. 278 ** 279 ** Although the settlement time might be also related to board 280 ** configurations such as the crystal clocking speed. 281 ** 282 ** Returns Firmware settlement delay 283 ** 284 *******************************************************************************/ 285 uint32_t look_up_fw_settlement_delay (void) 286 { 287 uint32_t ret_value; 288 fw_settlement_entry_t *p_entry; 289 290 if (FW_PATCH_SETTLEMENT_DELAY_MS > 0) 291 { 292 ret_value = FW_PATCH_SETTLEMENT_DELAY_MS; 293 } 294 #if (VENDOR_LIB_RUNTIME_TUNING_ENABLED == TRUE) 295 else if (fw_patch_settlement_delay >= 0) 296 { 297 ret_value = fw_patch_settlement_delay; 298 } 299 #endif 300 else 301 { 302 p_entry = (fw_settlement_entry_t *)fw_settlement_table; 303 304 while (p_entry->chipset_name != NULL) 305 { 306 if (strstr(hw_cfg_cb.local_chip_name, p_entry->chipset_name)!=NULL) 307 { 308 break; 309 } 310 311 p_entry++; 312 } 313 314 ret_value = p_entry->delay_time; 315 } 316 317 BTHWDBG( "Settlement delay -- %d ms", ret_value); 318 319 return (ret_value); 320 } 321 322 /******************************************************************************* 323 ** 324 ** Function ms_delay 325 ** 326 ** Description sleep unconditionally for timeout milliseconds 327 ** 328 ** Returns None 329 ** 330 *******************************************************************************/ 331 void ms_delay (uint32_t timeout) 332 { 333 struct timespec delay; 334 int err; 335 336 if (timeout == 0) 337 return; 338 339 delay.tv_sec = timeout / 1000; 340 delay.tv_nsec = 1000 * 1000 * (timeout%1000); 341 342 /* [u]sleep can't be used because it uses SIGALRM */ 343 do { 344 err = nanosleep(&delay, &delay); 345 } while (err < 0 && errno ==EINTR); 346 } 347 348 /******************************************************************************* 349 ** 350 ** Function line_speed_to_userial_baud 351 ** 352 ** Description helper function converts line speed number into USERIAL baud 353 ** rate symbol 354 ** 355 ** Returns unit8_t (USERIAL baud symbol) 356 ** 357 *******************************************************************************/ 358 uint8_t line_speed_to_userial_baud(uint32_t line_speed) 359 { 360 uint8_t baud; 361 362 if (line_speed == 4000000) 363 baud = USERIAL_BAUD_4M; 364 else if (line_speed == 3000000) 365 baud = USERIAL_BAUD_3M; 366 else if (line_speed == 2000000) 367 baud = USERIAL_BAUD_2M; 368 else if (line_speed == 1000000) 369 baud = USERIAL_BAUD_1M; 370 else if (line_speed == 921600) 371 baud = USERIAL_BAUD_921600; 372 else if (line_speed == 460800) 373 baud = USERIAL_BAUD_460800; 374 else if (line_speed == 230400) 375 baud = USERIAL_BAUD_230400; 376 else if (line_speed == 115200) 377 baud = USERIAL_BAUD_115200; 378 else if (line_speed == 57600) 379 baud = USERIAL_BAUD_57600; 380 else if (line_speed == 19200) 381 baud = USERIAL_BAUD_19200; 382 else if (line_speed == 9600) 383 baud = USERIAL_BAUD_9600; 384 else if (line_speed == 1200) 385 baud = USERIAL_BAUD_1200; 386 else if (line_speed == 600) 387 baud = USERIAL_BAUD_600; 388 else 389 { 390 ALOGE( "userial vendor: unsupported baud speed %d", line_speed); 391 baud = USERIAL_BAUD_115200; 392 } 393 394 return baud; 395 } 396 397 398 /******************************************************************************* 399 ** 400 ** Function hw_strncmp 401 ** 402 ** Description Used to compare two strings in caseless 403 ** 404 ** Returns 0: match, otherwise: not match 405 ** 406 *******************************************************************************/ 407 static int hw_strncmp (const char *p_str1, const char *p_str2, const int len) 408 { 409 int i; 410 411 if (!p_str1 || !p_str2) 412 return (1); 413 414 for (i = 0; i < len; i++) 415 { 416 if (toupper(p_str1[i]) != toupper(p_str2[i])) 417 return (i+1); 418 } 419 420 return 0; 421 } 422 423 /******************************************************************************* 424 ** 425 ** Function hw_config_findpatch 426 ** 427 ** Description Search for a proper firmware patch file 428 ** The selected firmware patch file name with full path 429 ** will be stored in the input string parameter, i.e. 430 ** p_chip_id_str, when returns. 431 ** 432 ** Returns TRUE when found the target patch file, otherwise FALSE 433 ** 434 *******************************************************************************/ 435 static uint8_t hw_config_findpatch(char *p_chip_id_str) 436 { 437 DIR *dirp; 438 struct dirent *dp; 439 int filenamelen; 440 uint8_t retval = FALSE; 441 442 BTHWDBG("Target name = [%s]", p_chip_id_str); 443 444 if (strlen(fw_patchfile_name)> 0) 445 { 446 /* If specific filepath and filename have been given in run-time 447 * configuration /etc/bluetooth/bt_vendor.conf file, we will use them 448 * to concatenate the filename to open rather than searching a file 449 * matching to chipset name in the fw_patchfile_path folder. 450 */ 451 sprintf(p_chip_id_str, "%s", fw_patchfile_path); 452 if (fw_patchfile_path[strlen(fw_patchfile_path)- 1] != '/') 453 { 454 strcat(p_chip_id_str, "/"); 455 } 456 strcat(p_chip_id_str, fw_patchfile_name); 457 458 ALOGI("FW patchfile: %s", p_chip_id_str); 459 return TRUE; 460 } 461 462 if ((dirp = opendir(fw_patchfile_path)) != NULL) 463 { 464 /* Fetch next filename in patchfile directory */ 465 while ((dp = readdir(dirp)) != NULL) 466 { 467 /* Check if filename starts with chip-id name */ 468 if ((hw_strncmp(dp->d_name, p_chip_id_str, strlen(p_chip_id_str)) \ 469 ) == 0) 470 { 471 /* Check if it has .hcd extenstion */ 472 filenamelen = strlen(dp->d_name); 473 if ((filenamelen >= FW_PATCHFILE_EXTENSION_LEN) && 474 ((hw_strncmp( 475 &dp->d_name[filenamelen-FW_PATCHFILE_EXTENSION_LEN], \ 476 FW_PATCHFILE_EXTENSION, \ 477 FW_PATCHFILE_EXTENSION_LEN) \ 478 ) == 0)) 479 { 480 ALOGI("Found patchfile: %s/%s", \ 481 fw_patchfile_path, dp->d_name); 482 483 /* Make sure length does not exceed maximum */ 484 if ((filenamelen + strlen(fw_patchfile_path)) > \ 485 FW_PATCHFILE_PATH_MAXLEN) 486 { 487 ALOGE("Invalid patchfile name (too long)"); 488 } 489 else 490 { 491 memset(p_chip_id_str, 0, FW_PATCHFILE_PATH_MAXLEN); 492 /* Found patchfile. Store location and name */ 493 strcpy(p_chip_id_str, fw_patchfile_path); 494 if (fw_patchfile_path[ \ 495 strlen(fw_patchfile_path)- 1 \ 496 ] != '/') 497 { 498 strcat(p_chip_id_str, "/"); 499 } 500 strcat(p_chip_id_str, dp->d_name); 501 retval = TRUE; 502 } 503 break; 504 } 505 } 506 } 507 508 closedir(dirp); 509 510 if (retval == FALSE) 511 { 512 /* Try again chip name without revision info */ 513 514 int len = strlen(p_chip_id_str); 515 char *p = p_chip_id_str + len - 1; 516 517 /* Scan backward and look for the first alphabet 518 which is not M or m 519 */ 520 while (len > 3) // BCM**** 521 { 522 if ((isdigit(*p)==0) && (*p != 'M') && (*p != 'm')) 523 break; 524 525 p--; 526 len--; 527 } 528 529 if (len > 3) 530 { 531 *p = 0; 532 retval = hw_config_findpatch(p_chip_id_str); 533 } 534 } 535 } 536 else 537 { 538 ALOGE("Could not open %s", fw_patchfile_path); 539 } 540 541 return (retval); 542 } 543 544 /******************************************************************************* 545 ** 546 ** Function hw_config_set_bdaddr 547 ** 548 ** Description Program controller's Bluetooth Device Address 549 ** 550 ** Returns TRUE, if valid address is sent 551 ** FALSE, otherwise 552 ** 553 *******************************************************************************/ 554 static uint8_t hw_config_set_bdaddr(HC_BT_HDR *p_buf) 555 { 556 uint8_t retval = FALSE; 557 uint8_t *p = (uint8_t *) (p_buf + 1); 558 559 ALOGI("Setting local bd addr to %02X:%02X:%02X:%02X:%02X:%02X", 560 vnd_local_bd_addr[0], vnd_local_bd_addr[1], vnd_local_bd_addr[2], 561 vnd_local_bd_addr[3], vnd_local_bd_addr[4], vnd_local_bd_addr[5]); 562 563 UINT16_TO_STREAM(p, HCI_VSC_WRITE_BD_ADDR); 564 *p++ = BD_ADDR_LEN; /* parameter length */ 565 *p++ = vnd_local_bd_addr[5]; 566 *p++ = vnd_local_bd_addr[4]; 567 *p++ = vnd_local_bd_addr[3]; 568 *p++ = vnd_local_bd_addr[2]; 569 *p++ = vnd_local_bd_addr[1]; 570 *p = vnd_local_bd_addr[0]; 571 572 p_buf->len = HCI_CMD_PREAMBLE_SIZE + BD_ADDR_LEN; 573 hw_cfg_cb.state = HW_CFG_SET_BD_ADDR; 574 575 retval = bt_vendor_cbacks->xmit_cb(HCI_VSC_WRITE_BD_ADDR, p_buf, \ 576 hw_config_cback); 577 578 return (retval); 579 } 580 581 #if (USE_CONTROLLER_BDADDR == TRUE) 582 /******************************************************************************* 583 ** 584 ** Function hw_config_read_bdaddr 585 ** 586 ** Description Read controller's Bluetooth Device Address 587 ** 588 ** Returns TRUE, if valid address is sent 589 ** FALSE, otherwise 590 ** 591 *******************************************************************************/ 592 static uint8_t hw_config_read_bdaddr(HC_BT_HDR *p_buf) 593 { 594 uint8_t retval = FALSE; 595 uint8_t *p = (uint8_t *) (p_buf + 1); 596 597 UINT16_TO_STREAM(p, HCI_READ_LOCAL_BDADDR); 598 *p = 0; /* parameter length */ 599 600 p_buf->len = HCI_CMD_PREAMBLE_SIZE; 601 hw_cfg_cb.state = HW_CFG_READ_BD_ADDR; 602 603 retval = bt_vendor_cbacks->xmit_cb(HCI_READ_LOCAL_BDADDR, p_buf, \ 604 hw_config_cback); 605 606 return (retval); 607 } 608 #endif // (USE_CONTROLLER_BDADDR == TRUE) 609 610 /******************************************************************************* 611 ** 612 ** Function hw_config_cback 613 ** 614 ** Description Callback function for controller configuration 615 ** 616 ** Returns None 617 ** 618 *******************************************************************************/ 619 void hw_config_cback(void *p_mem) 620 { 621 HC_BT_HDR *p_evt_buf = (HC_BT_HDR *) p_mem; 622 char *p_name, *p_tmp; 623 uint8_t *p, status; 624 uint16_t opcode; 625 HC_BT_HDR *p_buf=NULL; 626 uint8_t is_proceeding = FALSE; 627 int i; 628 int delay=100; 629 #if (USE_CONTROLLER_BDADDR == TRUE) 630 const uint8_t null_bdaddr[BD_ADDR_LEN] = {0,0,0,0,0,0}; 631 #endif 632 633 status = *((uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_STATUS_RET_BYTE); 634 p = (uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_OPCODE; 635 STREAM_TO_UINT16(opcode,p); 636 637 /* Ask a new buffer big enough to hold any HCI commands sent in here */ 638 if ((status == 0) && bt_vendor_cbacks) 639 p_buf = (HC_BT_HDR *) bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE + \ 640 HCI_CMD_MAX_LEN); 641 642 if (p_buf != NULL) 643 { 644 p_buf->event = MSG_STACK_TO_HC_HCI_CMD; 645 p_buf->offset = 0; 646 p_buf->len = 0; 647 p_buf->layer_specific = 0; 648 649 p = (uint8_t *) (p_buf + 1); 650 651 switch (hw_cfg_cb.state) 652 { 653 case HW_CFG_SET_UART_BAUD_1: 654 /* update baud rate of host's UART port */ 655 ALOGI("bt vendor lib: set UART baud %i", UART_TARGET_BAUD_RATE); 656 userial_vendor_set_baud( \ 657 line_speed_to_userial_baud(UART_TARGET_BAUD_RATE) \ 658 ); 659 660 /* read local name */ 661 UINT16_TO_STREAM(p, HCI_READ_LOCAL_NAME); 662 *p = 0; /* parameter length */ 663 664 p_buf->len = HCI_CMD_PREAMBLE_SIZE; 665 hw_cfg_cb.state = HW_CFG_READ_LOCAL_NAME; 666 667 is_proceeding = bt_vendor_cbacks->xmit_cb(HCI_READ_LOCAL_NAME, \ 668 p_buf, hw_config_cback); 669 break; 670 671 case HW_CFG_READ_LOCAL_NAME: 672 p_tmp = p_name = (char *) (p_evt_buf + 1) + \ 673 HCI_EVT_CMD_CMPL_LOCAL_NAME_STRING; 674 675 for (i=0; (i < LOCAL_NAME_BUFFER_LEN)||(*(p_name+i) != 0); i++) 676 *(p_name+i) = toupper(*(p_name+i)); 677 678 if ((p_name = strstr(p_name, "BCM")) != NULL) 679 { 680 strncpy(hw_cfg_cb.local_chip_name, p_name, \ 681 LOCAL_NAME_BUFFER_LEN-1); 682 } 683 #ifdef USE_BLUETOOTH_BCM4343 684 else if ((p_name = strstr(p_tmp, "4343")) != NULL) 685 { 686 snprintf(hw_cfg_cb.local_chip_name, 687 LOCAL_NAME_BUFFER_LEN-1, "BCM%s", p_name); 688 strncpy(p_name, hw_cfg_cb.local_chip_name, 689 LOCAL_NAME_BUFFER_LEN-1); 690 } 691 #endif 692 else 693 { 694 strncpy(hw_cfg_cb.local_chip_name, "UNKNOWN", \ 695 LOCAL_NAME_BUFFER_LEN-1); 696 p_name = p_tmp; 697 } 698 699 hw_cfg_cb.local_chip_name[LOCAL_NAME_BUFFER_LEN-1] = 0; 700 701 BTHWDBG("Chipset %s", hw_cfg_cb.local_chip_name); 702 703 if ((status = hw_config_findpatch(p_name)) == TRUE) 704 { 705 if ((hw_cfg_cb.fw_fd = open(p_name, O_RDONLY)) == -1) 706 { 707 ALOGE("vendor lib preload failed to open [%s]", p_name); 708 } 709 else 710 { 711 /* vsc_download_minidriver */ 712 UINT16_TO_STREAM(p, HCI_VSC_DOWNLOAD_MINIDRV); 713 *p = 0; /* parameter length */ 714 715 p_buf->len = HCI_CMD_PREAMBLE_SIZE; 716 hw_cfg_cb.state = HW_CFG_DL_MINIDRIVER; 717 718 is_proceeding = bt_vendor_cbacks->xmit_cb( \ 719 HCI_VSC_DOWNLOAD_MINIDRV, p_buf, \ 720 hw_config_cback); 721 } 722 } 723 else 724 { 725 ALOGE( \ 726 "vendor lib preload failed to locate firmware patch file" \ 727 ); 728 } 729 730 if (is_proceeding == FALSE) 731 { 732 is_proceeding = hw_config_set_bdaddr(p_buf); 733 } 734 break; 735 736 case HW_CFG_DL_MINIDRIVER: 737 /* give time for placing firmware in download mode */ 738 ms_delay(50); 739 hw_cfg_cb.state = HW_CFG_DL_FW_PATCH; 740 /* fall through intentionally */ 741 case HW_CFG_DL_FW_PATCH: 742 if (hw_cfg_cb.fw_fd >= 0) 743 { 744 int ret = read(hw_cfg_cb.fw_fd, p, HCI_CMD_PREAMBLE_SIZE); 745 if (ret > 0) 746 { 747 if ((ret < HCI_CMD_PREAMBLE_SIZE) || \ 748 (opcode == HCI_VSC_LAUNCH_RAM)) 749 { 750 ALOGW("firmware patch file might be altered!"); 751 } 752 else 753 { 754 p_buf->len = ret; 755 ret = read(hw_cfg_cb.fw_fd, \ 756 p+HCI_CMD_PREAMBLE_SIZE,\ 757 *(p+HCD_REC_PAYLOAD_LEN_BYTE)); 758 if (ret >= 0) 759 { 760 p_buf->len += ret; 761 STREAM_TO_UINT16(opcode,p); 762 is_proceeding = bt_vendor_cbacks->xmit_cb(opcode, \ 763 p_buf, hw_config_cback); 764 break; 765 } 766 } 767 } 768 if (ret < 0) 769 { 770 ALOGE("firmware patch file read failed (%s)", strerror(errno)); 771 } 772 close(hw_cfg_cb.fw_fd); 773 hw_cfg_cb.fw_fd = -1; 774 } 775 /* Normally the firmware patch configuration file 776 * sets the new starting baud rate at 115200. 777 * So, we need update host's baud rate accordingly. 778 */ 779 ALOGI("bt vendor lib: set UART baud 115200"); 780 userial_vendor_set_baud(USERIAL_BAUD_115200); 781 782 /* Next, we would like to boost baud rate up again 783 * to desired working speed. 784 */ 785 hw_cfg_cb.f_set_baud_2 = TRUE; 786 787 /* Check if we need to pause a few hundred milliseconds 788 * before sending down any HCI command. 789 */ 790 delay = look_up_fw_settlement_delay(); 791 ALOGI("Setting fw settlement delay to %d ", delay); 792 ms_delay(delay); 793 794 p_buf->len = HCI_CMD_PREAMBLE_SIZE; 795 UINT16_TO_STREAM(p, HCI_RESET); 796 *p = 0; /* parameter length */ 797 hw_cfg_cb.state = HW_CFG_START; 798 is_proceeding = bt_vendor_cbacks->xmit_cb(HCI_RESET, p_buf, hw_config_cback); 799 break; 800 801 case HW_CFG_START: 802 if (UART_TARGET_BAUD_RATE > 3000000) 803 { 804 /* set UART clock to 48MHz */ 805 UINT16_TO_STREAM(p, HCI_VSC_WRITE_UART_CLOCK_SETTING); 806 *p++ = 1; /* parameter length */ 807 *p = 1; /* (1,"UART CLOCK 48 MHz")(2,"UART CLOCK 24 MHz") */ 808 809 p_buf->len = HCI_CMD_PREAMBLE_SIZE + 1; 810 hw_cfg_cb.state = HW_CFG_SET_UART_CLOCK; 811 812 is_proceeding = bt_vendor_cbacks->xmit_cb( \ 813 HCI_VSC_WRITE_UART_CLOCK_SETTING, \ 814 p_buf, hw_config_cback); 815 break; 816 } 817 /* fall through intentionally */ 818 case HW_CFG_SET_UART_CLOCK: 819 /* set controller's UART baud rate to 3M */ 820 UINT16_TO_STREAM(p, HCI_VSC_UPDATE_BAUDRATE); 821 *p++ = UPDATE_BAUDRATE_CMD_PARAM_SIZE; /* parameter length */ 822 *p++ = 0; /* encoded baud rate */ 823 *p++ = 0; /* use encoded form */ 824 UINT32_TO_STREAM(p, UART_TARGET_BAUD_RATE); 825 826 p_buf->len = HCI_CMD_PREAMBLE_SIZE + \ 827 UPDATE_BAUDRATE_CMD_PARAM_SIZE; 828 hw_cfg_cb.state = (hw_cfg_cb.f_set_baud_2) ? \ 829 HW_CFG_SET_UART_BAUD_2 : HW_CFG_SET_UART_BAUD_1; 830 831 is_proceeding = bt_vendor_cbacks->xmit_cb(HCI_VSC_UPDATE_BAUDRATE, \ 832 p_buf, hw_config_cback); 833 break; 834 835 case HW_CFG_SET_UART_BAUD_2: 836 /* update baud rate of host's UART port */ 837 ALOGI("bt vendor lib: set UART baud %i", UART_TARGET_BAUD_RATE); 838 userial_vendor_set_baud( \ 839 line_speed_to_userial_baud(UART_TARGET_BAUD_RATE) \ 840 ); 841 842 #if (USE_CONTROLLER_BDADDR == TRUE) 843 if ((is_proceeding = hw_config_read_bdaddr(p_buf)) == TRUE) 844 break; 845 #else 846 if ((is_proceeding = hw_config_set_bdaddr(p_buf)) == TRUE) 847 break; 848 #endif 849 /* fall through intentionally */ 850 case HW_CFG_SET_BD_ADDR: 851 ALOGI("vendor lib fwcfg completed"); 852 bt_vendor_cbacks->dealloc(p_buf); 853 bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_SUCCESS); 854 855 hw_cfg_cb.state = 0; 856 857 if (hw_cfg_cb.fw_fd != -1) 858 { 859 close(hw_cfg_cb.fw_fd); 860 hw_cfg_cb.fw_fd = -1; 861 } 862 863 is_proceeding = TRUE; 864 break; 865 866 #if (USE_CONTROLLER_BDADDR == TRUE) 867 case HW_CFG_READ_BD_ADDR: 868 p_tmp = (char *) (p_evt_buf + 1) + \ 869 HCI_EVT_CMD_CMPL_LOCAL_BDADDR_ARRAY; 870 871 if (memcmp(p_tmp, null_bdaddr, BD_ADDR_LEN) == 0) 872 { 873 // Controller does not have a valid OTP BDADDR! 874 // Set the BTIF initial BDADDR instead. 875 if ((is_proceeding = hw_config_set_bdaddr(p_buf)) == TRUE) 876 break; 877 } 878 else 879 { 880 ALOGI("Controller OTP bdaddr %02X:%02X:%02X:%02X:%02X:%02X", 881 *(p_tmp+5), *(p_tmp+4), *(p_tmp+3), 882 *(p_tmp+2), *(p_tmp+1), *p_tmp); 883 } 884 885 ALOGI("vendor lib fwcfg completed"); 886 bt_vendor_cbacks->dealloc(p_buf); 887 bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_SUCCESS); 888 889 hw_cfg_cb.state = 0; 890 891 if (hw_cfg_cb.fw_fd != -1) 892 { 893 close(hw_cfg_cb.fw_fd); 894 hw_cfg_cb.fw_fd = -1; 895 } 896 897 is_proceeding = TRUE; 898 break; 899 #endif // (USE_CONTROLLER_BDADDR == TRUE) 900 } // switch(hw_cfg_cb.state) 901 } // if (p_buf != NULL) 902 903 /* Free the RX event buffer */ 904 if (bt_vendor_cbacks) 905 bt_vendor_cbacks->dealloc(p_evt_buf); 906 907 if (is_proceeding == FALSE) 908 { 909 ALOGE("vendor lib fwcfg aborted!!!"); 910 if (bt_vendor_cbacks) 911 { 912 if (p_buf != NULL) 913 bt_vendor_cbacks->dealloc(p_buf); 914 915 bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_FAIL); 916 } 917 918 if (hw_cfg_cb.fw_fd != -1) 919 { 920 close(hw_cfg_cb.fw_fd); 921 hw_cfg_cb.fw_fd = -1; 922 } 923 924 hw_cfg_cb.state = 0; 925 } 926 } 927 928 /****************************************************************************** 929 ** LPM Static Functions 930 ******************************************************************************/ 931 932 /******************************************************************************* 933 ** 934 ** Function hw_lpm_ctrl_cback 935 ** 936 ** Description Callback function for lpm enable/disable rquest 937 ** 938 ** Returns None 939 ** 940 *******************************************************************************/ 941 void hw_lpm_ctrl_cback(void *p_mem) 942 { 943 HC_BT_HDR *p_evt_buf = (HC_BT_HDR *) p_mem; 944 bt_vendor_op_result_t status = BT_VND_OP_RESULT_FAIL; 945 946 if (*((uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_STATUS_RET_BYTE) == 0) 947 { 948 status = BT_VND_OP_RESULT_SUCCESS; 949 } 950 951 if (bt_vendor_cbacks) 952 { 953 bt_vendor_cbacks->lpm_cb(status); 954 bt_vendor_cbacks->dealloc(p_evt_buf); 955 } 956 } 957 958 959 #if (SCO_CFG_INCLUDED == TRUE) 960 /***************************************************************************** 961 ** SCO Configuration Static Functions 962 *****************************************************************************/ 963 964 /******************************************************************************* 965 ** 966 ** Function hw_sco_i2spcm_cfg_cback 967 ** 968 ** Description Callback function for SCO I2S/PCM configuration rquest 969 ** 970 ** Returns None 971 ** 972 *******************************************************************************/ 973 static void hw_sco_i2spcm_cfg_cback(void *p_mem) 974 { 975 HC_BT_HDR *p_evt_buf = (HC_BT_HDR *)p_mem; 976 uint8_t *p; 977 uint16_t opcode; 978 HC_BT_HDR *p_buf = NULL; 979 bt_vendor_op_result_t status = BT_VND_OP_RESULT_FAIL; 980 981 p = (uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_OPCODE; 982 STREAM_TO_UINT16(opcode,p); 983 984 if (*((uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_STATUS_RET_BYTE) == 0) 985 { 986 status = BT_VND_OP_RESULT_SUCCESS; 987 } 988 989 /* Free the RX event buffer */ 990 if (bt_vendor_cbacks) 991 bt_vendor_cbacks->dealloc(p_evt_buf); 992 993 if (status == BT_VND_OP_RESULT_SUCCESS) 994 { 995 if ((opcode == HCI_VSC_WRITE_I2SPCM_INTERFACE_PARAM) && 996 (SCO_INTERFACE_PCM == sco_bus_interface)) 997 { 998 uint8_t ret = FALSE; 999 1000 /* Ask a new buffer to hold WRITE_SCO_PCM_INT_PARAM command */ 1001 if (bt_vendor_cbacks) 1002 p_buf = (HC_BT_HDR *)bt_vendor_cbacks->alloc( 1003 BT_HC_HDR_SIZE + HCI_CMD_PREAMBLE_SIZE + SCO_PCM_PARAM_SIZE); 1004 if (p_buf) 1005 { 1006 p_buf->event = MSG_STACK_TO_HC_HCI_CMD; 1007 p_buf->offset = 0; 1008 p_buf->layer_specific = 0; 1009 p_buf->len = HCI_CMD_PREAMBLE_SIZE + SCO_PCM_PARAM_SIZE; 1010 p = (uint8_t *)(p_buf + 1); 1011 1012 /* do we need this VSC for I2S??? */ 1013 UINT16_TO_STREAM(p, HCI_VSC_WRITE_SCO_PCM_INT_PARAM); 1014 *p++ = SCO_PCM_PARAM_SIZE; 1015 memcpy(p, &bt_sco_param, SCO_PCM_PARAM_SIZE); 1016 ALOGI("SCO PCM configure {0x%x, 0x%x, 0x%x, 0x%x, 0x%x}", 1017 bt_sco_param[0], bt_sco_param[1], bt_sco_param[2], bt_sco_param[3], 1018 bt_sco_param[4]); 1019 if ((ret = bt_vendor_cbacks->xmit_cb(HCI_VSC_WRITE_SCO_PCM_INT_PARAM, p_buf, 1020 hw_sco_i2spcm_cfg_cback)) == FALSE) 1021 { 1022 bt_vendor_cbacks->dealloc(p_buf); 1023 } 1024 else 1025 return; 1026 } 1027 status = BT_VND_OP_RESULT_FAIL; 1028 } 1029 else if ((opcode == HCI_VSC_WRITE_SCO_PCM_INT_PARAM) && 1030 (SCO_INTERFACE_PCM == sco_bus_interface)) 1031 { 1032 uint8_t ret = FALSE; 1033 1034 /* Ask a new buffer to hold WRITE_PCM_DATA_FORMAT_PARAM command */ 1035 if (bt_vendor_cbacks) 1036 p_buf = (HC_BT_HDR *)bt_vendor_cbacks->alloc( 1037 BT_HC_HDR_SIZE + HCI_CMD_PREAMBLE_SIZE + PCM_DATA_FORMAT_PARAM_SIZE); 1038 if (p_buf) 1039 { 1040 p_buf->event = MSG_STACK_TO_HC_HCI_CMD; 1041 p_buf->offset = 0; 1042 p_buf->layer_specific = 0; 1043 p_buf->len = HCI_CMD_PREAMBLE_SIZE + PCM_DATA_FORMAT_PARAM_SIZE; 1044 1045 p = (uint8_t *)(p_buf + 1); 1046 UINT16_TO_STREAM(p, HCI_VSC_WRITE_PCM_DATA_FORMAT_PARAM); 1047 *p++ = PCM_DATA_FORMAT_PARAM_SIZE; 1048 memcpy(p, &bt_pcm_data_fmt_param, PCM_DATA_FORMAT_PARAM_SIZE); 1049 1050 ALOGI("SCO PCM data format {0x%x, 0x%x, 0x%x, 0x%x, 0x%x}", 1051 bt_pcm_data_fmt_param[0], bt_pcm_data_fmt_param[1], 1052 bt_pcm_data_fmt_param[2], bt_pcm_data_fmt_param[3], 1053 bt_pcm_data_fmt_param[4]); 1054 1055 if ((ret = bt_vendor_cbacks->xmit_cb(HCI_VSC_WRITE_PCM_DATA_FORMAT_PARAM, 1056 p_buf, hw_sco_i2spcm_cfg_cback)) == FALSE) 1057 { 1058 bt_vendor_cbacks->dealloc(p_buf); 1059 } 1060 else 1061 return; 1062 } 1063 status = BT_VND_OP_RESULT_FAIL; 1064 } 1065 } 1066 1067 ALOGI("sco I2S/PCM config result %d [0-Success, 1-Fail]", status); 1068 if (bt_vendor_cbacks) 1069 { 1070 bt_vendor_cbacks->audio_state_cb(status); 1071 } 1072 } 1073 1074 /******************************************************************************* 1075 ** 1076 ** Function hw_set_MSBC_codec_cback 1077 ** 1078 ** Description Callback function for setting WBS codec 1079 ** 1080 ** Returns None 1081 ** 1082 *******************************************************************************/ 1083 static void hw_set_MSBC_codec_cback(void *p_mem) 1084 { 1085 /* whenever update the codec enable/disable, need to update I2SPCM */ 1086 ALOGI("SCO I2S interface change the sample rate to 16K"); 1087 hw_sco_i2spcm_config_from_command(p_mem, SCO_CODEC_MSBC); 1088 } 1089 1090 /******************************************************************************* 1091 ** 1092 ** Function hw_set_CVSD_codec_cback 1093 ** 1094 ** Description Callback function for setting NBS codec 1095 ** 1096 ** Returns None 1097 ** 1098 *******************************************************************************/ 1099 static void hw_set_CVSD_codec_cback(void *p_mem) 1100 { 1101 /* whenever update the codec enable/disable, need to update I2SPCM */ 1102 ALOGI("SCO I2S interface change the sample rate to 8K"); 1103 hw_sco_i2spcm_config_from_command(p_mem, SCO_CODEC_CVSD); 1104 } 1105 1106 #endif // SCO_CFG_INCLUDED 1107 1108 /***************************************************************************** 1109 ** Hardware Configuration Interface Functions 1110 *****************************************************************************/ 1111 1112 1113 /******************************************************************************* 1114 ** 1115 ** Function hw_config_start 1116 ** 1117 ** Description Kick off controller initialization process 1118 ** 1119 ** Returns None 1120 ** 1121 *******************************************************************************/ 1122 void hw_config_start(void) 1123 { 1124 HC_BT_HDR *p_buf = NULL; 1125 uint8_t *p; 1126 1127 hw_cfg_cb.state = 0; 1128 hw_cfg_cb.fw_fd = -1; 1129 hw_cfg_cb.f_set_baud_2 = FALSE; 1130 1131 /* Start from sending HCI_RESET */ 1132 1133 if (bt_vendor_cbacks) 1134 { 1135 p_buf = (HC_BT_HDR *) bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE + \ 1136 HCI_CMD_PREAMBLE_SIZE); 1137 } 1138 1139 if (p_buf) 1140 { 1141 p_buf->event = MSG_STACK_TO_HC_HCI_CMD; 1142 p_buf->offset = 0; 1143 p_buf->layer_specific = 0; 1144 p_buf->len = HCI_CMD_PREAMBLE_SIZE; 1145 1146 p = (uint8_t *) (p_buf + 1); 1147 UINT16_TO_STREAM(p, HCI_RESET); 1148 *p = 0; /* parameter length */ 1149 1150 hw_cfg_cb.state = HW_CFG_START; 1151 1152 bt_vendor_cbacks->xmit_cb(HCI_RESET, p_buf, hw_config_cback); 1153 } 1154 else 1155 { 1156 if (bt_vendor_cbacks) 1157 { 1158 ALOGE("vendor lib fw conf aborted [no buffer]"); 1159 bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_FAIL); 1160 } 1161 } 1162 } 1163 1164 /******************************************************************************* 1165 ** 1166 ** Function hw_lpm_enable 1167 ** 1168 ** Description Enalbe/Disable LPM 1169 ** 1170 ** Returns TRUE/FALSE 1171 ** 1172 *******************************************************************************/ 1173 uint8_t hw_lpm_enable(uint8_t turn_on) 1174 { 1175 HC_BT_HDR *p_buf = NULL; 1176 uint8_t *p; 1177 uint8_t ret = FALSE; 1178 1179 if (bt_vendor_cbacks) 1180 p_buf = (HC_BT_HDR *) bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE + \ 1181 HCI_CMD_PREAMBLE_SIZE + \ 1182 LPM_CMD_PARAM_SIZE); 1183 1184 if (p_buf) 1185 { 1186 p_buf->event = MSG_STACK_TO_HC_HCI_CMD; 1187 p_buf->offset = 0; 1188 p_buf->layer_specific = 0; 1189 p_buf->len = HCI_CMD_PREAMBLE_SIZE + LPM_CMD_PARAM_SIZE; 1190 1191 p = (uint8_t *) (p_buf + 1); 1192 UINT16_TO_STREAM(p, HCI_VSC_WRITE_SLEEP_MODE); 1193 *p++ = LPM_CMD_PARAM_SIZE; /* parameter length */ 1194 1195 if (turn_on) 1196 { 1197 memcpy(p, &lpm_param, LPM_CMD_PARAM_SIZE); 1198 upio_set(UPIO_LPM_MODE, UPIO_ASSERT, 0); 1199 } 1200 else 1201 { 1202 memset(p, 0, LPM_CMD_PARAM_SIZE); 1203 upio_set(UPIO_LPM_MODE, UPIO_DEASSERT, 0); 1204 } 1205 1206 if ((ret = bt_vendor_cbacks->xmit_cb(HCI_VSC_WRITE_SLEEP_MODE, p_buf, \ 1207 hw_lpm_ctrl_cback)) == FALSE) 1208 { 1209 bt_vendor_cbacks->dealloc(p_buf); 1210 } 1211 } 1212 1213 if ((ret == FALSE) && bt_vendor_cbacks) 1214 bt_vendor_cbacks->lpm_cb(BT_VND_OP_RESULT_FAIL); 1215 1216 return ret; 1217 } 1218 1219 /******************************************************************************* 1220 ** 1221 ** Function hw_lpm_get_idle_timeout 1222 ** 1223 ** Description Calculate idle time based on host stack idle threshold 1224 ** 1225 ** Returns idle timeout value 1226 ** 1227 *******************************************************************************/ 1228 uint32_t hw_lpm_get_idle_timeout(void) 1229 { 1230 uint32_t timeout_ms; 1231 1232 /* set idle time to be LPM_IDLE_TIMEOUT_MULTIPLE times of 1233 * host stack idle threshold (in 300ms/25ms) 1234 */ 1235 timeout_ms = (uint32_t)lpm_param.host_stack_idle_threshold \ 1236 * LPM_IDLE_TIMEOUT_MULTIPLE; 1237 if (strstr(hw_cfg_cb.local_chip_name, "BCM4325") != NULL) 1238 timeout_ms *= 25; // 12.5 or 25 ? 1239 else if (strstr(hw_cfg_cb.local_chip_name, "BCM4358") != NULL) 1240 timeout_ms *= 50; 1241 else if (strstr(hw_cfg_cb.local_chip_name, "BCM43013") != NULL) 1242 timeout_ms *= 1; 1243 else 1244 timeout_ms *= 300; 1245 1246 return timeout_ms; 1247 } 1248 1249 /******************************************************************************* 1250 ** 1251 ** Function hw_lpm_set_wake_state 1252 ** 1253 ** Description Assert/Deassert BT_WAKE 1254 ** 1255 ** Returns None 1256 ** 1257 *******************************************************************************/ 1258 void hw_lpm_set_wake_state(uint8_t wake_assert) 1259 { 1260 uint8_t state = (wake_assert) ? UPIO_ASSERT : UPIO_DEASSERT; 1261 1262 upio_set(UPIO_BT_WAKE, state, lpm_param.bt_wake_polarity); 1263 } 1264 1265 #if (SCO_CFG_INCLUDED == TRUE) 1266 /******************************************************************************* 1267 ** 1268 ** Function hw_sco_config 1269 ** 1270 ** Description Configure SCO related hardware settings 1271 ** 1272 ** Returns None 1273 ** 1274 *******************************************************************************/ 1275 void hw_sco_config(void) 1276 { 1277 if (SCO_INTERFACE_I2S == sco_bus_interface) 1278 { 1279 /* 'Enable' I2S mode */ 1280 bt_sco_i2spcm_param[0] = 1; 1281 1282 /* set nbs clock rate as the value in SCO_I2SPCM_IF_CLOCK_RATE field */ 1283 sco_bus_clock_rate = bt_sco_i2spcm_param[3]; 1284 } 1285 else 1286 { 1287 /* 'Disable' I2S mode */ 1288 bt_sco_i2spcm_param[0] = 0; 1289 1290 /* set nbs clock rate as the value in SCO_PCM_IF_CLOCK_RATE field */ 1291 sco_bus_clock_rate = bt_sco_param[1]; 1292 1293 /* sync up clock mode setting */ 1294 bt_sco_i2spcm_param[1] = bt_sco_param[4]; 1295 } 1296 1297 if (sco_bus_wbs_clock_rate == INVALID_SCO_CLOCK_RATE) 1298 { 1299 /* set default wbs clock rate */ 1300 sco_bus_wbs_clock_rate = SCO_I2SPCM_IF_CLOCK_RATE4WBS; 1301 1302 if (sco_bus_wbs_clock_rate < sco_bus_clock_rate) 1303 sco_bus_wbs_clock_rate = sco_bus_clock_rate; 1304 } 1305 1306 /* 1307 * To support I2S/PCM port multiplexing signals for sharing Bluetooth audio 1308 * and FM on the same PCM pins, we defer Bluetooth audio (SCO/eSCO) 1309 * configuration till SCO/eSCO is being established; 1310 * i.e. in hw_set_audio_state() call. 1311 * When configured as I2S only, Bluetooth audio configuration is executed 1312 * immediately with SCO_CODEC_CVSD by default. 1313 */ 1314 1315 if (SCO_INTERFACE_I2S == sco_bus_interface) { 1316 hw_sco_i2spcm_config(SCO_CODEC_CVSD); 1317 } 1318 1319 if (bt_vendor_cbacks) 1320 { 1321 bt_vendor_cbacks->scocfg_cb(BT_VND_OP_RESULT_SUCCESS); 1322 } 1323 } 1324 1325 static void hw_sco_i2spcm_config_from_command(void *p_mem, uint16_t codec) { 1326 HC_BT_HDR *p_evt_buf = (HC_BT_HDR *)p_mem; 1327 bool command_success = *((uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_STATUS_RET_BYTE) == 0; 1328 1329 /* Free the RX event buffer */ 1330 if (bt_vendor_cbacks) 1331 bt_vendor_cbacks->dealloc(p_evt_buf); 1332 1333 if (command_success) 1334 hw_sco_i2spcm_config(codec); 1335 else if (bt_vendor_cbacks) 1336 bt_vendor_cbacks->audio_state_cb(BT_VND_OP_RESULT_FAIL); 1337 } 1338 1339 1340 /******************************************************************************* 1341 ** 1342 ** Function hw_sco_i2spcm_config 1343 ** 1344 ** Description Configure SCO over I2S or PCM 1345 ** 1346 ** Returns None 1347 ** 1348 *******************************************************************************/ 1349 static void hw_sco_i2spcm_config(uint16_t codec) 1350 { 1351 HC_BT_HDR *p_buf = NULL; 1352 uint8_t *p, ret; 1353 uint16_t cmd_u16 = HCI_CMD_PREAMBLE_SIZE + SCO_I2SPCM_PARAM_SIZE; 1354 1355 if (bt_vendor_cbacks) 1356 p_buf = (HC_BT_HDR *)bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE + cmd_u16); 1357 1358 if (p_buf) 1359 { 1360 p_buf->event = MSG_STACK_TO_HC_HCI_CMD; 1361 p_buf->offset = 0; 1362 p_buf->layer_specific = 0; 1363 p_buf->len = cmd_u16; 1364 1365 p = (uint8_t *)(p_buf + 1); 1366 1367 UINT16_TO_STREAM(p, HCI_VSC_WRITE_I2SPCM_INTERFACE_PARAM); 1368 *p++ = SCO_I2SPCM_PARAM_SIZE; 1369 if (codec == SCO_CODEC_CVSD) 1370 { 1371 bt_sco_i2spcm_param[2] = 0; /* SCO_I2SPCM_IF_SAMPLE_RATE 8k */ 1372 bt_sco_i2spcm_param[3] = bt_sco_param[1] = sco_bus_clock_rate; 1373 } 1374 else if (codec == SCO_CODEC_MSBC) 1375 { 1376 bt_sco_i2spcm_param[2] = wbs_sample_rate; /* SCO_I2SPCM_IF_SAMPLE_RATE 16K */ 1377 bt_sco_i2spcm_param[3] = bt_sco_param[1] = sco_bus_wbs_clock_rate; 1378 } 1379 else 1380 { 1381 bt_sco_i2spcm_param[2] = 0; /* SCO_I2SPCM_IF_SAMPLE_RATE 8k */ 1382 bt_sco_i2spcm_param[3] = bt_sco_param[1] = sco_bus_clock_rate; 1383 ALOGE("wrong codec is use in hw_sco_i2spcm_config, goes default NBS"); 1384 } 1385 memcpy(p, &bt_sco_i2spcm_param, SCO_I2SPCM_PARAM_SIZE); 1386 cmd_u16 = HCI_VSC_WRITE_I2SPCM_INTERFACE_PARAM; 1387 ALOGI("I2SPCM config {0x%x, 0x%x, 0x%x, 0x%x}", 1388 bt_sco_i2spcm_param[0], bt_sco_i2spcm_param[1], 1389 bt_sco_i2spcm_param[2], bt_sco_i2spcm_param[3]); 1390 1391 if ((ret = bt_vendor_cbacks->xmit_cb(cmd_u16, p_buf, hw_sco_i2spcm_cfg_cback)) == FALSE) 1392 { 1393 bt_vendor_cbacks->dealloc(p_buf); 1394 } 1395 else 1396 return; 1397 } 1398 1399 bt_vendor_cbacks->audio_state_cb(BT_VND_OP_RESULT_FAIL); 1400 } 1401 1402 /******************************************************************************* 1403 ** 1404 ** Function hw_set_SCO_codec 1405 ** 1406 ** Description This functgion sends command to the controller to setup 1407 ** WBS/NBS codec for the upcoming eSCO connection. 1408 ** 1409 ** Returns -1 : Failed to send VSC 1410 ** 0 : Success 1411 ** 1412 *******************************************************************************/ 1413 static int hw_set_SCO_codec(uint16_t codec) 1414 { 1415 HC_BT_HDR *p_buf = NULL; 1416 uint8_t *p; 1417 uint8_t ret; 1418 int ret_val = 0; 1419 tINT_CMD_CBACK p_set_SCO_codec_cback; 1420 1421 BTHWDBG( "hw_set_SCO_codec 0x%x", codec); 1422 1423 if (bt_vendor_cbacks) 1424 p_buf = (HC_BT_HDR *)bt_vendor_cbacks->alloc( 1425 BT_HC_HDR_SIZE + HCI_CMD_PREAMBLE_SIZE + SCO_CODEC_PARAM_SIZE); 1426 1427 if (p_buf) 1428 { 1429 p_buf->event = MSG_STACK_TO_HC_HCI_CMD; 1430 p_buf->offset = 0; 1431 p_buf->layer_specific = 0; 1432 p = (uint8_t *)(p_buf + 1); 1433 1434 UINT16_TO_STREAM(p, HCI_VSC_ENABLE_WBS); 1435 1436 if (codec == SCO_CODEC_MSBC) 1437 { 1438 /* Enable mSBC */ 1439 *p++ = SCO_CODEC_PARAM_SIZE; /* set the parameter size */ 1440 UINT8_TO_STREAM(p,1); /* enable */ 1441 UINT16_TO_STREAM(p, codec); 1442 1443 /* set the totall size of this packet */ 1444 p_buf->len = HCI_CMD_PREAMBLE_SIZE + SCO_CODEC_PARAM_SIZE; 1445 1446 p_set_SCO_codec_cback = hw_set_MSBC_codec_cback; 1447 } 1448 else 1449 { 1450 /* Disable mSBC */ 1451 *p++ = (SCO_CODEC_PARAM_SIZE - 2); /* set the parameter size */ 1452 UINT8_TO_STREAM(p,0); /* disable */ 1453 1454 /* set the totall size of this packet */ 1455 p_buf->len = HCI_CMD_PREAMBLE_SIZE + SCO_CODEC_PARAM_SIZE - 2; 1456 1457 p_set_SCO_codec_cback = hw_set_CVSD_codec_cback; 1458 if ((codec != SCO_CODEC_CVSD) && (codec != SCO_CODEC_NONE)) 1459 { 1460 ALOGW("SCO codec setting is wrong: codec: 0x%x", codec); 1461 } 1462 } 1463 1464 if ((ret = bt_vendor_cbacks->xmit_cb(HCI_VSC_ENABLE_WBS, p_buf, p_set_SCO_codec_cback))\ 1465 == FALSE) 1466 { 1467 bt_vendor_cbacks->dealloc(p_buf); 1468 ret_val = -1; 1469 } 1470 } 1471 else 1472 { 1473 ret_val = -1; 1474 } 1475 1476 return ret_val; 1477 } 1478 1479 /******************************************************************************* 1480 ** 1481 ** Function hw_set_audio_state 1482 ** 1483 ** Description This function configures audio base on provided audio state 1484 ** 1485 ** Paramters pointer to audio state structure 1486 ** 1487 ** Returns 0: ok, -1: error 1488 ** 1489 *******************************************************************************/ 1490 int hw_set_audio_state(bt_vendor_op_audio_state_t *p_state) 1491 { 1492 int ret_val = -1; 1493 1494 if (!bt_vendor_cbacks) 1495 return ret_val; 1496 1497 ret_val = hw_set_SCO_codec(p_state->peer_codec); 1498 return ret_val; 1499 } 1500 1501 #else // SCO_CFG_INCLUDED 1502 int hw_set_audio_state(bt_vendor_op_audio_state_t *p_state) 1503 { 1504 return -256; 1505 } 1506 #endif 1507 /******************************************************************************* 1508 ** 1509 ** Function hw_set_patch_file_path 1510 ** 1511 ** Description Set the location of firmware patch file 1512 ** 1513 ** Returns 0 : Success 1514 ** Otherwise : Fail 1515 ** 1516 *******************************************************************************/ 1517 int hw_set_patch_file_path(char *p_conf_name, char *p_conf_value, int param) 1518 { 1519 1520 strcpy(fw_patchfile_path, p_conf_value); 1521 1522 return 0; 1523 } 1524 1525 /******************************************************************************* 1526 ** 1527 ** Function hw_set_patch_file_name 1528 ** 1529 ** Description Give the specific firmware patch filename 1530 ** 1531 ** Returns 0 : Success 1532 ** Otherwise : Fail 1533 ** 1534 *******************************************************************************/ 1535 int hw_set_patch_file_name(char *p_conf_name, char *p_conf_value, int param) 1536 { 1537 1538 strcpy(fw_patchfile_name, p_conf_value); 1539 1540 return 0; 1541 } 1542 1543 #if (VENDOR_LIB_RUNTIME_TUNING_ENABLED == TRUE) 1544 /******************************************************************************* 1545 ** 1546 ** Function hw_set_patch_settlement_delay 1547 ** 1548 ** Description Give the specific firmware patch settlement time in milliseconds 1549 ** 1550 ** Returns 0 : Success 1551 ** Otherwise : Fail 1552 ** 1553 *******************************************************************************/ 1554 int hw_set_patch_settlement_delay(char *p_conf_name, char *p_conf_value, int param) 1555 { 1556 fw_patch_settlement_delay = atoi(p_conf_value); 1557 1558 return 0; 1559 } 1560 #endif //VENDOR_LIB_RUNTIME_TUNING_ENABLED 1561 1562 /***************************************************************************** 1563 ** Sample Codes Section 1564 *****************************************************************************/ 1565 1566 #if (HW_END_WITH_HCI_RESET == TRUE) 1567 /******************************************************************************* 1568 ** 1569 ** Function hw_epilog_cback 1570 ** 1571 ** Description Callback function for Command Complete Events from HCI 1572 ** commands sent in epilog process. 1573 ** 1574 ** Returns None 1575 ** 1576 *******************************************************************************/ 1577 void hw_epilog_cback(void *p_mem) 1578 { 1579 HC_BT_HDR *p_evt_buf = (HC_BT_HDR *) p_mem; 1580 uint8_t *p, status; 1581 uint16_t opcode; 1582 1583 status = *((uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_STATUS_RET_BYTE); 1584 p = (uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_OPCODE; 1585 STREAM_TO_UINT16(opcode,p); 1586 1587 BTHWDBG("%s Opcode:0x%04X Status: %d", __FUNCTION__, opcode, status); 1588 1589 if (bt_vendor_cbacks) 1590 { 1591 /* Must free the RX event buffer */ 1592 bt_vendor_cbacks->dealloc(p_evt_buf); 1593 1594 /* Once epilog process is done, must call epilog_cb callback 1595 to notify caller */ 1596 bt_vendor_cbacks->epilog_cb(BT_VND_OP_RESULT_SUCCESS); 1597 } 1598 } 1599 1600 /******************************************************************************* 1601 ** 1602 ** Function hw_epilog_process 1603 ** 1604 ** Description Sample implementation of epilog process 1605 ** 1606 ** Returns None 1607 ** 1608 *******************************************************************************/ 1609 void hw_epilog_process(void) 1610 { 1611 HC_BT_HDR *p_buf = NULL; 1612 uint8_t *p; 1613 1614 BTHWDBG("hw_epilog_process"); 1615 1616 /* Sending a HCI_RESET */ 1617 if (bt_vendor_cbacks) 1618 { 1619 /* Must allocate command buffer via HC's alloc API */ 1620 p_buf = (HC_BT_HDR *) bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE + \ 1621 HCI_CMD_PREAMBLE_SIZE); 1622 } 1623 1624 if (p_buf) 1625 { 1626 p_buf->event = MSG_STACK_TO_HC_HCI_CMD; 1627 p_buf->offset = 0; 1628 p_buf->layer_specific = 0; 1629 p_buf->len = HCI_CMD_PREAMBLE_SIZE; 1630 1631 p = (uint8_t *) (p_buf + 1); 1632 UINT16_TO_STREAM(p, HCI_RESET); 1633 *p = 0; /* parameter length */ 1634 1635 /* Send command via HC's xmit_cb API */ 1636 bt_vendor_cbacks->xmit_cb(HCI_RESET, p_buf, hw_epilog_cback); 1637 } 1638 else 1639 { 1640 if (bt_vendor_cbacks) 1641 { 1642 ALOGE("vendor lib epilog process aborted [no buffer]"); 1643 bt_vendor_cbacks->epilog_cb(BT_VND_OP_RESULT_FAIL); 1644 } 1645 } 1646 } 1647 #endif // (HW_END_WITH_HCI_RESET == TRUE) 1648