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 p_buf->len = read(hw_cfg_cb.fw_fd, p, HCI_CMD_PREAMBLE_SIZE); 743 if (p_buf->len > 0) 744 { 745 if ((p_buf->len < HCI_CMD_PREAMBLE_SIZE) || \ 746 (opcode == HCI_VSC_LAUNCH_RAM)) 747 { 748 ALOGW("firmware patch file might be altered!"); 749 } 750 else 751 { 752 p_buf->len += read(hw_cfg_cb.fw_fd, \ 753 p+HCI_CMD_PREAMBLE_SIZE,\ 754 *(p+HCD_REC_PAYLOAD_LEN_BYTE)); 755 STREAM_TO_UINT16(opcode,p); 756 is_proceeding = bt_vendor_cbacks->xmit_cb(opcode, \ 757 p_buf, hw_config_cback); 758 break; 759 } 760 } 761 762 close(hw_cfg_cb.fw_fd); 763 hw_cfg_cb.fw_fd = -1; 764 765 /* Normally the firmware patch configuration file 766 * sets the new starting baud rate at 115200. 767 * So, we need update host's baud rate accordingly. 768 */ 769 ALOGI("bt vendor lib: set UART baud 115200"); 770 userial_vendor_set_baud(USERIAL_BAUD_115200); 771 772 /* Next, we would like to boost baud rate up again 773 * to desired working speed. 774 */ 775 hw_cfg_cb.f_set_baud_2 = TRUE; 776 777 /* Check if we need to pause a few hundred milliseconds 778 * before sending down any HCI command. 779 */ 780 delay = look_up_fw_settlement_delay(); 781 ALOGI("Setting fw settlement delay to %d ", delay); 782 ms_delay(delay); 783 784 p_buf->len = HCI_CMD_PREAMBLE_SIZE; 785 UINT16_TO_STREAM(p, HCI_RESET); 786 *p = 0; /* parameter length */ 787 hw_cfg_cb.state = HW_CFG_START; 788 is_proceeding = bt_vendor_cbacks->xmit_cb(HCI_RESET, p_buf, hw_config_cback); 789 break; 790 791 case HW_CFG_START: 792 if (UART_TARGET_BAUD_RATE > 3000000) 793 { 794 /* set UART clock to 48MHz */ 795 UINT16_TO_STREAM(p, HCI_VSC_WRITE_UART_CLOCK_SETTING); 796 *p++ = 1; /* parameter length */ 797 *p = 1; /* (1,"UART CLOCK 48 MHz")(2,"UART CLOCK 24 MHz") */ 798 799 p_buf->len = HCI_CMD_PREAMBLE_SIZE + 1; 800 hw_cfg_cb.state = HW_CFG_SET_UART_CLOCK; 801 802 is_proceeding = bt_vendor_cbacks->xmit_cb( \ 803 HCI_VSC_WRITE_UART_CLOCK_SETTING, \ 804 p_buf, hw_config_cback); 805 break; 806 } 807 /* fall through intentionally */ 808 case HW_CFG_SET_UART_CLOCK: 809 /* set controller's UART baud rate to 3M */ 810 UINT16_TO_STREAM(p, HCI_VSC_UPDATE_BAUDRATE); 811 *p++ = UPDATE_BAUDRATE_CMD_PARAM_SIZE; /* parameter length */ 812 *p++ = 0; /* encoded baud rate */ 813 *p++ = 0; /* use encoded form */ 814 UINT32_TO_STREAM(p, UART_TARGET_BAUD_RATE); 815 816 p_buf->len = HCI_CMD_PREAMBLE_SIZE + \ 817 UPDATE_BAUDRATE_CMD_PARAM_SIZE; 818 hw_cfg_cb.state = (hw_cfg_cb.f_set_baud_2) ? \ 819 HW_CFG_SET_UART_BAUD_2 : HW_CFG_SET_UART_BAUD_1; 820 821 is_proceeding = bt_vendor_cbacks->xmit_cb(HCI_VSC_UPDATE_BAUDRATE, \ 822 p_buf, hw_config_cback); 823 break; 824 825 case HW_CFG_SET_UART_BAUD_2: 826 /* update baud rate of host's UART port */ 827 ALOGI("bt vendor lib: set UART baud %i", UART_TARGET_BAUD_RATE); 828 userial_vendor_set_baud( \ 829 line_speed_to_userial_baud(UART_TARGET_BAUD_RATE) \ 830 ); 831 832 #if (USE_CONTROLLER_BDADDR == TRUE) 833 if ((is_proceeding = hw_config_read_bdaddr(p_buf)) == TRUE) 834 break; 835 #else 836 if ((is_proceeding = hw_config_set_bdaddr(p_buf)) == TRUE) 837 break; 838 #endif 839 /* fall through intentionally */ 840 case HW_CFG_SET_BD_ADDR: 841 ALOGI("vendor lib fwcfg completed"); 842 bt_vendor_cbacks->dealloc(p_buf); 843 bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_SUCCESS); 844 845 hw_cfg_cb.state = 0; 846 847 if (hw_cfg_cb.fw_fd != -1) 848 { 849 close(hw_cfg_cb.fw_fd); 850 hw_cfg_cb.fw_fd = -1; 851 } 852 853 is_proceeding = TRUE; 854 break; 855 856 #if (USE_CONTROLLER_BDADDR == TRUE) 857 case HW_CFG_READ_BD_ADDR: 858 p_tmp = (char *) (p_evt_buf + 1) + \ 859 HCI_EVT_CMD_CMPL_LOCAL_BDADDR_ARRAY; 860 861 if (memcmp(p_tmp, null_bdaddr, BD_ADDR_LEN) == 0) 862 { 863 // Controller does not have a valid OTP BDADDR! 864 // Set the BTIF initial BDADDR instead. 865 if ((is_proceeding = hw_config_set_bdaddr(p_buf)) == TRUE) 866 break; 867 } 868 else 869 { 870 ALOGI("Controller OTP bdaddr %02X:%02X:%02X:%02X:%02X:%02X", 871 *(p_tmp+5), *(p_tmp+4), *(p_tmp+3), 872 *(p_tmp+2), *(p_tmp+1), *p_tmp); 873 } 874 875 ALOGI("vendor lib fwcfg completed"); 876 bt_vendor_cbacks->dealloc(p_buf); 877 bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_SUCCESS); 878 879 hw_cfg_cb.state = 0; 880 881 if (hw_cfg_cb.fw_fd != -1) 882 { 883 close(hw_cfg_cb.fw_fd); 884 hw_cfg_cb.fw_fd = -1; 885 } 886 887 is_proceeding = TRUE; 888 break; 889 #endif // (USE_CONTROLLER_BDADDR == TRUE) 890 } // switch(hw_cfg_cb.state) 891 } // if (p_buf != NULL) 892 893 /* Free the RX event buffer */ 894 if (bt_vendor_cbacks) 895 bt_vendor_cbacks->dealloc(p_evt_buf); 896 897 if (is_proceeding == FALSE) 898 { 899 ALOGE("vendor lib fwcfg aborted!!!"); 900 if (bt_vendor_cbacks) 901 { 902 if (p_buf != NULL) 903 bt_vendor_cbacks->dealloc(p_buf); 904 905 bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_FAIL); 906 } 907 908 if (hw_cfg_cb.fw_fd != -1) 909 { 910 close(hw_cfg_cb.fw_fd); 911 hw_cfg_cb.fw_fd = -1; 912 } 913 914 hw_cfg_cb.state = 0; 915 } 916 } 917 918 /****************************************************************************** 919 ** LPM Static Functions 920 ******************************************************************************/ 921 922 /******************************************************************************* 923 ** 924 ** Function hw_lpm_ctrl_cback 925 ** 926 ** Description Callback function for lpm enable/disable rquest 927 ** 928 ** Returns None 929 ** 930 *******************************************************************************/ 931 void hw_lpm_ctrl_cback(void *p_mem) 932 { 933 HC_BT_HDR *p_evt_buf = (HC_BT_HDR *) p_mem; 934 bt_vendor_op_result_t status = BT_VND_OP_RESULT_FAIL; 935 936 if (*((uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_STATUS_RET_BYTE) == 0) 937 { 938 status = BT_VND_OP_RESULT_SUCCESS; 939 } 940 941 if (bt_vendor_cbacks) 942 { 943 bt_vendor_cbacks->lpm_cb(status); 944 bt_vendor_cbacks->dealloc(p_evt_buf); 945 } 946 } 947 948 949 #if (SCO_CFG_INCLUDED == TRUE) 950 /***************************************************************************** 951 ** SCO Configuration Static Functions 952 *****************************************************************************/ 953 954 /******************************************************************************* 955 ** 956 ** Function hw_sco_i2spcm_cfg_cback 957 ** 958 ** Description Callback function for SCO I2S/PCM configuration rquest 959 ** 960 ** Returns None 961 ** 962 *******************************************************************************/ 963 static void hw_sco_i2spcm_cfg_cback(void *p_mem) 964 { 965 HC_BT_HDR *p_evt_buf = (HC_BT_HDR *)p_mem; 966 uint8_t *p; 967 uint16_t opcode; 968 HC_BT_HDR *p_buf = NULL; 969 bt_vendor_op_result_t status = BT_VND_OP_RESULT_FAIL; 970 971 p = (uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_OPCODE; 972 STREAM_TO_UINT16(opcode,p); 973 974 if (*((uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_STATUS_RET_BYTE) == 0) 975 { 976 status = BT_VND_OP_RESULT_SUCCESS; 977 } 978 979 /* Free the RX event buffer */ 980 if (bt_vendor_cbacks) 981 bt_vendor_cbacks->dealloc(p_evt_buf); 982 983 if (status == BT_VND_OP_RESULT_SUCCESS) 984 { 985 if ((opcode == HCI_VSC_WRITE_I2SPCM_INTERFACE_PARAM) && 986 (SCO_INTERFACE_PCM == sco_bus_interface)) 987 { 988 uint8_t ret = FALSE; 989 990 /* Ask a new buffer to hold WRITE_SCO_PCM_INT_PARAM command */ 991 if (bt_vendor_cbacks) 992 p_buf = (HC_BT_HDR *)bt_vendor_cbacks->alloc( 993 BT_HC_HDR_SIZE + HCI_CMD_PREAMBLE_SIZE + SCO_PCM_PARAM_SIZE); 994 if (p_buf) 995 { 996 p_buf->event = MSG_STACK_TO_HC_HCI_CMD; 997 p_buf->offset = 0; 998 p_buf->layer_specific = 0; 999 p_buf->len = HCI_CMD_PREAMBLE_SIZE + SCO_PCM_PARAM_SIZE; 1000 p = (uint8_t *)(p_buf + 1); 1001 1002 /* do we need this VSC for I2S??? */ 1003 UINT16_TO_STREAM(p, HCI_VSC_WRITE_SCO_PCM_INT_PARAM); 1004 *p++ = SCO_PCM_PARAM_SIZE; 1005 memcpy(p, &bt_sco_param, SCO_PCM_PARAM_SIZE); 1006 ALOGI("SCO PCM configure {0x%x, 0x%x, 0x%x, 0x%x, 0x%x}", 1007 bt_sco_param[0], bt_sco_param[1], bt_sco_param[2], bt_sco_param[3], 1008 bt_sco_param[4]); 1009 if ((ret = bt_vendor_cbacks->xmit_cb(HCI_VSC_WRITE_SCO_PCM_INT_PARAM, p_buf, 1010 hw_sco_i2spcm_cfg_cback)) == FALSE) 1011 { 1012 bt_vendor_cbacks->dealloc(p_buf); 1013 } 1014 else 1015 return; 1016 } 1017 status = BT_VND_OP_RESULT_FAIL; 1018 } 1019 else if ((opcode == HCI_VSC_WRITE_SCO_PCM_INT_PARAM) && 1020 (SCO_INTERFACE_PCM == sco_bus_interface)) 1021 { 1022 uint8_t ret = FALSE; 1023 1024 /* Ask a new buffer to hold WRITE_PCM_DATA_FORMAT_PARAM command */ 1025 if (bt_vendor_cbacks) 1026 p_buf = (HC_BT_HDR *)bt_vendor_cbacks->alloc( 1027 BT_HC_HDR_SIZE + HCI_CMD_PREAMBLE_SIZE + PCM_DATA_FORMAT_PARAM_SIZE); 1028 if (p_buf) 1029 { 1030 p_buf->event = MSG_STACK_TO_HC_HCI_CMD; 1031 p_buf->offset = 0; 1032 p_buf->layer_specific = 0; 1033 p_buf->len = HCI_CMD_PREAMBLE_SIZE + PCM_DATA_FORMAT_PARAM_SIZE; 1034 1035 p = (uint8_t *)(p_buf + 1); 1036 UINT16_TO_STREAM(p, HCI_VSC_WRITE_PCM_DATA_FORMAT_PARAM); 1037 *p++ = PCM_DATA_FORMAT_PARAM_SIZE; 1038 memcpy(p, &bt_pcm_data_fmt_param, PCM_DATA_FORMAT_PARAM_SIZE); 1039 1040 ALOGI("SCO PCM data format {0x%x, 0x%x, 0x%x, 0x%x, 0x%x}", 1041 bt_pcm_data_fmt_param[0], bt_pcm_data_fmt_param[1], 1042 bt_pcm_data_fmt_param[2], bt_pcm_data_fmt_param[3], 1043 bt_pcm_data_fmt_param[4]); 1044 1045 if ((ret = bt_vendor_cbacks->xmit_cb(HCI_VSC_WRITE_PCM_DATA_FORMAT_PARAM, 1046 p_buf, hw_sco_i2spcm_cfg_cback)) == FALSE) 1047 { 1048 bt_vendor_cbacks->dealloc(p_buf); 1049 } 1050 else 1051 return; 1052 } 1053 status = BT_VND_OP_RESULT_FAIL; 1054 } 1055 } 1056 1057 ALOGI("sco I2S/PCM config result %d [0-Success, 1-Fail]", status); 1058 if (bt_vendor_cbacks) 1059 { 1060 bt_vendor_cbacks->audio_state_cb(status); 1061 } 1062 } 1063 1064 /******************************************************************************* 1065 ** 1066 ** Function hw_set_MSBC_codec_cback 1067 ** 1068 ** Description Callback function for setting WBS codec 1069 ** 1070 ** Returns None 1071 ** 1072 *******************************************************************************/ 1073 static void hw_set_MSBC_codec_cback(void *p_mem) 1074 { 1075 /* whenever update the codec enable/disable, need to update I2SPCM */ 1076 ALOGI("SCO I2S interface change the sample rate to 16K"); 1077 hw_sco_i2spcm_config_from_command(p_mem, SCO_CODEC_MSBC); 1078 } 1079 1080 /******************************************************************************* 1081 ** 1082 ** Function hw_set_CVSD_codec_cback 1083 ** 1084 ** Description Callback function for setting NBS codec 1085 ** 1086 ** Returns None 1087 ** 1088 *******************************************************************************/ 1089 static void hw_set_CVSD_codec_cback(void *p_mem) 1090 { 1091 /* whenever update the codec enable/disable, need to update I2SPCM */ 1092 ALOGI("SCO I2S interface change the sample rate to 8K"); 1093 hw_sco_i2spcm_config_from_command(p_mem, SCO_CODEC_CVSD); 1094 } 1095 1096 #endif // SCO_CFG_INCLUDED 1097 1098 /***************************************************************************** 1099 ** Hardware Configuration Interface Functions 1100 *****************************************************************************/ 1101 1102 1103 /******************************************************************************* 1104 ** 1105 ** Function hw_config_start 1106 ** 1107 ** Description Kick off controller initialization process 1108 ** 1109 ** Returns None 1110 ** 1111 *******************************************************************************/ 1112 void hw_config_start(void) 1113 { 1114 HC_BT_HDR *p_buf = NULL; 1115 uint8_t *p; 1116 1117 hw_cfg_cb.state = 0; 1118 hw_cfg_cb.fw_fd = -1; 1119 hw_cfg_cb.f_set_baud_2 = FALSE; 1120 1121 /* Start from sending HCI_RESET */ 1122 1123 if (bt_vendor_cbacks) 1124 { 1125 p_buf = (HC_BT_HDR *) bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE + \ 1126 HCI_CMD_PREAMBLE_SIZE); 1127 } 1128 1129 if (p_buf) 1130 { 1131 p_buf->event = MSG_STACK_TO_HC_HCI_CMD; 1132 p_buf->offset = 0; 1133 p_buf->layer_specific = 0; 1134 p_buf->len = HCI_CMD_PREAMBLE_SIZE; 1135 1136 p = (uint8_t *) (p_buf + 1); 1137 UINT16_TO_STREAM(p, HCI_RESET); 1138 *p = 0; /* parameter length */ 1139 1140 hw_cfg_cb.state = HW_CFG_START; 1141 1142 bt_vendor_cbacks->xmit_cb(HCI_RESET, p_buf, hw_config_cback); 1143 } 1144 else 1145 { 1146 if (bt_vendor_cbacks) 1147 { 1148 ALOGE("vendor lib fw conf aborted [no buffer]"); 1149 bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_FAIL); 1150 } 1151 } 1152 } 1153 1154 /******************************************************************************* 1155 ** 1156 ** Function hw_lpm_enable 1157 ** 1158 ** Description Enalbe/Disable LPM 1159 ** 1160 ** Returns TRUE/FALSE 1161 ** 1162 *******************************************************************************/ 1163 uint8_t hw_lpm_enable(uint8_t turn_on) 1164 { 1165 HC_BT_HDR *p_buf = NULL; 1166 uint8_t *p; 1167 uint8_t ret = FALSE; 1168 1169 if (bt_vendor_cbacks) 1170 p_buf = (HC_BT_HDR *) bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE + \ 1171 HCI_CMD_PREAMBLE_SIZE + \ 1172 LPM_CMD_PARAM_SIZE); 1173 1174 if (p_buf) 1175 { 1176 p_buf->event = MSG_STACK_TO_HC_HCI_CMD; 1177 p_buf->offset = 0; 1178 p_buf->layer_specific = 0; 1179 p_buf->len = HCI_CMD_PREAMBLE_SIZE + LPM_CMD_PARAM_SIZE; 1180 1181 p = (uint8_t *) (p_buf + 1); 1182 UINT16_TO_STREAM(p, HCI_VSC_WRITE_SLEEP_MODE); 1183 *p++ = LPM_CMD_PARAM_SIZE; /* parameter length */ 1184 1185 if (turn_on) 1186 { 1187 memcpy(p, &lpm_param, LPM_CMD_PARAM_SIZE); 1188 upio_set(UPIO_LPM_MODE, UPIO_ASSERT, 0); 1189 } 1190 else 1191 { 1192 memset(p, 0, LPM_CMD_PARAM_SIZE); 1193 upio_set(UPIO_LPM_MODE, UPIO_DEASSERT, 0); 1194 } 1195 1196 if ((ret = bt_vendor_cbacks->xmit_cb(HCI_VSC_WRITE_SLEEP_MODE, p_buf, \ 1197 hw_lpm_ctrl_cback)) == FALSE) 1198 { 1199 bt_vendor_cbacks->dealloc(p_buf); 1200 } 1201 } 1202 1203 if ((ret == FALSE) && bt_vendor_cbacks) 1204 bt_vendor_cbacks->lpm_cb(BT_VND_OP_RESULT_FAIL); 1205 1206 return ret; 1207 } 1208 1209 /******************************************************************************* 1210 ** 1211 ** Function hw_lpm_get_idle_timeout 1212 ** 1213 ** Description Calculate idle time based on host stack idle threshold 1214 ** 1215 ** Returns idle timeout value 1216 ** 1217 *******************************************************************************/ 1218 uint32_t hw_lpm_get_idle_timeout(void) 1219 { 1220 uint32_t timeout_ms; 1221 1222 /* set idle time to be LPM_IDLE_TIMEOUT_MULTIPLE times of 1223 * host stack idle threshold (in 300ms/25ms) 1224 */ 1225 timeout_ms = (uint32_t)lpm_param.host_stack_idle_threshold \ 1226 * LPM_IDLE_TIMEOUT_MULTIPLE; 1227 if (strstr(hw_cfg_cb.local_chip_name, "BCM4325") != NULL) 1228 timeout_ms *= 25; // 12.5 or 25 ? 1229 else if (strstr(hw_cfg_cb.local_chip_name, "BCM4358") != NULL) 1230 timeout_ms *= 50; 1231 else 1232 timeout_ms *= 300; 1233 1234 return timeout_ms; 1235 } 1236 1237 /******************************************************************************* 1238 ** 1239 ** Function hw_lpm_set_wake_state 1240 ** 1241 ** Description Assert/Deassert BT_WAKE 1242 ** 1243 ** Returns None 1244 ** 1245 *******************************************************************************/ 1246 void hw_lpm_set_wake_state(uint8_t wake_assert) 1247 { 1248 uint8_t state = (wake_assert) ? UPIO_ASSERT : UPIO_DEASSERT; 1249 1250 upio_set(UPIO_BT_WAKE, state, lpm_param.bt_wake_polarity); 1251 } 1252 1253 #if (SCO_CFG_INCLUDED == TRUE) 1254 /******************************************************************************* 1255 ** 1256 ** Function hw_sco_config 1257 ** 1258 ** Description Configure SCO related hardware settings 1259 ** 1260 ** Returns None 1261 ** 1262 *******************************************************************************/ 1263 void hw_sco_config(void) 1264 { 1265 if (SCO_INTERFACE_I2S == sco_bus_interface) 1266 { 1267 /* 'Enable' I2S mode */ 1268 bt_sco_i2spcm_param[0] = 1; 1269 1270 /* set nbs clock rate as the value in SCO_I2SPCM_IF_CLOCK_RATE field */ 1271 sco_bus_clock_rate = bt_sco_i2spcm_param[3]; 1272 } 1273 else 1274 { 1275 /* 'Disable' I2S mode */ 1276 bt_sco_i2spcm_param[0] = 0; 1277 1278 /* set nbs clock rate as the value in SCO_PCM_IF_CLOCK_RATE field */ 1279 sco_bus_clock_rate = bt_sco_param[1]; 1280 1281 /* sync up clock mode setting */ 1282 bt_sco_i2spcm_param[1] = bt_sco_param[4]; 1283 } 1284 1285 if (sco_bus_wbs_clock_rate == INVALID_SCO_CLOCK_RATE) 1286 { 1287 /* set default wbs clock rate */ 1288 sco_bus_wbs_clock_rate = SCO_I2SPCM_IF_CLOCK_RATE4WBS; 1289 1290 if (sco_bus_wbs_clock_rate < sco_bus_clock_rate) 1291 sco_bus_wbs_clock_rate = sco_bus_clock_rate; 1292 } 1293 1294 /* 1295 * To support I2S/PCM port multiplexing signals for sharing Bluetooth audio 1296 * and FM on the same PCM pins, we defer Bluetooth audio (SCO/eSCO) 1297 * configuration till SCO/eSCO is being established; 1298 * i.e. in hw_set_audio_state() call. 1299 * When configured as I2S only, Bluetooth audio configuration is executed 1300 * immediately with SCO_CODEC_CVSD by default. 1301 */ 1302 1303 if (SCO_INTERFACE_I2S == sco_bus_interface) { 1304 hw_sco_i2spcm_config(SCO_CODEC_CVSD); 1305 } 1306 1307 if (bt_vendor_cbacks) 1308 { 1309 bt_vendor_cbacks->scocfg_cb(BT_VND_OP_RESULT_SUCCESS); 1310 } 1311 } 1312 1313 static void hw_sco_i2spcm_config_from_command(void *p_mem, uint16_t codec) { 1314 HC_BT_HDR *p_evt_buf = (HC_BT_HDR *)p_mem; 1315 bool command_success = *((uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_STATUS_RET_BYTE) == 0; 1316 1317 /* Free the RX event buffer */ 1318 if (bt_vendor_cbacks) 1319 bt_vendor_cbacks->dealloc(p_evt_buf); 1320 1321 if (command_success) 1322 hw_sco_i2spcm_config(codec); 1323 else if (bt_vendor_cbacks) 1324 bt_vendor_cbacks->audio_state_cb(BT_VND_OP_RESULT_FAIL); 1325 } 1326 1327 1328 /******************************************************************************* 1329 ** 1330 ** Function hw_sco_i2spcm_config 1331 ** 1332 ** Description Configure SCO over I2S or PCM 1333 ** 1334 ** Returns None 1335 ** 1336 *******************************************************************************/ 1337 static void hw_sco_i2spcm_config(uint16_t codec) 1338 { 1339 HC_BT_HDR *p_buf = NULL; 1340 uint8_t *p, ret; 1341 uint16_t cmd_u16 = HCI_CMD_PREAMBLE_SIZE + SCO_I2SPCM_PARAM_SIZE; 1342 1343 if (bt_vendor_cbacks) 1344 p_buf = (HC_BT_HDR *)bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE + cmd_u16); 1345 1346 if (p_buf) 1347 { 1348 p_buf->event = MSG_STACK_TO_HC_HCI_CMD; 1349 p_buf->offset = 0; 1350 p_buf->layer_specific = 0; 1351 p_buf->len = cmd_u16; 1352 1353 p = (uint8_t *)(p_buf + 1); 1354 1355 UINT16_TO_STREAM(p, HCI_VSC_WRITE_I2SPCM_INTERFACE_PARAM); 1356 *p++ = SCO_I2SPCM_PARAM_SIZE; 1357 if (codec == SCO_CODEC_CVSD) 1358 { 1359 bt_sco_i2spcm_param[2] = 0; /* SCO_I2SPCM_IF_SAMPLE_RATE 8k */ 1360 bt_sco_i2spcm_param[3] = bt_sco_param[1] = sco_bus_clock_rate; 1361 } 1362 else if (codec == SCO_CODEC_MSBC) 1363 { 1364 bt_sco_i2spcm_param[2] = wbs_sample_rate; /* SCO_I2SPCM_IF_SAMPLE_RATE 16K */ 1365 bt_sco_i2spcm_param[3] = bt_sco_param[1] = sco_bus_wbs_clock_rate; 1366 } 1367 else 1368 { 1369 bt_sco_i2spcm_param[2] = 0; /* SCO_I2SPCM_IF_SAMPLE_RATE 8k */ 1370 bt_sco_i2spcm_param[3] = bt_sco_param[1] = sco_bus_clock_rate; 1371 ALOGE("wrong codec is use in hw_sco_i2spcm_config, goes default NBS"); 1372 } 1373 memcpy(p, &bt_sco_i2spcm_param, SCO_I2SPCM_PARAM_SIZE); 1374 cmd_u16 = HCI_VSC_WRITE_I2SPCM_INTERFACE_PARAM; 1375 ALOGI("I2SPCM config {0x%x, 0x%x, 0x%x, 0x%x}", 1376 bt_sco_i2spcm_param[0], bt_sco_i2spcm_param[1], 1377 bt_sco_i2spcm_param[2], bt_sco_i2spcm_param[3]); 1378 1379 if ((ret = bt_vendor_cbacks->xmit_cb(cmd_u16, p_buf, hw_sco_i2spcm_cfg_cback)) == FALSE) 1380 { 1381 bt_vendor_cbacks->dealloc(p_buf); 1382 } 1383 else 1384 return; 1385 } 1386 1387 bt_vendor_cbacks->audio_state_cb(BT_VND_OP_RESULT_FAIL); 1388 } 1389 1390 /******************************************************************************* 1391 ** 1392 ** Function hw_set_SCO_codec 1393 ** 1394 ** Description This functgion sends command to the controller to setup 1395 ** WBS/NBS codec for the upcoming eSCO connection. 1396 ** 1397 ** Returns -1 : Failed to send VSC 1398 ** 0 : Success 1399 ** 1400 *******************************************************************************/ 1401 static int hw_set_SCO_codec(uint16_t codec) 1402 { 1403 HC_BT_HDR *p_buf = NULL; 1404 uint8_t *p; 1405 uint8_t ret; 1406 int ret_val = 0; 1407 tINT_CMD_CBACK p_set_SCO_codec_cback; 1408 1409 BTHWDBG( "hw_set_SCO_codec 0x%x", codec); 1410 1411 if (bt_vendor_cbacks) 1412 p_buf = (HC_BT_HDR *)bt_vendor_cbacks->alloc( 1413 BT_HC_HDR_SIZE + HCI_CMD_PREAMBLE_SIZE + SCO_CODEC_PARAM_SIZE); 1414 1415 if (p_buf) 1416 { 1417 p_buf->event = MSG_STACK_TO_HC_HCI_CMD; 1418 p_buf->offset = 0; 1419 p_buf->layer_specific = 0; 1420 p = (uint8_t *)(p_buf + 1); 1421 1422 UINT16_TO_STREAM(p, HCI_VSC_ENABLE_WBS); 1423 1424 if (codec == SCO_CODEC_MSBC) 1425 { 1426 /* Enable mSBC */ 1427 *p++ = SCO_CODEC_PARAM_SIZE; /* set the parameter size */ 1428 UINT8_TO_STREAM(p,1); /* enable */ 1429 UINT16_TO_STREAM(p, codec); 1430 1431 /* set the totall size of this packet */ 1432 p_buf->len = HCI_CMD_PREAMBLE_SIZE + SCO_CODEC_PARAM_SIZE; 1433 1434 p_set_SCO_codec_cback = hw_set_MSBC_codec_cback; 1435 } 1436 else 1437 { 1438 /* Disable mSBC */ 1439 *p++ = (SCO_CODEC_PARAM_SIZE - 2); /* set the parameter size */ 1440 UINT8_TO_STREAM(p,0); /* disable */ 1441 1442 /* set the totall size of this packet */ 1443 p_buf->len = HCI_CMD_PREAMBLE_SIZE + SCO_CODEC_PARAM_SIZE - 2; 1444 1445 p_set_SCO_codec_cback = hw_set_CVSD_codec_cback; 1446 if ((codec != SCO_CODEC_CVSD) && (codec != SCO_CODEC_NONE)) 1447 { 1448 ALOGW("SCO codec setting is wrong: codec: 0x%x", codec); 1449 } 1450 } 1451 1452 if ((ret = bt_vendor_cbacks->xmit_cb(HCI_VSC_ENABLE_WBS, p_buf, p_set_SCO_codec_cback))\ 1453 == FALSE) 1454 { 1455 bt_vendor_cbacks->dealloc(p_buf); 1456 ret_val = -1; 1457 } 1458 } 1459 else 1460 { 1461 ret_val = -1; 1462 } 1463 1464 return ret_val; 1465 } 1466 1467 /******************************************************************************* 1468 ** 1469 ** Function hw_set_audio_state 1470 ** 1471 ** Description This function configures audio base on provided audio state 1472 ** 1473 ** Paramters pointer to audio state structure 1474 ** 1475 ** Returns 0: ok, -1: error 1476 ** 1477 *******************************************************************************/ 1478 int hw_set_audio_state(bt_vendor_op_audio_state_t *p_state) 1479 { 1480 int ret_val = -1; 1481 1482 if (!bt_vendor_cbacks) 1483 return ret_val; 1484 1485 ret_val = hw_set_SCO_codec(p_state->peer_codec); 1486 return ret_val; 1487 } 1488 1489 #else // SCO_CFG_INCLUDED 1490 int hw_set_audio_state(bt_vendor_op_audio_state_t *p_state) 1491 { 1492 return -256; 1493 } 1494 #endif 1495 /******************************************************************************* 1496 ** 1497 ** Function hw_set_patch_file_path 1498 ** 1499 ** Description Set the location of firmware patch file 1500 ** 1501 ** Returns 0 : Success 1502 ** Otherwise : Fail 1503 ** 1504 *******************************************************************************/ 1505 int hw_set_patch_file_path(char *p_conf_name, char *p_conf_value, int param) 1506 { 1507 1508 strcpy(fw_patchfile_path, p_conf_value); 1509 1510 return 0; 1511 } 1512 1513 /******************************************************************************* 1514 ** 1515 ** Function hw_set_patch_file_name 1516 ** 1517 ** Description Give the specific firmware patch filename 1518 ** 1519 ** Returns 0 : Success 1520 ** Otherwise : Fail 1521 ** 1522 *******************************************************************************/ 1523 int hw_set_patch_file_name(char *p_conf_name, char *p_conf_value, int param) 1524 { 1525 1526 strcpy(fw_patchfile_name, p_conf_value); 1527 1528 return 0; 1529 } 1530 1531 #if (VENDOR_LIB_RUNTIME_TUNING_ENABLED == TRUE) 1532 /******************************************************************************* 1533 ** 1534 ** Function hw_set_patch_settlement_delay 1535 ** 1536 ** Description Give the specific firmware patch settlement time in milliseconds 1537 ** 1538 ** Returns 0 : Success 1539 ** Otherwise : Fail 1540 ** 1541 *******************************************************************************/ 1542 int hw_set_patch_settlement_delay(char *p_conf_name, char *p_conf_value, int param) 1543 { 1544 fw_patch_settlement_delay = atoi(p_conf_value); 1545 1546 return 0; 1547 } 1548 #endif //VENDOR_LIB_RUNTIME_TUNING_ENABLED 1549 1550 /***************************************************************************** 1551 ** Sample Codes Section 1552 *****************************************************************************/ 1553 1554 #if (HW_END_WITH_HCI_RESET == TRUE) 1555 /******************************************************************************* 1556 ** 1557 ** Function hw_epilog_cback 1558 ** 1559 ** Description Callback function for Command Complete Events from HCI 1560 ** commands sent in epilog process. 1561 ** 1562 ** Returns None 1563 ** 1564 *******************************************************************************/ 1565 void hw_epilog_cback(void *p_mem) 1566 { 1567 HC_BT_HDR *p_evt_buf = (HC_BT_HDR *) p_mem; 1568 uint8_t *p, status; 1569 uint16_t opcode; 1570 1571 status = *((uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_STATUS_RET_BYTE); 1572 p = (uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_OPCODE; 1573 STREAM_TO_UINT16(opcode,p); 1574 1575 BTHWDBG("%s Opcode:0x%04X Status: %d", __FUNCTION__, opcode, status); 1576 1577 if (bt_vendor_cbacks) 1578 { 1579 /* Must free the RX event buffer */ 1580 bt_vendor_cbacks->dealloc(p_evt_buf); 1581 1582 /* Once epilog process is done, must call epilog_cb callback 1583 to notify caller */ 1584 bt_vendor_cbacks->epilog_cb(BT_VND_OP_RESULT_SUCCESS); 1585 } 1586 } 1587 1588 /******************************************************************************* 1589 ** 1590 ** Function hw_epilog_process 1591 ** 1592 ** Description Sample implementation of epilog process 1593 ** 1594 ** Returns None 1595 ** 1596 *******************************************************************************/ 1597 void hw_epilog_process(void) 1598 { 1599 HC_BT_HDR *p_buf = NULL; 1600 uint8_t *p; 1601 1602 BTHWDBG("hw_epilog_process"); 1603 1604 /* Sending a HCI_RESET */ 1605 if (bt_vendor_cbacks) 1606 { 1607 /* Must allocate command buffer via HC's alloc API */ 1608 p_buf = (HC_BT_HDR *) bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE + \ 1609 HCI_CMD_PREAMBLE_SIZE); 1610 } 1611 1612 if (p_buf) 1613 { 1614 p_buf->event = MSG_STACK_TO_HC_HCI_CMD; 1615 p_buf->offset = 0; 1616 p_buf->layer_specific = 0; 1617 p_buf->len = HCI_CMD_PREAMBLE_SIZE; 1618 1619 p = (uint8_t *) (p_buf + 1); 1620 UINT16_TO_STREAM(p, HCI_RESET); 1621 *p = 0; /* parameter length */ 1622 1623 /* Send command via HC's xmit_cb API */ 1624 bt_vendor_cbacks->xmit_cb(HCI_RESET, p_buf, hw_epilog_cback); 1625 } 1626 else 1627 { 1628 if (bt_vendor_cbacks) 1629 { 1630 ALOGE("vendor lib epilog process aborted [no buffer]"); 1631 bt_vendor_cbacks->epilog_cb(BT_VND_OP_RESULT_FAIL); 1632 } 1633 } 1634 } 1635 #endif // (HW_END_WITH_HCI_RESET == TRUE) 1636