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