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 <sys/stat.h> 34 #include <signal.h> 35 #include <time.h> 36 #include <errno.h> 37 #include <fcntl.h> 38 #include <dirent.h> 39 #include <ctype.h> 40 #include <cutils/properties.h> 41 #include <stdlib.h> 42 #include "bt_hci_bdroid.h" 43 #include "bt_vendor_brcm.h" 44 #include "userial.h" 45 #include "userial_vendor.h" 46 #include "upio.h" 47 48 /****************************************************************************** 49 ** Constants & Macros 50 ******************************************************************************/ 51 52 #ifndef BTHW_DBG 53 #define BTHW_DBG FALSE 54 #endif 55 56 #if (BTHW_DBG == TRUE) 57 #define BTHWDBG(param, ...) {ALOGD(param, ## __VA_ARGS__);} 58 #else 59 #define BTHWDBG(param, ...) {} 60 #endif 61 62 #define FW_PATCHFILE_EXTENSION ".hcd" 63 #define FW_PATCHFILE_EXTENSION_LEN 4 64 #define FW_PATCHFILE_PATH_MAXLEN 248 /* Local_Name length of return of 65 HCI_Read_Local_Name */ 66 67 #define HCI_CMD_MAX_LEN 258 68 69 #define HCI_RESET 0x0C03 70 #define HCI_VSC_WRITE_UART_CLOCK_SETTING 0xFC45 71 #define HCI_VSC_UPDATE_BAUDRATE 0xFC18 72 #define HCI_READ_LOCAL_NAME 0x0C14 73 #define HCI_VSC_DOWNLOAD_MINIDRV 0xFC2E 74 #define HCI_VSC_WRITE_BD_ADDR 0xFC01 75 #define HCI_VSC_WRITE_SLEEP_MODE 0xFC27 76 #define HCI_VSC_WRITE_SCO_PCM_INT_PARAM 0xFC1C 77 #define HCI_VSC_WRITE_PCM_DATA_FORMAT_PARAM 0xFC1E 78 #define HCI_VSC_WRITE_I2SPCM_INTERFACE_PARAM 0xFC6D 79 #define HCI_VSC_LAUNCH_RAM 0xFC4E 80 #define HCI_READ_LOCAL_BDADDR 0x1009 81 82 #define HCI_EVT_CMD_CMPL_STATUS_RET_BYTE 5 83 #define HCI_EVT_CMD_CMPL_LOCAL_NAME_STRING 6 84 #define HCI_EVT_CMD_CMPL_LOCAL_BDADDR_ARRAY 6 85 #define HCI_EVT_CMD_CMPL_OPCODE 3 86 #define LPM_CMD_PARAM_SIZE 12 87 #define UPDATE_BAUDRATE_CMD_PARAM_SIZE 6 88 #define HCI_CMD_PREAMBLE_SIZE 3 89 #define HCD_REC_PAYLOAD_LEN_BYTE 2 90 #define BD_ADDR_LEN 6 91 #define LOCAL_NAME_BUFFER_LEN 32 92 #define LOCAL_BDADDR_PATH_BUFFER_LEN 256 93 94 #define STREAM_TO_UINT16(u16, p) {u16 = ((uint16_t)(*(p)) + (((uint16_t)(*((p) + 1))) << 8)); (p) += 2;} 95 #define UINT16_TO_STREAM(p, u16) {*(p)++ = (uint8_t)(u16); *(p)++ = (uint8_t)((u16) >> 8);} 96 #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);} 97 98 /****************************************************************************** 99 ** Local type definitions 100 ******************************************************************************/ 101 102 /* Hardware Configuration State */ 103 enum { 104 HW_CFG_START = 1, 105 HW_CFG_SET_UART_CLOCK, 106 HW_CFG_SET_UART_BAUD_1, 107 HW_CFG_READ_LOCAL_NAME, 108 HW_CFG_DL_MINIDRIVER, 109 HW_CFG_DL_FW_PATCH, 110 HW_CFG_SET_UART_BAUD_2, 111 HW_CFG_SET_BD_ADDR 112 #if (USE_CONTROLLER_BDADDR == TRUE) 113 , HW_CFG_READ_BD_ADDR 114 #endif 115 }; 116 117 /* h/w config control block */ 118 typedef struct 119 { 120 uint8_t state; /* Hardware configuration state */ 121 int fw_fd; /* FW patch file fd */ 122 uint8_t f_set_baud_2; /* Baud rate switch state */ 123 char local_chip_name[LOCAL_NAME_BUFFER_LEN]; 124 } bt_hw_cfg_cb_t; 125 126 /* low power mode parameters */ 127 typedef struct 128 { 129 uint8_t sleep_mode; /* 0(disable),1(UART),9(H5) */ 130 uint8_t host_stack_idle_threshold; /* Unit scale 300ms/25ms */ 131 uint8_t host_controller_idle_threshold; /* Unit scale 300ms/25ms */ 132 uint8_t bt_wake_polarity; /* 0=Active Low, 1= Active High */ 133 uint8_t host_wake_polarity; /* 0=Active Low, 1= Active High */ 134 uint8_t allow_host_sleep_during_sco; 135 uint8_t combine_sleep_mode_and_lpm; 136 uint8_t enable_uart_txd_tri_state; /* UART_TXD Tri-State */ 137 uint8_t sleep_guard_time; /* sleep guard time in 12.5ms */ 138 uint8_t wakeup_guard_time; /* wakeup guard time in 12.5ms */ 139 uint8_t txd_config; /* TXD is high in sleep state */ 140 uint8_t pulsed_host_wake; /* pulsed host wake if mode = 1 */ 141 } bt_lpm_param_t; 142 143 /* Firmware re-launch settlement time */ 144 typedef struct { 145 const char *chipset_name; 146 const uint32_t delay_time; 147 } fw_settlement_entry_t; 148 149 150 /****************************************************************************** 151 ** Externs 152 ******************************************************************************/ 153 154 void hw_config_cback(void *p_evt_buf); 155 extern uint8_t vnd_local_bd_addr[BD_ADDR_LEN]; 156 157 158 /****************************************************************************** 159 ** Static variables 160 ******************************************************************************/ 161 162 static char fw_patchfile_path[256] = FW_PATCHFILE_LOCATION; 163 static char fw_patchfile_name[128] = { 0 }; 164 #if (VENDOR_LIB_RUNTIME_TUNING_ENABLED == TRUE) 165 static int fw_patch_settlement_delay = -1; 166 #endif 167 168 static bt_hw_cfg_cb_t hw_cfg_cb; 169 170 static bt_lpm_param_t lpm_param = 171 { 172 LPM_SLEEP_MODE, 173 LPM_IDLE_THRESHOLD, 174 LPM_HC_IDLE_THRESHOLD, 175 LPM_BT_WAKE_POLARITY, 176 LPM_HOST_WAKE_POLARITY, 177 LPM_ALLOW_HOST_SLEEP_DURING_SCO, 178 LPM_COMBINE_SLEEP_MODE_AND_LPM, 179 LPM_ENABLE_UART_TXD_TRI_STATE, 180 0, /* not applicable */ 181 0, /* not applicable */ 182 0, /* not applicable */ 183 LPM_PULSED_HOST_WAKE 184 }; 185 186 #if (!defined(SCO_USE_I2S_INTERFACE) || (SCO_USE_I2S_INTERFACE == FALSE)) 187 static uint8_t bt_sco_param[SCO_PCM_PARAM_SIZE] = 188 { 189 SCO_PCM_ROUTING, 190 SCO_PCM_IF_CLOCK_RATE, 191 SCO_PCM_IF_FRAME_TYPE, 192 SCO_PCM_IF_SYNC_MODE, 193 SCO_PCM_IF_CLOCK_MODE 194 }; 195 196 static uint8_t bt_pcm_data_fmt_param[PCM_DATA_FORMAT_PARAM_SIZE] = 197 { 198 PCM_DATA_FMT_SHIFT_MODE, 199 PCM_DATA_FMT_FILL_BITS, 200 PCM_DATA_FMT_FILL_METHOD, 201 PCM_DATA_FMT_FILL_NUM, 202 PCM_DATA_FMT_JUSTIFY_MODE 203 }; 204 #else 205 static uint8_t bt_sco_param[SCO_I2SPCM_PARAM_SIZE] = 206 { 207 SCO_I2SPCM_IF_MODE, 208 SCO_I2SPCM_IF_ROLE, 209 SCO_I2SPCM_IF_SAMPLE_RATE, 210 SCO_I2SPCM_IF_CLOCK_RATE 211 }; 212 #endif 213 214 /* 215 * The look-up table of recommended firmware settlement delay (milliseconds) on 216 * known chipsets. 217 */ 218 static const fw_settlement_entry_t fw_settlement_table[] = { 219 {"BCM43241", 200}, 220 {(const char *) NULL, 100} // Giving the generic fw settlement delay setting. 221 }; 222 223 /****************************************************************************** 224 ** Static functions 225 ******************************************************************************/ 226 227 /****************************************************************************** 228 ** Controller Initialization Static Functions 229 ******************************************************************************/ 230 231 /******************************************************************************* 232 ** 233 ** Function look_up_fw_settlement_delay 234 ** 235 ** Description If FW_PATCH_SETTLEMENT_DELAY_MS has not been explicitly 236 ** re-defined in the platform specific build-time configuration 237 ** file, we will search into the look-up table for a 238 ** recommended firmware settlement delay value. 239 ** 240 ** Although the settlement time might be also related to board 241 ** configurations such as the crystal clocking speed. 242 ** 243 ** Returns Firmware settlement delay 244 ** 245 *******************************************************************************/ 246 uint32_t look_up_fw_settlement_delay (void) 247 { 248 uint32_t ret_value; 249 fw_settlement_entry_t *p_entry; 250 251 if (FW_PATCH_SETTLEMENT_DELAY_MS > 0) 252 { 253 ret_value = FW_PATCH_SETTLEMENT_DELAY_MS; 254 } 255 #if (VENDOR_LIB_RUNTIME_TUNING_ENABLED == TRUE) 256 else if (fw_patch_settlement_delay >= 0) 257 { 258 ret_value = fw_patch_settlement_delay; 259 } 260 #endif 261 else 262 { 263 p_entry = (fw_settlement_entry_t *)fw_settlement_table; 264 265 while (p_entry->chipset_name != NULL) 266 { 267 if (strstr(hw_cfg_cb.local_chip_name, p_entry->chipset_name)!=NULL) 268 { 269 break; 270 } 271 272 p_entry++; 273 } 274 275 ret_value = p_entry->delay_time; 276 } 277 278 BTHWDBG( "Settlement delay -- %d ms", ret_value); 279 280 return (ret_value); 281 } 282 283 /******************************************************************************* 284 ** 285 ** Function ms_delay 286 ** 287 ** Description sleep unconditionally for timeout milliseconds 288 ** 289 ** Returns None 290 ** 291 *******************************************************************************/ 292 void ms_delay (uint32_t timeout) 293 { 294 struct timespec delay; 295 int err; 296 297 if (timeout == 0) 298 return; 299 300 delay.tv_sec = timeout / 1000; 301 delay.tv_nsec = 1000 * 1000 * (timeout%1000); 302 303 /* [u]sleep can't be used because it uses SIGALRM */ 304 do { 305 err = nanosleep(&delay, &delay); 306 } while (err < 0 && errno ==EINTR); 307 } 308 309 /******************************************************************************* 310 ** 311 ** Function line_speed_to_userial_baud 312 ** 313 ** Description helper function converts line speed number into USERIAL baud 314 ** rate symbol 315 ** 316 ** Returns unit8_t (USERIAL baud symbol) 317 ** 318 *******************************************************************************/ 319 uint8_t line_speed_to_userial_baud(uint32_t line_speed) 320 { 321 uint8_t baud; 322 323 if (line_speed == 4000000) 324 baud = USERIAL_BAUD_4M; 325 else if (line_speed == 3000000) 326 baud = USERIAL_BAUD_3M; 327 else if (line_speed == 2000000) 328 baud = USERIAL_BAUD_2M; 329 else if (line_speed == 1000000) 330 baud = USERIAL_BAUD_1M; 331 else if (line_speed == 921600) 332 baud = USERIAL_BAUD_921600; 333 else if (line_speed == 460800) 334 baud = USERIAL_BAUD_460800; 335 else if (line_speed == 230400) 336 baud = USERIAL_BAUD_230400; 337 else if (line_speed == 115200) 338 baud = USERIAL_BAUD_115200; 339 else if (line_speed == 57600) 340 baud = USERIAL_BAUD_57600; 341 else if (line_speed == 19200) 342 baud = USERIAL_BAUD_19200; 343 else if (line_speed == 9600) 344 baud = USERIAL_BAUD_9600; 345 else if (line_speed == 1200) 346 baud = USERIAL_BAUD_1200; 347 else if (line_speed == 600) 348 baud = USERIAL_BAUD_600; 349 else 350 { 351 ALOGE( "userial vendor: unsupported baud speed %d", line_speed); 352 baud = USERIAL_BAUD_115200; 353 } 354 355 return baud; 356 } 357 358 359 /******************************************************************************* 360 ** 361 ** Function hw_strncmp 362 ** 363 ** Description Used to compare two strings in caseless 364 ** 365 ** Returns 0: match, otherwise: not match 366 ** 367 *******************************************************************************/ 368 static int hw_strncmp (const char *p_str1, const char *p_str2, const int len) 369 { 370 int i; 371 372 if (!p_str1 || !p_str2) 373 return (1); 374 375 for (i = 0; i < len; i++) 376 { 377 if (toupper(p_str1[i]) != toupper(p_str2[i])) 378 return (i+1); 379 } 380 381 return 0; 382 } 383 384 /******************************************************************************* 385 ** 386 ** Function hw_config_findpatch 387 ** 388 ** Description Search for a proper firmware patch file 389 ** The selected firmware patch file name with full path 390 ** will be stored in the input string parameter, i.e. 391 ** p_chip_id_str, when returns. 392 ** 393 ** Returns TRUE when found the target patch file, otherwise FALSE 394 ** 395 *******************************************************************************/ 396 static uint8_t hw_config_findpatch(char *p_chip_id_str) 397 { 398 DIR *dirp; 399 struct dirent *dp; 400 int filenamelen; 401 uint8_t retval = FALSE; 402 403 BTHWDBG("Target name = [%s]", p_chip_id_str); 404 405 if (strlen(fw_patchfile_name)> 0) 406 { 407 /* If specific filepath and filename have been given in run-time 408 * configuration /etc/bluetooth/bt_vendor.conf file, we will use them 409 * to concatenate the filename to open rather than searching a file 410 * matching to chipset name in the fw_patchfile_path folder. 411 */ 412 sprintf(p_chip_id_str, "%s", fw_patchfile_path); 413 if (fw_patchfile_path[strlen(fw_patchfile_path)- 1] != '/') 414 { 415 strcat(p_chip_id_str, "/"); 416 } 417 strcat(p_chip_id_str, fw_patchfile_name); 418 419 ALOGI("FW patchfile: %s", p_chip_id_str); 420 return TRUE; 421 } 422 423 if ((dirp = opendir(fw_patchfile_path)) != NULL) 424 { 425 /* Fetch next filename in patchfile directory */ 426 while ((dp = readdir(dirp)) != NULL) 427 { 428 /* Check if filename starts with chip-id name */ 429 if ((hw_strncmp(dp->d_name, p_chip_id_str, strlen(p_chip_id_str)) \ 430 ) == 0) 431 { 432 /* Check if it has .hcd extenstion */ 433 filenamelen = strlen(dp->d_name); 434 if ((filenamelen >= FW_PATCHFILE_EXTENSION_LEN) && 435 ((hw_strncmp( 436 &dp->d_name[filenamelen-FW_PATCHFILE_EXTENSION_LEN], \ 437 FW_PATCHFILE_EXTENSION, \ 438 FW_PATCHFILE_EXTENSION_LEN) \ 439 ) == 0)) 440 { 441 ALOGI("Found patchfile: %s/%s", \ 442 fw_patchfile_path, dp->d_name); 443 444 /* Make sure length does not exceed maximum */ 445 if ((filenamelen + strlen(fw_patchfile_path)) > \ 446 FW_PATCHFILE_PATH_MAXLEN) 447 { 448 ALOGE("Invalid patchfile name (too long)"); 449 } 450 else 451 { 452 memset(p_chip_id_str, 0, FW_PATCHFILE_PATH_MAXLEN); 453 /* Found patchfile. Store location and name */ 454 strcpy(p_chip_id_str, fw_patchfile_path); 455 if (fw_patchfile_path[ \ 456 strlen(fw_patchfile_path)- 1 \ 457 ] != '/') 458 { 459 strcat(p_chip_id_str, "/"); 460 } 461 strcat(p_chip_id_str, dp->d_name); 462 retval = TRUE; 463 } 464 break; 465 } 466 } 467 } 468 469 closedir(dirp); 470 471 if (retval == FALSE) 472 { 473 /* Try again chip name without revision info */ 474 475 int len = strlen(p_chip_id_str); 476 char *p = p_chip_id_str + len - 1; 477 478 /* Scan backward and look for the first alphabet 479 which is not M or m 480 */ 481 while (len > 3) // BCM**** 482 { 483 if ((isdigit(*p)==0) && (*p != 'M') && (*p != 'm')) 484 break; 485 486 p--; 487 len--; 488 } 489 490 if (len > 3) 491 { 492 *p = 0; 493 retval = hw_config_findpatch(p_chip_id_str); 494 } 495 } 496 } 497 else 498 { 499 ALOGE("Could not open %s", fw_patchfile_path); 500 } 501 502 return (retval); 503 } 504 505 /******************************************************************************* 506 ** 507 ** Function hw_config_set_bdaddr 508 ** 509 ** Description Program controller's Bluetooth Device Address 510 ** 511 ** Returns TRUE, if valid address is sent 512 ** FALSE, otherwise 513 ** 514 *******************************************************************************/ 515 static uint8_t hw_config_set_bdaddr(HC_BT_HDR *p_buf) 516 { 517 uint8_t retval = FALSE; 518 uint8_t *p = (uint8_t *) (p_buf + 1); 519 520 ALOGI("Setting local bd addr to %02X:%02X:%02X:%02X:%02X:%02X", 521 vnd_local_bd_addr[0], vnd_local_bd_addr[1], vnd_local_bd_addr[2], 522 vnd_local_bd_addr[3], vnd_local_bd_addr[4], vnd_local_bd_addr[5]); 523 524 UINT16_TO_STREAM(p, HCI_VSC_WRITE_BD_ADDR); 525 *p++ = BD_ADDR_LEN; /* parameter length */ 526 *p++ = vnd_local_bd_addr[5]; 527 *p++ = vnd_local_bd_addr[4]; 528 *p++ = vnd_local_bd_addr[3]; 529 *p++ = vnd_local_bd_addr[2]; 530 *p++ = vnd_local_bd_addr[1]; 531 *p = vnd_local_bd_addr[0]; 532 533 p_buf->len = HCI_CMD_PREAMBLE_SIZE + BD_ADDR_LEN; 534 hw_cfg_cb.state = HW_CFG_SET_BD_ADDR; 535 536 retval = bt_vendor_cbacks->xmit_cb(HCI_VSC_WRITE_BD_ADDR, p_buf, \ 537 hw_config_cback); 538 539 return (retval); 540 } 541 542 #if (USE_CONTROLLER_BDADDR == TRUE) 543 /******************************************************************************* 544 ** 545 ** Function hw_config_read_bdaddr 546 ** 547 ** Description Read controller's Bluetooth Device Address 548 ** 549 ** Returns TRUE, if valid address is sent 550 ** FALSE, otherwise 551 ** 552 *******************************************************************************/ 553 static uint8_t hw_config_read_bdaddr(HC_BT_HDR *p_buf) 554 { 555 uint8_t retval = FALSE; 556 uint8_t *p = (uint8_t *) (p_buf + 1); 557 558 UINT16_TO_STREAM(p, HCI_READ_LOCAL_BDADDR); 559 *p = 0; /* parameter length */ 560 561 p_buf->len = HCI_CMD_PREAMBLE_SIZE; 562 hw_cfg_cb.state = HW_CFG_READ_BD_ADDR; 563 564 retval = bt_vendor_cbacks->xmit_cb(HCI_READ_LOCAL_BDADDR, p_buf, \ 565 hw_config_cback); 566 567 return (retval); 568 } 569 #endif // (USE_CONTROLLER_BDADDR == TRUE) 570 571 /******************************************************************************* 572 ** 573 ** Function hw_config_cback 574 ** 575 ** Description Callback function for controller configuration 576 ** 577 ** Returns None 578 ** 579 *******************************************************************************/ 580 void hw_config_cback(void *p_mem) 581 { 582 HC_BT_HDR *p_evt_buf = (HC_BT_HDR *) p_mem; 583 char *p_name, *p_tmp; 584 uint8_t *p, status; 585 uint16_t opcode; 586 HC_BT_HDR *p_buf=NULL; 587 uint8_t is_proceeding = FALSE; 588 int i; 589 #if (USE_CONTROLLER_BDADDR == TRUE) 590 const uint8_t null_bdaddr[BD_ADDR_LEN] = {0,0,0,0,0,0}; 591 #endif 592 593 status = *((uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_STATUS_RET_BYTE); 594 p = (uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_OPCODE; 595 STREAM_TO_UINT16(opcode,p); 596 597 /* Ask a new buffer big enough to hold any HCI commands sent in here */ 598 if ((status == 0) && bt_vendor_cbacks) 599 p_buf = (HC_BT_HDR *) bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE + \ 600 HCI_CMD_MAX_LEN); 601 602 if (p_buf != NULL) 603 { 604 p_buf->event = MSG_STACK_TO_HC_HCI_CMD; 605 p_buf->offset = 0; 606 p_buf->len = 0; 607 p_buf->layer_specific = 0; 608 609 p = (uint8_t *) (p_buf + 1); 610 611 switch (hw_cfg_cb.state) 612 { 613 case HW_CFG_SET_UART_BAUD_1: 614 /* update baud rate of host's UART port */ 615 ALOGI("bt vendor lib: set UART baud %i", UART_TARGET_BAUD_RATE); 616 userial_vendor_set_baud( \ 617 line_speed_to_userial_baud(UART_TARGET_BAUD_RATE) \ 618 ); 619 620 /* read local name */ 621 UINT16_TO_STREAM(p, HCI_READ_LOCAL_NAME); 622 *p = 0; /* parameter length */ 623 624 p_buf->len = HCI_CMD_PREAMBLE_SIZE; 625 hw_cfg_cb.state = HW_CFG_READ_LOCAL_NAME; 626 627 is_proceeding = bt_vendor_cbacks->xmit_cb(HCI_READ_LOCAL_NAME, \ 628 p_buf, hw_config_cback); 629 break; 630 631 case HW_CFG_READ_LOCAL_NAME: 632 p_tmp = p_name = (char *) (p_evt_buf + 1) + \ 633 HCI_EVT_CMD_CMPL_LOCAL_NAME_STRING; 634 635 for (i=0; (i < LOCAL_NAME_BUFFER_LEN)||(*(p_name+i) != 0); i++) 636 *(p_name+i) = toupper(*(p_name+i)); 637 638 if ((p_name = strstr(p_name, "BCM")) != NULL) 639 { 640 strncpy(hw_cfg_cb.local_chip_name, p_name, \ 641 LOCAL_NAME_BUFFER_LEN-1); 642 } 643 else 644 { 645 strncpy(hw_cfg_cb.local_chip_name, "UNKNOWN", \ 646 LOCAL_NAME_BUFFER_LEN-1); 647 p_name = p_tmp; 648 } 649 650 hw_cfg_cb.local_chip_name[LOCAL_NAME_BUFFER_LEN-1] = 0; 651 652 BTHWDBG("Chipset %s", hw_cfg_cb.local_chip_name); 653 654 if ((status = hw_config_findpatch(p_name)) == TRUE) 655 { 656 if ((hw_cfg_cb.fw_fd = open(p_name, O_RDONLY)) == -1) 657 { 658 ALOGE("vendor lib preload failed to open [%s]", p_name); 659 } 660 else 661 { 662 /* vsc_download_minidriver */ 663 UINT16_TO_STREAM(p, HCI_VSC_DOWNLOAD_MINIDRV); 664 *p = 0; /* parameter length */ 665 666 p_buf->len = HCI_CMD_PREAMBLE_SIZE; 667 hw_cfg_cb.state = HW_CFG_DL_MINIDRIVER; 668 669 is_proceeding = bt_vendor_cbacks->xmit_cb( \ 670 HCI_VSC_DOWNLOAD_MINIDRV, p_buf, \ 671 hw_config_cback); 672 } 673 } 674 else 675 { 676 ALOGE( \ 677 "vendor lib preload failed to locate firmware patch file" \ 678 ); 679 } 680 681 if (is_proceeding == FALSE) 682 { 683 is_proceeding = hw_config_set_bdaddr(p_buf); 684 } 685 break; 686 687 case HW_CFG_DL_MINIDRIVER: 688 /* give time for placing firmware in download mode */ 689 ms_delay(50); 690 hw_cfg_cb.state = HW_CFG_DL_FW_PATCH; 691 /* fall through intentionally */ 692 case HW_CFG_DL_FW_PATCH: 693 p_buf->len = read(hw_cfg_cb.fw_fd, p, HCI_CMD_PREAMBLE_SIZE); 694 if (p_buf->len > 0) 695 { 696 if ((p_buf->len < HCI_CMD_PREAMBLE_SIZE) || \ 697 (opcode == HCI_VSC_LAUNCH_RAM)) 698 { 699 ALOGW("firmware patch file might be altered!"); 700 } 701 else 702 { 703 p_buf->len += read(hw_cfg_cb.fw_fd, \ 704 p+HCI_CMD_PREAMBLE_SIZE,\ 705 *(p+HCD_REC_PAYLOAD_LEN_BYTE)); 706 STREAM_TO_UINT16(opcode,p); 707 is_proceeding = bt_vendor_cbacks->xmit_cb(opcode, \ 708 p_buf, hw_config_cback); 709 break; 710 } 711 } 712 713 close(hw_cfg_cb.fw_fd); 714 hw_cfg_cb.fw_fd = -1; 715 716 /* Normally the firmware patch configuration file 717 * sets the new starting baud rate at 115200. 718 * So, we need update host's baud rate accordingly. 719 */ 720 ALOGI("bt vendor lib: set UART baud 115200"); 721 userial_vendor_set_baud(USERIAL_BAUD_115200); 722 723 /* Next, we would like to boost baud rate up again 724 * to desired working speed. 725 */ 726 hw_cfg_cb.f_set_baud_2 = TRUE; 727 728 /* Check if we need to pause a few hundred milliseconds 729 * before sending down any HCI command. 730 */ 731 ms_delay(look_up_fw_settlement_delay()); 732 733 /* fall through intentionally */ 734 case HW_CFG_START: 735 if (UART_TARGET_BAUD_RATE > 3000000) 736 { 737 /* set UART clock to 48MHz */ 738 UINT16_TO_STREAM(p, HCI_VSC_WRITE_UART_CLOCK_SETTING); 739 *p++ = 1; /* parameter length */ 740 *p = 1; /* (1,"UART CLOCK 48 MHz")(2,"UART CLOCK 24 MHz") */ 741 742 p_buf->len = HCI_CMD_PREAMBLE_SIZE + 1; 743 hw_cfg_cb.state = HW_CFG_SET_UART_CLOCK; 744 745 is_proceeding = bt_vendor_cbacks->xmit_cb( \ 746 HCI_VSC_WRITE_UART_CLOCK_SETTING, \ 747 p_buf, hw_config_cback); 748 break; 749 } 750 /* fall through intentionally */ 751 case HW_CFG_SET_UART_CLOCK: 752 /* set controller's UART baud rate to 3M */ 753 UINT16_TO_STREAM(p, HCI_VSC_UPDATE_BAUDRATE); 754 *p++ = UPDATE_BAUDRATE_CMD_PARAM_SIZE; /* parameter length */ 755 *p++ = 0; /* encoded baud rate */ 756 *p++ = 0; /* use encoded form */ 757 UINT32_TO_STREAM(p, UART_TARGET_BAUD_RATE); 758 759 p_buf->len = HCI_CMD_PREAMBLE_SIZE + \ 760 UPDATE_BAUDRATE_CMD_PARAM_SIZE; 761 hw_cfg_cb.state = (hw_cfg_cb.f_set_baud_2) ? \ 762 HW_CFG_SET_UART_BAUD_2 : HW_CFG_SET_UART_BAUD_1; 763 764 is_proceeding = bt_vendor_cbacks->xmit_cb(HCI_VSC_UPDATE_BAUDRATE, \ 765 p_buf, hw_config_cback); 766 break; 767 768 case HW_CFG_SET_UART_BAUD_2: 769 /* update baud rate of host's UART port */ 770 ALOGI("bt vendor lib: set UART baud %i", UART_TARGET_BAUD_RATE); 771 userial_vendor_set_baud( \ 772 line_speed_to_userial_baud(UART_TARGET_BAUD_RATE) \ 773 ); 774 775 #if (USE_CONTROLLER_BDADDR == TRUE) 776 if ((is_proceeding = hw_config_read_bdaddr(p_buf)) == TRUE) 777 break; 778 #else 779 if ((is_proceeding = hw_config_set_bdaddr(p_buf)) == TRUE) 780 break; 781 #endif 782 /* fall through intentionally */ 783 case HW_CFG_SET_BD_ADDR: 784 ALOGI("vendor lib fwcfg completed"); 785 bt_vendor_cbacks->dealloc(p_buf); 786 bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_SUCCESS); 787 788 hw_cfg_cb.state = 0; 789 790 if (hw_cfg_cb.fw_fd != -1) 791 { 792 close(hw_cfg_cb.fw_fd); 793 hw_cfg_cb.fw_fd = -1; 794 } 795 796 is_proceeding = TRUE; 797 break; 798 799 #if (USE_CONTROLLER_BDADDR == TRUE) 800 case HW_CFG_READ_BD_ADDR: 801 p_tmp = (char *) (p_evt_buf + 1) + \ 802 HCI_EVT_CMD_CMPL_LOCAL_BDADDR_ARRAY; 803 804 if (memcmp(p_tmp, null_bdaddr, BD_ADDR_LEN) == 0) 805 { 806 // Controller does not have a valid OTP BDADDR! 807 // Set the BTIF initial BDADDR instead. 808 if ((is_proceeding = hw_config_set_bdaddr(p_buf)) == TRUE) 809 break; 810 } 811 else 812 { 813 ALOGI("Controller OTP bdaddr %02X:%02X:%02X:%02X:%02X:%02X", 814 *(p_tmp+5), *(p_tmp+4), *(p_tmp+3), 815 *(p_tmp+2), *(p_tmp+1), *p_tmp); 816 } 817 818 ALOGI("vendor lib fwcfg completed"); 819 bt_vendor_cbacks->dealloc(p_buf); 820 bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_SUCCESS); 821 822 hw_cfg_cb.state = 0; 823 824 if (hw_cfg_cb.fw_fd != -1) 825 { 826 close(hw_cfg_cb.fw_fd); 827 hw_cfg_cb.fw_fd = -1; 828 } 829 830 is_proceeding = TRUE; 831 break; 832 #endif // (USE_CONTROLLER_BDADDR == TRUE) 833 } // switch(hw_cfg_cb.state) 834 } // if (p_buf != NULL) 835 836 /* Free the RX event buffer */ 837 if (bt_vendor_cbacks) 838 bt_vendor_cbacks->dealloc(p_evt_buf); 839 840 if (is_proceeding == FALSE) 841 { 842 ALOGE("vendor lib fwcfg aborted!!!"); 843 if (bt_vendor_cbacks) 844 { 845 if (p_buf != NULL) 846 bt_vendor_cbacks->dealloc(p_buf); 847 848 bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_FAIL); 849 } 850 851 if (hw_cfg_cb.fw_fd != -1) 852 { 853 close(hw_cfg_cb.fw_fd); 854 hw_cfg_cb.fw_fd = -1; 855 } 856 857 hw_cfg_cb.state = 0; 858 } 859 } 860 861 /****************************************************************************** 862 ** LPM Static Functions 863 ******************************************************************************/ 864 865 /******************************************************************************* 866 ** 867 ** Function hw_lpm_ctrl_cback 868 ** 869 ** Description Callback function for lpm enable/disable rquest 870 ** 871 ** Returns None 872 ** 873 *******************************************************************************/ 874 void hw_lpm_ctrl_cback(void *p_mem) 875 { 876 HC_BT_HDR *p_evt_buf = (HC_BT_HDR *) p_mem; 877 bt_vendor_op_result_t status = BT_VND_OP_RESULT_FAIL; 878 879 if (*((uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_STATUS_RET_BYTE) == 0) 880 { 881 status = BT_VND_OP_RESULT_SUCCESS; 882 } 883 884 if (bt_vendor_cbacks) 885 { 886 bt_vendor_cbacks->lpm_cb(status); 887 bt_vendor_cbacks->dealloc(p_evt_buf); 888 } 889 } 890 891 892 #if (SCO_CFG_INCLUDED == TRUE) 893 /***************************************************************************** 894 ** SCO Configuration Static Functions 895 *****************************************************************************/ 896 897 /******************************************************************************* 898 ** 899 ** Function hw_sco_cfg_cback 900 ** 901 ** Description Callback function for SCO configuration rquest 902 ** 903 ** Returns None 904 ** 905 *******************************************************************************/ 906 void hw_sco_cfg_cback(void *p_mem) 907 { 908 HC_BT_HDR *p_evt_buf = (HC_BT_HDR *) p_mem; 909 uint8_t *p; 910 uint16_t opcode; 911 HC_BT_HDR *p_buf=NULL; 912 913 p = (uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_OPCODE; 914 STREAM_TO_UINT16(opcode,p); 915 916 /* Free the RX event buffer */ 917 if (bt_vendor_cbacks) 918 bt_vendor_cbacks->dealloc(p_evt_buf); 919 920 #if (!defined(SCO_USE_I2S_INTERFACE) || (SCO_USE_I2S_INTERFACE == FALSE)) 921 if (opcode == HCI_VSC_WRITE_SCO_PCM_INT_PARAM) 922 { 923 uint8_t ret = FALSE; 924 925 /* Ask a new buffer to hold WRITE_PCM_DATA_FORMAT_PARAM command */ 926 if (bt_vendor_cbacks) 927 p_buf = (HC_BT_HDR *) bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE + \ 928 HCI_CMD_PREAMBLE_SIZE + \ 929 PCM_DATA_FORMAT_PARAM_SIZE); 930 if (p_buf) 931 { 932 p_buf->event = MSG_STACK_TO_HC_HCI_CMD; 933 p_buf->offset = 0; 934 p_buf->layer_specific = 0; 935 p_buf->len = HCI_CMD_PREAMBLE_SIZE + PCM_DATA_FORMAT_PARAM_SIZE; 936 937 p = (uint8_t *) (p_buf + 1); 938 UINT16_TO_STREAM(p, HCI_VSC_WRITE_PCM_DATA_FORMAT_PARAM); 939 *p++ = PCM_DATA_FORMAT_PARAM_SIZE; 940 memcpy(p, &bt_pcm_data_fmt_param, PCM_DATA_FORMAT_PARAM_SIZE); 941 942 if ((ret = bt_vendor_cbacks->xmit_cb(HCI_VSC_WRITE_PCM_DATA_FORMAT_PARAM,\ 943 p_buf, hw_sco_cfg_cback)) == FALSE) 944 { 945 bt_vendor_cbacks->dealloc(p_buf); 946 } 947 else 948 return; 949 } 950 } 951 #endif // !SCO_USE_I2S_INTERFACE 952 953 if (bt_vendor_cbacks) 954 bt_vendor_cbacks->scocfg_cb(BT_VND_OP_RESULT_SUCCESS); 955 } 956 #endif // SCO_CFG_INCLUDED 957 958 /***************************************************************************** 959 ** Hardware Configuration Interface Functions 960 *****************************************************************************/ 961 962 963 /******************************************************************************* 964 ** 965 ** Function hw_config_start 966 ** 967 ** Description Kick off controller initialization process 968 ** 969 ** Returns None 970 ** 971 *******************************************************************************/ 972 void hw_config_start(void) 973 { 974 HC_BT_HDR *p_buf = NULL; 975 uint8_t *p; 976 977 hw_cfg_cb.state = 0; 978 hw_cfg_cb.fw_fd = -1; 979 hw_cfg_cb.f_set_baud_2 = FALSE; 980 981 /* Start from sending HCI_RESET */ 982 983 if (bt_vendor_cbacks) 984 { 985 p_buf = (HC_BT_HDR *) bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE + \ 986 HCI_CMD_PREAMBLE_SIZE); 987 } 988 989 if (p_buf) 990 { 991 p_buf->event = MSG_STACK_TO_HC_HCI_CMD; 992 p_buf->offset = 0; 993 p_buf->layer_specific = 0; 994 p_buf->len = HCI_CMD_PREAMBLE_SIZE; 995 996 p = (uint8_t *) (p_buf + 1); 997 UINT16_TO_STREAM(p, HCI_RESET); 998 *p = 0; /* parameter length */ 999 1000 hw_cfg_cb.state = HW_CFG_START; 1001 1002 bt_vendor_cbacks->xmit_cb(HCI_RESET, p_buf, hw_config_cback); 1003 } 1004 else 1005 { 1006 if (bt_vendor_cbacks) 1007 { 1008 ALOGE("vendor lib fw conf aborted [no buffer]"); 1009 bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_FAIL); 1010 } 1011 } 1012 } 1013 1014 /******************************************************************************* 1015 ** 1016 ** Function hw_lpm_enable 1017 ** 1018 ** Description Enalbe/Disable LPM 1019 ** 1020 ** Returns TRUE/FALSE 1021 ** 1022 *******************************************************************************/ 1023 uint8_t hw_lpm_enable(uint8_t turn_on) 1024 { 1025 HC_BT_HDR *p_buf = NULL; 1026 uint8_t *p; 1027 uint8_t ret = FALSE; 1028 1029 if (bt_vendor_cbacks) 1030 p_buf = (HC_BT_HDR *) bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE + \ 1031 HCI_CMD_PREAMBLE_SIZE + \ 1032 LPM_CMD_PARAM_SIZE); 1033 1034 if (p_buf) 1035 { 1036 p_buf->event = MSG_STACK_TO_HC_HCI_CMD; 1037 p_buf->offset = 0; 1038 p_buf->layer_specific = 0; 1039 p_buf->len = HCI_CMD_PREAMBLE_SIZE + LPM_CMD_PARAM_SIZE; 1040 1041 p = (uint8_t *) (p_buf + 1); 1042 UINT16_TO_STREAM(p, HCI_VSC_WRITE_SLEEP_MODE); 1043 *p++ = LPM_CMD_PARAM_SIZE; /* parameter length */ 1044 1045 if (turn_on) 1046 { 1047 memcpy(p, &lpm_param, LPM_CMD_PARAM_SIZE); 1048 upio_set(UPIO_LPM_MODE, UPIO_ASSERT, 0); 1049 } 1050 else 1051 { 1052 memset(p, 0, LPM_CMD_PARAM_SIZE); 1053 upio_set(UPIO_LPM_MODE, UPIO_DEASSERT, 0); 1054 } 1055 1056 if ((ret = bt_vendor_cbacks->xmit_cb(HCI_VSC_WRITE_SLEEP_MODE, p_buf, \ 1057 hw_lpm_ctrl_cback)) == FALSE) 1058 { 1059 bt_vendor_cbacks->dealloc(p_buf); 1060 } 1061 } 1062 1063 if ((ret == FALSE) && bt_vendor_cbacks) 1064 bt_vendor_cbacks->lpm_cb(BT_VND_OP_RESULT_FAIL); 1065 1066 return ret; 1067 } 1068 1069 /******************************************************************************* 1070 ** 1071 ** Function hw_lpm_get_idle_timeout 1072 ** 1073 ** Description Calculate idle time based on host stack idle threshold 1074 ** 1075 ** Returns idle timeout value 1076 ** 1077 *******************************************************************************/ 1078 uint32_t hw_lpm_get_idle_timeout(void) 1079 { 1080 uint32_t timeout_ms; 1081 1082 /* set idle time to be LPM_IDLE_TIMEOUT_MULTIPLE times of 1083 * host stack idle threshold (in 300ms/25ms) 1084 */ 1085 timeout_ms = (uint32_t)lpm_param.host_stack_idle_threshold \ 1086 * LPM_IDLE_TIMEOUT_MULTIPLE; 1087 1088 if (strstr(hw_cfg_cb.local_chip_name, "BCM4325") != NULL) 1089 timeout_ms *= 25; // 12.5 or 25 ? 1090 else 1091 timeout_ms *= 300; 1092 1093 return timeout_ms; 1094 } 1095 1096 /******************************************************************************* 1097 ** 1098 ** Function hw_lpm_set_wake_state 1099 ** 1100 ** Description Assert/Deassert BT_WAKE 1101 ** 1102 ** Returns None 1103 ** 1104 *******************************************************************************/ 1105 void hw_lpm_set_wake_state(uint8_t wake_assert) 1106 { 1107 uint8_t state = (wake_assert) ? UPIO_ASSERT : UPIO_DEASSERT; 1108 1109 upio_set(UPIO_BT_WAKE, state, lpm_param.bt_wake_polarity); 1110 } 1111 1112 #if (SCO_CFG_INCLUDED == TRUE) 1113 /******************************************************************************* 1114 ** 1115 ** Function hw_sco_config 1116 ** 1117 ** Description Configure SCO related hardware settings 1118 ** 1119 ** Returns None 1120 ** 1121 *******************************************************************************/ 1122 void hw_sco_config(void) 1123 { 1124 HC_BT_HDR *p_buf = NULL; 1125 uint8_t *p, ret; 1126 1127 #if (!defined(SCO_USE_I2S_INTERFACE) || (SCO_USE_I2S_INTERFACE == FALSE)) 1128 uint16_t cmd_u16 = HCI_CMD_PREAMBLE_SIZE + SCO_PCM_PARAM_SIZE; 1129 #else 1130 uint16_t cmd_u16 = HCI_CMD_PREAMBLE_SIZE + SCO_I2SPCM_PARAM_SIZE; 1131 #endif 1132 1133 if (bt_vendor_cbacks) 1134 p_buf = (HC_BT_HDR *) bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE+cmd_u16); 1135 1136 if (p_buf) 1137 { 1138 p_buf->event = MSG_STACK_TO_HC_HCI_CMD; 1139 p_buf->offset = 0; 1140 p_buf->layer_specific = 0; 1141 p_buf->len = cmd_u16; 1142 1143 p = (uint8_t *) (p_buf + 1); 1144 #if (!defined(SCO_USE_I2S_INTERFACE) || (SCO_USE_I2S_INTERFACE == FALSE)) 1145 UINT16_TO_STREAM(p, HCI_VSC_WRITE_SCO_PCM_INT_PARAM); 1146 *p++ = SCO_PCM_PARAM_SIZE; 1147 memcpy(p, &bt_sco_param, SCO_PCM_PARAM_SIZE); 1148 cmd_u16 = HCI_VSC_WRITE_SCO_PCM_INT_PARAM; 1149 ALOGI("SCO PCM configure {%d, %d, %d, %d, %d}", 1150 bt_sco_param[0], bt_sco_param[1], bt_sco_param[2], bt_sco_param[3], \ 1151 bt_sco_param[4]); 1152 1153 #else 1154 UINT16_TO_STREAM(p, HCI_VSC_WRITE_I2SPCM_INTERFACE_PARAM); 1155 *p++ = SCO_I2SPCM_PARAM_SIZE; 1156 memcpy(p, &bt_sco_param, SCO_I2SPCM_PARAM_SIZE); 1157 cmd_u16 = HCI_VSC_WRITE_I2SPCM_INTERFACE_PARAM; 1158 ALOGI("SCO over I2SPCM interface {%d, %d, %d, %d}", 1159 bt_sco_param[0], bt_sco_param[1], bt_sco_param[2], bt_sco_param[3]); 1160 #endif 1161 1162 if ((ret=bt_vendor_cbacks->xmit_cb(cmd_u16, p_buf, hw_sco_cfg_cback)) \ 1163 == FALSE) 1164 { 1165 bt_vendor_cbacks->dealloc(p_buf); 1166 } 1167 else 1168 return; 1169 } 1170 1171 if (bt_vendor_cbacks) 1172 { 1173 ALOGE("vendor lib scocfg aborted"); 1174 bt_vendor_cbacks->scocfg_cb(BT_VND_OP_RESULT_FAIL); 1175 } 1176 } 1177 #endif // SCO_CFG_INCLUDED 1178 1179 /******************************************************************************* 1180 ** 1181 ** Function hw_set_patch_file_path 1182 ** 1183 ** Description Set the location of firmware patch file 1184 ** 1185 ** Returns 0 : Success 1186 ** Otherwise : Fail 1187 ** 1188 *******************************************************************************/ 1189 int hw_set_patch_file_path(char *p_conf_name, char *p_conf_value, int param) 1190 { 1191 1192 strcpy(fw_patchfile_path, p_conf_value); 1193 1194 return 0; 1195 } 1196 1197 /******************************************************************************* 1198 ** 1199 ** Function hw_set_patch_file_name 1200 ** 1201 ** Description Give the specific firmware patch filename 1202 ** 1203 ** Returns 0 : Success 1204 ** Otherwise : Fail 1205 ** 1206 *******************************************************************************/ 1207 int hw_set_patch_file_name(char *p_conf_name, char *p_conf_value, int param) 1208 { 1209 1210 strcpy(fw_patchfile_name, p_conf_value); 1211 1212 return 0; 1213 } 1214 1215 #if (VENDOR_LIB_RUNTIME_TUNING_ENABLED == TRUE) 1216 /******************************************************************************* 1217 ** 1218 ** Function hw_set_patch_settlement_delay 1219 ** 1220 ** Description Give the specific firmware patch settlement time in milliseconds 1221 ** 1222 ** Returns 0 : Success 1223 ** Otherwise : Fail 1224 ** 1225 *******************************************************************************/ 1226 int hw_set_patch_settlement_delay(char *p_conf_name, char *p_conf_value, int param) 1227 { 1228 fw_patch_settlement_delay = atoi(p_conf_value); 1229 1230 return 0; 1231 } 1232 #endif //VENDOR_LIB_RUNTIME_TUNING_ENABLED 1233 1234 /***************************************************************************** 1235 ** Sample Codes Section 1236 *****************************************************************************/ 1237 1238 #if (HW_END_WITH_HCI_RESET == TRUE) 1239 /******************************************************************************* 1240 ** 1241 ** Function hw_epilog_cback 1242 ** 1243 ** Description Callback function for Command Complete Events from HCI 1244 ** commands sent in epilog process. 1245 ** 1246 ** Returns None 1247 ** 1248 *******************************************************************************/ 1249 void hw_epilog_cback(void *p_mem) 1250 { 1251 HC_BT_HDR *p_evt_buf = (HC_BT_HDR *) p_mem; 1252 uint8_t *p, status; 1253 uint16_t opcode; 1254 1255 status = *((uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_STATUS_RET_BYTE); 1256 p = (uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_OPCODE; 1257 STREAM_TO_UINT16(opcode,p); 1258 1259 BTHWDBG("%s Opcode:0x%04X Status: %d", __FUNCTION__, opcode, status); 1260 1261 if (bt_vendor_cbacks) 1262 { 1263 /* Must free the RX event buffer */ 1264 bt_vendor_cbacks->dealloc(p_evt_buf); 1265 1266 /* Once epilog process is done, must call epilog_cb callback 1267 to notify caller */ 1268 bt_vendor_cbacks->epilog_cb(BT_VND_OP_RESULT_SUCCESS); 1269 } 1270 } 1271 1272 /******************************************************************************* 1273 ** 1274 ** Function hw_epilog_process 1275 ** 1276 ** Description Sample implementation of epilog process 1277 ** 1278 ** Returns None 1279 ** 1280 *******************************************************************************/ 1281 void hw_epilog_process(void) 1282 { 1283 HC_BT_HDR *p_buf = NULL; 1284 uint8_t *p; 1285 1286 BTHWDBG("hw_epilog_process"); 1287 1288 /* Sending a HCI_RESET */ 1289 if (bt_vendor_cbacks) 1290 { 1291 /* Must allocate command buffer via HC's alloc API */ 1292 p_buf = (HC_BT_HDR *) bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE + \ 1293 HCI_CMD_PREAMBLE_SIZE); 1294 } 1295 1296 if (p_buf) 1297 { 1298 p_buf->event = MSG_STACK_TO_HC_HCI_CMD; 1299 p_buf->offset = 0; 1300 p_buf->layer_specific = 0; 1301 p_buf->len = HCI_CMD_PREAMBLE_SIZE; 1302 1303 p = (uint8_t *) (p_buf + 1); 1304 UINT16_TO_STREAM(p, HCI_RESET); 1305 *p = 0; /* parameter length */ 1306 1307 /* Send command via HC's xmit_cb API */ 1308 bt_vendor_cbacks->xmit_cb(HCI_RESET, p_buf, hw_epilog_cback); 1309 } 1310 else 1311 { 1312 if (bt_vendor_cbacks) 1313 { 1314 ALOGE("vendor lib epilog process aborted [no buffer]"); 1315 bt_vendor_cbacks->epilog_cb(BT_VND_OP_RESULT_FAIL); 1316 } 1317 } 1318 } 1319 #endif // (HW_END_WITH_HCI_RESET == TRUE) 1320